From 7038f0700898a17cb87b5a2e408480c1226a47f4 Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Mon, 16 Feb 2026 10:28:01 +0000 Subject: [PATCH 01/12] perf: switch to clack for CLI prompts (#14589) * perf: switch to clack spinner This is an incremental change as part of the wider move to clack. * perf: switch to clack for box rendering Switches to using clack for rendering boxes in the terminal. Part of the wider migration to clack. * perf: switch to clack for confirm prompts Switches to using clack for confirm prompts rather than `prompts` package. Part of the wider clack migration. * chore: use new spinner API * chore: use bold confirm messages * fix * fix * upgrade clack * update clack * improve * improve * changeset --------- Co-authored-by: Florian Lefebvre --- .changeset/tall-worms-live.md | 6 + packages/astro/package.json | 5 +- packages/astro/src/cli/add/index.ts | 102 +++++++------- packages/astro/src/cli/index.ts | 6 +- .../{prompts-prompt.ts => clack-prompt.ts} | 14 +- packages/astro/src/cli/install-package.ts | 37 +++--- packages/db/package.json | 3 +- .../db/src/core/cli/commands/push/index.ts | 11 +- pnpm-lock.yaml | 124 ++++-------------- 9 files changed, 110 insertions(+), 198 deletions(-) create mode 100644 .changeset/tall-worms-live.md rename packages/astro/src/cli/info/infra/{prompts-prompt.ts => clack-prompt.ts} (57%) diff --git a/.changeset/tall-worms-live.md b/.changeset/tall-worms-live.md new file mode 100644 index 000000000000..cc7e0bc676dc --- /dev/null +++ b/.changeset/tall-worms-live.md @@ -0,0 +1,6 @@ +--- +'astro': patch +'@astrojs/db': patch +--- + +Improves CLI styling diff --git a/packages/astro/package.json b/packages/astro/package.json index f4ae18f1ee60..3ca3ac051683 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -121,11 +121,11 @@ "@astrojs/markdown-remark": "workspace:*", "@astrojs/telemetry": "workspace:*", "@capsizecss/unpack": "^4.0.0", + "@clack/prompts": "^1.0.1", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.3.0", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", - "boxen": "8.0.1", "ci-info": "^4.4.0", "clsx": "^2.1.1", "common-ancestor-path": "^2.0.0", @@ -154,7 +154,6 @@ "package-manager-detector": "^1.6.0", "piccolore": "^0.1.3", "picomatch": "^4.0.3", - "prompts": "^2.4.2", "rehype": "^13.0.2", "semver": "^7.7.3", "shiki": "^3.22.0", @@ -172,7 +171,6 @@ "vitefu": "^1.1.1", "xxhash-wasm": "^1.1.0", "yargs-parser": "^22.0.0", - "yocto-spinner": "^1.0.0", "zod": "^4.3.6" }, "optionalDependencies": { @@ -190,7 +188,6 @@ "@types/http-cache-semantics": "^4.2.0", "@types/js-yaml": "^4.0.9", "@types/picomatch": "^4.0.2", - "@types/prompts": "^2.4.9", "@types/semver": "^7.7.1", "@types/yargs-parser": "^21.0.3", "astro-scripts": "workspace:*", diff --git a/packages/astro/src/cli/add/index.ts b/packages/astro/src/cli/add/index.ts index 001ed0e1d5e8..d00c226df0c8 100644 --- a/packages/astro/src/cli/add/index.ts +++ b/packages/astro/src/cli/add/index.ts @@ -2,17 +2,15 @@ import fsMod, { existsSync, promises as fs } from 'node:fs'; import { createRequire } from 'node:module'; import path from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; +import * as clack from '@clack/prompts'; import { assertValidPackageName } from '@astrojs/internal-helpers/cli'; -import boxen from 'boxen'; import { diffWords } from 'diff'; import { type ASTNode, builders, generateCode, loadFile, type ProxifiedModule } from 'magicast'; import { getDefaultExportOptions } from 'magicast/helpers'; import { detect, resolveCommand } from 'package-manager-detector'; import colors from 'piccolore'; -import prompts from 'prompts'; import maxSatisfying from 'semver/ranges/max-satisfying.js'; import type yargsParser from 'yargs-parser'; -import yoctoSpinner from 'yocto-spinner'; import { loadTSConfig, resolveConfig, @@ -484,19 +482,21 @@ export async function add(names: string[], { flags }: AddOptions) { ), ); if (integrations.find((integration) => integration.integrationName === 'tailwind')) { - const code = boxen(getDiffContent('---\n---', "---\nimport '../styles/global.css'\n---")!, { - margin: 0.5, - padding: 0.5, - borderStyle: 'round', - title: 'src/layouts/Layout.astro', - }); logger.warn( 'SKIP_FORMAT', msg.actionRequired( 'You must import your Tailwind stylesheet, e.g. in a shared layout:\n', ), ); - logger.info('SKIP_FORMAT', code + '\n'); + clack.box( + getDiffContent('---\n---', "---\nimport '../styles/global.css'\n---")!, + 'src/layouts/Layout.astro', + { + rounded: true, + withGuide: false, + width: 'auto', + }, + ); } } } @@ -684,18 +684,17 @@ async function updateAstroConfig({ return UpdateResult.none; } - const message = `\n${boxen(diff, { - margin: 0.5, - padding: 0.5, - borderStyle: 'round', - title: configURL.pathname.split('/').pop(), - })}\n`; - logger.info( 'SKIP_FORMAT', - `\n ${magenta('Astro will make the following changes to your config file:')}\n${message}`, + `\n ${magenta('Astro will make the following changes to your config file:')}`, ); + clack.box(diff, configURL.pathname.split('/').pop(), { + rounded: true, + withGuide: false, + width: 'auto', + }); + if (logAdapterInstructions) { logger.info( 'SKIP_FORMAT', @@ -757,18 +756,17 @@ async function updatePackageJsonScripts({ return UpdateResult.none; } - const message = `\n${boxen(diff, { - margin: 0.5, - padding: 0.5, - borderStyle: 'round', - title: 'package.json', - })}\n`; - logger.info( 'SKIP_FORMAT', - `\n ${magenta('Astro will add the following scripts to your package.json:')}\n${message}`, + `\n ${magenta('Astro will add the following scripts to your package.json:')}`, ); + clack.box(diff, 'package.json', { + rounded: true, + withGuide: false, + width: 'auto', + }); + if (await askToContinue({ flags, logger })) { await fs.writeFile(pkgPath, output, { encoding: 'utf-8' }); logger.debug('add', 'Updated package.json scripts'); @@ -861,20 +859,21 @@ async function tryToInstallIntegrations({ ); const coloredOutput = `${bold(installCommand.command)} ${installCommand.args.join(' ')} ${cyan(installSpecifiers.join(' '))}`; - const message = `\n${boxen(coloredOutput, { - margin: 0.5, - padding: 0.5, - borderStyle: 'round', - })}\n`; logger.info( 'SKIP_FORMAT', `\n ${magenta('Astro will run the following command:')}\n ${dim( 'If you skip this step, you can always run it yourself later', - )}\n${message}`, + )}`, ); + clack.box(coloredOutput, undefined, { + rounded: true, + withGuide: false, + width: 'auto', + }); if (await askToContinue({ flags, logger })) { - const spinner = yoctoSpinner({ text: 'Installing dependencies...' }).start(); + const spinner = clack.spinner({ withGuide: false }); + spinner.start('Installing dependencies...'); try { await exec(installCommand.command, [...installCommand.args, ...installSpecifiers], { nodeOptions: { @@ -883,10 +882,10 @@ async function tryToInstallIntegrations({ env: { NODE_ENV: undefined }, }, }); - spinner.success(); + spinner.stop('Dependencies installed.'); return UpdateResult.updated; } catch (err: any) { - spinner.error(); + spinner.error('Error installing dependencies.'); logger.debug('add', 'Error installing dependencies', err); // NOTE: `err.stdout` can be an empty string, so log the full error instead for a more helpful log console.error('\n', err.stdout || err.message, '\n'); @@ -907,7 +906,8 @@ async function validateIntegrations( assertValidPackageName(integration); } - const spinner = yoctoSpinner({ text: 'Resolving packages...' }).start(); + const spinner = clack.spinner({ withGuide: false }); + spinner.start('Resolving packages...'); try { const integrationEntries = await Promise.all( integrations.map(async (integration): Promise => { @@ -925,9 +925,9 @@ async function validateIntegrations( const firstPartyPkgCheck = await fetchPackageJson('@astrojs', name, tag); if (firstPartyPkgCheck instanceof Error) { if (firstPartyPkgCheck.message) { - spinner.warning(yellow(firstPartyPkgCheck.message)); + spinner.message(yellow(firstPartyPkgCheck.message)); } - spinner.warning(yellow(`${bold(integration)} is not an official Astro package.`)); + spinner.message(yellow(`${bold(integration)} is not an official Astro package.`)); if (!(await askToContinue({ flags, logger }))) { throw new Error( `No problem! Find our official integrations at ${cyan( @@ -935,7 +935,7 @@ async function validateIntegrations( )}`, ); } - spinner.start('Resolving with third party packages...'); + spinner.message('Resolving with third party packages...'); pkgType = 'third-party'; } else { pkgType = 'first-party'; @@ -946,7 +946,7 @@ async function validateIntegrations( const thirdPartyPkgCheck = await fetchPackageJson(scope, name, tag); if (thirdPartyPkgCheck instanceof Error) { if (thirdPartyPkgCheck.message) { - spinner.warning(yellow(thirdPartyPkgCheck.message)); + spinner.message(yellow(thirdPartyPkgCheck.message)); } throw new Error(`Unable to fetch ${bold(integration)}. Does the package exist?`); } else { @@ -1004,7 +1004,7 @@ async function validateIntegrations( }; }), ); - spinner.success(); + spinner.stop('Resolved packages.'); return integrationEntries; } catch (e) { if (e instanceof Error) { @@ -1071,16 +1071,9 @@ async function updateTSConfig( return UpdateResult.none; } - const message = `\n${boxen(diff, { - margin: 0.5, - padding: 0.5, - borderStyle: 'round', - title: configFileName, - })}\n`; - logger.info( 'SKIP_FORMAT', - `\n ${magenta(`Astro will make the following changes to your ${configFileName}:`)}\n${message}`, + `\n ${magenta(`Astro will make the following changes to your ${configFileName}:`)}`, ); if (firstIntegrationWithTSSettings) { @@ -1150,14 +1143,13 @@ async function askToContinue({ hasHintedAboutYesFlag = true; logger.info('SKIP_FORMAT', dim(' To run this command without prompts, pass the --yes flag\n')); } - const response = await prompts({ - type: 'confirm', - name: 'askToContinue', - message: 'Continue?', - initial: true, + const response = await clack.confirm({ + message: colors.bold('Continue?'), + initialValue: true, + withGuide: false, }); - return Boolean(response.askToContinue); + return response === true; } function getDiffContent(input: string, output: string): string | null { diff --git a/packages/astro/src/cli/index.ts b/packages/astro/src/cli/index.ts index f4b650b52fa4..76866a0d5d0b 100644 --- a/packages/astro/src/cli/index.ts +++ b/packages/astro/src/cli/index.ts @@ -101,7 +101,7 @@ async function runCommand(cmd: string, flags: yargs.Arguments) { { TinyexecCommandExecutor }, { getPackageManager }, { StyledDebugInfoFormatter }, - { PromptsPrompt }, + { ClackPrompt }, { CliClipboard }, { PassthroughTextStyler }, { infoCommand }, @@ -114,7 +114,7 @@ async function runCommand(cmd: string, flags: yargs.Arguments) { import('./infra/tinyexec-command-executor.js'), import('./info/core/get-package-manager.js'), import('./info/infra/styled-debug-info-formatter.js'), - import('./info/infra/prompts-prompt.js'), + import('./info/infra/clack-prompt.js'), import('./info/infra/cli-clipboard.js'), import('./infra/passthrough-text-styler.js'), import('./info/core/info.js'), @@ -134,7 +134,7 @@ async function runCommand(cmd: string, flags: yargs.Arguments) { }), nodeVersionProvider, }); - const prompt = new PromptsPrompt({ force: flags.copy }); + const prompt = new ClackPrompt({ force: flags.copy }); const clipboard = new CliClipboard({ commandExecutor, logger, diff --git a/packages/astro/src/cli/info/infra/prompts-prompt.ts b/packages/astro/src/cli/info/infra/clack-prompt.ts similarity index 57% rename from packages/astro/src/cli/info/infra/prompts-prompt.ts rename to packages/astro/src/cli/info/infra/clack-prompt.ts index e46934492c22..56217532f4e3 100644 --- a/packages/astro/src/cli/info/infra/prompts-prompt.ts +++ b/packages/astro/src/cli/info/infra/clack-prompt.ts @@ -1,7 +1,7 @@ -import prompts from 'prompts'; +import { confirm } from '@clack/prompts'; import type { Prompt } from '../definitions.js'; -export class PromptsPrompt implements Prompt { +export class ClackPrompt implements Prompt { readonly #force: boolean; constructor({ force }: { force: boolean }) { @@ -18,12 +18,12 @@ export class PromptsPrompt implements Prompt { if (this.#force) { return true; } - const { value } = await prompts({ - type: 'confirm', - name: 'value', + const response = await confirm({ message, - initial: defaultValue, + initialValue: defaultValue, + withGuide: false, }); - return value; + // Response is a symbol when cancelled + return response === true; } } diff --git a/packages/astro/src/cli/install-package.ts b/packages/astro/src/cli/install-package.ts index 9910f2a54bda..495c6d2abbbc 100644 --- a/packages/astro/src/cli/install-package.ts +++ b/packages/astro/src/cli/install-package.ts @@ -1,10 +1,8 @@ import { createRequire } from 'node:module'; -import boxen from 'boxen'; +import * as clack from '@clack/prompts'; import ci from 'ci-info'; import { detect, resolveCommand } from 'package-manager-detector'; import colors from 'piccolore'; -import prompts from 'prompts'; -import yoctoSpinner from 'yocto-spinner'; import type { Logger } from '../core/logger/core.js'; import { exec } from './exec.js'; @@ -76,34 +74,33 @@ async function installPackage( packageNames = packageNames.map((name) => `npm:${name}`); } const coloredOutput = `${bold(installCommand.command)} ${installCommand.args.join(' ')} ${cyan(packageNames.join(' '))}`; - const message = `\n${boxen(coloredOutput, { - margin: 0.5, - padding: 0.5, - borderStyle: 'round', - })}\n`; logger.info( 'SKIP_FORMAT', `\n ${magenta('Astro will run the following command:')}\n ${dim( 'If you skip this step, you can always run it yourself later', - )}\n${message}`, + )}`, ); + clack.box(coloredOutput, undefined, { + rounded: true, + withGuide: false, + width: 'auto', + }); let response; if (options.skipAsk) { response = true; } else { - response = ( - await prompts({ - type: 'confirm', - name: 'askToContinue', - message: 'Continue?', - initial: true, - }) - ).askToContinue; + response = + (await clack.confirm({ + message: colors.bold('Continue?'), + initialValue: true, + withGuide: false, + })) === true; } if (Boolean(response)) { - const spinner = yoctoSpinner({ text: 'Installing dependencies...' }).start(); + const spinner = clack.spinner({ withGuide: false }); + spinner.start('Installing dependencies...'); try { await exec(installCommand.command, [...installCommand.args, ...packageNames], { nodeOptions: { @@ -112,12 +109,12 @@ async function installPackage( env: { NODE_ENV: undefined }, }, }); - spinner.success(); + spinner.stop('Dependencies installed.'); return true; } catch (err) { logger.debug('add', 'Error installing dependencies', err); - spinner.error(); + spinner.error('Failed to install dependencies.'); return false; } diff --git a/packages/db/package.json b/packages/db/package.json index 01f885f8482d..b69520fef98c 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -72,18 +72,17 @@ "test:types": "tsc --project test/types/tsconfig.json" }, "dependencies": { + "@clack/prompts": "^1.0.1", "@libsql/client": "^0.17.0", "deep-diff": "^1.0.2", "drizzle-orm": "^0.42.0", "nanoid": "^5.1.6", "piccolore": "^0.1.3", - "prompts": "^2.4.2", "yargs-parser": "^22.0.0", "zod": "^4.3.6" }, "devDependencies": { "@types/deep-diff": "^1.0.5", - "@types/prompts": "^2.4.9", "@types/yargs-parser": "^21.0.3", "astro": "workspace:*", "astro-scripts": "workspace:*", diff --git a/packages/db/src/core/cli/commands/push/index.ts b/packages/db/src/core/cli/commands/push/index.ts index a9781af37ae7..6223394fabe1 100644 --- a/packages/db/src/core/cli/commands/push/index.ts +++ b/packages/db/src/core/cli/commands/push/index.ts @@ -1,6 +1,6 @@ +import * as clack from '@clack/prompts'; import type { AstroConfig } from 'astro'; import { sql } from 'drizzle-orm'; -import prompts from 'prompts'; import type { Arguments } from 'yargs-parser'; import { MIGRATION_VERSION } from '../../../consts.js'; import { createClient } from '../../../db-client/libsql-node.js'; @@ -47,14 +47,13 @@ export async function cmd({ } if (isForceReset) { - const { begin } = await prompts({ - type: 'confirm', - name: 'begin', + const begin = await clack.confirm({ message: `Reset your database? All of your data will be erased and your schema created from scratch.`, - initial: false, + initialValue: false, + withGuide: false, }); - if (!begin) { + if (begin !== true) { console.log('Canceled.'); process.exit(0); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d6d3add58ebd..47f97bd98fc5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -517,6 +517,9 @@ importers: '@capsizecss/unpack': specifier: ^4.0.0 version: 4.0.0 + '@clack/prompts': + specifier: ^1.0.1 + version: 1.0.1 '@oslojs/encoding': specifier: ^1.1.0 version: 1.1.0 @@ -529,9 +532,6 @@ importers: axobject-query: specifier: ^4.1.0 version: 4.1.0 - boxen: - specifier: 8.0.1 - version: 8.0.1 ci-info: specifier: ^4.4.0 version: 4.4.0 @@ -616,9 +616,6 @@ importers: picomatch: specifier: ^4.0.3 version: 4.0.3 - prompts: - specifier: ^2.4.2 - version: 2.4.2 rehype: specifier: ^13.0.2 version: 13.0.2 @@ -670,9 +667,6 @@ importers: yargs-parser: specifier: ^22.0.0 version: 22.0.0 - yocto-spinner: - specifier: ^1.0.0 - version: 1.0.0 zod: specifier: ^4.3.6 version: 4.3.6 @@ -710,9 +704,6 @@ importers: '@types/picomatch': specifier: ^4.0.2 version: 4.0.2 - '@types/prompts': - specifier: ^2.4.9 - version: 2.4.9 '@types/semver': specifier: ^7.7.1 version: 7.7.1 @@ -4677,6 +4668,9 @@ importers: packages/db: dependencies: + '@clack/prompts': + specifier: ^1.0.1 + version: 1.0.1 '@libsql/client': specifier: ^0.17.0 version: 0.17.0 @@ -4692,9 +4686,6 @@ importers: piccolore: specifier: ^0.1.3 version: 0.1.3 - prompts: - specifier: ^2.4.2 - version: 2.4.2 yargs-parser: specifier: ^22.0.0 version: 22.0.0 @@ -4705,9 +4696,6 @@ importers: '@types/deep-diff': specifier: ^1.0.5 version: 1.0.5 - '@types/prompts': - specifier: ^2.4.9 - version: 2.4.9 '@types/yargs-parser': specifier: ^21.0.3 version: 21.0.3 @@ -7581,11 +7569,17 @@ packages: '@clack/core@0.3.5': resolution: {integrity: sha512-5cfhQNH+1VQ2xLQlmzXMqUoiaH0lRBq9/CLW9lTyMbuKLC3+xEK01tHVvyut++mLOn5urSHmkm6I0Lg9MaJSTQ==} + '@clack/core@1.0.1': + resolution: {integrity: sha512-WKeyK3NOBwDOzagPR5H08rFk9D/WuN705yEbuZvKqlkmoLM2woKtXb10OO2k1NoSU4SFG947i2/SCYh+2u5e4g==} + '@clack/prompts@0.7.0': resolution: {integrity: sha512-0MhX9/B4iL6Re04jPrttDm+BsP8y6mS7byuv0BvXgdXhbV5PdlsHt55dvNsuBCPZ7xq1oTAOOuotR9NFbQyMSA==} bundledDependencies: - is-unicode-supported + '@clack/prompts@1.0.1': + resolution: {integrity: sha512-/42G73JkuYdyWZ6m8d/CJtBrGl1Hegyc7Fy78m5Ob+jF85TOUmLR5XLce/U3LxYAw0kJ8CT5aI99RIvPHcGp/Q==} + '@cloudflare/kv-asset-handler@0.4.2': resolution: {integrity: sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ==} engines: {node: '>=18.0.0'} @@ -10256,9 +10250,6 @@ packages: '@types/prismjs@1.26.6': resolution: {integrity: sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw==} - '@types/prompts@2.4.9': - resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==} - '@types/prop-types@15.7.15': resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} @@ -10840,9 +10831,6 @@ packages: alpinejs@3.15.8: resolution: {integrity: sha512-zxIfCRTBGvF1CCLIOMQOxAyBuqibxSEwS6Jm1a3HGA9rgrJVcjEWlwLcQTVGAWGS8YhAsTRLVrtQ5a5QT9bSSQ==} - ansi-align@3.0.1: - resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} - ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -11080,10 +11068,6 @@ packages: boundary@2.0.0: resolution: {integrity: sha512-rJKn5ooC9u8q13IMCrW0RSp31pxBCHE3y9V/tp3TdWSLf8Em3p6Di4NBpfzbJge9YjjFEsD0RtFEjtvHL5VyEA==} - boxen@8.0.1: - resolution: {integrity: sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==} - engines: {node: '>=18'} - brace-expansion@1.1.12: resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} @@ -11166,10 +11150,6 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - camelcase@8.0.0: - resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} - engines: {node: '>=16'} - caniuse-lite@1.0.30001767: resolution: {integrity: sha512-34+zUAMhSH+r+9eKmYG+k2Rpt8XttfE4yXAjoZvkAPs15xcYQhyBYdalJ65BzivAvGRMViEjy6oKr/S91loekQ==} @@ -11264,10 +11244,6 @@ packages: cjs-module-lexer@1.4.3: resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} - cli-boxes@3.0.0: - resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} - engines: {node: '>=10'} - cli-cursor@4.0.0: resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -13025,10 +13001,6 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - kleur@4.1.5: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} @@ -14414,10 +14386,6 @@ packages: promise-limit@2.7.0: resolution: {integrity: sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==} - prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - property-information@6.5.0: resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} @@ -16225,10 +16193,6 @@ packages: wicked-good-xpath@1.3.0: resolution: {integrity: sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw==} - widest-line@5.0.0: - resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} - engines: {node: '>=18'} - winston-transport@4.9.0: resolution: {integrity: sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==} engines: {node: '>= 12.0.0'} @@ -16271,10 +16235,6 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} - wrap-ansi@9.0.2: - resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} - engines: {node: '>=18'} - wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -16403,10 +16363,6 @@ packages: resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==} engines: {node: '>=12.20'} - yocto-spinner@1.0.0: - resolution: {integrity: sha512-VPX8P/+Z2Fnpx8PC/JELbxp3QRrBxjAekio6yulGtA5gKt9YyRc5ycCb+NHgZCbZ0kx9KxwZp7gC6UlrCcCdSQ==} - engines: {node: '>=18.19'} - yoctocolors@2.1.2: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} @@ -17182,12 +17138,23 @@ snapshots: picocolors: 1.1.1 sisteransi: 1.0.5 + '@clack/core@1.0.1': + dependencies: + picocolors: 1.1.1 + sisteransi: 1.0.5 + '@clack/prompts@0.7.0': dependencies: '@clack/core': 0.3.5 picocolors: 1.1.1 sisteransi: 1.0.5 + '@clack/prompts@1.0.1': + dependencies: + '@clack/core': 1.0.1 + picocolors: 1.1.1 + sisteransi: 1.0.5 + '@cloudflare/kv-asset-handler@0.4.2': {} '@cloudflare/unenv-preset@2.12.0(unenv@2.0.0-rc.24)(workerd@1.20260131.0)': @@ -19594,11 +19561,6 @@ snapshots: '@types/prismjs@1.26.6': {} - '@types/prompts@2.4.9': - dependencies: - '@types/node': 18.19.130 - kleur: 3.0.3 - '@types/prop-types@15.7.15': {} '@types/react-dom@18.3.7(@types/react@18.3.28)': @@ -20446,10 +20408,6 @@ snapshots: dependencies: '@vue/reactivity': 3.1.5 - ansi-align@3.0.1: - dependencies: - string-width: 4.2.3 - ansi-colors@4.1.3: {} ansi-escapes@5.0.0: @@ -20705,17 +20663,6 @@ snapshots: boundary@2.0.0: {} - boxen@8.0.1: - dependencies: - ansi-align: 3.0.1 - camelcase: 8.0.0 - chalk: 5.6.2 - cli-boxes: 3.0.0 - string-width: 7.2.0 - type-fest: 4.41.0 - widest-line: 5.0.0 - wrap-ansi: 9.0.2 - brace-expansion@1.1.12: dependencies: balanced-match: 1.0.2 @@ -20797,8 +20744,6 @@ snapshots: camelcase@6.3.0: {} - camelcase@8.0.0: {} - caniuse-lite@1.0.30001767: {} canvas-confetti@1.9.4: {} @@ -20902,8 +20847,6 @@ snapshots: cjs-module-lexer@1.4.3: {} - cli-boxes@3.0.0: {} - cli-cursor@4.0.0: dependencies: restore-cursor: 4.0.0 @@ -22802,8 +22745,6 @@ snapshots: dependencies: json-buffer: 3.0.1 - kleur@3.0.3: {} - kleur@4.1.5: {} knip@5.82.1(@types/node@18.19.130)(typescript@5.9.3): @@ -24567,11 +24508,6 @@ snapshots: promise-limit@2.7.0: {} - prompts@2.4.2: - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - property-information@6.5.0: {} property-information@7.1.0: {} @@ -26621,10 +26557,6 @@ snapshots: wicked-good-xpath@1.3.0: {} - widest-line@5.0.0: - dependencies: - string-width: 7.2.0 - winston-transport@4.9.0: dependencies: logform: 2.7.0 @@ -26692,12 +26624,6 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.1.2 - wrap-ansi@9.0.2: - dependencies: - ansi-styles: 6.2.3 - string-width: 7.2.0 - strip-ansi: 7.1.2 - wrappy@1.0.2: {} write-file-atomic@5.0.1: @@ -26820,10 +26746,6 @@ snapshots: yocto-queue@1.2.1: {} - yocto-spinner@1.0.0: - dependencies: - yoctocolors: 2.1.2 - yoctocolors@2.1.2: {} youch-core@0.3.3: From 6c932012e6b7b2fcb53169fe6abf478393018973 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 11:28:14 +0100 Subject: [PATCH 02/12] fix(deps): update astro client runtimes (#15530) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/integrations/preact/package.json | 2 +- packages/integrations/react/package.json | 4 +- .../fixtures/react-component/package.json | 2 +- packages/integrations/svelte/package.json | 2 +- .../fixtures/async-rendering/package.json | 2 +- .../conditional-rendering/package.json | 2 +- .../test/fixtures/prop-types/package.json | 2 +- packages/integrations/vue/package.json | 10 +- .../app-entrypoint-async/package.json | 2 +- .../package.json | 2 +- .../test/fixtures/app-entrypoint/package.json | 2 +- .../vue/test/fixtures/prop-types/package.json | 2 +- pnpm-lock.yaml | 177 ++++++++---------- 13 files changed, 94 insertions(+), 117 deletions(-) diff --git a/packages/integrations/preact/package.json b/packages/integrations/preact/package.json index 5de34d64c3b8..870a7b5737e3 100644 --- a/packages/integrations/preact/package.json +++ b/packages/integrations/preact/package.json @@ -36,7 +36,7 @@ }, "dependencies": { "@preact/preset-vite": "^2.10.3", - "@preact/signals": "^2.6.2", + "@preact/signals": "^2.7.1", "preact-render-to-string": "^6.6.5", "vite": "^7.3.1" }, diff --git a/packages/integrations/react/package.json b/packages/integrations/react/package.json index 78c17bde5a19..1f2affa85c37 100644 --- a/packages/integrations/react/package.json +++ b/packages/integrations/react/package.json @@ -39,12 +39,12 @@ "test": "astro-scripts test \"test/**/*.test.js\"" }, "dependencies": { - "@vitejs/plugin-react": "^5.1.2", + "@vitejs/plugin-react": "^5.1.4", "ultrahtml": "^1.6.0", "vite": "^7.3.1" }, "devDependencies": { - "@types/react": "^18.3.27", + "@types/react": "^18.3.28", "@types/react-dom": "^18.3.7", "astro": "workspace:*", "astro-scripts": "workspace:*", diff --git a/packages/integrations/react/test/fixtures/react-component/package.json b/packages/integrations/react/test/fixtures/react-component/package.json index 2545f7df3384..7b5619f983b7 100644 --- a/packages/integrations/react/test/fixtures/react-component/package.json +++ b/packages/integrations/react/test/fixtures/react-component/package.json @@ -8,6 +8,6 @@ "astro": "workspace:*", "react": "^18.3.1", "react-dom": "^18.3.1", - "vue": "^3.5.27" + "vue": "^3.5.28" } } diff --git a/packages/integrations/svelte/package.json b/packages/integrations/svelte/package.json index 2eac9c6165a8..cd881dcbe12c 100644 --- a/packages/integrations/svelte/package.json +++ b/packages/integrations/svelte/package.json @@ -46,7 +46,7 @@ "astro": "workspace:*", "astro-scripts": "workspace:*", "cheerio": "1.2.0", - "svelte": "^5.49.1" + "svelte": "^5.50.3" }, "peerDependencies": { "astro": "^6.0.0-alpha.0", diff --git a/packages/integrations/svelte/test/fixtures/async-rendering/package.json b/packages/integrations/svelte/test/fixtures/async-rendering/package.json index fc5e4bdc5955..0e290e477ac1 100644 --- a/packages/integrations/svelte/test/fixtures/async-rendering/package.json +++ b/packages/integrations/svelte/test/fixtures/async-rendering/package.json @@ -11,6 +11,6 @@ "dependencies": { "@astrojs/svelte": "workspace:*", "astro": "workspace:*", - "svelte": "5.49.1" + "svelte": "5.50.3" } } diff --git a/packages/integrations/svelte/test/fixtures/conditional-rendering/package.json b/packages/integrations/svelte/test/fixtures/conditional-rendering/package.json index ff456f757024..31aa9310b0e7 100644 --- a/packages/integrations/svelte/test/fixtures/conditional-rendering/package.json +++ b/packages/integrations/svelte/test/fixtures/conditional-rendering/package.json @@ -11,6 +11,6 @@ "dependencies": { "@astrojs/svelte": "workspace:*", "astro": "workspace:*", - "svelte": "5.49.1" + "svelte": "5.50.3" } } diff --git a/packages/integrations/svelte/test/fixtures/prop-types/package.json b/packages/integrations/svelte/test/fixtures/prop-types/package.json index d62bab01cec2..e3efd2f9ed6c 100644 --- a/packages/integrations/svelte/test/fixtures/prop-types/package.json +++ b/packages/integrations/svelte/test/fixtures/prop-types/package.json @@ -11,6 +11,6 @@ "dependencies": { "@astrojs/svelte": "workspace:*", "astro": "workspace:*", - "svelte": "^5.49.1" + "svelte": "^5.50.3" } } diff --git a/packages/integrations/vue/package.json b/packages/integrations/vue/package.json index 51cd5a82e9b7..1a6e46ae9ade 100644 --- a/packages/integrations/vue/package.json +++ b/packages/integrations/vue/package.json @@ -38,18 +38,18 @@ "test": "astro-scripts test \"test/**/*.test.js\"" }, "dependencies": { - "@vitejs/plugin-vue": "^6.0.3", - "@vitejs/plugin-vue-jsx": "^5.1.3", - "@vue/compiler-sfc": "^3.5.27", + "@vitejs/plugin-vue": "^6.0.4", + "@vitejs/plugin-vue-jsx": "^5.1.4", + "@vue/compiler-sfc": "^3.5.28", "vite": "^7.3.1", - "vite-plugin-vue-devtools": "^8.0.5" + "vite-plugin-vue-devtools": "^8.0.6" }, "devDependencies": { "astro": "workspace:*", "astro-scripts": "workspace:*", "cheerio": "1.2.0", "linkedom": "^0.18.12", - "vue": "^3.5.27" + "vue": "^3.5.28" }, "peerDependencies": { "astro": "^6.0.0-alpha.0", diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-async/package.json b/packages/integrations/vue/test/fixtures/app-entrypoint-async/package.json index 757b8fea048b..e627486e92a7 100644 --- a/packages/integrations/vue/test/fixtures/app-entrypoint-async/package.json +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-async/package.json @@ -6,6 +6,6 @@ "@astrojs/vue": "workspace:*", "astro": "workspace:*", "vite-svg-loader": "5.1.0", - "vue": "^3.5.27" + "vue": "^3.5.28" } } \ No newline at end of file diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/package.json b/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/package.json index 4d91f82d43f4..85b38bfe64ed 100644 --- a/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/package.json +++ b/packages/integrations/vue/test/fixtures/app-entrypoint-no-export-default/package.json @@ -9,6 +9,6 @@ "@astrojs/vue": "workspace:*", "astro": "workspace:*", "vite-svg-loader": "5.1.0", - "vue": "^3.5.27" + "vue": "^3.5.28" } } diff --git a/packages/integrations/vue/test/fixtures/app-entrypoint/package.json b/packages/integrations/vue/test/fixtures/app-entrypoint/package.json index 1e4b73767957..c446f80180f1 100644 --- a/packages/integrations/vue/test/fixtures/app-entrypoint/package.json +++ b/packages/integrations/vue/test/fixtures/app-entrypoint/package.json @@ -6,6 +6,6 @@ "@astrojs/vue": "workspace:*", "astro": "workspace:*", "vite-svg-loader": "5.1.0", - "vue": "^3.5.27" + "vue": "^3.5.28" } } \ No newline at end of file diff --git a/packages/integrations/vue/test/fixtures/prop-types/package.json b/packages/integrations/vue/test/fixtures/prop-types/package.json index 9e15650eb582..1722992b4b4c 100644 --- a/packages/integrations/vue/test/fixtures/prop-types/package.json +++ b/packages/integrations/vue/test/fixtures/prop-types/package.json @@ -11,6 +11,6 @@ "dependencies": { "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "vue": "^3.5.27" + "vue": "^3.5.28" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 47f97bd98fc5..aa9d6052d23d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -288,7 +288,7 @@ importers: version: 1.9.11 svelte: specifier: ^5.50.3 - version: 5.51.2 + version: 5.50.3 vue: specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) @@ -351,7 +351,7 @@ importers: version: link:../../packages/astro svelte: specifier: ^5.50.3 - version: 5.51.2 + version: 5.50.3 examples/framework-vue: dependencies: @@ -405,7 +405,7 @@ importers: version: link:../../packages/astro svelte: specifier: ^5.50.3 - version: 5.51.2 + version: 5.50.3 examples/starlog: dependencies: @@ -938,7 +938,7 @@ importers: version: 1.9.11 svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 vue: specifier: ^3.5.27 version: 3.5.28(typescript@5.9.3) @@ -1136,7 +1136,7 @@ importers: version: 1.9.11 svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 vue: specifier: ^3.5.27 version: 3.5.28(typescript@5.9.3) @@ -1193,7 +1193,7 @@ importers: version: 1.9.11 svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 vue: specifier: ^3.5.27 version: 3.5.28(typescript@5.9.3) @@ -1249,7 +1249,7 @@ importers: version: 1.9.11 svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 vue: specifier: ^3.5.27 version: 3.5.28(typescript@5.9.3) @@ -1289,7 +1289,7 @@ importers: version: 1.9.11 svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 vue: specifier: ^3.5.27 version: 3.5.28(typescript@5.9.3) @@ -1329,7 +1329,7 @@ importers: version: 1.9.11 svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 vue: specifier: ^3.5.27 version: 3.5.28(typescript@5.9.3) @@ -1369,7 +1369,7 @@ importers: version: 1.9.11 svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 vue: specifier: ^3.5.27 version: 3.5.28(typescript@5.9.3) @@ -1409,7 +1409,7 @@ importers: version: 1.9.11 svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 vue: specifier: ^3.5.27 version: 3.5.28(typescript@5.9.3) @@ -1449,7 +1449,7 @@ importers: version: 1.9.11 svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 vue: specifier: ^3.5.27 version: 3.5.28(typescript@5.9.3) @@ -1645,7 +1645,7 @@ importers: version: link:../../.. svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 packages/astro/e2e/fixtures/tailwindcss: dependencies: @@ -1705,7 +1705,7 @@ importers: version: 1.9.11 svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 vue: specifier: ^3.5.27 version: 3.5.28(typescript@5.9.3) @@ -1849,7 +1849,7 @@ importers: version: 18.3.1(react@18.3.1) svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 vue: specifier: ^3.5.27 version: 3.5.28(typescript@5.9.3) @@ -1870,7 +1870,7 @@ importers: version: link:../../.. svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 packages/astro/test/fixtures/alias-tsconfig: dependencies: @@ -1885,7 +1885,7 @@ importers: version: link:../../.. svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 packages/astro/test/fixtures/alias-tsconfig-baseurl-only: dependencies: @@ -1897,7 +1897,7 @@ importers: version: link:../../.. svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 packages/astro/test/fixtures/alias-tsconfig-no-baseurl: dependencies: @@ -2043,7 +2043,7 @@ importers: version: 10.28.3 svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 vue: specifier: ^3.5.27 version: 3.5.28(typescript@5.9.3) @@ -2076,7 +2076,7 @@ importers: version: 18.3.1(react@18.3.1) svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 packages/astro/test/fixtures/astro-client-only/pkg: {} @@ -2168,7 +2168,7 @@ importers: version: 18.3.1(react@18.3.1) svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 packages/astro/test/fixtures/astro-env: dependencies: @@ -2543,7 +2543,7 @@ importers: version: 1.9.11 svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 vue: specifier: ^3.5.27 version: 3.5.28(typescript@5.9.3) @@ -2633,7 +2633,7 @@ importers: version: 18.3.1(react@18.3.1) svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 packages/astro/test/fixtures/component-library-shared: dependencies: @@ -3029,7 +3029,7 @@ importers: version: link:../../.. svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 packages/astro/test/fixtures/css-deduplication: dependencies: @@ -3344,7 +3344,7 @@ importers: version: 10.28.3 svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 vue: specifier: ^3.5.27 version: 3.5.28(typescript@5.9.3) @@ -3599,7 +3599,7 @@ importers: version: 1.9.11 svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 vue: specifier: ^3.5.27 version: 3.5.28(typescript@5.9.3) @@ -3814,7 +3814,7 @@ importers: version: 1.9.11 svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 vue: specifier: ^3.5.27 version: 3.5.28(typescript@5.9.3) @@ -4080,7 +4080,7 @@ importers: version: link:../../../.. svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 packages/astro/test/fixtures/server-islands/ssr: dependencies: @@ -4095,7 +4095,7 @@ importers: version: link:../../../.. svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 packages/astro/test/fixtures/sessions: dependencies: @@ -4170,7 +4170,7 @@ importers: version: link:../../.. svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 packages/astro/test/fixtures/slots-vue: dependencies: @@ -4484,7 +4484,7 @@ importers: version: link:../../.. svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 packages/astro/test/fixtures/svg-deduplication: dependencies: @@ -4613,7 +4613,7 @@ importers: version: link:../../.. svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 vue: specifier: ^3.5.27 version: 3.5.28(typescript@5.9.3) @@ -5162,7 +5162,7 @@ importers: version: 0.34.5 svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 vue: specifier: ^3.5.27 version: 3.5.28(typescript@5.9.3) @@ -5204,7 +5204,7 @@ importers: version: link:../../../../../astro svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 packages/integrations/cloudflare/test/fixtures/with-vue: dependencies: @@ -6070,7 +6070,7 @@ importers: specifier: ^2.10.3 version: 2.10.3(@babel/core@7.29.0)(preact@10.28.3)(rollup@4.57.1)(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2)) '@preact/signals': - specifier: ^2.6.2 + specifier: ^2.7.1 version: 2.8.0(preact@10.28.3) preact-render-to-string: specifier: ^6.6.5 @@ -6092,8 +6092,8 @@ importers: packages/integrations/react: dependencies: '@vitejs/plugin-react': - specifier: ^5.1.2 - version: 5.1.3(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2)) + specifier: ^5.1.4 + version: 5.1.4(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2)) ultrahtml: specifier: ^1.6.0 version: 1.6.0 @@ -6102,7 +6102,7 @@ importers: version: 7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2) devDependencies: '@types/react': - specifier: ^18.3.27 + specifier: ^18.3.28 version: 18.3.28 '@types/react-dom': specifier: ^18.3.7 @@ -6141,7 +6141,7 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/integrations/sitemap: @@ -6237,10 +6237,10 @@ importers: dependencies: '@sveltejs/vite-plugin-svelte': specifier: ^6.2.4 - version: 6.2.4(svelte@5.51.2)(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2)) + version: 6.2.4(svelte@5.50.3)(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2)) svelte2tsx: specifier: ^0.7.47 - version: 0.7.47(svelte@5.51.2)(typescript@5.9.3) + version: 0.7.47(svelte@5.50.3)(typescript@5.9.3) vite: specifier: ^7.3.1 version: 7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2) @@ -6255,8 +6255,8 @@ importers: specifier: 1.2.0 version: 1.2.0 svelte: - specifier: ^5.49.1 - version: 5.51.2 + specifier: ^5.50.3 + version: 5.50.3 packages/integrations/svelte/test/fixtures/async-rendering: dependencies: @@ -6267,8 +6267,8 @@ importers: specifier: workspace:* version: link:../../../../../astro svelte: - specifier: 5.49.1 - version: 5.49.1 + specifier: 5.50.3 + version: 5.50.3 packages/integrations/svelte/test/fixtures/conditional-rendering: dependencies: @@ -6279,8 +6279,8 @@ importers: specifier: workspace:* version: link:../../../../../astro svelte: - specifier: 5.49.1 - version: 5.49.1 + specifier: 5.50.3 + version: 5.50.3 packages/integrations/svelte/test/fixtures/prop-types: dependencies: @@ -6291,8 +6291,8 @@ importers: specifier: workspace:* version: link:../../../../../astro svelte: - specifier: ^5.49.1 - version: 5.51.2 + specifier: ^5.50.3 + version: 5.50.3 packages/integrations/vercel: dependencies: @@ -6301,7 +6301,7 @@ importers: version: link:../../internal-helpers '@vercel/analytics': specifier: ^1.6.1 - version: 1.6.1(react@19.2.4)(svelte@5.51.2)(vue@3.5.28(typescript@5.9.3)) + version: 1.6.1(react@19.2.4)(svelte@5.50.3)(vue@3.5.28(typescript@5.9.3)) '@vercel/functions': specifier: ^3.4.0 version: 3.4.1 @@ -6517,19 +6517,19 @@ importers: packages/integrations/vue: dependencies: '@vitejs/plugin-vue': - specifier: ^6.0.3 + specifier: ^6.0.4 version: 6.0.4(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.28(typescript@5.9.3)) '@vitejs/plugin-vue-jsx': - specifier: ^5.1.3 + specifier: ^5.1.4 version: 5.1.4(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.28(typescript@5.9.3)) '@vue/compiler-sfc': - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28 vite: specifier: ^7.3.1 version: 7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2) vite-plugin-vue-devtools: - specifier: ^8.0.5 + specifier: ^8.0.6 version: 8.0.6(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.28(typescript@5.9.3)) devDependencies: astro: @@ -6545,7 +6545,7 @@ importers: specifier: ^0.18.12 version: 0.18.12 vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/integrations/vue/test/fixtures/app-entrypoint: @@ -6560,7 +6560,7 @@ importers: specifier: 5.1.0 version: 5.1.0(vue@3.5.28(typescript@5.9.3)) vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/integrations/vue/test/fixtures/app-entrypoint-async: @@ -6575,7 +6575,7 @@ importers: specifier: 5.1.0 version: 5.1.0(vue@3.5.28(typescript@5.9.3)) vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/integrations/vue/test/fixtures/app-entrypoint-css: @@ -6599,7 +6599,7 @@ importers: specifier: 5.1.0 version: 5.1.0(vue@3.5.28(typescript@5.9.3)) vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/integrations/vue/test/fixtures/app-entrypoint-relative: @@ -6638,7 +6638,7 @@ importers: specifier: workspace:* version: link:../../../../../astro vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/internal-helpers: @@ -6773,7 +6773,7 @@ importers: version: link:../../../astro svelte: specifier: ^5.49.1 - version: 5.51.2 + version: 5.50.3 devDependencies: tinyglobby: specifier: ^0.2.15 @@ -10461,8 +10461,8 @@ packages: peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 - '@vitejs/plugin-react@5.1.3': - resolution: {integrity: sha512-NVUnA6gQCl8jfoYqKqQU5Clv0aPw14KkZYCsX6T9Lfu9slI0LOU10OTwFHS/WmptsMMpshNd/1tuWsHQ2Uk+cg==} + '@vitejs/plugin-react@5.1.4': + resolution: {integrity: sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 @@ -15163,12 +15163,8 @@ packages: svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0 typescript: ^4.9.4 || ^5.0.0 - svelte@5.49.1: - resolution: {integrity: sha512-jj95WnbKbXsXXngYj28a4zx8jeZx50CN/J4r0CEeax2pbfdsETv/J1K8V9Hbu3DCXnpHz5qAikICuxEooi7eNQ==} - engines: {node: '>=18'} - - svelte@5.51.2: - resolution: {integrity: sha512-AqApqNOxVS97V4Ko9UHTHeSuDJrwauJhZpLDs1gYD8Jk48ntCSWD7NxKje+fnGn5Ja1O3u2FzQZHPdifQjXe3w==} + svelte@5.50.3: + resolution: {integrity: sha512-5JCO8P/cFlwyfi1LeZ9uppMZvuaHWygyZmqxyKOIqbV3PoHKaddvV1C6njL/InpDXplNYZnAVEbn8mLslycBxQ==} engines: {node: '>=18'} svgo@3.3.2: @@ -19308,20 +19304,20 @@ snapshots: dependencies: acorn: 8.15.0 - '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.51.2)(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.51.2)(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2))': + '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.50.3)(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.50.3)(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.51.2)(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2)) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.50.3)(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2)) obug: 2.1.1 - svelte: 5.51.2 + svelte: 5.50.3 vite: 7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2) - '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.51.2)(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2))': + '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.50.3)(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.51.2)(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.51.2)(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2)) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.50.3)(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2)))(svelte@5.50.3)(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2)) deepmerge: 4.3.1 magic-string: 0.30.21 obug: 2.1.1 - svelte: 5.51.2 + svelte: 5.50.3 vite: 7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2) vitefu: 1.1.1(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2)) @@ -19756,10 +19752,10 @@ snapshots: dependencies: valibot: 1.2.0(typescript@5.9.3) - '@vercel/analytics@1.6.1(react@19.2.4)(svelte@5.51.2)(vue@3.5.28(typescript@5.9.3))': + '@vercel/analytics@1.6.1(react@19.2.4)(svelte@5.50.3)(vue@3.5.28(typescript@5.9.3))': optionalDependencies: react: 19.2.4 - svelte: 5.51.2 + svelte: 5.50.3 vue: 3.5.28(typescript@5.9.3) '@vercel/functions@3.4.1': @@ -19825,12 +19821,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-react@5.1.3(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2))': + '@vitejs/plugin-react@5.1.4(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) - '@rolldown/pluginutils': 1.0.0-rc.2 + '@rolldown/pluginutils': 1.0.0-rc.3 '@types/babel__core': 7.20.5 react-refresh: 0.18.0 vite: 7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2) @@ -25485,38 +25481,19 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte2tsx@0.7.47(svelte@5.51.2)(typescript@5.9.3): + svelte2tsx@0.7.47(svelte@5.50.3)(typescript@5.9.3): dependencies: dedent-js: 1.0.1 scule: 1.3.0 - svelte: 5.51.2 + svelte: 5.50.3 typescript: 5.9.3 - svelte@5.49.1: - dependencies: - '@jridgewell/remapping': 2.3.5 - '@jridgewell/sourcemap-codec': 1.5.5 - '@sveltejs/acorn-typescript': 1.0.6(acorn@8.15.0) - '@types/estree': 1.0.8 - acorn: 8.15.0 - aria-query: 5.3.2 - axobject-query: 4.1.0 - clsx: 2.1.1 - devalue: 5.6.2 - esm-env: 1.2.2 - esrap: 2.2.2 - is-reference: 3.0.3 - locate-character: 3.0.0 - magic-string: 0.30.21 - zimmerframe: 1.1.4 - - svelte@5.51.2: + svelte@5.50.3: dependencies: '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.5.5 '@sveltejs/acorn-typescript': 1.0.6(acorn@8.15.0) '@types/estree': 1.0.8 - '@types/trusted-types': 2.0.7 acorn: 8.15.0 aria-query: 5.3.2 axobject-query: 4.1.0 From e118214eeaaa27384528c882af8b68e8daa61e2c Mon Sep 17 00:00:00 2001 From: Alexander Niebuhr Date: Mon, 16 Feb 2026 11:40:33 +0100 Subject: [PATCH 03/12] drops official cloudflare pages support (#15480) --- .changeset/young-pandas-talk.md | 7 + packages/integrations/cloudflare/package.json | 2 +- .../entrypoints/image-transform-endpoint.ts | 1 + packages/integrations/cloudflare/src/index.ts | 54 +-- .../src/utils/generate-routes-json.ts | 321 +--------------- .../cloudflare/src/utils/handler.ts | 5 +- .../cloudflare/test/custom-entryfile.test.js | 2 +- .../test/external-image-service.test.js | 2 +- .../fixtures/routes-json/astro.config.mjs | 8 - .../test/fixtures/routes-json/package.json | 9 - .../fixtures/routes-json/public/_redirects | 1 - .../fixtures/routes-json/public/public.txt | 1 - .../routes-json/src/dynamicOnly/env.d.ts | 2 - .../src/dynamicOnly/pages/dynamic1.astro | 5 - .../src/dynamicOnly/pages/dynamic2.astro | 5 - .../src/dynamicOnly/pages/dynamic3.astro | 5 - .../src/dynamicOnly/pages/index.astro | 5 - .../routes-json/src/manyStatic/env.d.ts | 1 - .../src/manyStatic/pages/[id].astro | 16 - .../src/manyStatic/pages/dynamic.astro | 5 - .../src/manyStaticWith404/env.d.ts | 1 - .../src/manyStaticWith404/pages/404.astro | 0 .../src/manyStaticWith404/pages/[id].astro | 16 - .../src/manyStaticWith404/pages/dynamic.astro | 5 - .../fixtures/routes-json/src/mixed/env.d.ts | 2 - .../routes-json/src/mixed/pages/404.astro | 3 - .../src/mixed/pages/a/[...rest].astro | 5 - .../routes-json/src/mixed/pages/a/[id].astro | 5 - .../routes-json/src/mixed/pages/a/endpoint.ts | 1 - .../routes-json/src/mixed/pages/a/index.astro | 1 - .../routes-json/src/mixed/pages/b/index.html | 1 - .../routes-json/src/reduceComplexity/env.d.ts | 2 - .../src/reduceComplexity/pages/404.astro | 3 - .../pages/dynamicPages/dynamic1.astro | 5 - .../pages/dynamicPages/dynamic2.astro | 5 - .../pages/dynamicPages/dynamic3.astro | 5 - .../src/reduceComplexity/pages/index.astro | 5 - .../pages/mixedPages/dynamic.astro | 5 - .../pages/mixedPages/static.astro | 5 - .../pages/mixedPages/subfolder/dynamic.astro | 5 - .../pages/mixedPages/subfolder/static.astro | 5 - .../pages/staticPages/static1.astro | 5 - .../pages/staticPages/static2.astro | 5 - .../pages/staticPages/static3.astro | 5 - .../routes-json/src/staticOnly/env.d.ts | 2 - .../src/staticOnly/pages/404.astro | 3 - .../src/staticOnly/pages/index.astro | 1 - .../cloudflare/test/routes-json.test.js | 351 ------------------ .../cloudflare/test/server-entry.test.js | 4 +- pnpm-lock.yaml | 48 ++- 50 files changed, 59 insertions(+), 907 deletions(-) create mode 100644 .changeset/young-pandas-talk.md delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/astro.config.mjs delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/package.json delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/public/_redirects delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/public/public.txt delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/env.d.ts delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/pages/dynamic1.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/pages/dynamic2.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/pages/dynamic3.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/pages/index.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStatic/env.d.ts delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStatic/pages/[id].astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStatic/pages/dynamic.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStaticWith404/env.d.ts delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStaticWith404/pages/404.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStaticWith404/pages/[id].astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStaticWith404/pages/dynamic.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/env.d.ts delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/404.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/a/[...rest].astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/a/[id].astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/a/endpoint.ts delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/a/index.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/b/index.html delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/env.d.ts delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/404.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/dynamicPages/dynamic1.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/dynamicPages/dynamic2.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/dynamicPages/dynamic3.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/index.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/mixedPages/dynamic.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/mixedPages/static.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/mixedPages/subfolder/dynamic.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/mixedPages/subfolder/static.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/staticPages/static1.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/staticPages/static2.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/staticPages/static3.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/staticOnly/env.d.ts delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/staticOnly/pages/404.astro delete mode 100644 packages/integrations/cloudflare/test/fixtures/routes-json/src/staticOnly/pages/index.astro delete mode 100644 packages/integrations/cloudflare/test/routes-json.test.js diff --git a/.changeset/young-pandas-talk.md b/.changeset/young-pandas-talk.md new file mode 100644 index 000000000000..964fe003491f --- /dev/null +++ b/.changeset/young-pandas-talk.md @@ -0,0 +1,7 @@ +--- +'@astrojs/cloudflare': major +--- + +Drops official support for Cloudflare Pages in favor of Cloudflare Workers + +The Astro Cloudflare adapter now only supports deployment to Cloudflare Workers by default in order to comply with Cloudflare's recommendations for new projects. If you are currently deploying to Cloudflare Pages, consider [migrating to Workers by following the Cloudflare guide](https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages/) for an optimal experience and full feature support. diff --git a/packages/integrations/cloudflare/package.json b/packages/integrations/cloudflare/package.json index 6b8881d00427..57ab11c17f93 100644 --- a/packages/integrations/cloudflare/package.json +++ b/packages/integrations/cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@astrojs/cloudflare", - "description": "Deploy your site to Cloudflare Workers/Pages", + "description": "Deploy your site to Cloudflare Workers", "version": "13.0.0-beta.7", "type": "module", "types": "./dist/index.d.ts", diff --git a/packages/integrations/cloudflare/src/entrypoints/image-transform-endpoint.ts b/packages/integrations/cloudflare/src/entrypoints/image-transform-endpoint.ts index 808abd06b773..aee90bb1f911 100644 --- a/packages/integrations/cloudflare/src/entrypoints/image-transform-endpoint.ts +++ b/packages/integrations/cloudflare/src/entrypoints/image-transform-endpoint.ts @@ -1,5 +1,6 @@ import type { APIRoute } from 'astro'; import { transform } from '../utils/image-binding-transform.js'; +// NOTE we have to use `cloudflare:workers` since "live" bindings are not populated to process.env import { env } from 'cloudflare:workers'; export const prerender = false; diff --git a/packages/integrations/cloudflare/src/index.ts b/packages/integrations/cloudflare/src/index.ts index 412b4a5dddcf..c2c73b03decb 100644 --- a/packages/integrations/cloudflare/src/index.ts +++ b/packages/integrations/cloudflare/src/index.ts @@ -6,7 +6,7 @@ import { createRedirectsFromAstroRoutes, printAsRedirects } from '@astrojs/under import { cloudflare as cfVitePlugin, type PluginConfig } from '@cloudflare/vite-plugin'; import type { AstroConfig, AstroIntegration, IntegrationResolvedRoute } from 'astro'; import { astroFrontmatterScanPlugin } from './esbuild-plugin-astro-frontmatter.js'; -import { createRoutesFile, getParts } from './utils/generate-routes-json.js'; +import { getParts } from './utils/generate-routes-json.js'; import { type ImageService, setImageConfig } from './utils/image-config.js'; import { createConfigPlugin } from './vite-plugin-config.js'; import { @@ -24,31 +24,6 @@ export type Options = { /** Options for handling images. */ imageService?: ImageService; - /** Configuration for `_routes.json` generation. A _routes.json file controls when your Function is invoked. This file will include three different properties: - * - * - version: Defines the version of the schema. Currently there is only one version of the schema (version 1), however, we may add more in the future and aim to be backwards compatible. - * - include: Defines routes that will be invoked by Functions. Accepts wildcard behavior. - * - exclude: Defines routes that will not be invoked by Functions. Accepts wildcard behavior. `exclude` always take priority over `include`. - * - * Wildcards match any number of path segments (slashes). For example, `/users/*` will match everything after the `/users/` path. - * - */ - routes?: { - /** Extend `_routes.json` */ - extend: { - /** Paths which should be routed to the SSR function */ - include?: { - /** Generally this is in pathname format, but does support wildcards, e.g. `/users`, `/products/*` */ - pattern: string; - }[]; - /** Paths which should be routed as static assets */ - exclude?: { - /** Generally this is in pathname format, but does support wildcards, e.g. `/static`, `/assets/*`, `/images/avatar.jpg` */ - pattern: string; - }[]; - }; - }; - /** * By default, Astro will be configured to use Cloudflare KV to store session data. The KV namespace * will be automatically provisioned when you deploy. @@ -128,8 +103,6 @@ export default function createIntegration(args?: Options): AstroIntegration { updateConfig({ build: { - client: new URL(`./client/`, config.outDir), - server: new URL('./_worker.js/', config.outDir), redirects: false, }, session, @@ -265,6 +238,7 @@ export default function createIntegration(args?: Options): AstroIntegration { }, }); + // QUESTION could be removed based on https://developers.cloudflare.com/workers/configuration/compatibility-flags/#enable-auto-populating-processenv // Assign .dev.vars to process.env so astro:env can find these vars const devVarsPath = new URL('.dev.vars', config.root); if (existsSync(devVarsPath)) { @@ -317,7 +291,7 @@ export default function createIntegration(args?: Options): AstroIntegration { }; } }, - 'astro:build:done': async ({ pages, dir, logger, assets }) => { + 'astro:build:done': async ({ dir, logger, assets }) => { let redirectsExists = false; try { const redirectsStat = await stat(new URL('./_redirects', _config.build.client)); @@ -353,28 +327,6 @@ export default function createIntegration(args?: Options): AstroIntegration { } } - let routesExists = false; - try { - const routesStat = await stat(new URL('./_routes.json', _config.build.client)); - if (routesStat.isFile()) { - routesExists = true; - } - } catch (_error) { - routesExists = false; - } - - if (!routesExists) { - await createRoutesFile( - _config, - logger, - _routes, - pages, - redirects, - args?.routes?.extend?.include, - args?.routes?.extend?.exclude, - ); - } - const trueRedirects = createRedirectsFromAstroRoutes({ config: _config, routeToDynamicTargetMap: new Map( diff --git a/packages/integrations/cloudflare/src/utils/generate-routes-json.ts b/packages/integrations/cloudflare/src/utils/generate-routes-json.ts index 480e29b694a4..9330e74e94d5 100644 --- a/packages/integrations/cloudflare/src/utils/generate-routes-json.ts +++ b/packages/integrations/cloudflare/src/utils/generate-routes-json.ts @@ -1,20 +1,6 @@ -import { existsSync } from 'node:fs'; -import { writeFile } from 'node:fs/promises'; -import path from 'node:path'; -import { fileURLToPath } from 'node:url'; -import { - prependForwardSlash, - removeLeadingForwardSlash, - removeTrailingForwardSlash, -} from '@astrojs/internal-helpers/path'; -import type { - AstroConfig, - AstroIntegrationLogger, - IntegrationResolvedRoute, - RoutePart, -} from 'astro'; -import { glob } from 'tinyglobby'; +import type { RoutePart } from 'astro'; +// QUESTION could be removed when we expose it from core https://discord.com/channels/830184174198718474/1471406261294727254 // Copied from https://github.com/withastro/astro/blob/3776ecf0aa9e08a992d3ae76e90682fd04093721/packages/astro/src/core/routing/manifest/create.ts#L45-L70 // We're not sure how to improve this regex yet // eslint-disable-next-line regexp/no-super-linear-backtracking @@ -41,306 +27,3 @@ export function getParts(part: string) { return result; } - -async function writeRoutesFileToOutDir( - _config: AstroConfig, - logger: AstroIntegrationLogger, - include: string[], - exclude: string[], -) { - try { - await writeFile( - new URL('./_routes.json', _config.outDir), - JSON.stringify( - { - version: 1, - include: include, - exclude: exclude, - }, - null, - 2, - ), - 'utf-8', - ); - } catch (_error) { - logger.error("There was an error writing the '_routes.json' file to the output directory."); - } -} - -function segmentsToCfSyntax(segments: IntegrationResolvedRoute['segments'], _config: AstroConfig) { - const pathSegments = []; - if (removeLeadingForwardSlash(removeTrailingForwardSlash(_config.base)).length > 0) { - pathSegments.push(removeLeadingForwardSlash(removeTrailingForwardSlash(_config.base))); - } - for (const segment of segments.flat()) { - if (segment.dynamic) pathSegments.push('*'); - else pathSegments.push(segment.content); - } - return pathSegments; -} - -class TrieNode { - children = new Map(); - isEndOfPath = false; - hasWildcardChild = false; -} - -class PathTrie { - root: TrieNode; - returnHasWildcard = false; - - constructor() { - this.root = new TrieNode(); - } - - insert(thisPath: string[]) { - let node = this.root; - for (const segment of thisPath) { - if (segment === '*') { - node.hasWildcardChild = true; - break; - } - if (!node.children.has(segment)) { - node.children.set(segment, new TrieNode()); - } - - node = node.children.get(segment)!; - } - - node.isEndOfPath = true; - } - - /** - * Depth-first search (dfs), traverses the "graph" segment by segment until the end or wildcard (*). - * It makes sure that all necessary paths are returned, but not paths with an existing wildcard prefix. - * e.g. if we have a path like /foo/* and /foo/bar, we only want to return /foo/* - */ - private dfs(node: TrieNode, thisPath: string[], allPaths: string[][]): void { - if (node.hasWildcardChild) { - this.returnHasWildcard = true; - allPaths.push([...thisPath, '*']); - return; - } - - if (node.isEndOfPath) { - allPaths.push([...thisPath]); - } - - for (const [segment, childNode] of node.children) { - this.dfs(childNode, [...thisPath, segment], allPaths); - } - } - - /** - * The reduce function is used to remove unnecessary paths from the trie. - * It receives a trie node to compare with the current node. - */ - private reduce(compNode: TrieNode, node: TrieNode): void { - if (node.hasWildcardChild || compNode.hasWildcardChild) return; - - for (const [segment, childNode] of node.children) { - if (childNode.children.size === 0) continue; - - const compChildNode = compNode.children.get(segment); - if (compChildNode === undefined) { - childNode.hasWildcardChild = true; - continue; - } - - this.reduce(compChildNode, childNode); - } - } - - reduceAllPaths(compTrie: PathTrie): this { - this.reduce(compTrie.root, this.root); - return this; - } - - getAllPaths(): [string[][], boolean] { - const allPaths: string[][] = []; - this.dfs(this.root, [], allPaths); - return [allPaths, this.returnHasWildcard]; - } -} - -export async function createRoutesFile( - _config: AstroConfig, - logger: AstroIntegrationLogger, - routes: IntegrationResolvedRoute[], - pages: { - pathname: string; - }[], - redirects: IntegrationResolvedRoute['segments'][], - includeExtends: - | { - pattern: string; - }[] - | undefined, - excludeExtends: - | { - pattern: string; - }[] - | undefined, -) { - const includePaths: string[][] = []; - const excludePaths: string[][] = []; - - /** - * All files in the `_config.build.assets` path, e.g. `_astro` - * are considered static assets and should not be handled by the function - * therefore we exclude a wildcard for that, e.g. `/_astro/*` - */ - const assetsPath = segmentsToCfSyntax( - [ - [{ content: _config.build.assets, dynamic: false, spread: false }], - [{ content: '', dynamic: true, spread: false }], - ], - _config, - ); - excludePaths.push(assetsPath); - - for (const redirect of redirects) { - excludePaths.push(segmentsToCfSyntax(redirect, _config)); - } - - if (existsSync(fileURLToPath(_config.publicDir))) { - const staticFiles = await glob(`**/*`, { - cwd: fileURLToPath(_config.publicDir), - dot: true, - }); - for (const staticFile of staticFiles) { - if (['_headers', '_redirects', '_routes.json'].includes(staticFile)) continue; - const staticPath = staticFile; - - const segments = removeLeadingForwardSlash(staticPath) - .split(path.sep) - .filter(Boolean) - .map((s: string) => { - return getParts(s); - }); - excludePaths.push(segmentsToCfSyntax(segments, _config)); - } - } - - let hasPrerendered404 = false; - for (const route of routes) { - const convertedPath = segmentsToCfSyntax(route.segments, _config); - if (route.pathname === '/404' && route.isPrerendered === true) hasPrerendered404 = true; - - // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check - switch (route.type) { - case 'page': - if (route.isPrerendered === false) includePaths.push(convertedPath); - - break; - - case 'endpoint': - if (route.isPrerendered === false) includePaths.push(convertedPath); - else excludePaths.push(convertedPath); - - break; - - case 'redirect': - excludePaths.push(convertedPath); - - break; - - default: - /** - * We don't know the type, so we are conservative! - * Invoking the function on these is a safe-bet because - * the function will fallback to static asset fetching - */ - includePaths.push(convertedPath); - - break; - } - } - - for (const page of pages) { - if (page.pathname === '404') hasPrerendered404 = true; - const pageSegments = removeLeadingForwardSlash(page.pathname) - .split(path.posix.sep) - .filter(Boolean) - .map((s) => { - return getParts(s); - }); - excludePaths.push(segmentsToCfSyntax(pageSegments, _config)); - } - - const includeTrie = new PathTrie(); - for (const includePath of includePaths) { - includeTrie.insert(includePath); - } - - const excludeTrie = new PathTrie(); - for (const excludePath of excludePaths) { - /** - * A excludePath with starts with a wildcard (*) is a catch-all - * that would mean all routes are static, that would be equal to a full SSG project - * the adapter is not needed in this case, so we do not consider such paths - */ - if (excludePath[0] === '*') continue; - excludeTrie.insert(excludePath); - } - - const [deduplicatedIncludePaths, includedPathsHaveWildcard] = includeTrie - .reduceAllPaths(excludeTrie) - .getAllPaths(); - - const [deduplicatedExcludePaths, _excludedPathsHaveWildcard] = excludeTrie - .reduceAllPaths(includeTrie) - .getAllPaths(); - - /** - * Cloudflare allows no more than 100 include/exclude rules combined - * https://developers.cloudflare.com/pages/functions/routing/#limits - */ - const CLOUDFLARE_COMBINED_LIMIT = 100; - /** - * Calculate the number of automated and extended include rules - */ - const AUTOMATIC_INCLUDE_RULES_COUNT = deduplicatedIncludePaths.length; - const EXTENDED_INCLUDE_RULES_COUNT = includeExtends?.length ?? 0; - const INCLUDE_RULES_COUNT = AUTOMATIC_INCLUDE_RULES_COUNT + EXTENDED_INCLUDE_RULES_COUNT; - /** - * Calculate the number of automated and extended exclude rules - */ - const AUTOMATIC_EXCLUDE_RULES_COUNT = deduplicatedExcludePaths.length; - const EXTENDED_EXCLUDE_RULES_COUNT = excludeExtends?.length ?? 0; - const EXCLUDE_RULES_COUNT = AUTOMATIC_EXCLUDE_RULES_COUNT + EXTENDED_EXCLUDE_RULES_COUNT; - - const OPTION2_TOTAL_COUNT = - INCLUDE_RULES_COUNT + (includedPathsHaveWildcard ? EXCLUDE_RULES_COUNT : 0); - - if (!hasPrerendered404 || OPTION2_TOTAL_COUNT > CLOUDFLARE_COMBINED_LIMIT) { - await writeRoutesFileToOutDir( - _config, - logger, - ['/*'].concat(includeExtends?.map((entry) => entry.pattern) ?? []), - deduplicatedExcludePaths - .map((thisPath) => `${prependForwardSlash(thisPath.join('/'))}`) - .slice( - 0, - CLOUDFLARE_COMBINED_LIMIT - - EXTENDED_INCLUDE_RULES_COUNT - - EXTENDED_EXCLUDE_RULES_COUNT - - 1, - ) - .concat(excludeExtends?.map((entry) => entry.pattern) ?? []), - ); - } else { - await writeRoutesFileToOutDir( - _config, - logger, - deduplicatedIncludePaths - .map((thisPath) => `${prependForwardSlash(thisPath.join('/'))}`) - .concat(includeExtends?.map((entry) => entry.pattern) ?? []), - includedPathsHaveWildcard - ? deduplicatedExcludePaths - .map((thisPath) => `${prependForwardSlash(thisPath.join('/'))}`) - .concat(excludeExtends?.map((entry) => entry.pattern) ?? []) - : [], - ); - } -} diff --git a/packages/integrations/cloudflare/src/utils/handler.ts b/packages/integrations/cloudflare/src/utils/handler.ts index 9a1385695d92..c14ba9b50ca6 100644 --- a/packages/integrations/cloudflare/src/utils/handler.ts +++ b/packages/integrations/cloudflare/src/utils/handler.ts @@ -50,7 +50,7 @@ export async function handle( }); } - // static assets fallback, in case default _routes.json is not used + // NOTE this ASSETS binding path is needed for users who are using `run_worker_first` routing if (app.manifest.assets.has(requestPathname)) { return env.ASSETS.fetch(request.url.replace(/\.html$/, '')); } @@ -66,7 +66,7 @@ export async function handle( } if (!routeData) { - // https://developers.cloudflare.com/pages/functions/api-reference/#envassetsfetch + // NOTE this ASSETS binding path is needed for users who are using `run_worker_first` routing const asset = await env.ASSETS.fetch( request.url.replace(/index.html$/, '').replace(/\.html$/, ''), ); @@ -108,6 +108,7 @@ export async function handle( routeData, locals, prerenderedErrorPageFetch: async (url: string) => { + // NOTE this ASSETS binding path is needed for users who are using `run_worker_first` routing return env.ASSETS.fetch(url.replace(/\.html$/, '')); }, clientAddress: request.headers.get('cf-connecting-ip') ?? undefined, diff --git a/packages/integrations/cloudflare/test/custom-entryfile.test.js b/packages/integrations/cloudflare/test/custom-entryfile.test.js index f05fcd148038..630c4e00016e 100644 --- a/packages/integrations/cloudflare/test/custom-entryfile.test.js +++ b/packages/integrations/cloudflare/test/custom-entryfile.test.js @@ -22,7 +22,7 @@ describe('Custom entry file', () => { }); it('filters out duplicate "default" export and builds', async () => { - const filePath = fileURLToPath(new URL('dist/_worker.js', root)); + const filePath = fileURLToPath(new URL('dist/server', root)); const hasBuilt = existsSync(filePath); assert.equal(hasBuilt, true, `Expected ${filePath} to exist after build`); }); diff --git a/packages/integrations/cloudflare/test/external-image-service.test.js b/packages/integrations/cloudflare/test/external-image-service.test.js index cc3b08ed7dd3..6b22ebd54969 100644 --- a/packages/integrations/cloudflare/test/external-image-service.test.js +++ b/packages/integrations/cloudflare/test/external-image-service.test.js @@ -23,7 +23,7 @@ describe('ExternalImageService', () => { it('has correct image service', async () => { const files = await glob('**/image-service*', { - cwd: fileURLToPath(new URL('dist/_worker.js', root)), + cwd: fileURLToPath(new URL('dist/server', root)), filesOnly: true, absolute: true, flush: true, diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/astro.config.mjs b/packages/integrations/cloudflare/test/fixtures/routes-json/astro.config.mjs deleted file mode 100644 index 3aaa37d9aea7..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/astro.config.mjs +++ /dev/null @@ -1,8 +0,0 @@ -import { defineConfig } from 'astro/config'; - -export default defineConfig({ - output: 'static', - redirects: { - '/a/redirect': '/', - }, -}); diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/package.json b/packages/integrations/cloudflare/test/fixtures/routes-json/package.json deleted file mode 100644 index 4ff746f02bde..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "@test/astro-cloudflare-routes-json", - "version": "0.0.0", - "private": true, - "dependencies": { - "@astrojs/cloudflare": "workspace:*", - "astro": "workspace:*" - } -} diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/public/_redirects b/packages/integrations/cloudflare/test/fixtures/routes-json/public/_redirects deleted file mode 100644 index 14e38c465f84..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/public/_redirects +++ /dev/null @@ -1 +0,0 @@ -/redirectme / 302 diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/public/public.txt b/packages/integrations/cloudflare/test/fixtures/routes-json/public/public.txt deleted file mode 100644 index 9766475a4185..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/public/public.txt +++ /dev/null @@ -1 +0,0 @@ -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/env.d.ts b/packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/env.d.ts deleted file mode 100644 index 2da76ba243c5..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/env.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -/// -/// \ No newline at end of file diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/pages/dynamic1.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/pages/dynamic1.astro deleted file mode 100644 index 9a2306b864fa..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/pages/dynamic1.astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -export const prerender=false; ---- - -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/pages/dynamic2.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/pages/dynamic2.astro deleted file mode 100644 index 9a2306b864fa..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/pages/dynamic2.astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -export const prerender=false; ---- - -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/pages/dynamic3.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/pages/dynamic3.astro deleted file mode 100644 index 9a2306b864fa..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/pages/dynamic3.astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -export const prerender=false; ---- - -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/pages/index.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/pages/index.astro deleted file mode 100644 index 9a2306b864fa..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/dynamicOnly/pages/index.astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -export const prerender=false; ---- - -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStatic/env.d.ts b/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStatic/env.d.ts deleted file mode 100644 index 4e6b85c4ac1e..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStatic/env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// \ No newline at end of file diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStatic/pages/[id].astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStatic/pages/[id].astro deleted file mode 100644 index 1931fc8a6e5a..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStatic/pages/[id].astro +++ /dev/null @@ -1,16 +0,0 @@ ---- -import type { GetStaticPaths } from "astro"; - -export const getStaticPaths = (() => { - - return Array.from({length:100}).map((_, i) => ({ - params: { - id: i.toString() - } - })); -}) satisfies GetStaticPaths; - -const { id } = Astro.params; ---- - -id={id} diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStatic/pages/dynamic.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStatic/pages/dynamic.astro deleted file mode 100644 index 13502d70c372..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStatic/pages/dynamic.astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -export const prerender = false; ---- - -dynamic diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStaticWith404/env.d.ts b/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStaticWith404/env.d.ts deleted file mode 100644 index 4e6b85c4ac1e..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStaticWith404/env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// \ No newline at end of file diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStaticWith404/pages/404.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStaticWith404/pages/404.astro deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStaticWith404/pages/[id].astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStaticWith404/pages/[id].astro deleted file mode 100644 index 1931fc8a6e5a..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStaticWith404/pages/[id].astro +++ /dev/null @@ -1,16 +0,0 @@ ---- -import type { GetStaticPaths } from "astro"; - -export const getStaticPaths = (() => { - - return Array.from({length:100}).map((_, i) => ({ - params: { - id: i.toString() - } - })); -}) satisfies GetStaticPaths; - -const { id } = Astro.params; ---- - -id={id} diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStaticWith404/pages/dynamic.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStaticWith404/pages/dynamic.astro deleted file mode 100644 index 13502d70c372..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/manyStaticWith404/pages/dynamic.astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -export const prerender = false; ---- - -dynamic diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/env.d.ts b/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/env.d.ts deleted file mode 100644 index 1fc1db4594de..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/env.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -/// -/// diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/404.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/404.astro deleted file mode 100644 index 42af67a78f67..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/404.astro +++ /dev/null @@ -1,3 +0,0 @@ ---- -export const prerender = true; ---- diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/a/[...rest].astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/a/[...rest].astro deleted file mode 100644 index 9a2306b864fa..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/a/[...rest].astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -export const prerender=false; ---- - -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/a/[id].astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/a/[id].astro deleted file mode 100644 index 9a2306b864fa..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/a/[id].astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -export const prerender=false; ---- - -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/a/endpoint.ts b/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/a/endpoint.ts deleted file mode 100644 index d43d0cd2a55d..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/a/endpoint.ts +++ /dev/null @@ -1 +0,0 @@ -export const prerender = false; diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/a/index.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/a/index.astro deleted file mode 100644 index 9766475a4185..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/a/index.astro +++ /dev/null @@ -1 +0,0 @@ -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/b/index.html b/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/b/index.html deleted file mode 100644 index 9766475a4185..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/mixed/pages/b/index.html +++ /dev/null @@ -1 +0,0 @@ -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/env.d.ts b/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/env.d.ts deleted file mode 100644 index 2da76ba243c5..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/env.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -/// -/// \ No newline at end of file diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/404.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/404.astro deleted file mode 100644 index 42af67a78f67..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/404.astro +++ /dev/null @@ -1,3 +0,0 @@ ---- -export const prerender = true; ---- diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/dynamicPages/dynamic1.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/dynamicPages/dynamic1.astro deleted file mode 100644 index 9a2306b864fa..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/dynamicPages/dynamic1.astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -export const prerender=false; ---- - -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/dynamicPages/dynamic2.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/dynamicPages/dynamic2.astro deleted file mode 100644 index 9a2306b864fa..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/dynamicPages/dynamic2.astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -export const prerender=false; ---- - -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/dynamicPages/dynamic3.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/dynamicPages/dynamic3.astro deleted file mode 100644 index 9a2306b864fa..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/dynamicPages/dynamic3.astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -export const prerender=false; ---- - -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/index.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/index.astro deleted file mode 100644 index 9a2306b864fa..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/index.astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -export const prerender=false; ---- - -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/mixedPages/dynamic.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/mixedPages/dynamic.astro deleted file mode 100644 index 9a2306b864fa..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/mixedPages/dynamic.astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -export const prerender=false; ---- - -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/mixedPages/static.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/mixedPages/static.astro deleted file mode 100644 index d5683c216b8d..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/mixedPages/static.astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -export const prerender=true; ---- - -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/mixedPages/subfolder/dynamic.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/mixedPages/subfolder/dynamic.astro deleted file mode 100644 index 9a2306b864fa..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/mixedPages/subfolder/dynamic.astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -export const prerender=false; ---- - -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/mixedPages/subfolder/static.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/mixedPages/subfolder/static.astro deleted file mode 100644 index d5683c216b8d..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/mixedPages/subfolder/static.astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -export const prerender=true; ---- - -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/staticPages/static1.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/staticPages/static1.astro deleted file mode 100644 index d5683c216b8d..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/staticPages/static1.astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -export const prerender=true; ---- - -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/staticPages/static2.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/staticPages/static2.astro deleted file mode 100644 index d5683c216b8d..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/staticPages/static2.astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -export const prerender=true; ---- - -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/staticPages/static3.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/staticPages/static3.astro deleted file mode 100644 index d5683c216b8d..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/reduceComplexity/pages/staticPages/static3.astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -export const prerender=true; ---- - -ok diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/staticOnly/env.d.ts b/packages/integrations/cloudflare/test/fixtures/routes-json/src/staticOnly/env.d.ts deleted file mode 100644 index 2da76ba243c5..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/staticOnly/env.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -/// -/// \ No newline at end of file diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/staticOnly/pages/404.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/staticOnly/pages/404.astro deleted file mode 100644 index 42af67a78f67..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/staticOnly/pages/404.astro +++ /dev/null @@ -1,3 +0,0 @@ ---- -export const prerender = true; ---- diff --git a/packages/integrations/cloudflare/test/fixtures/routes-json/src/staticOnly/pages/index.astro b/packages/integrations/cloudflare/test/fixtures/routes-json/src/staticOnly/pages/index.astro deleted file mode 100644 index 9766475a4185..000000000000 --- a/packages/integrations/cloudflare/test/fixtures/routes-json/src/staticOnly/pages/index.astro +++ /dev/null @@ -1 +0,0 @@ -ok diff --git a/packages/integrations/cloudflare/test/routes-json.test.js b/packages/integrations/cloudflare/test/routes-json.test.js deleted file mode 100644 index 8f4b7bcfe5a0..000000000000 --- a/packages/integrations/cloudflare/test/routes-json.test.js +++ /dev/null @@ -1,351 +0,0 @@ -import * as assert from 'node:assert/strict'; -import { after, before, describe, it } from 'node:test'; -import cloudflare from '../dist/index.js'; -import { loadFixture } from './_test-utils.js'; - -describe('_routes.json generation', () => { - describe('of on-demand and prerenderd', () => { - /** @type {import('../../../astro/test/test-utils').Fixture} */ - let fixture; - - before(async () => { - fixture = await loadFixture({ - root: new URL('./fixtures/routes-json/', import.meta.url).toString(), - srcDir: './src/mixed', - adapter: cloudflare({}), - }); - await fixture.build(); - }); - - it('creates `include` for on-demand and `exclude` for prerenderd', async () => { - const _routesJson = await fixture.readFile('/_routes.json'); - const routes = JSON.parse(_routesJson); - - assert.deepEqual(routes, { - version: 1, - include: ['/_server-islands/*', '/_image', '/a/*'], - exclude: ['/_astro/*', '/redirectme', '/public.txt', '/a', '/a/redirect', '/404', '/b'], - }); - }); - }); - - describe('of only on-demand', () => { - let fixture; - - before(async () => { - fixture = await loadFixture({ - root: new URL('./fixtures/routes-json/', import.meta.url).toString(), - srcDir: './src/dynamicOnly', - adapter: cloudflare({}), - }); - await fixture.build(); - }); - - after(async () => { - await fixture.clean(); - }); - - it('creates a wildcard `include` and `exclude` only for static assets and redirects', async () => { - const _routesJson = await fixture.readFile('/_routes.json'); - const routes = JSON.parse(_routesJson); - - assert.deepEqual(routes, { - version: 1, - include: ['/*'], - exclude: ['/_astro/*', '/redirectme', '/public.txt', '/a/*'], - }); - }); - }); - - describe('of only prerenderd', () => { - let fixture; - - before(async () => { - fixture = await loadFixture({ - root: new URL('./fixtures/routes-json/', import.meta.url).toString(), - srcDir: './src/staticOnly', - adapter: cloudflare({}), - }); - await fixture.build(); - }); - - it( - 'create only one `include` and `exclude` that are supposed to match nothing', - { todo: 'Review test, because the expectation is to have empty include and exclude.' }, - async () => { - const _routesJson = await fixture.readFile('/_routes.json'); - const routes = JSON.parse(_routesJson); - - assert.deepEqual(routes, { - version: 1, - include: ['/_server-islands/*', '/_image'], - exclude: ['/', '/_astro/*', '/redirectme', '/public.txt', '/a/*', '/404'], - }); - }, - ); - }); - - describe('with additional `include` entries', () => { - let fixture; - - before(async () => { - fixture = await loadFixture({ - root: new URL('./fixtures/routes-json/', import.meta.url).toString(), - srcDir: './src/mixed', - adapter: cloudflare({ - routes: { - extend: { - include: [{ pattern: '/another' }], - }, - }, - }), - }); - await fixture.build(); - }); - - it('creates `include` for functions and `exclude` for static files where needed', async () => { - const _routesJson = await fixture.readFile('/_routes.json'); - const routes = JSON.parse(_routesJson); - - assert.deepEqual(routes, { - version: 1, - include: ['/_server-islands/*', '/_image', '/a/*', '/another'], - exclude: ['/_astro/*', '/redirectme', '/public.txt', '/a', '/a/redirect', '/404', '/b'], - }); - }); - }); - - describe('with additional `exclude` entries', () => { - let fixture; - - before(async () => { - fixture = await loadFixture({ - root: new URL('./fixtures/routes-json/', import.meta.url).toString(), - srcDir: './src/mixed', - adapter: cloudflare({ - routes: { - extend: { - exclude: [{ pattern: '/another' }, { pattern: '/a/index.html' }], - }, - }, - }), - }); - await fixture.build(); - }); - - it('creates `include` for functions and `exclude` for static files where needed', async () => { - const _routesJson = await fixture.readFile('/_routes.json'); - const routes = JSON.parse(_routesJson); - - assert.deepEqual(routes, { - version: 1, - include: ['/_server-islands/*', '/_image', '/a/*'], - exclude: [ - '/_astro/*', - '/redirectme', - '/public.txt', - '/a', - '/a/redirect', - '/404', - '/b', - '/another', - '/a/index.html', - ], - }); - }); - }); - - describe('with nested on demand and prerendered routes', () => { - let fixture; - - before(async () => { - fixture = await loadFixture({ - root: new URL('./fixtures/routes-json/', import.meta.url).toString(), - srcDir: './src/reduceComplexity', - adapter: cloudflare({}), - }); - await fixture.build(); - }); - - it('reduces the amount of include and exclude entries by applying wildcards wherever possible', async () => { - const _routesJson = await fixture.readFile('/_routes.json'); - const routes = JSON.parse(_routesJson); - - assert.deepEqual(routes, { - version: 1, - include: [ - '/', - '/_server-islands/*', - '/_image', - '/dynamicPages/*', - '/mixedPages/dynamic', - '/mixedPages/subfolder/dynamic', - ], - exclude: [ - '/_astro/*', - '/redirectme', - '/public.txt', - '/a/*', - '/404', - '/mixedPages/static', - '/mixedPages/subfolder/static', - '/staticPages/*', - ], - }); - }); - }); - - describe('with many static files', () => { - let fixture; - - before(async () => { - fixture = await loadFixture({ - root: new URL('./fixtures/routes-json/', import.meta.url).toString(), - srcDir: './src/manyStatic', - adapter: cloudflare({}), - }); - await fixture.build(); - }); - - it('creates a wildcard `include` and `exclude` for as many static assets and redirects as possible, truncating after 100 rules', async () => { - const _routesJson = await fixture.readFile('/_routes.json'); - const routes = JSON.parse(_routesJson); - - assert.deepEqual(routes, { - version: 1, - include: ['/*'], - exclude: [ - '/_astro/*', - '/redirectme', - '/public.txt', - '/a/*', - ...Array.from({ length: 95 }, (_, i) => `/${i}`), - ], - }); - }); - }); - - describe('with many static files when a static 404 is present', () => { - let fixture; - - before(async () => { - fixture = await loadFixture({ - root: new URL('./fixtures/routes-json/', import.meta.url).toString(), - srcDir: './src/manyStaticWith404', - adapter: cloudflare({}), - }); - await fixture.build(); - }); - - it('creates `include` for on-demand and `exclude` that are supposed to match nothing', async () => { - const _routesJson = await fixture.readFile('/_routes.json'); - const routes = JSON.parse(_routesJson); - - assert.deepEqual(routes, { - version: 1, - include: ['/*'], - exclude: [ - '/_astro/*', - '/redirectme', - '/public.txt', - '/a/*', - '/404', - '/0', - '/1', - '/2', - '/3', - '/4', - '/5', - '/6', - '/7', - '/8', - '/9', - '/10', - '/11', - '/12', - '/13', - '/14', - '/15', - '/16', - '/17', - '/18', - '/19', - '/20', - '/21', - '/22', - '/23', - '/24', - '/25', - '/26', - '/27', - '/28', - '/29', - '/30', - '/31', - '/32', - '/33', - '/34', - '/35', - '/36', - '/37', - '/38', - '/39', - '/40', - '/41', - '/42', - '/43', - '/44', - '/45', - '/46', - '/47', - '/48', - '/49', - '/50', - '/51', - '/52', - '/53', - '/54', - '/55', - '/56', - '/57', - '/58', - '/59', - '/60', - '/61', - '/62', - '/63', - '/64', - '/65', - '/66', - '/67', - '/68', - '/69', - '/70', - '/71', - '/72', - '/73', - '/74', - '/75', - '/76', - '/77', - '/78', - '/79', - '/80', - '/81', - '/82', - '/83', - '/84', - '/85', - '/86', - '/87', - '/88', - '/89', - '/90', - '/91', - '/92', - '/93', - ], - }); - }); - }); -}); diff --git a/packages/integrations/cloudflare/test/server-entry.test.js b/packages/integrations/cloudflare/test/server-entry.test.js index f61090e8f490..6c4c8e34ee9b 100644 --- a/packages/integrations/cloudflare/test/server-entry.test.js +++ b/packages/integrations/cloudflare/test/server-entry.test.js @@ -14,9 +14,7 @@ describe('Server entry', () => { await fixture.build(); - const itExits = existsSync( - fileURLToPath(new URL('_worker.js/custom.mjs', fixture.config.outDir)), - ); + const itExits = existsSync(fileURLToPath(new URL('server/custom.mjs', fixture.config.outDir))); assert.ok(itExits); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aa9d6052d23d..b39e91d38cca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5024,38 +5024,68 @@ importers: specifier: workspace:* version: link:../../../../../astro - packages/integrations/cloudflare/test/fixtures/no-output: + packages/integrations/cloudflare/test/fixtures/manual-pages-support: dependencies: '@astrojs/cloudflare': specifier: workspace:* version: link:../../.. + '@astrojs/mdx': + specifier: ^4.3.5 + version: 4.3.13(astro@packages+astro) + '@astrojs/react': + specifier: workspace:* + version: link:../../../../react + '@astrojs/vue': + specifier: workspace:* + version: link:../../../../vue + '@types/react': + specifier: ^18.3.24 + version: 18.3.28 + '@types/react-dom': + specifier: ^18.3.7 + version: 18.3.7(@types/react@18.3.28) + '@vitejs/plugin-vue': + specifier: ^6.0.2 + version: 6.0.4(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)) astro: specifier: workspace:* version: link:../../../../../astro + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + sharp: + specifier: ^0.34.3 + version: 0.34.5 + vue: + specifier: ^3.5.25 + version: 3.5.27(typescript@5.9.3) - packages/integrations/cloudflare/test/fixtures/prerender-styles: + packages/integrations/cloudflare/test/fixtures/no-output: dependencies: '@astrojs/cloudflare': specifier: workspace:* version: link:../../.. - '@tailwindcss/vite': - specifier: ^4.1.18 - version: 4.1.18(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2)) astro: specifier: workspace:* version: link:../../../../../astro - tailwindcss: - specifier: ^4.1.18 - version: 4.1.18 - packages/integrations/cloudflare/test/fixtures/routes-json: + packages/integrations/cloudflare/test/fixtures/prerender-styles: dependencies: '@astrojs/cloudflare': specifier: workspace:* version: link:../../.. + '@tailwindcss/vite': + specifier: ^4.1.18 + version: 4.1.18(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2)) astro: specifier: workspace:* version: link:../../../../../astro + tailwindcss: + specifier: ^4.1.18 + version: 4.1.18 packages/integrations/cloudflare/test/fixtures/routing-priority: dependencies: From 091de67b87706428db92c3b9af9b7de0dbc3aee2 Mon Sep 17 00:00:00 2001 From: Alexander Niebuhr Date: Mon, 16 Feb 2026 11:50:23 +0100 Subject: [PATCH 04/12] fix: lockfile (#15532) --- pnpm-lock.yaml | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b39e91d38cca..b2dfcbfe5f84 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5024,45 +5024,6 @@ importers: specifier: workspace:* version: link:../../../../../astro - packages/integrations/cloudflare/test/fixtures/manual-pages-support: - dependencies: - '@astrojs/cloudflare': - specifier: workspace:* - version: link:../../.. - '@astrojs/mdx': - specifier: ^4.3.5 - version: 4.3.13(astro@packages+astro) - '@astrojs/react': - specifier: workspace:* - version: link:../../../../react - '@astrojs/vue': - specifier: workspace:* - version: link:../../../../vue - '@types/react': - specifier: ^18.3.24 - version: 18.3.28 - '@types/react-dom': - specifier: ^18.3.7 - version: 18.3.7(@types/react@18.3.28) - '@vitejs/plugin-vue': - specifier: ^6.0.2 - version: 6.0.4(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)) - astro: - specifier: workspace:* - version: link:../../../../../astro - react: - specifier: ^18.3.1 - version: 18.3.1 - react-dom: - specifier: ^18.3.1 - version: 18.3.1(react@18.3.1) - sharp: - specifier: ^0.34.3 - version: 0.34.5 - vue: - specifier: ^3.5.25 - version: 3.5.27(typescript@5.9.3) - packages/integrations/cloudflare/test/fixtures/no-output: dependencies: '@astrojs/cloudflare': From e90856f273764e4c8b0b6334f9b0a2271d2281b8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 11:51:11 +0100 Subject: [PATCH 05/12] chore(deps): update github-actions to v6 (#15533) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build-sandbox-image.yml | 2 +- .github/workflows/issue-triage.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-sandbox-image.yml b/.github/workflows/build-sandbox-image.yml index a5551fcd4d49..38d06cce8afe 100644 --- a/.github/workflows/build-sandbox-image.yml +++ b/.github/workflows/build-sandbox-image.yml @@ -18,7 +18,7 @@ jobs: - name: Lowercase image name run: echo "IMAGE=${IMAGE,,}" >> "$GITHUB_ENV" - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: diff --git a/.github/workflows/issue-triage.yml b/.github/workflows/issue-triage.yml index 7ba93865d604..b51afff30604 100644 --- a/.github/workflows/issue-triage.yml +++ b/.github/workflows/issue-triage.yml @@ -38,7 +38,7 @@ jobs: run: echo "IMAGE=${IMAGE,,}" >> "$GITHUB_ENV" - name: Checkout - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Configure Git identity run: | @@ -49,7 +49,7 @@ jobs: uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 - name: Setup Node - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: 24.13.1 cache: pnpm From 33e95b903cc355117f90283718ac3de3cbe2a8ff Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 13:42:19 +0100 Subject: [PATCH 06/12] fix(deps): update astro dependencies (#15531) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .../e2e/fixtures/actions-blog/package.json | 2 +- .../e2e/fixtures/astro-envs/package.json | 2 +- .../e2e/fixtures/client-only/package.json | 4 +- .../e2e/fixtures/cloudflare/package.json | 6 +- .../astro/e2e/fixtures/errors/package.json | 4 +- .../fixtures/multiple-frameworks/package.json | 4 +- .../fixtures/nested-in-preact/package.json | 4 +- .../e2e/fixtures/nested-in-react/package.json | 4 +- .../e2e/fixtures/nested-in-solid/package.json | 4 +- .../fixtures/nested-in-svelte/package.json | 4 +- .../e2e/fixtures/nested-in-vue/package.json | 4 +- .../fixtures/nested-recursive/package.json | 4 +- .../fixtures/svelte-component/package.json | 2 +- .../fixtures/view-transitions/package.json | 4 +- .../e2e/fixtures/vue-component/package.json | 2 +- packages/astro/package.json | 10 +- .../performance/fixtures/md/package.json | 2 +- .../performance/fixtures/mdoc/package.json | 2 +- .../performance/fixtures/mdx/package.json | 2 +- .../astro/test/fixtures/0-css/package.json | 4 +- .../alias-tsconfig-baseurl-only/package.json | 2 +- .../test/fixtures/alias-tsconfig/package.json | 2 +- .../astro/test/fixtures/alias/package.json | 2 +- .../test/fixtures/astro-children/package.json | 4 +- .../fixtures/astro-client-only/package.json | 2 +- .../test/fixtures/astro-dynamic/package.json | 2 +- .../test/fixtures/astro-envs/package.json | 2 +- .../fixtures/astro-slots-nested/package.json | 4 +- .../fixtures/component-library/package.json | 2 +- .../container-custom-renderers/package.json | 2 +- .../css-dangling-references/package.json | 2 +- .../fixtures/css-deduplication/package.json | 2 +- .../astro/test/fixtures/fetch/package.json | 4 +- packages/astro/test/fixtures/jsx/package.json | 4 +- .../astro/test/fixtures/postcss/package.json | 6 +- .../fixtures/preact-component/package.json | 2 +- .../server-islands/hybrid/package.json | 2 +- .../fixtures/server-islands/ssr/package.json | 2 +- .../test/fixtures/slots-svelte/package.json | 2 +- .../test/fixtures/slots-vue/package.json | 2 +- .../fixtures/svelte-component/package.json | 2 +- .../test/fixtures/vue-component/package.json | 2 +- .../astro/test/fixtures/vue-jsx/package.json | 2 +- .../vue-with-multi-renderer/package.json | 4 +- pnpm-lock.yaml | 221 ++++++++---------- 45 files changed, 160 insertions(+), 197 deletions(-) diff --git a/packages/astro/e2e/fixtures/actions-blog/package.json b/packages/astro/e2e/fixtures/actions-blog/package.json index 3627bbaab014..c5ee22becbec 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.27", + "@types/react": "^18.3.28", "@types/react-dom": "^18.3.7", "astro": "workspace:*", "react": "^18.3.1", diff --git a/packages/astro/e2e/fixtures/astro-envs/package.json b/packages/astro/e2e/fixtures/astro-envs/package.json index ca0170b964bd..fed7f2e282b6 100644 --- a/packages/astro/e2e/fixtures/astro-envs/package.json +++ b/packages/astro/e2e/fixtures/astro-envs/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "vue": "^3.5.27" + "vue": "^3.5.28" } } diff --git a/packages/astro/e2e/fixtures/client-only/package.json b/packages/astro/e2e/fixtures/client-only/package.json index 565105bd5ff9..2b5eab5e7a4e 100644 --- a/packages/astro/e2e/fixtures/client-only/package.json +++ b/packages/astro/e2e/fixtures/client-only/package.json @@ -15,7 +15,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "solid-js": "^1.9.11", - "svelte": "^5.49.1", - "vue": "^3.5.27" + "svelte": "^5.50.3", + "vue": "^3.5.28" } } diff --git a/packages/astro/e2e/fixtures/cloudflare/package.json b/packages/astro/e2e/fixtures/cloudflare/package.json index 1ad687ad736b..e722a46d90eb 100644 --- a/packages/astro/e2e/fixtures/cloudflare/package.json +++ b/packages/astro/e2e/fixtures/cloudflare/package.json @@ -14,9 +14,9 @@ "@astrojs/vue": "workspace:*", "preact": "^10.28.3", "@test/e2e-my-lib": "workspace:*", - "vue": "^3.5.27", - "@vitejs/plugin-vue": "^6.0.3", - "@types/react": "^18.3.27", + "vue": "^3.5.28", + "@vitejs/plugin-vue": "^6.0.4", + "@types/react": "^18.3.28", "@types/react-dom": "^18.3.7", "astro": "workspace:*", "clsx": "^2.1.1", diff --git a/packages/astro/e2e/fixtures/errors/package.json b/packages/astro/e2e/fixtures/errors/package.json index 971a8e46322e..5313c72e36e1 100644 --- a/packages/astro/e2e/fixtures/errors/package.json +++ b/packages/astro/e2e/fixtures/errors/package.json @@ -14,7 +14,7 @@ "react-dom": "^18.3.1", "sass": "^1.97.3", "solid-js": "^1.9.11", - "svelte": "^5.49.1", - "vue": "^3.5.27" + "svelte": "^5.50.3", + "vue": "^3.5.28" } } diff --git a/packages/astro/e2e/fixtures/multiple-frameworks/package.json b/packages/astro/e2e/fixtures/multiple-frameworks/package.json index b4afa323937d..ad20cf5eeab4 100644 --- a/packages/astro/e2e/fixtures/multiple-frameworks/package.json +++ b/packages/astro/e2e/fixtures/multiple-frameworks/package.json @@ -17,7 +17,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "solid-js": "^1.9.11", - "svelte": "^5.49.1", - "vue": "^3.5.27" + "svelte": "^5.50.3", + "vue": "^3.5.28" } } diff --git a/packages/astro/e2e/fixtures/nested-in-preact/package.json b/packages/astro/e2e/fixtures/nested-in-preact/package.json index 006ab217d3c6..068aec903a7f 100644 --- a/packages/astro/e2e/fixtures/nested-in-preact/package.json +++ b/packages/astro/e2e/fixtures/nested-in-preact/package.json @@ -15,7 +15,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "solid-js": "^1.9.11", - "svelte": "^5.49.1", - "vue": "^3.5.27" + "svelte": "^5.50.3", + "vue": "^3.5.28" } } diff --git a/packages/astro/e2e/fixtures/nested-in-react/package.json b/packages/astro/e2e/fixtures/nested-in-react/package.json index af92a9cfa9e2..7ba9195043c6 100644 --- a/packages/astro/e2e/fixtures/nested-in-react/package.json +++ b/packages/astro/e2e/fixtures/nested-in-react/package.json @@ -15,7 +15,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "solid-js": "^1.9.11", - "svelte": "^5.49.1", - "vue": "^3.5.27" + "svelte": "^5.50.3", + "vue": "^3.5.28" } } diff --git a/packages/astro/e2e/fixtures/nested-in-solid/package.json b/packages/astro/e2e/fixtures/nested-in-solid/package.json index 1e07223e103a..76f234c7a6db 100644 --- a/packages/astro/e2e/fixtures/nested-in-solid/package.json +++ b/packages/astro/e2e/fixtures/nested-in-solid/package.json @@ -15,7 +15,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "solid-js": "^1.9.11", - "svelte": "^5.49.1", - "vue": "^3.5.27" + "svelte": "^5.50.3", + "vue": "^3.5.28" } } diff --git a/packages/astro/e2e/fixtures/nested-in-svelte/package.json b/packages/astro/e2e/fixtures/nested-in-svelte/package.json index a714ec31b550..325ee50908be 100644 --- a/packages/astro/e2e/fixtures/nested-in-svelte/package.json +++ b/packages/astro/e2e/fixtures/nested-in-svelte/package.json @@ -15,7 +15,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "solid-js": "^1.9.11", - "svelte": "^5.49.1", - "vue": "^3.5.27" + "svelte": "^5.50.3", + "vue": "^3.5.28" } } diff --git a/packages/astro/e2e/fixtures/nested-in-vue/package.json b/packages/astro/e2e/fixtures/nested-in-vue/package.json index 31db4833f278..f342f7641c6c 100644 --- a/packages/astro/e2e/fixtures/nested-in-vue/package.json +++ b/packages/astro/e2e/fixtures/nested-in-vue/package.json @@ -15,7 +15,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "solid-js": "^1.9.11", - "svelte": "^5.49.1", - "vue": "^3.5.27" + "svelte": "^5.50.3", + "vue": "^3.5.28" } } diff --git a/packages/astro/e2e/fixtures/nested-recursive/package.json b/packages/astro/e2e/fixtures/nested-recursive/package.json index b6e816ef3dd4..974a1e8398b7 100644 --- a/packages/astro/e2e/fixtures/nested-recursive/package.json +++ b/packages/astro/e2e/fixtures/nested-recursive/package.json @@ -15,8 +15,8 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "solid-js": "^1.9.11", - "svelte": "^5.49.1", - "vue": "^3.5.27" + "svelte": "^5.50.3", + "vue": "^3.5.28" }, "scripts": { "dev": "astro dev" diff --git a/packages/astro/e2e/fixtures/svelte-component/package.json b/packages/astro/e2e/fixtures/svelte-component/package.json index b4cbce10ac1e..74442ab80682 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": "^5.49.1" + "svelte": "^5.50.3" } } diff --git a/packages/astro/e2e/fixtures/view-transitions/package.json b/packages/astro/e2e/fixtures/view-transitions/package.json index dc2156eac5ea..7f5cb4c201fc 100644 --- a/packages/astro/e2e/fixtures/view-transitions/package.json +++ b/packages/astro/e2e/fixtures/view-transitions/package.json @@ -12,7 +12,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "solid-js": "^1.9.11", - "svelte": "^5.49.1", - "vue": "^3.5.27" + "svelte": "^5.50.3", + "vue": "^3.5.28" } } diff --git a/packages/astro/e2e/fixtures/vue-component/package.json b/packages/astro/e2e/fixtures/vue-component/package.json index 20f98d51cbe7..3fd6b07fda0c 100644 --- a/packages/astro/e2e/fixtures/vue-component/package.json +++ b/packages/astro/e2e/fixtures/vue-component/package.json @@ -6,6 +6,6 @@ "@astrojs/mdx": "workspace:*", "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "vue": "^3.5.27" + "vue": "^3.5.28" } } diff --git a/packages/astro/package.json b/packages/astro/package.json index 3ca3ac051683..161d9d923cca 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -146,16 +146,16 @@ "http-cache-semantics": "^4.2.0", "js-yaml": "^4.1.1", "magic-string": "^0.30.21", - "magicast": "^0.5.1", + "magicast": "^0.5.2", "mrmime": "^2.0.1", "neotraverse": "^0.6.18", - "p-limit": "^7.2.0", + "p-limit": "^7.3.0", "p-queue": "^9.1.0", "package-manager-detector": "^1.6.0", "piccolore": "^0.1.3", "picomatch": "^4.0.3", "rehype": "^13.0.2", - "semver": "^7.7.3", + "semver": "^7.7.4", "shiki": "^3.22.0", "smol-toml": "^1.6.0", "svgo": "^4.0.0", @@ -178,7 +178,7 @@ }, "devDependencies": { "@astrojs/check": "workspace:*", - "@playwright/test": "1.58.1", + "@playwright/test": "1.58.2", "@types/aria-query": "^5.0.4", "@types/cssesc": "^3.0.2", "@types/debug": "^4.1.12", @@ -206,7 +206,7 @@ "rollup": "^4.57.1", "sass": "^1.97.3", "typescript": "^5.9.3", - "undici": "^7.19.2", + "undici": "^7.21.0", "unified": "^11.0.5", "vitest": "^3.2.4" }, diff --git a/packages/astro/performance/fixtures/md/package.json b/packages/astro/performance/fixtures/md/package.json index bd931aa47f00..9237ac74476b 100644 --- a/packages/astro/performance/fixtures/md/package.json +++ b/packages/astro/performance/fixtures/md/package.json @@ -14,7 +14,7 @@ "dependencies": { "@astrojs/react": "workspace:*", "@performance/utils": "workspace:*", - "@types/react": "^18.3.27", + "@types/react": "^18.3.28", "@types/react-dom": "^18.3.7", "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 97b0cd3a6a30..f98097c556d6 100644 --- a/packages/astro/performance/fixtures/mdoc/package.json +++ b/packages/astro/performance/fixtures/mdoc/package.json @@ -15,7 +15,7 @@ "@astrojs/markdoc": "workspace:*", "@astrojs/react": "workspace:*", "@performance/utils": "workspace:*", - "@types/react": "^18.3.27", + "@types/react": "^18.3.28", "@types/react-dom": "^18.3.7", "astro": "workspace:*", "react": "^18.3.1", diff --git a/packages/astro/performance/fixtures/mdx/package.json b/packages/astro/performance/fixtures/mdx/package.json index e93f6875de9e..57869acb77f9 100644 --- a/packages/astro/performance/fixtures/mdx/package.json +++ b/packages/astro/performance/fixtures/mdx/package.json @@ -15,7 +15,7 @@ "@astrojs/mdx": "workspace:*", "@astrojs/react": "workspace:*", "@performance/utils": "workspace:*", - "@types/react": "^18.3.27", + "@types/react": "^18.3.28", "@types/react-dom": "^18.3.7", "astro": "workspace:*", "react": "^18.3.1", diff --git a/packages/astro/test/fixtures/0-css/package.json b/packages/astro/test/fixtures/0-css/package.json index a71bc78f80f0..0287cc2e35a6 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": "^5.49.1", - "vue": "^3.5.27" + "svelte": "^5.50.3", + "vue": "^3.5.28" } } 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 4dde5d3bc7c5..a1bdf2f29cd7 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": "^5.49.1" + "svelte": "^5.50.3" } } diff --git a/packages/astro/test/fixtures/alias-tsconfig/package.json b/packages/astro/test/fixtures/alias-tsconfig/package.json index 8748e08373e2..25fbb46048cc 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": "^5.49.1" + "svelte": "^5.50.3" } } diff --git a/packages/astro/test/fixtures/alias/package.json b/packages/astro/test/fixtures/alias/package.json index c8a1bb06ed6e..df1da2ed17ea 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": "^5.49.1" + "svelte": "^5.50.3" } } diff --git a/packages/astro/test/fixtures/astro-children/package.json b/packages/astro/test/fixtures/astro-children/package.json index b1e1d137a0d1..4ba99302492f 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.28.3", - "svelte": "^5.49.1", - "vue": "^3.5.27" + "svelte": "^5.50.3", + "vue": "^3.5.28" } } diff --git a/packages/astro/test/fixtures/astro-client-only/package.json b/packages/astro/test/fixtures/astro-client-only/package.json index 83282fcc4e90..d07669535683 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": "^5.49.1" + "svelte": "^5.50.3" } } diff --git a/packages/astro/test/fixtures/astro-dynamic/package.json b/packages/astro/test/fixtures/astro-dynamic/package.json index 220a3300d546..608fb8082ff6 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": "^5.49.1" + "svelte": "^5.50.3" } } diff --git a/packages/astro/test/fixtures/astro-envs/package.json b/packages/astro/test/fixtures/astro-envs/package.json index 789a3b70db7d..84041411cbd2 100644 --- a/packages/astro/test/fixtures/astro-envs/package.json +++ b/packages/astro/test/fixtures/astro-envs/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "vue": "^3.5.27" + "vue": "^3.5.28" } } diff --git a/packages/astro/test/fixtures/astro-slots-nested/package.json b/packages/astro/test/fixtures/astro-slots-nested/package.json index ff9c8b90ea0b..437679b2e44e 100644 --- a/packages/astro/test/fixtures/astro-slots-nested/package.json +++ b/packages/astro/test/fixtures/astro-slots-nested/package.json @@ -13,7 +13,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "solid-js": "^1.9.11", - "svelte": "^5.49.1", - "vue": "^3.5.27" + "svelte": "^5.50.3", + "vue": "^3.5.28" } } diff --git a/packages/astro/test/fixtures/component-library/package.json b/packages/astro/test/fixtures/component-library/package.json index 28237d2df0f1..26f2d061b146 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.28.3", "react": "^18.3.1", "react-dom": "^18.3.1", - "svelte": "^5.49.1" + "svelte": "^5.50.3" } } diff --git a/packages/astro/test/fixtures/container-custom-renderers/package.json b/packages/astro/test/fixtures/container-custom-renderers/package.json index 18add9583bad..762988734c8a 100644 --- a/packages/astro/test/fixtures/container-custom-renderers/package.json +++ b/packages/astro/test/fixtures/container-custom-renderers/package.json @@ -9,6 +9,6 @@ "astro": "workspace:*", "react": "^18.3.1", "react-dom": "^18.3.1", - "vue": "^3.5.27" + "vue": "^3.5.28" } } diff --git a/packages/astro/test/fixtures/css-dangling-references/package.json b/packages/astro/test/fixtures/css-dangling-references/package.json index ca57e37de35f..e299cf9ae95a 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": "^5.49.1" + "svelte": "^5.50.3" } } diff --git a/packages/astro/test/fixtures/css-deduplication/package.json b/packages/astro/test/fixtures/css-deduplication/package.json index edc31c98c31a..314960a97772 100644 --- a/packages/astro/test/fixtures/css-deduplication/package.json +++ b/packages/astro/test/fixtures/css-deduplication/package.json @@ -5,7 +5,7 @@ "dependencies": { "astro": "workspace:*", "@astrojs/react": "workspace:*", - "@types/react": "^18.3.27", + "@types/react": "^18.3.28", "@types/react-dom": "^18.3.7", "react": "^18.3.1", "react-dom": "^18.3.1" diff --git a/packages/astro/test/fixtures/fetch/package.json b/packages/astro/test/fixtures/fetch/package.json index b0eb755e7040..e09f1a2672bb 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.28.3", - "svelte": "^5.49.1", - "vue": "^3.5.27" + "svelte": "^5.50.3", + "vue": "^3.5.28" } } diff --git a/packages/astro/test/fixtures/jsx/package.json b/packages/astro/test/fixtures/jsx/package.json index 98bf7820bf70..3570e8ef431b 100644 --- a/packages/astro/test/fixtures/jsx/package.json +++ b/packages/astro/test/fixtures/jsx/package.json @@ -16,7 +16,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "solid-js": "^1.9.11", - "svelte": "^5.49.1", - "vue": "^3.5.27" + "svelte": "^5.50.3", + "vue": "^3.5.28" } } diff --git a/packages/astro/test/fixtures/postcss/package.json b/packages/astro/test/fixtures/postcss/package.json index f6b37dcc20e8..3dc53b9b879b 100644 --- a/packages/astro/test/fixtures/postcss/package.json +++ b/packages/astro/test/fixtures/postcss/package.json @@ -10,10 +10,10 @@ "autoprefixer": "^10.4.24", "postcss": "^8.5.6", "solid-js": "^1.9.11", - "svelte": "^5.49.1", - "vue": "^3.5.27" + "svelte": "^5.50.3", + "vue": "^3.5.28" }, "devDependencies": { - "postcss-preset-env": "^11.1.2" + "postcss-preset-env": "^11.1.3" } } diff --git a/packages/astro/test/fixtures/preact-component/package.json b/packages/astro/test/fixtures/preact-component/package.json index e985146b9f1f..538fa60b0703 100644 --- a/packages/astro/test/fixtures/preact-component/package.json +++ b/packages/astro/test/fixtures/preact-component/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "@astrojs/preact": "workspace:*", - "@preact/signals": "2.6.2", + "@preact/signals": "2.7.1", "astro": "workspace:*", "preact": "^10.28.3" } diff --git a/packages/astro/test/fixtures/server-islands/hybrid/package.json b/packages/astro/test/fixtures/server-islands/hybrid/package.json index 1055c55637ee..1384a37d530c 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": "^5.49.1" + "svelte": "^5.50.3" } } diff --git a/packages/astro/test/fixtures/server-islands/ssr/package.json b/packages/astro/test/fixtures/server-islands/ssr/package.json index 26e469098126..3b601121b261 100644 --- a/packages/astro/test/fixtures/server-islands/ssr/package.json +++ b/packages/astro/test/fixtures/server-islands/ssr/package.json @@ -6,6 +6,6 @@ "@astrojs/mdx": "workspace:*", "@astrojs/svelte": "workspace:*", "astro": "workspace:*", - "svelte": "^5.49.1" + "svelte": "^5.50.3" } } diff --git a/packages/astro/test/fixtures/slots-svelte/package.json b/packages/astro/test/fixtures/slots-svelte/package.json index a487ebc85127..8500b9875040 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": "^5.49.1" + "svelte": "^5.50.3" } } diff --git a/packages/astro/test/fixtures/slots-vue/package.json b/packages/astro/test/fixtures/slots-vue/package.json index 247978de0e0e..fbae4fce4130 100644 --- a/packages/astro/test/fixtures/slots-vue/package.json +++ b/packages/astro/test/fixtures/slots-vue/package.json @@ -6,6 +6,6 @@ "@astrojs/mdx": "workspace:*", "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "vue": "^3.5.27" + "vue": "^3.5.28" } } diff --git a/packages/astro/test/fixtures/svelte-component/package.json b/packages/astro/test/fixtures/svelte-component/package.json index 294c95dea437..20a0ac768713 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": "^5.49.1" + "svelte": "^5.50.3" } } diff --git a/packages/astro/test/fixtures/vue-component/package.json b/packages/astro/test/fixtures/vue-component/package.json index 19eb1ed93ed9..66608bc08098 100644 --- a/packages/astro/test/fixtures/vue-component/package.json +++ b/packages/astro/test/fixtures/vue-component/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "vue": "^3.5.27" + "vue": "^3.5.28" } } diff --git a/packages/astro/test/fixtures/vue-jsx/package.json b/packages/astro/test/fixtures/vue-jsx/package.json index 1b842740ac02..32334683dff6 100644 --- a/packages/astro/test/fixtures/vue-jsx/package.json +++ b/packages/astro/test/fixtures/vue-jsx/package.json @@ -5,6 +5,6 @@ "dependencies": { "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "vue": "^3.5.27" + "vue": "^3.5.28" } } 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 736c346ed2f8..e8dcc15c670a 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": "^5.49.1", - "vue": "^3.5.27" + "svelte": "^5.50.3", + "vue": "^3.5.28" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b2dfcbfe5f84..f6e6e686012a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -300,7 +300,7 @@ importers: version: link:../../packages/integrations/preact '@preact/signals': specifier: ^2.7.1 - version: 2.8.0(preact@10.28.3) + version: 2.7.1(preact@10.28.3) astro: specifier: ^6.0.0-beta.11 version: link:../../packages/astro @@ -593,8 +593,8 @@ importers: specifier: ^0.30.21 version: 0.30.21 magicast: - specifier: ^0.5.1 - version: 0.5.1 + specifier: ^0.5.2 + version: 0.5.2 mrmime: specifier: ^2.0.1 version: 2.0.1 @@ -602,7 +602,7 @@ importers: specifier: ^0.6.18 version: 0.6.18 p-limit: - specifier: ^7.2.0 + specifier: ^7.3.0 version: 7.3.0 p-queue: specifier: ^9.1.0 @@ -620,7 +620,7 @@ importers: specifier: ^13.0.2 version: 13.0.2 semver: - specifier: ^7.7.3 + specifier: ^7.7.4 version: 7.7.4 shiki: specifier: ^3.22.0 @@ -675,8 +675,8 @@ importers: specifier: workspace:* version: link:../language-tools/astro-check '@playwright/test': - specifier: 1.58.1 - version: 1.58.1 + specifier: 1.58.2 + version: 1.58.2 '@types/aria-query': specifier: ^5.0.4 version: 5.0.4 @@ -759,8 +759,8 @@ importers: specifier: ^5.9.3 version: 5.9.3 undici: - specifier: ^7.19.2 - version: 7.20.0 + specifier: ^7.21.0 + version: 7.22.0 unified: specifier: ^11.0.5 version: 11.0.5 @@ -828,7 +828,7 @@ importers: specifier: workspace:* version: link:../../../../integrations/react '@types/react': - specifier: ^18.3.27 + specifier: ^18.3.28 version: 18.3.28 '@types/react-dom': specifier: ^18.3.7 @@ -903,7 +903,7 @@ importers: specifier: workspace:* version: link:../../.. vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/astro/e2e/fixtures/client-idle-timeout: @@ -937,10 +937,10 @@ importers: specifier: ^1.9.11 version: 1.9.11 svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) devDependencies: '@astrojs/preact': @@ -983,13 +983,13 @@ importers: specifier: workspace:* version: link:packages/my-lib '@types/react': - specifier: ^18.3.27 + specifier: ^18.3.28 version: 18.3.28 '@types/react-dom': specifier: ^18.3.7 version: 18.3.7(@types/react@18.3.28) '@vitejs/plugin-vue': - specifier: ^6.0.3 + specifier: ^6.0.4 version: 6.0.4(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.28(typescript@5.9.3)) astro: specifier: workspace:* @@ -1010,7 +1010,7 @@ importers: specifier: ^0.34.3 version: 0.34.5 vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/astro/e2e/fixtures/cloudflare/packages/my-lib: {} @@ -1135,10 +1135,10 @@ importers: specifier: ^1.9.11 version: 1.9.11 svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/astro/e2e/fixtures/hmr: @@ -1192,10 +1192,10 @@ importers: specifier: ^1.9.11 version: 1.9.11 svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) devDependencies: '@astrojs/preact': @@ -1248,10 +1248,10 @@ importers: specifier: ^1.9.11 version: 1.9.11 svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) devDependencies: '@astrojs/preact': @@ -1288,10 +1288,10 @@ importers: specifier: ^1.9.11 version: 1.9.11 svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) devDependencies: '@astrojs/preact': @@ -1328,10 +1328,10 @@ importers: specifier: ^1.9.11 version: 1.9.11 svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) devDependencies: '@astrojs/preact': @@ -1368,10 +1368,10 @@ importers: specifier: ^1.9.11 version: 1.9.11 svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) devDependencies: '@astrojs/preact': @@ -1408,10 +1408,10 @@ importers: specifier: ^1.9.11 version: 1.9.11 svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) devDependencies: '@astrojs/preact': @@ -1448,10 +1448,10 @@ importers: specifier: ^1.9.11 version: 1.9.11 svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) devDependencies: '@astrojs/preact': @@ -1644,7 +1644,7 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 packages/astro/e2e/fixtures/tailwindcss: @@ -1704,10 +1704,10 @@ importers: specifier: ^1.9.11 version: 1.9.11 svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/astro/e2e/fixtures/vite-virtual-modules: @@ -1728,7 +1728,7 @@ importers: specifier: workspace:* version: link:../../.. vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/astro/performance: @@ -1746,7 +1746,7 @@ importers: specifier: workspace:* version: link:../utils '@types/react': - specifier: ^18.3.27 + specifier: ^18.3.28 version: 18.3.28 '@types/react-dom': specifier: ^18.3.7 @@ -1773,7 +1773,7 @@ importers: specifier: workspace:* version: link:../utils '@types/react': - specifier: ^18.3.27 + specifier: ^18.3.28 version: 18.3.28 '@types/react-dom': specifier: ^18.3.7 @@ -1800,7 +1800,7 @@ importers: specifier: workspace:* version: link:../utils '@types/react': - specifier: ^18.3.27 + specifier: ^18.3.28 version: 18.3.28 '@types/react-dom': specifier: ^18.3.7 @@ -1848,10 +1848,10 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/astro/test/fixtures/actions: @@ -1869,7 +1869,7 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 packages/astro/test/fixtures/alias-tsconfig: @@ -1884,7 +1884,7 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 packages/astro/test/fixtures/alias-tsconfig-baseurl-only: @@ -1896,7 +1896,7 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 packages/astro/test/fixtures/alias-tsconfig-no-baseurl: @@ -2042,10 +2042,10 @@ importers: specifier: ^10.28.3 version: 10.28.3 svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/astro/test/fixtures/astro-class-list: @@ -2075,7 +2075,7 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 packages/astro/test/fixtures/astro-client-only/pkg: {} @@ -2167,7 +2167,7 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 packages/astro/test/fixtures/astro-env: @@ -2209,7 +2209,7 @@ importers: specifier: workspace:* version: link:../../.. vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/astro/test/fixtures/astro-expr: @@ -2542,10 +2542,10 @@ importers: specifier: ^1.9.11 version: 1.9.11 svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/astro/test/fixtures/before-hydration: @@ -2632,7 +2632,7 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 packages/astro/test/fixtures/component-library-shared: @@ -2690,7 +2690,7 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/astro/test/fixtures/content: @@ -3028,7 +3028,7 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 packages/astro/test/fixtures/css-deduplication: @@ -3037,7 +3037,7 @@ importers: specifier: workspace:* version: link:../../../../integrations/react '@types/react': - specifier: ^18.3.27 + specifier: ^18.3.28 version: 18.3.28 '@types/react-dom': specifier: ^18.3.7 @@ -3343,10 +3343,10 @@ importers: specifier: ^10.28.3 version: 10.28.3 svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/astro/test/fixtures/fonts: @@ -3598,10 +3598,10 @@ importers: specifier: ^1.9.11 version: 1.9.11 svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) devDependencies: '@astrojs/mdx': @@ -3813,15 +3813,15 @@ importers: specifier: ^1.9.11 version: 1.9.11 svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) devDependencies: postcss-preset-env: - specifier: ^11.1.2 - version: 11.1.2(postcss@8.5.6) + specifier: ^11.1.3 + version: 11.1.3(postcss@8.5.6) packages/astro/test/fixtures/preact-compat-component: dependencies: @@ -3850,8 +3850,8 @@ importers: specifier: workspace:* version: link:../../../../integrations/preact '@preact/signals': - specifier: 2.6.2 - version: 2.6.2(preact@10.28.3) + specifier: 2.7.1 + version: 2.7.1(preact@10.28.3) astro: specifier: workspace:* version: link:../../.. @@ -4079,7 +4079,7 @@ importers: specifier: workspace:* version: link:../../../.. svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 packages/astro/test/fixtures/server-islands/ssr: @@ -4094,7 +4094,7 @@ importers: specifier: workspace:* version: link:../../../.. svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 packages/astro/test/fixtures/sessions: @@ -4169,7 +4169,7 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 packages/astro/test/fixtures/slots-vue: @@ -4184,7 +4184,7 @@ importers: specifier: workspace:* version: link:../../.. vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/astro/test/fixtures/solid-component: @@ -4483,7 +4483,7 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 packages/astro/test/fixtures/svg-deduplication: @@ -4585,7 +4585,7 @@ importers: specifier: workspace:* version: link:../../.. vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/astro/test/fixtures/vue-jsx: @@ -4597,7 +4597,7 @@ importers: specifier: workspace:* version: link:../../.. vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/astro/test/fixtures/vue-with-multi-renderer: @@ -4612,10 +4612,10 @@ importers: specifier: workspace:* version: link:../../.. svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 vue: - specifier: ^3.5.27 + specifier: ^3.5.28 version: 3.5.28(typescript@5.9.3) packages/astro/test/fixtures/with-endpoint-routes: @@ -6062,7 +6062,7 @@ importers: version: 2.10.3(@babel/core@7.29.0)(preact@10.28.3)(rollup@4.57.1)(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.3)(tsx@4.21.0)(yaml@2.8.2)) '@preact/signals': specifier: ^2.7.1 - version: 2.8.0(preact@10.28.3) + version: 2.7.1(preact@10.28.3) preact-render-to-string: specifier: ^6.6.5 version: 6.6.5(preact@10.28.3) @@ -7914,8 +7914,8 @@ packages: peerDependencies: postcss: ^8.4 - '@csstools/postcss-text-decoration-shorthand@5.0.1': - resolution: {integrity: sha512-yH9VyYE1LFLfyp6fYMLSUVON7vILzp1U2NkiCEIi7FM0M5thKd4XJJioD2a2a4t5sHwKesVaGyg89k2Hf1z0Sg==} + '@csstools/postcss-text-decoration-shorthand@5.0.2': + resolution: {integrity: sha512-0VUTt79lfQ2LGQLfyOBeqpinDLzOf3w+tlA1Re/KjSOc86H6tRz6TeXbISrBSJlfM1fYKNmBNw+ON8Ovy6aNeg==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -9654,11 +9654,6 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@playwright/test@1.58.1': - resolution: {integrity: sha512-6LdVIUERWxQMmUSSQi0I53GgCBYgM2RpGngCPY7hSeju+VrKjq3lvs7HpJoPbDiY5QM5EYRtRX5fvrinnMAz3w==} - engines: {node: '>=18'} - hasBin: true - '@playwright/test@1.58.2': resolution: {integrity: sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA==} engines: {node: '>=18'} @@ -9685,13 +9680,8 @@ packages: '@preact/signals-core@1.13.0': resolution: {integrity: sha512-slT6XeTCAbdql61GVLlGU4x7XHI7kCZV5Um5uhE4zLX4ApgiiXc0UYFvVOKq06xcovzp7p+61l68oPi563ARKg==} - '@preact/signals@2.6.2': - resolution: {integrity: sha512-80PMfNS3d8t/J3cRNEJP14zRioWnavgqzX/+tsNGiCX6rpD26+eLkUQpa1sIeOERZMink+dAi34y0MJhg11LKQ==} - peerDependencies: - preact: '>= 10.25.0 || >=11.0.0-0' - - '@preact/signals@2.8.0': - resolution: {integrity: sha512-lcILM82mei8s/53n2M6uZlrDHLlgLld8Squ0PVSUL5Ae1M45uEstWfHm+wcDqp2U5I/ZYrBvCY65udFyTo5OZw==} + '@preact/signals@2.7.1': + resolution: {integrity: sha512-mP2+wMYHqDXVKFGzjqkL6CiHj3okB8eVTTJUZBrSVGozi/XfA+zZRCEALKKZYRoSoqLyT4J6qM4lhwT9155s1Q==} peerDependencies: preact: '>= 10.25.0 || >=11.0.0-0' @@ -13257,8 +13247,8 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - magicast@0.5.1: - resolution: {integrity: sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==} + magicast@0.5.2: + resolution: {integrity: sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==} make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} @@ -14105,21 +14095,11 @@ packages: pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - playwright-core@1.58.1: - resolution: {integrity: sha512-bcWzOaTxcW+VOOGBCQgnaKToLJ65d6AqfLVKEWvexyS3AS6rbXl+xdpYRMGSRBClPvyj44njOWoxjNdL/H9UNg==} - engines: {node: '>=18'} - hasBin: true - playwright-core@1.58.2: resolution: {integrity: sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==} engines: {node: '>=18'} hasBin: true - playwright@1.58.1: - resolution: {integrity: sha512-+2uTZHxSCcxjvGc5C891LrS1/NlxglGxzrC4seZiVjcYVQfUa87wBL6rTDqzGjuoWNjnBzRqKmF6zRYGMvQUaQ==} - engines: {node: '>=18'} - hasBin: true - playwright@1.58.2: resolution: {integrity: sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==} engines: {node: '>=18'} @@ -14265,8 +14245,8 @@ packages: peerDependencies: postcss: ^8.4 - postcss-preset-env@11.1.2: - resolution: {integrity: sha512-rtRQeKP7xZgAAE4YSxjYyX62qpgn9n7BczxtpA0AP4u9JYn1wfUhsd3ZmV9mi8IlU111aF1TtJMqT/QhmtAgLA==} + postcss-preset-env@11.1.3: + resolution: {integrity: sha512-kZOfgzUc52yq2fJRZig7sHgWaHJoDOLABBoswe6TPTHgW3581VkP3eRj+Silhc7cJTomMjZZsyRHNjQ+bW11Gg==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -15463,8 +15443,8 @@ packages: resolution: {integrity: sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw==} engines: {node: '>=20.18.1'} - undici@7.20.0: - resolution: {integrity: sha512-MJZrkjyd7DeC+uPZh+5/YaMDxFiiEEaDgbUSVMXayofAkDWF1088CDo+2RPg7B1BuS1qf1vgNE7xqwPxE0DuSQ==} + undici@7.22.0: + resolution: {integrity: sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==} engines: {node: '>=20.18.1'} unenv@2.0.0-rc.24: @@ -17494,7 +17474,7 @@ snapshots: '@csstools/css-tokenizer': 4.0.0 postcss: 8.5.6 - '@csstools/postcss-text-decoration-shorthand@5.0.1(postcss@8.5.6)': + '@csstools/postcss-text-decoration-shorthand@5.0.2(postcss@8.5.6)': dependencies: '@csstools/color-helpers': 6.0.1 postcss: 8.5.6 @@ -18992,10 +18972,6 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@playwright/test@1.58.1': - dependencies: - playwright: 1.58.1 - '@playwright/test@1.58.2': dependencies: playwright: 1.58.2 @@ -19033,12 +19009,7 @@ snapshots: '@preact/signals-core@1.13.0': {} - '@preact/signals@2.6.2(preact@10.28.3)': - dependencies: - '@preact/signals-core': 1.13.0 - preact: 10.28.3 - - '@preact/signals@2.8.0(preact@10.28.3)': + '@preact/signals@2.7.1(preact@10.28.3)': dependencies: '@preact/signals-core': 1.13.0 preact: 10.28.3 @@ -20794,7 +20765,7 @@ snapshots: parse5: 7.3.0 parse5-htmlparser2-tree-adapter: 7.1.0 parse5-parser-stream: 7.1.2 - undici: 7.20.0 + undici: 7.22.0 whatwg-mimetype: 4.0.0 chokidar@3.6.0: @@ -23008,7 +22979,7 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - magicast@0.5.1: + magicast@0.5.2: dependencies: '@babel/parser': 7.29.0 '@babel/types': 7.29.0 @@ -24156,16 +24127,8 @@ snapshots: mlly: 1.8.0 pathe: 2.0.3 - playwright-core@1.58.1: {} - playwright-core@1.58.2: {} - playwright@1.58.1: - dependencies: - playwright-core: 1.58.1 - optionalDependencies: - fsevents: 2.3.2 - playwright@1.58.2: dependencies: playwright-core: 1.58.2 @@ -24309,7 +24272,7 @@ snapshots: postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-preset-env@11.1.2(postcss@8.5.6): + postcss-preset-env@11.1.3(postcss@8.5.6): dependencies: '@csstools/postcss-alpha-function': 2.0.2(postcss@8.5.6) '@csstools/postcss-cascade-layers': 6.0.0(postcss@8.5.6) @@ -24349,7 +24312,7 @@ snapshots: '@csstools/postcss-stepped-value-functions': 5.0.0(postcss@8.5.6) '@csstools/postcss-syntax-descriptor-syntax-production': 2.0.0(postcss@8.5.6) '@csstools/postcss-system-ui-font-family': 2.0.0(postcss@8.5.6) - '@csstools/postcss-text-decoration-shorthand': 5.0.1(postcss@8.5.6) + '@csstools/postcss-text-decoration-shorthand': 5.0.2(postcss@8.5.6) '@csstools/postcss-trigonometric-functions': 5.0.0(postcss@8.5.6) '@csstools/postcss-unset-value': 5.0.0(postcss@8.5.6) autoprefixer: 10.4.24(postcss@8.5.6) @@ -25781,7 +25744,7 @@ snapshots: undici@7.18.2: {} - undici@7.20.0: {} + undici@7.22.0: {} unenv@2.0.0-rc.24: dependencies: From b2d547a3d925c4756e9f7435acc41a669439fbec Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Mon, 16 Feb 2026 07:58:15 -0500 Subject: [PATCH 07/12] Refactor ssr response tests to unit tests (#15517) This is similar to https://github.com/withastro/astro/pull/15516 but refactors tests around responses to various scenarios, such as trailing slash behavior. --- .../test/fixtures/ssr-response/package.json | 8 - .../fixtures/ssr-response/src/pages/404.astro | 8 - .../ssr-response/src/pages/another.astro | 13 - .../ssr-response/src/pages/index.astro | 13 - .../ssr-response/src/pages/some-header.astro | 13 - .../ssr-response/src/pages/status-code.astro | 13 - .../ssr-response/src/pages/sub/path.astro | 13 - packages/astro/test/ssr-response.test.js | 59 ----- .../astro/test/units/app/response.test.js | 198 ++++++++++++++ .../app/trailing-slash.test.js} | 246 ++++++++++++------ 10 files changed, 368 insertions(+), 216 deletions(-) delete mode 100644 packages/astro/test/fixtures/ssr-response/package.json delete mode 100644 packages/astro/test/fixtures/ssr-response/src/pages/404.astro delete mode 100644 packages/astro/test/fixtures/ssr-response/src/pages/another.astro delete mode 100644 packages/astro/test/fixtures/ssr-response/src/pages/index.astro delete mode 100644 packages/astro/test/fixtures/ssr-response/src/pages/some-header.astro delete mode 100644 packages/astro/test/fixtures/ssr-response/src/pages/status-code.astro delete mode 100644 packages/astro/test/fixtures/ssr-response/src/pages/sub/path.astro delete mode 100644 packages/astro/test/ssr-response.test.js create mode 100644 packages/astro/test/units/app/response.test.js rename packages/astro/test/{ssr-trailing-slash.test.js => units/app/trailing-slash.test.js} (72%) diff --git a/packages/astro/test/fixtures/ssr-response/package.json b/packages/astro/test/fixtures/ssr-response/package.json deleted file mode 100644 index 420d01c5571d..000000000000 --- a/packages/astro/test/fixtures/ssr-response/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "@test/ssr-response", - "version": "0.0.0", - "private": true, - "dependencies": { - "astro": "workspace:*" - } -} diff --git a/packages/astro/test/fixtures/ssr-response/src/pages/404.astro b/packages/astro/test/fixtures/ssr-response/src/pages/404.astro deleted file mode 100644 index c1180882d633..000000000000 --- a/packages/astro/test/fixtures/ssr-response/src/pages/404.astro +++ /dev/null @@ -1,8 +0,0 @@ - - - Custom 404 - - -

Custom 404

- - \ No newline at end of file diff --git a/packages/astro/test/fixtures/ssr-response/src/pages/another.astro b/packages/astro/test/fixtures/ssr-response/src/pages/another.astro deleted file mode 100644 index 5d9e2e97dde6..000000000000 --- a/packages/astro/test/fixtures/ssr-response/src/pages/another.astro +++ /dev/null @@ -1,13 +0,0 @@ ---- ---- - - - - - - Document - - -

Hello {Astro.url}

- - diff --git a/packages/astro/test/fixtures/ssr-response/src/pages/index.astro b/packages/astro/test/fixtures/ssr-response/src/pages/index.astro deleted file mode 100644 index a9f08bffe9e8..000000000000 --- a/packages/astro/test/fixtures/ssr-response/src/pages/index.astro +++ /dev/null @@ -1,13 +0,0 @@ ---- ---- - - - - - - Document - - -

Hello /

- - diff --git a/packages/astro/test/fixtures/ssr-response/src/pages/some-header.astro b/packages/astro/test/fixtures/ssr-response/src/pages/some-header.astro deleted file mode 100644 index 4f6eb6b0c589..000000000000 --- a/packages/astro/test/fixtures/ssr-response/src/pages/some-header.astro +++ /dev/null @@ -1,13 +0,0 @@ ---- -Astro.response.headers.set('One-Two', 'three'); -Astro.response.headers.set('Four-Five', 'six'); -Astro.response.headers.set("Cache-Control", `max-age=0, s-maxage=86400`); ---- - - - Testing - - -

Testing

- - diff --git a/packages/astro/test/fixtures/ssr-response/src/pages/status-code.astro b/packages/astro/test/fixtures/ssr-response/src/pages/status-code.astro deleted file mode 100644 index 9426467a9540..000000000000 --- a/packages/astro/test/fixtures/ssr-response/src/pages/status-code.astro +++ /dev/null @@ -1,13 +0,0 @@ ---- -Astro.response.status = 404; -Astro.response.statusText = 'Oops'; -Astro.response.headers.set('One-Two', 'three'); ---- - - - Testing - - -

Testing

- - diff --git a/packages/astro/test/fixtures/ssr-response/src/pages/sub/path.astro b/packages/astro/test/fixtures/ssr-response/src/pages/sub/path.astro deleted file mode 100644 index 5d9e2e97dde6..000000000000 --- a/packages/astro/test/fixtures/ssr-response/src/pages/sub/path.astro +++ /dev/null @@ -1,13 +0,0 @@ ---- ---- - - - - - - Document - - -

Hello {Astro.url}

- - diff --git a/packages/astro/test/ssr-response.test.js b/packages/astro/test/ssr-response.test.js deleted file mode 100644 index 9be7e0fb966f..000000000000 --- a/packages/astro/test/ssr-response.test.js +++ /dev/null @@ -1,59 +0,0 @@ -import assert from 'node:assert/strict'; -import { before, describe, it } from 'node:test'; -import testAdapter from './test-adapter.js'; -import { loadFixture } from './test-utils.js'; - -describe('Using Astro.response in SSR', () => { - /** @type {import('./test-utils').Fixture} */ - let fixture; - - before(async () => { - fixture = await loadFixture({ - root: './fixtures/ssr-response/', - adapter: testAdapter(), - output: 'server', - }); - await fixture.build(); - }); - - it('Can set the status', async () => { - const app = await fixture.loadTestAdapterApp(); - const request = new Request('http://example.com/status-code'); - const response = await app.render(request); - assert.equal(response.status, 404); - }); - - it('Can set the statusText', async () => { - const app = await fixture.loadTestAdapterApp(); - const request = new Request('http://example.com/status-code'); - const response = await app.render(request); - assert.equal(response.statusText, 'Oops'); - }); - - it('Can set headers for 404 page', async () => { - const app = await fixture.loadTestAdapterApp(); - const request = new Request('http://example.com/status-code'); - const response = await app.render(request); - const headers = response.headers; - assert.equal(headers.get('one-two'), 'three'); - }); - - it('Returns the page, not the custom 404.astro', async () => { - const app = await fixture.loadTestAdapterApp(); - const request = new Request('http://example.com/status-code'); - const response = await app.render(request); - const html = await response.text(); - assert.equal(html.includes('

Testing

'), true); - assert.equal(html.includes('

Custom 404

'), false); - }); - - it('Can add headers', async () => { - const app = await fixture.loadTestAdapterApp(); - const request = new Request('http://example.com/some-header'); - const response = await app.render(request); - const headers = response.headers; - assert.equal(headers.get('one-two'), 'three'); - assert.equal(headers.get('four-five'), 'six'); - assert.equal(headers.get('Cache-Control'), `max-age=0, s-maxage=86400`); - }); -}); diff --git a/packages/astro/test/units/app/response.test.js b/packages/astro/test/units/app/response.test.js new file mode 100644 index 000000000000..2b289e634d77 --- /dev/null +++ b/packages/astro/test/units/app/response.test.js @@ -0,0 +1,198 @@ +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; +import { App } from '../../../dist/core/app/app.js'; +import { createComponent, render } from '../../../dist/runtime/server/index.js'; + +function createManifest({ routes, pageMap }) { + const rootDir = new URL('file:///astro-test/'); + const buildDir = new URL('file:///astro-test/dist/'); + + return { + adapterName: 'test-adapter', + routes, + site: undefined, + base: '/', + userAssetsBase: undefined, + trailingSlash: 'ignore', + buildFormat: 'directory', + compressHTML: false, + assetsPrefix: undefined, + renderers: [], + serverLike: true, + clientDirectives: new Map(), + entryModules: {}, + inlinedScripts: new Map(), + assets: new Set(), + componentMetadata: new Map(), + pageModule: undefined, + pageMap, + serverIslandMappings: undefined, + key: Promise.resolve(/** @type {CryptoKey} */ ({})), + i18n: undefined, + middleware: undefined, + actions: undefined, + sessionDriver: undefined, + checkOrigin: false, + allowedDomains: undefined, + sessionConfig: undefined, + cacheDir: rootDir, + srcDir: rootDir, + outDir: buildDir, + rootDir, + publicDir: rootDir, + assetsDir: 'assets', + buildClientDir: buildDir, + buildServerDir: buildDir, + csp: undefined, + image: {}, + shouldInjectCspMetaTags: false, + devToolbar: { + enabled: false, + latestAstroVersion: undefined, + debugInfoOutput: undefined, + placement: undefined, + }, + internalFetchHeaders: undefined, + logLevel: 'silent', + }; +} + +const statusRouteData = { + route: '/status-code', + component: 'src/pages/status-code.astro', + params: [], + pathname: '/status-code', + distURL: [], + pattern: /^\/status-code\/?$/, + segments: [[{ content: 'status-code', dynamic: false, spread: false }]], + type: 'page', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', +}; + +const someHeaderRouteData = { + route: '/some-header', + component: 'src/pages/some-header.astro', + params: [], + pathname: '/some-header', + distURL: [], + pattern: /^\/some-header\/?$/, + segments: [[{ content: 'some-header', dynamic: false, spread: false }]], + type: 'page', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', +}; + +const notFoundRouteData = { + route: '/404', + component: 'src/pages/404.astro', + params: [], + pathname: '/404', + distURL: [], + pattern: /^\/404\/?$/, + segments: [[{ content: '404', dynamic: false, spread: false }]], + type: 'page', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', +}; + +const statusPage = createComponent((result, props, slots) => { + const Astro = result.createAstro(props, slots); + Astro.response.status = 404; + Astro.response.statusText = 'Oops'; + Astro.response.headers.set('One-Two', 'three'); + return render`

Testing

`; +}); + +const someHeaderPage = createComponent((result, props, slots) => { + const Astro = result.createAstro(props, slots); + Astro.response.headers.set('One-Two', 'three'); + Astro.response.headers.set('Four-Five', 'six'); + Astro.response.headers.set('Cache-Control', 'max-age=0, s-maxage=86400'); + return render`

Testing

`; +}); + +const notFoundPage = createComponent(() => { + return render`

Custom 404

`; +}); + +const pageMap = new Map([ + [ + statusRouteData.component, + async () => ({ + page: async () => ({ + default: statusPage, + }), + }), + ], + [ + someHeaderRouteData.component, + async () => ({ + page: async () => ({ + default: someHeaderPage, + }), + }), + ], + [ + notFoundRouteData.component, + async () => ({ + page: async () => ({ + default: notFoundPage, + }), + }), + ], +]); + +const app = new App( + createManifest({ + routes: [ + { routeData: statusRouteData }, + { routeData: someHeaderRouteData }, + { routeData: notFoundRouteData }, + ], + pageMap, + }), +); + +describe('Using Astro.response in SSR', () => { + it('Can set the status', async () => { + const request = new Request('http://example.com/status-code'); + const response = await app.render(request); + assert.equal(response.status, 404); + }); + + it('Can set the statusText', async () => { + const request = new Request('http://example.com/status-code'); + const response = await app.render(request); + assert.equal(response.statusText, 'Oops'); + }); + + it('Can set headers for 404 page', async () => { + const request = new Request('http://example.com/status-code'); + const response = await app.render(request); + assert.equal(response.headers.get('one-two'), 'three'); + }); + + it('Returns the page, not the custom 404.astro', async () => { + const request = new Request('http://example.com/status-code'); + const response = await app.render(request); + const html = await response.text(); + assert.equal(html.includes('

Testing

'), true); + assert.equal(html.includes('

Custom 404

'), false); + }); + + it('Can add headers', async () => { + const request = new Request('http://example.com/some-header'); + const response = await app.render(request); + const headers = response.headers; + assert.equal(headers.get('one-two'), 'three'); + assert.equal(headers.get('four-five'), 'six'); + assert.equal(headers.get('Cache-Control'), 'max-age=0, s-maxage=86400'); + }); +}); diff --git a/packages/astro/test/ssr-trailing-slash.test.js b/packages/astro/test/units/app/trailing-slash.test.js similarity index 72% rename from packages/astro/test/ssr-trailing-slash.test.js rename to packages/astro/test/units/app/trailing-slash.test.js index c114ad393fa1..5f5b5f08bc09 100644 --- a/packages/astro/test/ssr-trailing-slash.test.js +++ b/packages/astro/test/units/app/trailing-slash.test.js @@ -1,24 +1,155 @@ import assert from 'node:assert/strict'; -import { before, describe, it } from 'node:test'; -import testAdapter from './test-adapter.js'; -import { loadFixture } from './test-utils.js'; +import { describe, it } from 'node:test'; +import { App } from '../../../dist/core/app/app.js'; +import { createComponent, render } from '../../../dist/runtime/server/index.js'; + +function createManifest({ routes, pageMap, base = '/', trailingSlash = 'ignore' }) { + const rootDir = new URL('file:///astro-test/'); + const buildDir = new URL('file:///astro-test/dist/'); + + return { + adapterName: 'test-adapter', + routes, + site: undefined, + base, + userAssetsBase: undefined, + trailingSlash, + buildFormat: 'directory', + compressHTML: false, + assetsPrefix: undefined, + renderers: [], + serverLike: true, + clientDirectives: new Map(), + entryModules: {}, + inlinedScripts: new Map(), + assets: new Set(), + componentMetadata: new Map(), + pageModule: undefined, + pageMap, + serverIslandMappings: undefined, + key: Promise.resolve(/** @type {CryptoKey} */ ({})), + i18n: undefined, + middleware: undefined, + actions: undefined, + sessionDriver: undefined, + checkOrigin: false, + allowedDomains: undefined, + sessionConfig: undefined, + cacheDir: rootDir, + srcDir: rootDir, + outDir: buildDir, + rootDir, + publicDir: rootDir, + assetsDir: 'assets', + buildClientDir: buildDir, + buildServerDir: buildDir, + csp: undefined, + image: {}, + shouldInjectCspMetaTags: false, + devToolbar: { + enabled: false, + latestAstroVersion: undefined, + debugInfoOutput: undefined, + placement: undefined, + }, + internalFetchHeaders: undefined, + logLevel: 'silent', + }; +} + +function escapeRoute(route) { + return route.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +} + +function createRouteData(route) { + const segments = route + .split('/') + .filter(Boolean) + .map((segment) => [{ content: segment, dynamic: false, spread: false }]); + + return { + route, + component: `src/pages${route}.astro`, + params: [], + pathname: route, + distURL: [], + pattern: new RegExp(`^${escapeRoute(route)}\\/?$`), + segments, + type: 'page', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', + }; +} + +const okPage = createComponent(() => { + return render`

Ok

`; +}); -describe('Redirecting trailing slashes in SSR', () => { - /** @type {import('./test-utils.js').Fixture} */ - let fixture; +const notFoundPage = createComponent(() => { + return render`

Not Found

`; +}); +const anotherRouteData = createRouteData('/another'); +const subPathRouteData = createRouteData('/sub/path'); +const dotPathRouteData = createRouteData('/dot.in.directory/path'); +const notFoundRouteData = { + ...createRouteData('/404'), + component: 'src/pages/404.astro', +}; + +const pageMap = new Map([ + [ + anotherRouteData.component, + async () => ({ + page: async () => ({ + default: okPage, + }), + }), + ], + [ + subPathRouteData.component, + async () => ({ + page: async () => ({ + default: okPage, + }), + }), + ], + [ + dotPathRouteData.component, + async () => ({ + page: async () => ({ + default: okPage, + }), + }), + ], + [ + notFoundRouteData.component, + async () => ({ + page: async () => ({ + default: notFoundPage, + }), + }), + ], +]); + +describe('Redirecting trailing slashes in SSR', () => { describe('trailingSlash: always', () => { - before(async () => { - fixture = await loadFixture({ - root: './fixtures/ssr-response/', - adapter: testAdapter(), - output: 'server', + const app = new App( + createManifest({ trailingSlash: 'always', - }); - await fixture.build(); - }); + routes: [ + { routeData: anotherRouteData }, + { routeData: subPathRouteData }, + { routeData: dotPathRouteData }, + { routeData: notFoundRouteData }, + ], + pageMap, + }), + ); + it('Redirects to add a trailing slash', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/another'); const response = await app.render(request); assert.equal(response.status, 301); @@ -26,7 +157,6 @@ describe('Redirecting trailing slashes in SSR', () => { }); it('Redirects to collapse multiple trailing slashes', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/another///'); const response = await app.render(request); assert.equal(response.status, 301); @@ -34,7 +164,6 @@ describe('Redirecting trailing slashes in SSR', () => { }); it('Redirects to collapse multiple trailing slashes with query param', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/another///?hello=world'); const response = await app.render(request); assert.equal(response.status, 301); @@ -42,28 +171,24 @@ describe('Redirecting trailing slashes in SSR', () => { }); it('Does not redirect to collapse multiple internal slashes', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/another///path/'); const response = await app.render(request); assert.equal(response.status, 404); }); it('Does not redirect trailing slashes on query params', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/another/?hello=world///'); const response = await app.render(request); assert.equal(response.status, 200); }); it('Does not redirect when trailing slash is present', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/another/'); const response = await app.render(request); assert.equal(response.status, 200); }); it('Redirects with query params', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/another?foo=bar'); const response = await app.render(request); assert.equal(response.status, 301); @@ -71,14 +196,12 @@ describe('Redirecting trailing slashes in SSR', () => { }); it('Does not redirect with query params when trailing slash is present', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/another/?foo=bar'); const response = await app.render(request); assert.equal(response.status, 200); }); it('Redirects subdirectories to add a trailing slash', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/sub/path'); const response = await app.render(request); assert.equal(response.status, 301); @@ -86,21 +209,18 @@ describe('Redirecting trailing slashes in SSR', () => { }); it('Does not redirect requests for files', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/favicon.ico'); const response = await app.render(request); assert.equal(response.status, 404); }); it('Does not redirect requests for files in subdirectories', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/sub/favicon.ico'); const response = await app.render(request); assert.equal(response.status, 404); }); it('Does redirect if the dot is in a directory name', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/dot.in.directory/path'); const response = await app.render(request); assert.equal(response.status, 301); @@ -108,8 +228,6 @@ describe('Redirecting trailing slashes in SSR', () => { }); it('Does not redirect internal paths', async () => { - const app = await fixture.loadTestAdapterApp(); - for (const path of [ '/_astro/something', '/_image?url=http://example.com/foo.jpg', @@ -125,7 +243,6 @@ describe('Redirecting trailing slashes in SSR', () => { }); it('Redirects POST requests', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/another', { method: 'POST' }); const response = await app.render(request); assert.equal(response.status, 308); @@ -134,18 +251,19 @@ describe('Redirecting trailing slashes in SSR', () => { }); describe('trailingSlash: never', () => { - before(async () => { - fixture = await loadFixture({ - root: './fixtures/ssr-response/', - adapter: testAdapter(), - output: 'server', + const app = new App( + createManifest({ trailingSlash: 'never', - }); - await fixture.build(); - }); + routes: [ + { routeData: anotherRouteData }, + { routeData: subPathRouteData }, + { routeData: notFoundRouteData }, + ], + pageMap, + }), + ); it('Redirects to remove a trailing slash', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/another/'); const response = await app.render(request); assert.equal(response.status, 301); @@ -153,7 +271,6 @@ describe('Redirecting trailing slashes in SSR', () => { }); it('Redirects to collapse multiple trailing slashes', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/another///'); const response = await app.render(request); assert.equal(response.status, 301); @@ -161,14 +278,12 @@ describe('Redirecting trailing slashes in SSR', () => { }); it('Does not redirect when trailing slash is absent', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/another'); const response = await app.render(request); assert.equal(response.status, 200); }); it('Redirects with query params', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/another/?foo=bar'); const response = await app.render(request); assert.equal(response.status, 301); @@ -176,21 +291,18 @@ describe('Redirecting trailing slashes in SSR', () => { }); it('Does not redirect with query params when trailing slash is absent', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/another?foo=bar'); const response = await app.render(request); assert.equal(response.status, 200); }); it("Does not redirect when there's a slash at the end of query params", async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/another?foo=bar/'); const response = await app.render(request); assert.equal(response.status, 200); }); it('Redirects subdirectories to remove a trailing slash', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/sub/path/'); const response = await app.render(request); assert.equal(response.status, 301); @@ -198,7 +310,6 @@ describe('Redirecting trailing slashes in SSR', () => { }); it("Redirects even if there's a dot in the directory name", async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/favicon.ico/'); const response = await app.render(request); assert.equal(response.status, 301); @@ -206,8 +317,6 @@ describe('Redirecting trailing slashes in SSR', () => { }); it('Does not redirect internal paths', async () => { - const app = await fixture.loadTestAdapterApp(); - for (const path of [ '/_astro/something/', '/_image/?url=http://example.com/foo.jpg', @@ -216,14 +325,13 @@ describe('Redirecting trailing slashes in SSR', () => { '/.netlify/image/?url=http://example.com/foo.jpg', '//target.example/path/', ]) { - const request = new Request(`http://example.com${path}/`); + const request = new Request(`http://example.com${path}`); const response = await app.render(request); assert.notEqual(response.status, 301); } }); it('Redirects POST requests', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/another/', { method: 'POST' }); const response = await app.render(request); assert.equal(response.status, 308); @@ -232,19 +340,16 @@ describe('Redirecting trailing slashes in SSR', () => { }); describe('trailingSlash: never with base path', () => { - before(async () => { - fixture = await loadFixture({ - root: './fixtures/ssr-response/', - adapter: testAdapter(), - output: 'server', - trailingSlash: 'never', + const app = new App( + createManifest({ base: '/mybase', - }); - await fixture.build(); - }); + trailingSlash: 'never', + routes: [{ routeData: anotherRouteData }, { routeData: notFoundRouteData }], + pageMap, + }), + ); it('Redirects to remove a trailing slash on base path', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/mybase/'); const response = await app.render(request); assert.equal(response.status, 301); @@ -252,16 +357,13 @@ describe('Redirecting trailing slashes in SSR', () => { }); it('Does not redirect when base path has no trailing slash', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/mybase'); const response = await app.render(request); - // Should not redirect, but will 404 since we don't have an index page assert.notEqual(response.status, 301); assert.notEqual(response.status, 308); }); it('Redirects to remove trailing slash on sub-paths with base', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/mybase/another/'); const response = await app.render(request); assert.equal(response.status, 301); @@ -269,7 +371,6 @@ describe('Redirecting trailing slashes in SSR', () => { }); it('Does not redirect sub-paths without trailing slash with base', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/mybase/another'); const response = await app.render(request); assert.equal(response.status, 200); @@ -277,18 +378,15 @@ describe('Redirecting trailing slashes in SSR', () => { }); describe('trailingSlash: ignore', () => { - before(async () => { - fixture = await loadFixture({ - root: './fixtures/ssr-response/', - adapter: testAdapter(), - output: 'server', + const app = new App( + createManifest({ trailingSlash: 'ignore', - }); - await fixture.build(); - }); + routes: [{ routeData: anotherRouteData }, { routeData: notFoundRouteData }], + pageMap, + }), + ); it('Redirects to collapse multiple trailing slashes', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/another///'); const response = await app.render(request); assert.equal(response.status, 301); @@ -296,22 +394,18 @@ describe('Redirecting trailing slashes in SSR', () => { }); it('Does not redirect when trailing slash is absent', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/another'); const response = await app.render(request); assert.equal(response.status, 200); }); it('Does not redirect when trailing slash is present', async () => { - const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/another/'); const response = await app.render(request); assert.equal(response.status, 200); }); it('Does not redirect internal paths', async () => { - const app = await fixture.loadTestAdapterApp(); - for (const path of [ '/_astro/something//', '/_image//?url=http://example.com/foo.jpg', From 020660efcbdf73f43cf5070d3fda32a170a25ba5 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Mon, 16 Feb 2026 08:00:28 -0500 Subject: [PATCH 08/12] Convert locals tests to unit tests (#15519) These test various scenarios where `Astro.locals` is used, such as when passed down from an adapter. Converted to unit tests and removed the fixture. --- .../test/fixtures/ssr-locals/package.json | 8 - .../fixtures/ssr-locals/src/pages/404.astro | 4 - .../fixtures/ssr-locals/src/pages/500.astro | 4 - .../test/fixtures/ssr-locals/src/pages/api.js | 10 - .../fixtures/ssr-locals/src/pages/foo.astro | 4 - .../src/pages/go-to-error-page.astro | 3 - packages/astro/test/ssr-locals.test.js | 64 ----- packages/astro/test/units/app/locals.test.js | 252 ++++++++++++++++++ 8 files changed, 252 insertions(+), 97 deletions(-) delete mode 100644 packages/astro/test/fixtures/ssr-locals/package.json delete mode 100644 packages/astro/test/fixtures/ssr-locals/src/pages/404.astro delete mode 100644 packages/astro/test/fixtures/ssr-locals/src/pages/500.astro delete mode 100644 packages/astro/test/fixtures/ssr-locals/src/pages/api.js delete mode 100644 packages/astro/test/fixtures/ssr-locals/src/pages/foo.astro delete mode 100644 packages/astro/test/fixtures/ssr-locals/src/pages/go-to-error-page.astro delete mode 100644 packages/astro/test/ssr-locals.test.js create mode 100644 packages/astro/test/units/app/locals.test.js diff --git a/packages/astro/test/fixtures/ssr-locals/package.json b/packages/astro/test/fixtures/ssr-locals/package.json deleted file mode 100644 index ae9ee4649690..000000000000 --- a/packages/astro/test/fixtures/ssr-locals/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "@test/ssr-locals", - "version": "0.0.0", - "private": true, - "dependencies": { - "astro": "workspace:*" - } -} diff --git a/packages/astro/test/fixtures/ssr-locals/src/pages/404.astro b/packages/astro/test/fixtures/ssr-locals/src/pages/404.astro deleted file mode 100644 index 66b1f7a045b1..000000000000 --- a/packages/astro/test/fixtures/ssr-locals/src/pages/404.astro +++ /dev/null @@ -1,4 +0,0 @@ ---- -const { foo } = Astro.locals; ---- -

{ foo }

diff --git a/packages/astro/test/fixtures/ssr-locals/src/pages/500.astro b/packages/astro/test/fixtures/ssr-locals/src/pages/500.astro deleted file mode 100644 index 66b1f7a045b1..000000000000 --- a/packages/astro/test/fixtures/ssr-locals/src/pages/500.astro +++ /dev/null @@ -1,4 +0,0 @@ ---- -const { foo } = Astro.locals; ---- -

{ foo }

diff --git a/packages/astro/test/fixtures/ssr-locals/src/pages/api.js b/packages/astro/test/fixtures/ssr-locals/src/pages/api.js deleted file mode 100644 index 366f26aaeec1..000000000000 --- a/packages/astro/test/fixtures/ssr-locals/src/pages/api.js +++ /dev/null @@ -1,10 +0,0 @@ - -export async function GET({ locals }) { - let out = { ...locals }; - - return new Response(JSON.stringify(out), { - headers: { - 'Content-Type': 'application/json' - } - }); -} diff --git a/packages/astro/test/fixtures/ssr-locals/src/pages/foo.astro b/packages/astro/test/fixtures/ssr-locals/src/pages/foo.astro deleted file mode 100644 index 66b1f7a045b1..000000000000 --- a/packages/astro/test/fixtures/ssr-locals/src/pages/foo.astro +++ /dev/null @@ -1,4 +0,0 @@ ---- -const { foo } = Astro.locals; ---- -

{ foo }

diff --git a/packages/astro/test/fixtures/ssr-locals/src/pages/go-to-error-page.astro b/packages/astro/test/fixtures/ssr-locals/src/pages/go-to-error-page.astro deleted file mode 100644 index ee962857d4d0..000000000000 --- a/packages/astro/test/fixtures/ssr-locals/src/pages/go-to-error-page.astro +++ /dev/null @@ -1,3 +0,0 @@ ---- -throw new Error ---- \ No newline at end of file diff --git a/packages/astro/test/ssr-locals.test.js b/packages/astro/test/ssr-locals.test.js deleted file mode 100644 index 3adb2a8cd67e..000000000000 --- a/packages/astro/test/ssr-locals.test.js +++ /dev/null @@ -1,64 +0,0 @@ -import assert from 'node:assert/strict'; -import { before, describe, it } from 'node:test'; -import * as cheerio from 'cheerio'; -import testAdapter from './test-adapter.js'; -import { loadFixture } from './test-utils.js'; - -describe('SSR Astro.locals from server', () => { - /** @type {import('./test-utils').Fixture} */ - let fixture; - /** @type {import('./test-utils.js').App} */ - let app; - - before(async () => { - fixture = await loadFixture({ - root: './fixtures/ssr-locals/', - output: 'server', - adapter: testAdapter(), - }); - await fixture.build(); - app = await fixture.loadTestAdapterApp(); - }); - - it('Can access Astro.locals in page', async () => { - const request = new Request('http://example.com/foo'); - const locals = { foo: 'bar' }; - const response = await app.render(request, { locals }); - const html = await response.text(); - - const $ = cheerio.load(html); - assert.equal($('#foo').text(), 'bar'); - }); - - it('Can access Astro.locals in api context', async () => { - const request = new Request('http://example.com/api'); - const locals = { foo: 'bar' }; - const response = await app.render(request, { routeData: undefined, locals }); - assert.equal(response.status, 200); - const body = await response.json(); - - assert.equal(body.foo, 'bar'); - }); - - it('404.astro can access locals provided to app.render()', async () => { - const request = new Request('http://example.com/slkfnasf'); - const locals = { foo: 'par' }; - const response = await app.render(request, { locals }); - assert.equal(response.status, 404); - - const html = await response.text(); - const $ = cheerio.load(html); - assert.equal($('#foo').text(), 'par'); - }); - - it('500.astro can access locals provided to app.render()', async () => { - const request = new Request('http://example.com/go-to-error-page'); - const locals = { foo: 'par' }; - const response = await app.render(request, { locals }); - assert.equal(response.status, 500); - - const html = await response.text(); - const $ = cheerio.load(html); - assert.equal($('#foo').text(), 'par'); - }); -}); diff --git a/packages/astro/test/units/app/locals.test.js b/packages/astro/test/units/app/locals.test.js new file mode 100644 index 000000000000..c5aa18655410 --- /dev/null +++ b/packages/astro/test/units/app/locals.test.js @@ -0,0 +1,252 @@ +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; +import { App } from '../../../dist/core/app/app.js'; +import { createComponent, render } from '../../../dist/runtime/server/index.js'; + +function createManifest({ routes, pageMap }) { + const rootDir = new URL('file:///astro-test/'); + const buildDir = new URL('file:///astro-test/dist/'); + + return { + adapterName: 'test-adapter', + routes, + site: undefined, + base: '/', + userAssetsBase: undefined, + trailingSlash: 'ignore', + buildFormat: 'directory', + compressHTML: false, + assetsPrefix: undefined, + renderers: [], + serverLike: true, + clientDirectives: new Map(), + entryModules: {}, + inlinedScripts: new Map(), + assets: new Set(), + componentMetadata: new Map(), + pageModule: undefined, + pageMap, + serverIslandMappings: undefined, + key: Promise.resolve(/** @type {CryptoKey} */ ({})), + i18n: undefined, + middleware: undefined, + actions: undefined, + sessionDriver: undefined, + checkOrigin: false, + allowedDomains: undefined, + sessionConfig: undefined, + cacheDir: rootDir, + srcDir: rootDir, + outDir: buildDir, + rootDir, + publicDir: rootDir, + assetsDir: 'assets', + buildClientDir: buildDir, + buildServerDir: buildDir, + csp: undefined, + image: {}, + shouldInjectCspMetaTags: false, + devToolbar: { + enabled: false, + latestAstroVersion: undefined, + debugInfoOutput: undefined, + placement: undefined, + }, + internalFetchHeaders: undefined, + logLevel: 'silent', + }; +} + +const fooRouteData = { + route: '/foo', + component: 'src/pages/foo.astro', + params: [], + pathname: '/foo', + distURL: [], + pattern: /^\/foo\/?$/, + segments: [[{ content: 'foo', dynamic: false, spread: false }]], + type: 'page', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', +}; + +const apiRouteData = { + route: '/api', + component: 'src/pages/api.js', + params: [], + pathname: '/api', + distURL: [], + pattern: /^\/api\/?$/, + segments: [[{ content: 'api', dynamic: false, spread: false }]], + type: 'endpoint', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', +}; + +const errorRouteData = { + route: '/go-to-error-page', + component: 'src/pages/go-to-error-page.astro', + params: [], + pathname: '/go-to-error-page', + distURL: [], + pattern: /^\/go-to-error-page\/?$/, + segments: [[{ content: 'go-to-error-page', dynamic: false, spread: false }]], + type: 'page', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', +}; + +const notFoundRouteData = { + route: '/404', + component: 'src/pages/404.astro', + params: [], + pathname: '/404', + distURL: [], + pattern: /^\/404\/?$/, + segments: [[{ content: '404', dynamic: false, spread: false }]], + type: 'page', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', +}; + +const internalErrorRouteData = { + route: '/500', + component: 'src/pages/500.astro', + params: [], + pathname: '/500', + distURL: [], + pattern: /^\/500\/?$/, + segments: [[{ content: '500', dynamic: false, spread: false }]], + type: 'page', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', +}; + +const fooPage = createComponent((result, props, slots) => { + const Astro = result.createAstro(props, slots); + return render`

${Astro.locals.foo}

`; +}); + +const notFoundPage = createComponent((result, props, slots) => { + const Astro = result.createAstro(props, slots); + return render`

${Astro.locals.foo}

`; +}); + +const internalErrorPage = createComponent((result, props, slots) => { + const Astro = result.createAstro(props, slots); + return render`

${Astro.locals.foo}

`; +}); + +const pageMap = new Map([ + [ + fooRouteData.component, + async () => ({ + page: async () => ({ + default: fooPage, + }), + }), + ], + [ + apiRouteData.component, + async () => ({ + page: async () => ({ + GET: async ({ locals }) => + new Response(JSON.stringify({ ...locals }), { + headers: { + 'Content-Type': 'application/json', + }, + }), + }), + }), + ], + [ + errorRouteData.component, + async () => ({ + page: async () => ({ + default: createComponent(() => { + throw new Error('boom'); + }), + }), + }), + ], + [ + notFoundRouteData.component, + async () => ({ + page: async () => ({ + default: notFoundPage, + }), + }), + ], + [ + internalErrorRouteData.component, + async () => ({ + page: async () => ({ + default: internalErrorPage, + }), + }), + ], +]); + +const app = new App( + createManifest({ + routes: [ + { routeData: fooRouteData }, + { routeData: apiRouteData }, + { routeData: errorRouteData }, + { routeData: notFoundRouteData }, + { routeData: internalErrorRouteData }, + ], + pageMap, + }), +); + +describe('SSR Astro.locals from server', () => { + it('Can access Astro.locals in page', async () => { + const request = new Request('http://example.com/foo'); + const locals = { foo: 'bar' }; + const response = await app.render(request, { locals }); + const html = await response.text(); + + assert.match(html, /id="foo">bar/); + }); + + it('Can access Astro.locals in api context', async () => { + const request = new Request('http://example.com/api'); + const locals = { foo: 'bar' }; + const response = await app.render(request, { routeData: undefined, locals }); + assert.equal(response.status, 200); + const body = await response.json(); + + assert.equal(body.foo, 'bar'); + }); + + it('404.astro can access locals provided to app.render()', async () => { + const request = new Request('http://example.com/slkfnasf'); + const locals = { foo: 'par' }; + const response = await app.render(request, { locals }); + assert.equal(response.status, 404); + + const html = await response.text(); + assert.match(html, /id="foo">par/); + }); + + it('500.astro can access locals provided to app.render()', async () => { + const request = new Request('http://example.com/go-to-error-page'); + const locals = { foo: 'par' }; + const response = await app.render(request, { locals }); + assert.equal(response.status, 500); + + const html = await response.text(); + assert.match(html, /id="foo">par/); + }); +}); From da5f4645713e843e6d368c5f9d09b50a034bd831 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 15:08:25 +0100 Subject: [PATCH 09/12] fix(deps): update language tools (#15536) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .../language-server/package.json | 2 +- .../language-server/test/package.json | 2 +- .../language-tools/ts-plugin/package.json | 4 +- packages/language-tools/vscode/package.json | 4 +- pnpm-lock.yaml | 56 ++++++++----------- 5 files changed, 28 insertions(+), 40 deletions(-) diff --git a/packages/language-tools/language-server/package.json b/packages/language-tools/language-server/package.json index 9db987643643..24cba6cbcedb 100644 --- a/packages/language-tools/language-server/package.json +++ b/packages/language-tools/language-server/package.json @@ -26,7 +26,7 @@ "test:match": "pnpm run test --match" }, "dependencies": { - "@astrojs/compiler": "^2.13.0", + "@astrojs/compiler": "^2.13.1", "@astrojs/yaml2ts": "^0.2.2", "@jridgewell/sourcemap-codec": "^1.5.5", "@volar/kit": "~2.4.28", diff --git a/packages/language-tools/language-server/test/package.json b/packages/language-tools/language-server/test/package.json index 2d1b5ffdbd35..d275d6b50205 100644 --- a/packages/language-tools/language-server/test/package.json +++ b/packages/language-tools/language-server/test/package.json @@ -6,7 +6,7 @@ "@astrojs/svelte": "workspace:*", "@astrojs/vue": "workspace:*", "astro": "workspace:*", - "svelte": "^5.49.1" + "svelte": "^5.50.3" }, "devDependencies": { "tinyglobby": "^0.2.15" diff --git a/packages/language-tools/ts-plugin/package.json b/packages/language-tools/ts-plugin/package.json index ff58a96453e8..eb5163ca6c28 100644 --- a/packages/language-tools/ts-plugin/package.json +++ b/packages/language-tools/ts-plugin/package.json @@ -27,12 +27,12 @@ "author": "withastro", "license": "MIT", "dependencies": { - "@astrojs/compiler": "^2.13.0", + "@astrojs/compiler": "^2.13.1", "@astrojs/yaml2ts": "^0.2.2", "@jridgewell/sourcemap-codec": "^1.5.5", "@volar/language-core": "~2.4.28", "@volar/typescript": "~2.4.28", - "semver": "^7.7.3", + "semver": "^7.7.4", "vscode-languageserver-textdocument": "^1.0.12" }, "devDependencies": { diff --git a/packages/language-tools/vscode/package.json b/packages/language-tools/vscode/package.json index 22ed93cbd9b3..911c93237c94 100644 --- a/packages/language-tools/vscode/package.json +++ b/packages/language-tools/vscode/package.json @@ -262,12 +262,12 @@ "js-yaml": "^4.1.1", "kleur": "^4.1.5", "mocha": "^11.7.5", - "ovsx": "^0.10.8", + "ovsx": "^0.10.9", "vscode-languageclient": "^9.0.1", "vscode-tmgrammar-test": "^0.1.3" }, "dependencies": { - "@astrojs/compiler": "^2.13.0", + "@astrojs/compiler": "^2.13.1", "prettier": "^3.8.1", "prettier-plugin-astro": "^0.14.1" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f6e6e686012a..95d2bb092269 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4295,12 +4295,6 @@ importers: specifier: workspace:* version: link:../../.. - packages/astro/test/fixtures/ssr-locals: - dependencies: - astro: - specifier: workspace:* - version: link:../../.. - packages/astro/test/fixtures/ssr-markdown: dependencies: astro: @@ -4346,12 +4340,6 @@ importers: specifier: workspace:* version: link:../../.. - packages/astro/test/fixtures/ssr-response: - dependencies: - astro: - specifier: workspace:* - version: link:../../.. - packages/astro/test/fixtures/ssr-script: dependencies: astro: @@ -6672,8 +6660,8 @@ importers: packages/language-tools/language-server: dependencies: '@astrojs/compiler': - specifier: ^2.13.0 - version: 2.13.0 + specifier: ^2.13.1 + version: 2.13.1 '@astrojs/yaml2ts': specifier: ^0.2.2 version: link:../yaml2ts @@ -6763,7 +6751,7 @@ importers: specifier: workspace:* version: link:../../../astro svelte: - specifier: ^5.49.1 + specifier: ^5.50.3 version: 5.50.3 devDependencies: tinyglobby: @@ -6779,8 +6767,8 @@ importers: packages/language-tools/ts-plugin: dependencies: '@astrojs/compiler': - specifier: ^2.13.0 - version: 2.13.0 + specifier: ^2.13.1 + version: 2.13.1 '@astrojs/yaml2ts': specifier: ^0.2.2 version: link:../yaml2ts @@ -6794,7 +6782,7 @@ importers: specifier: ~2.4.28 version: 2.4.28 semver: - specifier: ^7.7.3 + specifier: ^7.7.4 version: 7.7.4 vscode-languageserver-textdocument: specifier: ^1.0.12 @@ -6828,8 +6816,8 @@ importers: packages/language-tools/vscode: dependencies: '@astrojs/compiler': - specifier: ^2.13.0 - version: 2.13.0 + specifier: ^2.13.1 + version: 2.13.1 prettier: specifier: ^3.8.1 version: 3.8.1 @@ -6883,8 +6871,8 @@ importers: specifier: ^11.7.5 version: 11.7.5 ovsx: - specifier: ^0.10.8 - version: 0.10.8 + specifier: ^0.10.9 + version: 0.10.9 vscode-languageclient: specifier: ^9.0.1 version: 9.0.1 @@ -7134,8 +7122,8 @@ packages: resolution: {integrity: sha512-bVzyKzEpIwqjihBU/aUzt1LQckJuHK0agd3/ITdXhPUYculrc6K1/K7H+XG4rwjXtg+ikT3PM05V1MVYWiIvQw==} engines: {node: '>=18.14.1'} - '@astrojs/compiler@2.13.0': - resolution: {integrity: sha512-mqVORhUJViA28fwHYaWmsXSzLO9osbdZ5ImUfxBarqsYdMlPbqAqGJCxsNzvppp1BEzc1mJNjOVvQqeDN8Vspw==} + '@astrojs/compiler@2.13.1': + resolution: {integrity: sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg==} '@astrojs/compiler@3.0.0-beta.0': resolution: {integrity: sha512-wrWArjuyeEhoUZUr+o3Ts3CFbxB+QFYvzsnnR0wr3L0b84JDxq107mZOfmNZ/XPE4VjFzjjApvHKCVGQjNJm8Q==} @@ -10628,8 +10616,8 @@ packages: engines: {node: '>= 16'} hasBin: true - '@vscode/vsce@3.6.2': - resolution: {integrity: sha512-gvBfarWF+Ii20ESqjA3dpnPJpQJ8fFJYtcWtjwbRADommCzGg1emtmb34E+DKKhECYvaVyAl+TF9lWS/3GSPvg==} + '@vscode/vsce@3.7.1': + resolution: {integrity: sha512-OTm2XdMt2YkpSn2Nx7z2EJtSuhRHsTPYsSK59hr3v8jRArK+2UEoju4Jumn1CmpgoBLGI6ReHLJ/czYltNUW3g==} engines: {node: '>= 20'} hasBin: true @@ -13855,8 +13843,8 @@ packages: outdent@0.5.0: resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} - ovsx@0.10.8: - resolution: {integrity: sha512-Vf6ZQi2l4ENUUdO8eZhduQVcxYjhLt3LT2OL1ah+4XOZjJakanjhDr563wmcqZJZgbK/Tn09RAMkhblrp0lt/g==} + ovsx@0.10.9: + resolution: {integrity: sha512-gY6912U50YzzNdAEFr9IxAqu59pKySXZzJUxzHRzi3/h/fWFdDDFCCXyjik6VL4TmiVKeor1Yv/cg7I3KfOUuQ==} engines: {node: '>= 20'} hasBin: true @@ -16418,7 +16406,7 @@ snapshots: log-update: 5.0.1 sisteransi: 1.0.5 - '@astrojs/compiler@2.13.0': {} + '@astrojs/compiler@2.13.1': {} '@astrojs/compiler@3.0.0-beta.0': {} @@ -16428,7 +16416,7 @@ snapshots: '@astrojs/language-server@2.16.2(prettier-plugin-astro@0.14.1)(prettier@3.8.1)(typescript@5.9.3)': dependencies: - '@astrojs/compiler': 2.13.0 + '@astrojs/compiler': 2.13.1 '@astrojs/yaml2ts': 0.2.2 '@jridgewell/sourcemap-codec': 1.5.5 '@volar/kit': 2.4.28(typescript@5.9.3) @@ -20067,7 +20055,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@vscode/vsce@3.6.2': + '@vscode/vsce@3.7.1': dependencies: '@azure/identity': 4.13.0 '@secretlint/node': 10.2.2 @@ -23874,9 +23862,9 @@ snapshots: outdent@0.5.0: {} - ovsx@0.10.8: + ovsx@0.10.9: dependencies: - '@vscode/vsce': 3.6.2 + '@vscode/vsce': 3.7.1 commander: 6.2.1 follow-redirects: 1.15.11 is-ci: 2.0.0 @@ -24428,7 +24416,7 @@ snapshots: prettier-plugin-astro@0.14.1: dependencies: - '@astrojs/compiler': 2.13.0 + '@astrojs/compiler': 2.13.1 prettier: 3.8.1 sass-formatter: 0.7.9 From 913863a11491f9ccf9f5aa59bd2c89c7a30b1124 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Mon, 16 Feb 2026 09:32:20 -0500 Subject: [PATCH 10/12] Refactor error page rendering tests to unit tests (#15516) * Refactor error page rendering tests to unit tests This took ssr-error-pages.test.js which was testing how we handle error pages, like for example rendering the 404.astro route when the page route returned a 400, and then converted those to error tests. Note that the tests are a little verbose at present. Further refactors, especially around routing, will make these smaller. * Fix lint * Update packages/astro/test/units/app/error-pages.test.js Co-authored-by: Florian Lefebvre --------- Co-authored-by: Florian Lefebvre --- .../fixtures/ssr-error-pages/astro.config.mjs | 7 - .../fixtures/ssr-error-pages/package.json | 8 - .../src/content/pages/index.md | 7 - .../ssr-error-pages/src/pages/404.astro | 5 - .../ssr-error-pages/src/pages/500.astro | 1 - .../ssr-error-pages/src/pages/api/route.js | 4 - .../src/pages/blog/[...ssrPath].astro | 9 - .../src/pages/causes-404.astro | 6 - .../src/pages/causes-error.astro | 3 - .../ssr-error-pages/src/styles/main.css | 3 - .../test/fixtures/ssr-error/package.json | 8 - .../ssr-error/src/pages/[...slug].astro | 8 - .../fixtures/ssr-error/src/pages/index.astro | 6 - packages/astro/test/ssr-error-pages.test.js | 196 ------ .../astro/test/units/app/error-pages.test.js | 562 ++++++++++++++++++ 15 files changed, 562 insertions(+), 271 deletions(-) delete mode 100644 packages/astro/test/fixtures/ssr-error-pages/astro.config.mjs delete mode 100644 packages/astro/test/fixtures/ssr-error-pages/package.json delete mode 100644 packages/astro/test/fixtures/ssr-error-pages/src/content/pages/index.md delete mode 100644 packages/astro/test/fixtures/ssr-error-pages/src/pages/404.astro delete mode 100644 packages/astro/test/fixtures/ssr-error-pages/src/pages/500.astro delete mode 100644 packages/astro/test/fixtures/ssr-error-pages/src/pages/api/route.js delete mode 100644 packages/astro/test/fixtures/ssr-error-pages/src/pages/blog/[...ssrPath].astro delete mode 100644 packages/astro/test/fixtures/ssr-error-pages/src/pages/causes-404.astro delete mode 100644 packages/astro/test/fixtures/ssr-error-pages/src/pages/causes-error.astro delete mode 100644 packages/astro/test/fixtures/ssr-error-pages/src/styles/main.css delete mode 100644 packages/astro/test/fixtures/ssr-error/package.json delete mode 100644 packages/astro/test/fixtures/ssr-error/src/pages/[...slug].astro delete mode 100644 packages/astro/test/fixtures/ssr-error/src/pages/index.astro delete mode 100644 packages/astro/test/ssr-error-pages.test.js create mode 100644 packages/astro/test/units/app/error-pages.test.js diff --git a/packages/astro/test/fixtures/ssr-error-pages/astro.config.mjs b/packages/astro/test/fixtures/ssr-error-pages/astro.config.mjs deleted file mode 100644 index 1ddc69dcc089..000000000000 --- a/packages/astro/test/fixtures/ssr-error-pages/astro.config.mjs +++ /dev/null @@ -1,7 +0,0 @@ -import { defineConfig } from "astro/config"; - -export default defineConfig({ - security: { - checkOrigin: false - } -}) diff --git a/packages/astro/test/fixtures/ssr-error-pages/package.json b/packages/astro/test/fixtures/ssr-error-pages/package.json deleted file mode 100644 index cebb0cbafcb6..000000000000 --- a/packages/astro/test/fixtures/ssr-error-pages/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "@test/ssr-api-route-custom-404", - "version": "0.0.0", - "private": true, - "dependencies": { - "astro": "workspace:*" - } -} diff --git a/packages/astro/test/fixtures/ssr-error-pages/src/content/pages/index.md b/packages/astro/test/fixtures/ssr-error-pages/src/content/pages/index.md deleted file mode 100644 index c98c9ad9ea37..000000000000 --- a/packages/astro/test/fixtures/ssr-error-pages/src/content/pages/index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Astro ---- - -## Index - -Home page \ No newline at end of file diff --git a/packages/astro/test/fixtures/ssr-error-pages/src/pages/404.astro b/packages/astro/test/fixtures/ssr-error-pages/src/pages/404.astro deleted file mode 100644 index c64eee468caf..000000000000 --- a/packages/astro/test/fixtures/ssr-error-pages/src/pages/404.astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -import "../styles/main.css" ---- - -

Something went horribly wrong!

diff --git a/packages/astro/test/fixtures/ssr-error-pages/src/pages/500.astro b/packages/astro/test/fixtures/ssr-error-pages/src/pages/500.astro deleted file mode 100644 index 0e36085e2d47..000000000000 --- a/packages/astro/test/fixtures/ssr-error-pages/src/pages/500.astro +++ /dev/null @@ -1 +0,0 @@ -

This is an error page

diff --git a/packages/astro/test/fixtures/ssr-error-pages/src/pages/api/route.js b/packages/astro/test/fixtures/ssr-error-pages/src/pages/api/route.js deleted file mode 100644 index 3547e0ad676d..000000000000 --- a/packages/astro/test/fixtures/ssr-error-pages/src/pages/api/route.js +++ /dev/null @@ -1,4 +0,0 @@ - -export function POST() { - return Response.json({ ok: true }); -} diff --git a/packages/astro/test/fixtures/ssr-error-pages/src/pages/blog/[...ssrPath].astro b/packages/astro/test/fixtures/ssr-error-pages/src/pages/blog/[...ssrPath].astro deleted file mode 100644 index aa40e4d8c9c6..000000000000 --- a/packages/astro/test/fixtures/ssr-error-pages/src/pages/blog/[...ssrPath].astro +++ /dev/null @@ -1,9 +0,0 @@ ---- -import { getEntry } from 'astro:content'; -const { ssrPath } = Astro.params; -const page = await getEntry('pages', ssrPath === undefined ? 'index' : ssrPath); -if (!page) return new Response(null, { - status: 404, - statusText: 'Not found' -}); ---- diff --git a/packages/astro/test/fixtures/ssr-error-pages/src/pages/causes-404.astro b/packages/astro/test/fixtures/ssr-error-pages/src/pages/causes-404.astro deleted file mode 100644 index 9331037be3c5..000000000000 --- a/packages/astro/test/fixtures/ssr-error-pages/src/pages/causes-404.astro +++ /dev/null @@ -1,6 +0,0 @@ ---- -return new Response(null, { - status: 404, - statusText: 'Not found', -}); ---- diff --git a/packages/astro/test/fixtures/ssr-error-pages/src/pages/causes-error.astro b/packages/astro/test/fixtures/ssr-error-pages/src/pages/causes-error.astro deleted file mode 100644 index 28a3b7cc21bb..000000000000 --- a/packages/astro/test/fixtures/ssr-error-pages/src/pages/causes-error.astro +++ /dev/null @@ -1,3 +0,0 @@ ---- -throw new Error(`oops`); ---- diff --git a/packages/astro/test/fixtures/ssr-error-pages/src/styles/main.css b/packages/astro/test/fixtures/ssr-error-pages/src/styles/main.css deleted file mode 100644 index 4717ad4b94f6..000000000000 --- a/packages/astro/test/fixtures/ssr-error-pages/src/styles/main.css +++ /dev/null @@ -1,3 +0,0 @@ -h1 { - color: red; -} \ No newline at end of file diff --git a/packages/astro/test/fixtures/ssr-error/package.json b/packages/astro/test/fixtures/ssr-error/package.json deleted file mode 100644 index ee13c03790c2..000000000000 --- a/packages/astro/test/fixtures/ssr-error/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "@test/ssr", - "version": "0.0.0", - "private": true, - "dependencies": { - "astro": "workspace:*" - } -} diff --git a/packages/astro/test/fixtures/ssr-error/src/pages/[...slug].astro b/packages/astro/test/fixtures/ssr-error/src/pages/[...slug].astro deleted file mode 100644 index 1fbb67e0c776..000000000000 --- a/packages/astro/test/fixtures/ssr-error/src/pages/[...slug].astro +++ /dev/null @@ -1,8 +0,0 @@ ---- -return new Response("oops", { - status: 500, - headers: new Headers({ - "X-Debug": "1234", - }), -}); ---- diff --git a/packages/astro/test/fixtures/ssr-error/src/pages/index.astro b/packages/astro/test/fixtures/ssr-error/src/pages/index.astro deleted file mode 100644 index 9509e01e50f3..000000000000 --- a/packages/astro/test/fixtures/ssr-error/src/pages/index.astro +++ /dev/null @@ -1,6 +0,0 @@ - -Hello world - -

Hello world

- - diff --git a/packages/astro/test/ssr-error-pages.test.js b/packages/astro/test/ssr-error-pages.test.js deleted file mode 100644 index beab4fa963f2..000000000000 --- a/packages/astro/test/ssr-error-pages.test.js +++ /dev/null @@ -1,196 +0,0 @@ -import assert from 'node:assert/strict'; -import { after, before, describe, it } from 'node:test'; -import * as cheerio from 'cheerio'; -import testAdapter from './test-adapter.js'; -import { loadFixture } from './test-utils.js'; - -describe('Default 500 page', () => { - /** @type {import('./test-utils.js').Fixture} */ - let fixture; - /** @type {import('./test-utils.js').App} */ - let app; - - before(async () => { - fixture = await loadFixture({ - root: './fixtures/ssr-error/', - output: 'server', - adapter: testAdapter(), - // test suite was authored when inlineStylesheets defaulted to never - build: { inlineStylesheets: 'never' }, - }); - await fixture.build({}); - app = await fixture.loadTestAdapterApp(); - }); - - it('should correctly merge headers coming from the original response and the 500 response, when calling a catch-all route', async () => { - const request = new Request('http://example.com/any'); - const response = await app.render(request); - assert.equal(response.status, 500); - assert.equal(response.headers.get('x-debug'), '1234'); - const html = await response.text(); - assert.match(html, /oops/); - }); -}); - -describe('404 and 500 pages', () => { - /** @type {import('./test-utils.js').Fixture} */ - let fixture; - - before(async () => { - fixture = await loadFixture({ - root: './fixtures/ssr-error-pages/', - output: 'server', - adapter: testAdapter(), - // test suite was authored when inlineStylesheets defaulted to never - build: { inlineStylesheets: 'never' }, - }); - }); - - describe('Development', () => { - /** @type {import('./test-utils.js').DevServer} */ - let devServer; - - before(async () => { - devServer = await fixture.startDevServer(); - }); - - after(async () => { - await devServer.stop(); - }); - - it('Returns 404 when hitting an API route with the wrong method', async () => { - let res = await fixture.fetch('/api/route', { - method: 'PUT', - }); - let html = await res.text(); - let $ = cheerio.load(html); - assert.equal($('h1').text(), `Something went horribly wrong!`); - }); - }); - - describe('Production', () => { - /** @type {import('./test-utils.js').App} */ - let app; - - before(async () => { - await fixture.build({}); - app = await fixture.loadTestAdapterApp(); - }); - - it('404 page returned when a route does not match', async () => { - const request = new Request('http://example.com/some/fake/route'); - const response = await app.render(request); - assert.equal(response.status, 404); - const html = await response.text(); - const $ = cheerio.load(html); - assert.equal($('h1').text(), 'Something went horribly wrong!'); - }); - - it('404 page returned when a route does not match and passing routeData', async () => { - const request = new Request('http://example.com/some/fake/route'); - const routeData = app.match(request); - const response = await app.render(request, { routeData }); - assert.equal(response.status, 404); - const html = await response.text(); - const $ = cheerio.load(html); - assert.equal($('h1').text(), 'Something went horribly wrong!'); - }); - - it('404 page returned when a route does not match and imports are included', async () => { - const request = new Request('http://example.com/blog/fake/route'); - const routeData = app.match(request); - const response = await app.render(request, { routeData }); - assert.equal(response.status, 404); - const html = await response.text(); - const $ = cheerio.load(html); - assert.equal($('head link').length, 1); - }); - - it('404 page returned when there is an 404 response returned from route', async () => { - const request = new Request('http://example.com/causes-404'); - const response = await app.render(request); - assert.equal(response.status, 404); - const html = await response.text(); - const $ = cheerio.load(html); - assert.equal($('h1').text(), 'Something went horribly wrong!'); - }); - - it('500 page returned when there is an error', async () => { - const request = new Request('http://example.com/causes-error'); - const response = await app.render(request); - assert.equal(response.status, 500); - const html = await response.text(); - const $ = cheerio.load(html); - assert.equal($('h1').text(), 'This is an error page'); - }); - - it('Returns 404 when hitting an API route with the wrong method', async () => { - const request = new Request('http://example.com/api/route', { - method: 'PUT', - }); - const response = await app.render(request); - assert.equal(response.status, 404); - const html = await response.text(); - const $ = cheerio.load(html); - assert.equal($('h1').text(), `Something went horribly wrong!`); - }); - }); -}); - -describe('trailing slashes for error pages', () => { - /** @type {import('./test-utils.js').Fixture} */ - let fixture; - - before(async () => { - fixture = await loadFixture({ - root: './fixtures/ssr-error-pages/', - output: 'server', - adapter: testAdapter(), - trailingSlash: 'always', - }); - }); - - describe('Development', () => { - /** @type {import('./test-utils.js').DevServer} */ - let devServer; - - before(async () => { - devServer = await fixture.startDevServer(); - }); - - after(async () => { - await devServer.stop(); - }); - - it('renders 404 page when a route does not match the request', async () => { - const response = await fixture.fetch('/ashbfjkasn/'); - assert.equal(response.status, 404); - const html = await response.text(); - const $ = cheerio.load(html); - assert.equal($('h1').text(), `Something went horribly wrong!`); - }); - - it('serves Vite assets correctly when trailingSlash is always', async () => { - const response = await fixture.fetch('/@vite/client'); - assert.equal(response.status, 200); - }); - }); - - describe('Production', () => { - /** @type {import('./test-utils.js').App} */ - let app; - - before(async () => { - await fixture.build({}); - app = await fixture.loadTestAdapterApp(); - }); - - it('renders 404 page when a route does not match the request', async () => { - const response = await app.render(new Request('http://example.com/ajksalscla/')); - assert.equal(response.status, 404); - const html = await response.text(); - const $ = cheerio.load(html); - assert.equal($('h1').text(), 'Something went horribly wrong!'); - }); - }); -}); diff --git a/packages/astro/test/units/app/error-pages.test.js b/packages/astro/test/units/app/error-pages.test.js new file mode 100644 index 000000000000..352a7b83d8ff --- /dev/null +++ b/packages/astro/test/units/app/error-pages.test.js @@ -0,0 +1,562 @@ +// @ts-check +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; +import { App } from '../../../dist/core/app/app.js'; +import { createComponent, maybeRenderHead, render } from '../../../dist/runtime/server/index.js'; + +function createManifest({ routes, pageMap, trailingSlash = 'ignore' }) { + const rootDir = new URL('file:///astro-test/'); + const buildDir = new URL('file:///astro-test/dist/'); + + return { + adapterName: 'test-adapter', + routes, + site: undefined, + base: '/', + userAssetsBase: undefined, + trailingSlash, + buildFormat: 'directory', + compressHTML: false, + assetsPrefix: undefined, + renderers: [], + serverLike: true, + clientDirectives: new Map(), + entryModules: {}, + inlinedScripts: new Map(), + assets: new Set(), + componentMetadata: new Map(), + pageModule: undefined, + pageMap, + serverIslandMappings: undefined, + key: Promise.resolve(/** @type {CryptoKey} */ ({})), + i18n: undefined, + middleware: undefined, + actions: undefined, + sessionDriver: undefined, + checkOrigin: false, + allowedDomains: undefined, + sessionConfig: undefined, + cacheDir: rootDir, + srcDir: rootDir, + outDir: buildDir, + rootDir, + publicDir: rootDir, + assetsDir: 'assets', + buildClientDir: buildDir, + buildServerDir: buildDir, + csp: undefined, + image: {}, + shouldInjectCspMetaTags: false, + devToolbar: { + enabled: false, + latestAstroVersion: undefined, + debugInfoOutput: undefined, + placement: undefined, + }, + internalFetchHeaders: undefined, + logLevel: 'silent', + }; +} + +describe('App render error pages', () => { + it('preserves headers and body for 500 responses from routes', async () => { + const routeData = { + route: '/[...slug]', + component: 'src/pages/[...slug].astro', + params: ['...slug'], + pathname: undefined, + distURL: [], + pattern: /^\/(.*?)\/?$/, + segments: [[{ content: '...slug', dynamic: true, spread: true }]], + type: 'endpoint', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', + }; + + const pageMap = new Map([ + [ + routeData.component, + async () => ({ + page: async () => ({ + ALL: async () => + new Response('oops', { + status: 500, + headers: { + 'X-Debug': '1234', + }, + }), + }), + }), + ], + ]); + + const app = new App(createManifest({ routes: [{ routeData }], pageMap })); + const request = new Request('http://example.com/any'); + const response = await app.render(request, { routeData }); + + assert.equal(response.status, 500); + assert.equal(response.headers.get('x-debug'), '1234'); + assert.match(await response.text(), /oops/); + }); + + it('renders the 404 page when an API route lacks a handler for the request method', async () => { + const apiRouteData = { + route: '/api/route', + component: 'src/pages/api/route.js', + params: [], + pathname: '/api/route', + distURL: [], + pattern: /^\/api\/route\/?$/, + segments: [ + [{ content: 'api', dynamic: false, spread: false }], + [{ content: 'route', dynamic: false, spread: false }], + ], + type: 'endpoint', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', + }; + + const notFoundRouteData = { + route: '/404', + component: 'src/pages/404.astro', + params: [], + pathname: '/404', + distURL: [], + pattern: /^\/404\/?$/, + segments: [[{ content: '404', dynamic: false, spread: false }]], + type: 'page', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', + }; + + const notFoundPage = createComponent((_result) => { + return render`

Something went horribly wrong!

`; + }); + + const pageMap = new Map([ + [ + apiRouteData.component, + async () => ({ + page: async () => ({ + POST: async () => new Response(JSON.stringify({ ok: true })), + }), + }), + ], + [ + notFoundRouteData.component, + async () => ({ + page: async () => ({ + default: notFoundPage, + }), + }), + ], + ]); + + const app = new App( + createManifest({ + routes: [{ routeData: apiRouteData }, { routeData: notFoundRouteData }], + pageMap, + }), + ); + const request = new Request('http://example.com/api/route', { method: 'PUT' }); + const response = await app.render(request, { routeData: apiRouteData }); + + assert.equal(response.status, 404); + assert.match(await response.text(), /Something went horribly wrong!/); + }); + + it('renders the 404 page when a route does not match', async () => { + const notFoundRouteData = { + route: '/404', + component: 'src/pages/404.astro', + params: [], + pathname: '/404', + distURL: [], + pattern: /^\/404\/?$/, + segments: [[{ content: '404', dynamic: false, spread: false }]], + type: 'page', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', + }; + + const notFoundPage = createComponent(() => { + return render`

Something went horribly wrong!

`; + }); + + const pageMap = new Map([ + [ + notFoundRouteData.component, + async () => ({ + page: async () => ({ + default: notFoundPage, + }), + }), + ], + ]); + + const app = new App(createManifest({ routes: [{ routeData: notFoundRouteData }], pageMap })); + const request = new Request('http://example.com/some/fake/route'); + const response = await app.render(request); + + assert.equal(response.status, 404); + assert.match(await response.text(), /Something went horribly wrong!/); + }); + + it('renders the 404 page when a route does not match and routeData is provided', async () => { + const notFoundRouteData = { + route: '/404', + component: 'src/pages/404.astro', + params: [], + pathname: '/404', + distURL: [], + pattern: /^\/404\/?$/, + segments: [[{ content: '404', dynamic: false, spread: false }]], + type: 'page', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', + }; + + const notFoundPage = createComponent(() => { + return render`

Something went horribly wrong!

`; + }); + + const pageMap = new Map([ + [ + notFoundRouteData.component, + async () => ({ + page: async () => ({ + default: notFoundPage, + }), + }), + ], + ]); + + const app = new App(createManifest({ routes: [{ routeData: notFoundRouteData }], pageMap })); + const request = new Request('http://example.com/some/fake/route'); + const routeData = app.match(request); + const response = await app.render(request, { routeData }); + + assert.equal(response.status, 404); + assert.match(await response.text(), /Something went horribly wrong!/); + }); + + it('renders the 404 page with imports when a matching route returns 404', async () => { + const blogRouteData = { + route: '/blog/[...ssrPath]', + component: 'src/pages/blog/[...ssrPath].astro', + params: ['...ssrPath'], + pathname: undefined, + distURL: [], + pattern: /^\/blog(?:\/(.*))?$/, + segments: [ + [{ content: 'blog', dynamic: false, spread: false }], + [{ content: '...ssrPath', dynamic: true, spread: true }], + ], + type: 'page', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', + }; + + const notFoundRouteData = { + route: '/404', + component: 'src/pages/404.astro', + params: [], + pathname: '/404', + distURL: [], + pattern: /^\/404\/?$/, + segments: [[{ content: '404', dynamic: false, spread: false }]], + type: 'page', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', + }; + + const notFoundPage = createComponent((result) => { + return render`${maybeRenderHead(result)}

Something went horribly wrong!

`; + }); + + const pageMap = new Map([ + [ + blogRouteData.component, + async () => ({ + // Returning 404 should trigger 404 route + page: async () => ({ + default: createComponent(() => new Response(null, { status: 404 })), + }), + }), + ], + [ + notFoundRouteData.component, + async () => ({ + page: async () => ({ + default: notFoundPage, + }), + }), + ], + ]); + + const app = new App( + createManifest({ + routes: [ + { routeData: blogRouteData }, + { + routeData: notFoundRouteData, + styles: [{ type: 'external', src: '/main.css' }], + }, + ], + pageMap, + }), + ); + const request = new Request('http://example.com/blog/fake/route'); + const routeData = app.match(request); + const response = await app.render(request, { routeData }); + + assert.equal(response.status, 404); + const html = await response.text(); + assert.match(html, /Something went horribly wrong!/); + assert.match(html, /]*href="\/main\.css"/); + }); + + it('renders the 500 page when a route throws an error', async () => { + const errorRouteData = { + route: '/causes-error', + component: 'src/pages/causes-error.astro', + params: [], + pathname: '/causes-error', + distURL: [], + pattern: /^\/causes-error\/?$/, + segments: [[{ content: 'causes-error', dynamic: false, spread: false }]], + type: 'page', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', + }; + + const internalErrorRouteData = { + route: '/500', + component: 'src/pages/500.astro', + params: [], + pathname: '/500', + distURL: [], + pattern: /^\/500\/?$/, + segments: [[{ content: '500', dynamic: false, spread: false }]], + type: 'page', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', + }; + + const internalErrorPage = createComponent(() => { + return render`

This is an error page

`; + }); + + const pageMap = new Map([ + [ + errorRouteData.component, + async () => ({ + page: async () => ({ + default: createComponent(() => { + throw new Error('oops'); + }), + }), + }), + ], + [ + internalErrorRouteData.component, + async () => ({ + page: async () => ({ + default: internalErrorPage, + }), + }), + ], + ]); + + const app = new App( + createManifest({ + routes: [{ routeData: errorRouteData }, { routeData: internalErrorRouteData }], + pageMap, + }), + ); + const request = new Request('http://example.com/causes-error'); + const response = await app.render(request, { routeData: errorRouteData }); + + assert.equal(response.status, 500); + assert.match(await response.text(), /This is an error page/); + }); + + it('renders the 404 page when an API route lacks a handler in production', async () => { + const apiRouteData = { + route: '/api/route', + component: 'src/pages/api/route.js', + params: [], + pathname: '/api/route', + distURL: [], + pattern: /^\/api\/route\/?$/, + segments: [ + [{ content: 'api', dynamic: false, spread: false }], + [{ content: 'route', dynamic: false, spread: false }], + ], + type: 'endpoint', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', + }; + + const notFoundRouteData = { + route: '/404', + component: 'src/pages/404.astro', + params: [], + pathname: '/404', + distURL: [], + pattern: /^\/404\/?$/, + segments: [[{ content: '404', dynamic: false, spread: false }]], + type: 'page', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', + }; + + const notFoundPage = createComponent((result) => { + return render`${maybeRenderHead(result)}

Something went horribly wrong!

`; + }); + + const pageMap = new Map([ + [ + apiRouteData.component, + async () => ({ + page: async () => ({ + POST: async () => new Response(JSON.stringify({ ok: true })), + }), + }), + ], + [ + notFoundRouteData.component, + async () => ({ + page: async () => ({ + default: notFoundPage, + }), + }), + ], + ]); + + const app = new App( + createManifest({ + routes: [{ routeData: apiRouteData }, { routeData: notFoundRouteData }], + pageMap, + }), + ); + const request = new Request('http://example.com/api/route', { method: 'PUT' }); + const response = await app.render(request); + + assert.equal(response.status, 404); + assert.match(await response.text(), /Something went horribly wrong!/); + }); + + it('renders the 404 page when a route does not match with trailingSlash always', async () => { + const notFoundRouteData = { + route: '/404', + component: 'src/pages/404.astro', + params: [], + pathname: '/404', + distURL: [], + pattern: /^\/404\/?$/, + segments: [[{ content: '404', dynamic: false, spread: false }]], + type: 'page', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', + }; + + const notFoundPage = createComponent(() => { + return render`

Something went horribly wrong!

`; + }); + + const pageMap = new Map([ + [ + notFoundRouteData.component, + async () => ({ + page: async () => ({ + default: notFoundPage, + }), + }), + ], + ]); + + const app = new App( + createManifest({ + routes: [{ routeData: notFoundRouteData }], + pageMap, + trailingSlash: 'always', + }), + ); + const request = new Request('http://example.com/ajksalscla/'); + const response = await app.render(request); + + assert.equal(response.status, 404); + assert.match(await response.text(), /Something went horribly wrong!/); + }); + + it('renders the 404 page when a route does not match with trailingSlash always and routeData', async () => { + const notFoundRouteData = { + route: '/404', + component: 'src/pages/404.astro', + params: [], + pathname: '/404', + distURL: [], + pattern: /^\/404\/?$/, + segments: [[{ content: '404', dynamic: false, spread: false }]], + type: 'page', + prerender: false, + fallbackRoutes: [], + isIndex: false, + origin: 'project', + }; + + const notFoundPage = createComponent(() => { + return render`

Something went horribly wrong!

`; + }); + + const pageMap = new Map([ + [ + notFoundRouteData.component, + async () => ({ + page: async () => ({ + default: notFoundPage, + }), + }), + ], + ]); + + const app = new App( + createManifest({ + routes: [{ routeData: notFoundRouteData }], + pageMap, + trailingSlash: 'always', + }), + ); + const request = new Request('http://example.com/ajksalscla/'); + const routeData = app.match(request); + const response = await app.render(request, { routeData }); + + assert.equal(response.status, 404); + assert.match(await response.text(), /Something went horribly wrong!/); + }); +}); From a93c81de493e912aeba1d829d9ccf6997b2eb806 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Mon, 16 Feb 2026 09:33:04 -0500 Subject: [PATCH 11/12] fix(content): reload markdown updates in dev (#15497) * fix(content): reload markdown updates in dev * fix lint + comment * test: fix hmr markdown fixture --- .changeset/fix-content-hmr.md | 5 +++ .../content/vite-plugin-content-imports.ts | 4 +- .../vite-plugin-content-virtual-mod.ts | 4 +- .../fixtures/hmr-markdown/astro.config.mjs | 3 ++ .../test/fixtures/hmr-markdown/package.json | 8 ++++ .../hmr-markdown/src/content.config.ts | 12 +++++ .../hmr-markdown/src/content/blog/post.md | 5 +++ .../hmr-markdown/src/pages/index.astro | 21 +++++++++ packages/astro/test/hmr-markdown.test.js | 44 +++++++++++++++++++ pnpm-lock.yaml | 6 +++ 10 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 .changeset/fix-content-hmr.md create mode 100644 packages/astro/test/fixtures/hmr-markdown/astro.config.mjs create mode 100644 packages/astro/test/fixtures/hmr-markdown/package.json create mode 100644 packages/astro/test/fixtures/hmr-markdown/src/content.config.ts create mode 100644 packages/astro/test/fixtures/hmr-markdown/src/content/blog/post.md create mode 100644 packages/astro/test/fixtures/hmr-markdown/src/pages/index.astro create mode 100644 packages/astro/test/hmr-markdown.test.js diff --git a/.changeset/fix-content-hmr.md b/.changeset/fix-content-hmr.md new file mode 100644 index 000000000000..f62fe0f2c8e8 --- /dev/null +++ b/.changeset/fix-content-hmr.md @@ -0,0 +1,5 @@ +--- +"astro": patch +--- + +Fix dev reloads for content collection Markdown updates under Vite 7. diff --git a/packages/astro/src/content/vite-plugin-content-imports.ts b/packages/astro/src/content/vite-plugin-content-imports.ts index f9a4bb5a1b55..c5cb5f2d61e1 100644 --- a/packages/astro/src/content/vite-plugin-content-imports.ts +++ b/packages/astro/src/content/vite-plugin-content-imports.ts @@ -163,6 +163,7 @@ export const _internal = { viteServer.watcher.on('all', async (event, entry) => { if (CHOKIDAR_MODIFIED_EVENTS.includes(event)) { const environment = viteServer.environments[ASTRO_VITE_ENVIRONMENT_NAMES.ssr]; + const timestamp = Date.now(); const entryType = getEntryType(entry, contentPaths, contentEntryExts, dataEntryExts); if (!COLLECTION_TYPES_TO_INVALIDATE_ON.includes(entryType)) return; @@ -191,7 +192,8 @@ export const _internal = { try { const mod = await environment.moduleGraph.getModuleByUrl(modUrl); if (mod) { - environment.moduleGraph.invalidateModule(mod); + // Pass `true` to mark this as HMR invalidation so Vite drops cached SSR results. + environment.moduleGraph.invalidateModule(mod, undefined, timestamp, true); } } catch (e: any) { // The server may be closed due to a restart caused by this file change diff --git a/packages/astro/src/content/vite-plugin-content-virtual-mod.ts b/packages/astro/src/content/vite-plugin-content-virtual-mod.ts index 6d862323e04c..f2a67f35b5e9 100644 --- a/packages/astro/src/content/vite-plugin-content-virtual-mod.ts +++ b/packages/astro/src/content/vite-plugin-content-virtual-mod.ts @@ -35,7 +35,9 @@ function invalidateDataStore(viteServer: ViteDevServer) { const environment = viteServer.environments[ASTRO_VITE_ENVIRONMENT_NAMES.ssr]; const module = environment.moduleGraph.getModuleById(RESOLVED_DATA_STORE_VIRTUAL_ID); if (module) { - environment.moduleGraph.invalidateModule(module); + const timestamp = Date.now(); + // Pass `true` to mark this as HMR invalidation so Vite drops cached SSR results. + environment.moduleGraph.invalidateModule(module, undefined, timestamp, true); } viteServer.environments.client.hot.send({ type: 'full-reload', diff --git a/packages/astro/test/fixtures/hmr-markdown/astro.config.mjs b/packages/astro/test/fixtures/hmr-markdown/astro.config.mjs new file mode 100644 index 000000000000..86dbfb924824 --- /dev/null +++ b/packages/astro/test/fixtures/hmr-markdown/astro.config.mjs @@ -0,0 +1,3 @@ +import { defineConfig } from 'astro/config'; + +export default defineConfig({}); diff --git a/packages/astro/test/fixtures/hmr-markdown/package.json b/packages/astro/test/fixtures/hmr-markdown/package.json new file mode 100644 index 000000000000..3e0fafefe6dd --- /dev/null +++ b/packages/astro/test/fixtures/hmr-markdown/package.json @@ -0,0 +1,8 @@ +{ + "name": "@test/hmr-markdown", + "version": "0.0.0", + "private": true, + "dependencies": { + "astro": "workspace:*" + } +} diff --git a/packages/astro/test/fixtures/hmr-markdown/src/content.config.ts b/packages/astro/test/fixtures/hmr-markdown/src/content.config.ts new file mode 100644 index 000000000000..aea3a32e9dee --- /dev/null +++ b/packages/astro/test/fixtures/hmr-markdown/src/content.config.ts @@ -0,0 +1,12 @@ +import { defineCollection } from 'astro:content'; +import { glob } from 'astro/loaders'; +import { z } from 'astro/zod'; + +const blog = defineCollection({ + loader: glob({ pattern: '**/*.md', base: './src/content/blog' }), + schema: z.object({ + title: z.string(), + }), +}); + +export const collections = { blog }; diff --git a/packages/astro/test/fixtures/hmr-markdown/src/content/blog/post.md b/packages/astro/test/fixtures/hmr-markdown/src/content/blog/post.md new file mode 100644 index 000000000000..629e3a9e78f4 --- /dev/null +++ b/packages/astro/test/fixtures/hmr-markdown/src/content/blog/post.md @@ -0,0 +1,5 @@ +--- +title: HMR Markdown +--- + +Original content diff --git a/packages/astro/test/fixtures/hmr-markdown/src/pages/index.astro b/packages/astro/test/fixtures/hmr-markdown/src/pages/index.astro new file mode 100644 index 000000000000..353f1ece89ad --- /dev/null +++ b/packages/astro/test/fixtures/hmr-markdown/src/pages/index.astro @@ -0,0 +1,21 @@ +--- +import { getCollection } from 'astro:content'; + +const [post] = await getCollection('blog'); +--- + + + HMR Markdown + + +

Blog Posts

+ {post ? ( + <> +

{post.data.title}

+
{post.body}
+ + ) : ( +

Empty

+ )} + + diff --git a/packages/astro/test/hmr-markdown.test.js b/packages/astro/test/hmr-markdown.test.js new file mode 100644 index 000000000000..93257fb37154 --- /dev/null +++ b/packages/astro/test/hmr-markdown.test.js @@ -0,0 +1,44 @@ +import assert from 'node:assert/strict'; +import { after, before, describe, it } from 'node:test'; +import { isWindows, loadFixture } from './test-utils.js'; + +const UPDATED_CONTENT = '---\ntitle: HMR Markdown\n---\n\nUpdated content\n'; + +describe('HMR: Markdown updates', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture; + /** @type {import('./test-utils').DevServer} */ + let devServer; + /** @type {string} */ + let markdownPath; + + before(async () => { + fixture = await loadFixture({ root: './fixtures/hmr-markdown/' }); + devServer = await fixture.startDevServer(); + + markdownPath = '/src/content/blog/post.md'; + }); + + after(async () => { + await devServer.stop(); + }); + + it( + 'should update HTML when markdown changes', + { skip: isWindows, todo: 'HMR tests hang on Windows' }, + async () => { + let response = await fixture.fetch('/'); + assert.equal(response.status, 200); + let html = await response.text(); + assert.ok(html.includes('Original content')); + + await fixture.editFile(markdownPath, UPDATED_CONTENT); + await fixture.onNextDataStoreChange(); + + response = await fixture.fetch('/'); + assert.equal(response.status, 200); + html = await response.text(); + assert.ok(html.includes('Updated content')); + }, + ); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 95d2bb092269..f807ebdf6031 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3391,6 +3391,12 @@ importers: specifier: workspace:* version: link:../../.. + packages/astro/test/fixtures/hmr-markdown: + dependencies: + astro: + specifier: workspace:* + version: link:../../.. + packages/astro/test/fixtures/hmr-new-page: dependencies: astro: From 9f21b243d21478cdc5fb0193e05adad8e753839f Mon Sep 17 00:00:00 2001 From: Florian Lefebvre Date: Mon, 16 Feb 2026 15:58:09 +0100 Subject: [PATCH 12/12] feat: improve naming of new adapter api (#15461) * feat: improve naming of new adapter api * chore: changesets * Apply suggestions from code review * fix * Update .changeset/light-parrots-find.md * feat: warning * Apply suggestions from code review * Apply suggestion from @florian-lefebvre * Update packages/astro/src/types/public/integrations.ts * Update packages/astro/src/types/public/integrations.ts * Update .changeset/light-parrots-find.md * Apply suggestions from code review Co-authored-by: Sarah Rainsberger <5098874+sarah11918@users.noreply.github.com> * Update .changeset/bright-symbols-see.md Co-authored-by: Sarah Rainsberger <5098874+sarah11918@users.noreply.github.com> * Update .changeset/bright-symbols-see.md Co-authored-by: Sarah Rainsberger <5098874+sarah11918@users.noreply.github.com> --------- Co-authored-by: Sarah Rainsberger <5098874+sarah11918@users.noreply.github.com> --- .changeset/bright-symbols-see.md | 28 +++++++++++++++++++ .changeset/light-parrots-find.md | 5 ++++ .changeset/puny-dragons-fail.md | 6 ++++ .../src/core/build/plugins/plugin-ssr.ts | 6 ++-- packages/astro/src/core/build/static-build.ts | 15 +++++----- .../astro/src/core/dev/adapter-validation.ts | 5 ++++ .../astro/src/types/public/integrations.ts | 25 +++++++++-------- .../src/vite-plugin-adapter-config/index.ts | 2 +- .../server-entry/fake-adapter/index.js | 2 +- packages/astro/test/test-adapter.js | 2 +- packages/integrations/cloudflare/src/index.ts | 2 +- packages/integrations/netlify/src/index.ts | 2 +- packages/integrations/vercel/src/index.ts | 2 +- 13 files changed, 74 insertions(+), 28 deletions(-) create mode 100644 .changeset/bright-symbols-see.md create mode 100644 .changeset/light-parrots-find.md create mode 100644 .changeset/puny-dragons-fail.md diff --git a/.changeset/bright-symbols-see.md b/.changeset/bright-symbols-see.md new file mode 100644 index 000000000000..a6d194413d9b --- /dev/null +++ b/.changeset/bright-symbols-see.md @@ -0,0 +1,28 @@ +--- +'astro': major +--- + +**BREAKING CHANGE to the v6 beta Adapter API only**: renames `entryType` to `entrypointResolution` and updates possible values + +Astro 6 introduced a way to let adapters have more control over the entrypoint by passing `entryType: 'self'` to `setAdapter()`. However during beta development, the name was unclear and confusing. + +`entryType` is now renamed to `entrypointResolution` and its possible values are updated: + +- `legacy-dynamic` becomes `explicit`. +- `self` becomes `auto`. + +If you are building an adapter with v6 beta and specifying `entryType`, update it: + +```diff +setAdapter({ + // ... +- entryType: 'legacy-dynamic' ++ entrypointResolution: 'explicit' +}) + +setAdapter({ + // ... +- entryType: 'self' ++ entrypointResolution: 'auto' +}) +``` diff --git a/.changeset/light-parrots-find.md b/.changeset/light-parrots-find.md new file mode 100644 index 000000000000..344f1725850d --- /dev/null +++ b/.changeset/light-parrots-find.md @@ -0,0 +1,5 @@ +--- +'astro': major +--- + +Deprecates `createExports()` and `start()` (Adapter API) - ([v6 upgrade guidance](https://v6.docs.astro.build/en/guides/upgrade-to/v6/#deprecated-createexports-and-start-adapter-api)) diff --git a/.changeset/puny-dragons-fail.md b/.changeset/puny-dragons-fail.md new file mode 100644 index 000000000000..f5fac0ef5058 --- /dev/null +++ b/.changeset/puny-dragons-fail.md @@ -0,0 +1,6 @@ +--- +'@astrojs/netlify': patch +'@astrojs/vercel': patch +--- + +Updates to new Adapter API introduced in v6 diff --git a/packages/astro/src/core/build/plugins/plugin-ssr.ts b/packages/astro/src/core/build/plugins/plugin-ssr.ts index 66cf1b19d492..11b7e9eaa7a2 100644 --- a/packages/astro/src/core/build/plugins/plugin-ssr.ts +++ b/packages/astro/src/core/build/plugins/plugin-ssr.ts @@ -4,10 +4,10 @@ import type { BuildInternals } from '../internal.js'; import type { StaticBuildOptions } from '../types.js'; import { ASTRO_VITE_ENVIRONMENT_NAMES } from '../../constants.js'; -type LegacyAdapter = Extract; +type LegacyAdapter = Extract; -function isLegacyAdapter(adapter: AstroAdapter): adapter is LegacyAdapter { - return adapter.entryType === undefined || adapter.entryType === 'legacy-dynamic'; +export function isLegacyAdapter(adapter: AstroAdapter): adapter is LegacyAdapter { + return adapter.entrypointResolution === undefined || adapter.entrypointResolution === 'explicit'; } export const LEGACY_SSR_ENTRY_VIRTUAL_MODULE = 'virtual:astro:legacy-ssr-entry'; diff --git a/packages/astro/src/core/build/static-build.ts b/packages/astro/src/core/build/static-build.ts index 19e604f3c182..9fe2fbdb8149 100644 --- a/packages/astro/src/core/build/static-build.ts +++ b/packages/astro/src/core/build/static-build.ts @@ -22,6 +22,7 @@ import { trackPageData } from './internal.js'; import { getAllBuildPlugins } from './plugins/index.js'; import { manifestBuildPostHook } from './plugins/plugin-manifest.js'; import { + isLegacyAdapter, LEGACY_SSR_ENTRY_VIRTUAL_MODULE, RESOLVED_LEGACY_SSR_ENTRY_VIRTUAL_MODULE, } from './plugins/plugin-ssr.js'; @@ -152,9 +153,7 @@ async function buildEnvironments(opts: StaticBuildOptions, internals: BuildInter const { allPages, settings, viteConfig } = opts; const routes = Object.values(allPages).flatMap((pageData) => pageData.route); - // Determine if we should use the legacy-dynamic entrypoint - const entryType = settings.adapter?.entryType ?? 'legacy-dynamic'; - const useLegacyDynamic = entryType === 'legacy-dynamic'; + const legacyAdapter = !settings.adapter || isLegacyAdapter(settings.adapter); const buildPlugins = getAllBuildPlugins(internals, opts); const flatPlugins = buildPlugins.flat().filter(Boolean); @@ -246,7 +245,7 @@ async function buildEnvironments(opts: StaticBuildOptions, internals: BuildInter ...viteConfig.build?.rollupOptions, // Setting as `exports-only` allows us to safely delete inputs that are only used during prerendering preserveEntrySignatures: 'exports-only', - ...(useLegacyDynamic && settings.buildOutput === 'server' + ...(legacyAdapter && settings.buildOutput === 'server' ? { input: LEGACY_SSR_ENTRY_VIRTUAL_MODULE } : {}), output: { @@ -285,8 +284,8 @@ async function buildEnvironments(opts: StaticBuildOptions, internals: BuildInter ); } else if ( chunkInfo.facadeModuleId === RESOLVED_LEGACY_SSR_ENTRY_VIRTUAL_MODULE || - // This catches the case when the adapter uses `entryType: 'self'. When doing so, - // the adapter must set rollupOptions.input. + // This catches the case when the adapter uses `entrypointResolution: 'auto'`. When doing so, + // the adapter must set rollupOptions.input or Astro sets it from `serverEntrypoint`. isRollupInput(chunkInfo.name) || isRollupInput(chunkInfo.facadeModuleId) ) { @@ -367,9 +366,9 @@ async function buildEnvironments(opts: StaticBuildOptions, internals: BuildInter emitAssets: true, outDir: fileURLToPath(new URL('./.prerender/', getServerOutputDirectory(settings))), rollupOptions: { - // Only skip the default prerender entrypoint if an adapter with entryType: 'self' is used + // Only skip the default prerender entrypoint if an adapter with `entrypointResolution: 'self'` is used // AND provides a custom prerenderer. Otherwise, use the default. - ...(!useLegacyDynamic && settings.prerenderer + ...(!legacyAdapter && settings.prerenderer ? {} : { input: 'astro/entrypoints/prerender' }), output: { diff --git a/packages/astro/src/core/dev/adapter-validation.ts b/packages/astro/src/core/dev/adapter-validation.ts index 43471d24870c..445a1aaefc51 100644 --- a/packages/astro/src/core/dev/adapter-validation.ts +++ b/packages/astro/src/core/dev/adapter-validation.ts @@ -47,4 +47,9 @@ export function validateSetAdapter( ); } } + + if (adapter.entrypointResolution === undefined) { + logger.warn(null, `The adapter ${adapter.name} uses \`entrypointResolution: "explicit"\` by default, which is deprecated and will be removed in a future major version.`) + logger.warn(null, 'Update your adapter to use \`entrypointResolution: "auto"\` or contact the maintainers to update.'); + } } diff --git a/packages/astro/src/types/public/integrations.ts b/packages/astro/src/types/public/integrations.ts index f2a2b9af97f1..767bb45d6037 100644 --- a/packages/astro/src/types/public/integrations.ts +++ b/packages/astro/src/types/public/integrations.ts @@ -119,27 +119,30 @@ export interface AstroAdapterClientConfig { assetQueryParams?: URLSearchParams; } -interface AdapterLegacyDynamicProperties { +interface AdapterExplicitProperties { /** * Determines how the adapter's entrypoint is handled during the build. - * - `'self'`: The adapter defines its own entrypoint and sets rollupOptions.input - * - `'legacy-dynamic'`: Uses the virtual module entrypoint with dynamic exports - * @default 'legacy-dynamic' + * - `'auto'`: The adapter defines its own entrypoint and provides either serverEntrypoint or rollupOptions.input + * - `'explicit'`: Uses the virtual module entrypoint with dynamic exports + * @default 'explicit' + * @deprecated This will be removed in a future major version and `'auto'` will become the default */ - entryType?: 'legacy-dynamic'; + entrypointResolution?: 'explicit'; serverEntrypoint?: string | URL; + /** @deprecated This will be removed in a future major version, alongside `entrypointResolution: 'explicit'` */ exports?: string[]; + /** @deprecated This will be removed in a future major version, alongside `entrypointResolution: 'explicit'` */ args?: any; } -interface AdapterSelfProperties { +interface AdapterAutoProperties { /** * Determines how the adapter's entrypoint is handled during the build. - * - `'self'`: The adapter defines its own entrypoint and sets rollupOptions.input - * - `'legacy-dynamic'`: Uses the virtual module entrypoint with dynamic exports - * @default 'legacy-dynamic' + * - `'auto'`: The adapter defines its own entrypoint and provides either serverEntrypoint or rollupOptions.input + * - `'explicit'`: Uses the virtual module entrypoint with dynamic exports + * @default 'explicit' */ - entryType: 'self'; + entrypointResolution: 'auto'; serverEntrypoint?: string | URL; } @@ -157,7 +160,7 @@ export type AstroAdapter = { * Configuration for Astro's client-side code. */ client?: AstroAdapterClientConfig; -} & (AdapterLegacyDynamicProperties | AdapterSelfProperties); +} & (AdapterExplicitProperties | AdapterAutoProperties); /** * A pathname with its associated route, used for prerendering. diff --git a/packages/astro/src/vite-plugin-adapter-config/index.ts b/packages/astro/src/vite-plugin-adapter-config/index.ts index 99ffdcc867f7..539186ed5246 100644 --- a/packages/astro/src/vite-plugin-adapter-config/index.ts +++ b/packages/astro/src/vite-plugin-adapter-config/index.ts @@ -12,7 +12,7 @@ export function vitePluginAdapterConfig(settings: AstroSettings): VitePlugin { name: 'astro:adapter-config', config() { const { adapter } = settings; - if (adapter && adapter.entryType === 'self' && adapter.serverEntrypoint) { + if (adapter && adapter.entrypointResolution === 'auto' && adapter.serverEntrypoint) { return { build: { rollupOptions: { diff --git a/packages/astro/test/fixtures/server-entry/fake-adapter/index.js b/packages/astro/test/fixtures/server-entry/fake-adapter/index.js index 97a3e55567ac..62747246d4be 100644 --- a/packages/astro/test/fixtures/server-entry/fake-adapter/index.js +++ b/packages/astro/test/fixtures/server-entry/fake-adapter/index.js @@ -30,7 +30,7 @@ export default function fakeAdapter(options) { 'astro:config:done': (params) => { params.setAdapter({ name:'@test/server-entry-fake-adapter', - entryType: 'self', + entrypointResolution: 'auto', serverEntrypoint: options.type === 'serverEntrypoint' ? ENTRYPOINT : undefined, supportedAstroFeatures: { serverOutput: 'stable' diff --git a/packages/astro/test/test-adapter.js b/packages/astro/test/test-adapter.js index 0f7a50494722..bf2190585e2e 100644 --- a/packages/astro/test/test-adapter.js +++ b/packages/astro/test/test-adapter.js @@ -255,7 +255,7 @@ export function selfTestAdapter({ setAdapter({ name: 'my-ssr-adapter', serverEntrypoint: '@my-ssr', - entryType: 'self', + entrypointResolution: 'auto', supportedAstroFeatures: { serverOutput: 'stable', envGetSecret: 'stable', diff --git a/packages/integrations/cloudflare/src/index.ts b/packages/integrations/cloudflare/src/index.ts index c2c73b03decb..71048175ce1e 100644 --- a/packages/integrations/cloudflare/src/index.ts +++ b/packages/integrations/cloudflare/src/index.ts @@ -220,7 +220,7 @@ export default function createIntegration(args?: Options): AstroIntegration { edgeMiddleware: false, buildOutput: 'server', }, - entryType: 'self', + entrypointResolution: 'auto', previewEntrypoint: '@astrojs/cloudflare/entrypoints/preview', supportedAstroFeatures: { serverOutput: 'stable', diff --git a/packages/integrations/netlify/src/index.ts b/packages/integrations/netlify/src/index.ts index b5f404002fd5..e89be60126e0 100644 --- a/packages/integrations/netlify/src/index.ts +++ b/packages/integrations/netlify/src/index.ts @@ -682,7 +682,7 @@ export default function netlifyIntegration( setAdapter({ name: '@astrojs/netlify', - entryType: 'self', + entrypointResolution: 'auto', serverEntrypoint: '@astrojs/netlify/ssr-function.js', adapterFeatures: { edgeMiddleware: useEdgeMiddleware, diff --git a/packages/integrations/vercel/src/index.ts b/packages/integrations/vercel/src/index.ts index 87205ecc0946..e6db88a9c907 100644 --- a/packages/integrations/vercel/src/index.ts +++ b/packages/integrations/vercel/src/index.ts @@ -109,7 +109,7 @@ function getAdapter({ }): AstroAdapter { return { name: PACKAGE_NAME, - entryType: 'self', + entrypointResolution: 'auto', serverEntrypoint: `${PACKAGE_NAME}/entrypoint`, adapterFeatures: { edgeMiddleware,