mirror of
https://github.com/withastro/astro.git
synced 2025-03-17 23:11:29 -05:00
Merge branch 'next' into responsive-images
This commit is contained in:
commit
ffe063c544
102 changed files with 1425 additions and 783 deletions
5
.changeset/empty-houses-melt.md
Normal file
5
.changeset/empty-houses-melt.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': minor
|
||||
---
|
||||
|
||||
Updates to Vite 6.0.0-beta.6
|
|
@ -53,6 +53,7 @@
|
|||
"eighty-boxes-applaud",
|
||||
"eighty-donkeys-fly",
|
||||
"eighty-ligers-punch",
|
||||
"empty-houses-melt",
|
||||
"five-jars-hear",
|
||||
"fluffy-jars-live",
|
||||
"forty-trains-notice",
|
||||
|
@ -84,6 +85,7 @@
|
|||
"nasty-crabs-worry",
|
||||
"neat-dots-hear",
|
||||
"neat-queens-learn",
|
||||
"old-actors-learn",
|
||||
"old-zebras-teach",
|
||||
"perfect-fans-fly",
|
||||
"pink-yaks-exercise",
|
||||
|
@ -91,6 +93,7 @@
|
|||
"poor-dots-add",
|
||||
"poor-frogs-dream",
|
||||
"poor-seals-clap",
|
||||
"pretty-walls-camp",
|
||||
"quick-ads-exercise",
|
||||
"quick-onions-leave",
|
||||
"rotten-phones-scream",
|
||||
|
@ -113,6 +116,7 @@
|
|||
"ten-walls-tap",
|
||||
"three-days-cough",
|
||||
"three-olives-reflect",
|
||||
"tough-planets-dress",
|
||||
"twelve-comics-march",
|
||||
"twenty-cobras-push",
|
||||
"unlucky-bobcats-sit",
|
||||
|
|
5
.changeset/pretty-walls-camp.md
Normal file
5
.changeset/pretty-walls-camp.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@astrojs/svelte': patch
|
||||
---
|
||||
|
||||
New release to include changes from 5.7.3
|
5
.changeset/tough-planets-dress.md
Normal file
5
.changeset/tough-planets-dress.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': minor
|
||||
---
|
||||
|
||||
Adds a new components exported from `astro/components`: Welcome, to be used by the new Basics template
|
50
.github/workflows/continuous_benchmark.yml
vendored
Normal file
50
.github/workflows/continuous_benchmark.yml
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
name: Continuous benchmark
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
FORCE_COLOR: true
|
||||
CODSPEED_TOKEN: ${{ secrets.CODSPEED_TOKEN }}
|
||||
CODSPEED: true
|
||||
|
||||
jobs:
|
||||
codspeed:
|
||||
if: ${{ github.repository_owner == 'withastro' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup PNPM
|
||||
uses: pnpm/action-setup@v3
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
cache: "pnpm"
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Build
|
||||
run: pnpm run build
|
||||
|
||||
- name: Run the benchmarks
|
||||
uses: CodSpeedHQ/action@fa1dcde8d58f2ab0b407a6a24d6cc5a8c1444a8c # v3.1.0
|
||||
timeout-minutes: 30
|
||||
with:
|
||||
run: pnpm benchmark codspeed
|
||||
|
|
@ -14,7 +14,7 @@ export const astroBin = path.resolve(astroPkgPath, '../astro.js');
|
|||
export function calculateStat(numbers) {
|
||||
const avg = numbers.reduce((a, b) => a + b, 0) / numbers.length;
|
||||
const stdev = Math.sqrt(
|
||||
numbers.map((x) => Math.pow(x - avg, 2)).reduce((a, b) => a + b, 0) / numbers.length
|
||||
numbers.map((x) => Math.pow(x - avg, 2)).reduce((a, b) => a + b, 0) / numbers.length,
|
||||
);
|
||||
const max = Math.max(...numbers);
|
||||
return { avg, stdev, max };
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { fileURLToPath } from 'node:url';
|
||||
import { exec } from 'tinyexec';
|
||||
import { markdownTable } from 'markdown-table';
|
||||
import { exec } from 'tinyexec';
|
||||
import { astroBin, calculateStat } from './_util.js';
|
||||
|
||||
/** Default project to run for this benchmark if not specified */
|
||||
|
@ -8,9 +8,8 @@ export const defaultProject = 'render-default';
|
|||
|
||||
/**
|
||||
* @param {URL} projectDir
|
||||
* @param {URL} outputFile
|
||||
*/
|
||||
export async function run(projectDir, outputFile) {
|
||||
export async function run(projectDir) {
|
||||
const root = fileURLToPath(projectDir);
|
||||
|
||||
console.log('Benchmarking `astro --help`...');
|
||||
|
@ -28,7 +27,7 @@ export async function run(projectDir, outputFile) {
|
|||
printResult({
|
||||
'astro --help': helpStat,
|
||||
'astro info': infoStat,
|
||||
})
|
||||
}),
|
||||
);
|
||||
console.log('='.repeat(10));
|
||||
}
|
||||
|
@ -45,7 +44,7 @@ async function benchmarkCommand(command, args, root) {
|
|||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const start = performance.now();
|
||||
await exec(command, args, { nodeOptions: { cwd: root } });
|
||||
await exec(command, args, { nodeOptions: { cwd: root }, throwOnError: true });
|
||||
durations.push(performance.now() - start);
|
||||
}
|
||||
|
||||
|
@ -69,6 +68,6 @@ function printResult(result) {
|
|||
],
|
||||
{
|
||||
align: ['l', 'r', 'r', 'r'],
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
50
benchmark/bench/codspeed.js
Normal file
50
benchmark/bench/codspeed.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
import path from 'node:path';
|
||||
import { withCodSpeed } from '@codspeed/tinybench-plugin';
|
||||
import { Bench } from 'tinybench';
|
||||
import { exec } from 'tinyexec';
|
||||
import { renderPages } from '../make-project/render-default.js';
|
||||
import { astroBin } from './_util.js';
|
||||
|
||||
export async function run({ memory: _memory, render, stress: _stress }) {
|
||||
const options = {
|
||||
iterations: 10,
|
||||
};
|
||||
const bench = process.env.CODSPEED ? withCodSpeed(new Bench(options)) : new Bench(options);
|
||||
let app;
|
||||
bench.add(
|
||||
'Rendering',
|
||||
async () => {
|
||||
console.info('Start task.');
|
||||
const result = {};
|
||||
for (const fileName of renderPages) {
|
||||
const pathname = '/' + fileName.slice(0, -path.extname(fileName).length);
|
||||
const request = new Request(new URL(pathname, 'http://exmpale.com'));
|
||||
const response = await app.render(request);
|
||||
const html = await response.text();
|
||||
if (!result[pathname]) result[pathname] = [];
|
||||
result[pathname].push(html);
|
||||
}
|
||||
console.info('Finish task.');
|
||||
return result;
|
||||
},
|
||||
{
|
||||
async beforeAll() {
|
||||
// build for rendering
|
||||
await exec(astroBin, ['build'], {
|
||||
nodeOptions: {
|
||||
cwd: render.root,
|
||||
stdio: 'inherit',
|
||||
},
|
||||
});
|
||||
|
||||
const entry = new URL('./dist/server/entry.mjs', `file://${render.root}`);
|
||||
const { manifest, createApp } = await import(entry);
|
||||
app = createApp(manifest);
|
||||
app.manifest = manifest;
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
await bench.run();
|
||||
console.table(bench.table());
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import { exec } from 'tinyexec';
|
||||
import { markdownTable } from 'markdown-table';
|
||||
import fs from 'node:fs/promises';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { markdownTable } from 'markdown-table';
|
||||
import { exec } from 'tinyexec';
|
||||
import { astroBin } from './_util.js';
|
||||
|
||||
/** @typedef {Record<string, import('../../packages/astro/src/core/config/timer').Stat>} AstroTimerStat */
|
||||
|
@ -26,6 +26,7 @@ export async function run(projectDir, outputFile) {
|
|||
ASTRO_TIMER_PATH: outputFilePath,
|
||||
},
|
||||
},
|
||||
throwOnError: true,
|
||||
});
|
||||
|
||||
console.log('Raw results written to', outputFilePath);
|
||||
|
@ -55,6 +56,6 @@ function printResult(output) {
|
|||
],
|
||||
{
|
||||
align: ['l', 'r', 'r', 'r'],
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { exec } from 'tinyexec';
|
||||
import { markdownTable } from 'markdown-table';
|
||||
import fs from 'node:fs/promises';
|
||||
import http from 'node:http';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { markdownTable } from 'markdown-table';
|
||||
import { waitUntilBusy } from 'port-authority';
|
||||
import { calculateStat, astroBin } from './_util.js';
|
||||
import { exec } from 'tinyexec';
|
||||
import { renderPages } from '../make-project/render-default.js';
|
||||
import { astroBin, calculateStat } from './_util.js';
|
||||
|
||||
const port = 4322;
|
||||
|
||||
|
@ -25,6 +25,7 @@ export async function run(projectDir, outputFile) {
|
|||
cwd: root,
|
||||
stdio: 'inherit',
|
||||
},
|
||||
throwOnError: true,
|
||||
});
|
||||
|
||||
console.log('Previewing...');
|
||||
|
@ -33,6 +34,7 @@ export async function run(projectDir, outputFile) {
|
|||
cwd: root,
|
||||
stdio: 'inherit',
|
||||
},
|
||||
throwOnError: true,
|
||||
});
|
||||
|
||||
console.log('Waiting for server ready...');
|
||||
|
@ -58,14 +60,14 @@ export async function run(projectDir, outputFile) {
|
|||
console.log('Done!');
|
||||
}
|
||||
|
||||
async function benchmarkRenderTime() {
|
||||
export async function benchmarkRenderTime(portToListen = port) {
|
||||
/** @type {Record<string, number[]>} */
|
||||
const result = {};
|
||||
for (const fileName of renderPages) {
|
||||
// Render each file 100 times and push to an array
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const pathname = '/' + fileName.slice(0, -path.extname(fileName).length);
|
||||
const renderTime = await fetchRenderTime(`http://localhost:${port}${pathname}`);
|
||||
const renderTime = await fetchRenderTime(`http://localhost:${portToListen}${pathname}`);
|
||||
if (!result[pathname]) result[pathname] = [];
|
||||
result[pathname].push(renderTime);
|
||||
}
|
||||
|
@ -95,7 +97,7 @@ function printResult(result) {
|
|||
],
|
||||
{
|
||||
align: ['l', 'r', 'r', 'r'],
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import autocannon from 'autocannon';
|
||||
import { exec } from 'tinyexec';
|
||||
import { markdownTable } from 'markdown-table';
|
||||
import fs from 'node:fs/promises';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import autocannon from 'autocannon';
|
||||
import { markdownTable } from 'markdown-table';
|
||||
import { waitUntilBusy } from 'port-authority';
|
||||
import pb from 'pretty-bytes';
|
||||
import { exec } from 'tinyexec';
|
||||
import { astroBin } from './_util.js';
|
||||
|
||||
const port = 4321;
|
||||
|
@ -24,12 +24,15 @@ export async function run(projectDir, outputFile) {
|
|||
cwd: root,
|
||||
stdio: 'inherit',
|
||||
},
|
||||
throwOnError: true,
|
||||
});
|
||||
|
||||
console.log('Previewing...');
|
||||
const previewProcess = execaCommand(`${astroBin} preview --port ${port}`, {
|
||||
cwd: root,
|
||||
stdio: 'inherit',
|
||||
const previewProcess = await exec(astroBin, ['preview', '--port', port], {
|
||||
nodeOptions: {
|
||||
cwd: root,
|
||||
stdio: 'inherit',
|
||||
},
|
||||
});
|
||||
|
||||
console.log('Waiting for server ready...');
|
||||
|
@ -58,7 +61,7 @@ export async function run(projectDir, outputFile) {
|
|||
/**
|
||||
* @returns {Promise<import('autocannon').Result>}
|
||||
*/
|
||||
async function benchmarkCannon() {
|
||||
export async function benchmarkCannon() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const instance = autocannon(
|
||||
{
|
||||
|
@ -75,7 +78,7 @@ async function benchmarkCannon() {
|
|||
instance.stop();
|
||||
resolve(result);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
autocannon.track(instance, { renderResultsTable: false });
|
||||
});
|
||||
|
@ -94,7 +97,7 @@ function printResult(output) {
|
|||
],
|
||||
{
|
||||
align: ['l', 'r', 'r', 'r'],
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const reqAndBytesTable = markdownTable(
|
||||
|
@ -105,7 +108,7 @@ function printResult(output) {
|
|||
],
|
||||
{
|
||||
align: ['l', 'r', 'r', 'r', 'r'],
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return `${latencyTable}\n\n${reqAndBytesTable}`;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import mri from 'mri';
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
import {fileURLToPath, pathToFileURL} from 'node:url';
|
||||
|
||||
const args = mri(process.argv.slice(2));
|
||||
|
||||
|
@ -14,6 +14,7 @@ Command
|
|||
memory Run build memory and speed test
|
||||
render Run rendering speed test
|
||||
server-stress Run server stress test
|
||||
codspeed Run codspeed test
|
||||
cli-startup Run CLI startup speed test
|
||||
|
||||
Options
|
||||
|
@ -29,6 +30,7 @@ const benchmarks = {
|
|||
render: () => import('./bench/render.js'),
|
||||
'server-stress': () => import('./bench/server-stress.js'),
|
||||
'cli-startup': () => import('./bench/cli-startup.js'),
|
||||
codspeed: () => import('./bench/codspeed.js')
|
||||
};
|
||||
|
||||
if (commandName && !(commandName in benchmarks)) {
|
||||
|
@ -37,12 +39,26 @@ if (commandName && !(commandName in benchmarks)) {
|
|||
}
|
||||
|
||||
if (commandName) {
|
||||
// Run single benchmark
|
||||
const bench = benchmarks[commandName];
|
||||
const benchMod = await bench();
|
||||
const projectDir = await makeProject(args.project || benchMod.defaultProject);
|
||||
const outputFile = await getOutputFile(commandName);
|
||||
await benchMod.run(projectDir, outputFile);
|
||||
if (commandName === 'codspeed') {
|
||||
const render = await makeProject('render-bench');
|
||||
const rootRender = fileURLToPath(render);
|
||||
const bench = benchmarks[commandName];
|
||||
const benchMod = await bench();
|
||||
const payload = {
|
||||
render: {
|
||||
root: rootRender,
|
||||
output: await getOutputFile('render')
|
||||
},
|
||||
};
|
||||
await benchMod.run(payload);
|
||||
} else {
|
||||
// Run single benchmark
|
||||
const bench = benchmarks[commandName];
|
||||
const benchMod = await bench();
|
||||
const projectDir = await makeProject(args.project || benchMod.defaultProject);
|
||||
const outputFile = await getOutputFile(commandName);
|
||||
await benchMod.run(projectDir, outputFile);
|
||||
}
|
||||
} else {
|
||||
// Run all benchmarks
|
||||
for (const name in benchmarks) {
|
||||
|
@ -54,7 +70,7 @@ if (commandName) {
|
|||
}
|
||||
}
|
||||
|
||||
async function makeProject(name) {
|
||||
export async function makeProject(name) {
|
||||
console.log('Making project:', name);
|
||||
const projectDir = new URL(`./projects/${name}/`, import.meta.url);
|
||||
|
||||
|
@ -78,6 +94,5 @@ async function getOutputFile(benchmarkName) {
|
|||
|
||||
// Prepare output file directory
|
||||
await fs.mkdir(new URL('./', file), { recursive: true });
|
||||
|
||||
return file;
|
||||
}
|
||||
|
|
132
benchmark/make-project/render-bench.js
Normal file
132
benchmark/make-project/render-bench.js
Normal file
|
@ -0,0 +1,132 @@
|
|||
import fs from 'node:fs/promises';
|
||||
import { loremIpsumHtml, loremIpsumMd } from './_util.js';
|
||||
|
||||
// Map of files to be generated and tested for rendering.
|
||||
// Ideally each content should be similar for comparison.
|
||||
const renderFiles = {
|
||||
'components/ListItem.astro': `\
|
||||
---
|
||||
const { className, item, attrs } = Astro.props;
|
||||
const nested = item !== 0;
|
||||
---
|
||||
<li class={className}>
|
||||
<a
|
||||
href={item}
|
||||
aria-current={item === 0}
|
||||
class:list={[{ large: !nested }, className]}
|
||||
{...attrs}
|
||||
>
|
||||
<span>{item}</span>
|
||||
</a>
|
||||
</li>
|
||||
`,
|
||||
'components/Sublist.astro': `\
|
||||
---
|
||||
import ListItem from '../components/ListItem.astro';
|
||||
const { items } = Astro.props;
|
||||
const className = "text-red-500";
|
||||
const style = { color: "red" };
|
||||
---
|
||||
<ul style={style}>
|
||||
{items.map((item) => (
|
||||
<ListItem className={className} item={item} attrs={{}} />
|
||||
))}
|
||||
</ul>
|
||||
`,
|
||||
'pages/astro.astro': `\
|
||||
---
|
||||
const className = "text-red-500";
|
||||
const style = { color: "red" };
|
||||
const items = Array.from({ length: 10000 }, (_, i) => ({i}));
|
||||
---
|
||||
<html>
|
||||
<head>
|
||||
<title>My Site</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1 class={className + ' text-lg'}>List</h1>
|
||||
<ul style={style}>
|
||||
{items.map((item) => (
|
||||
<li class={className}>
|
||||
<a
|
||||
href={item.i}
|
||||
aria-current={item.i === 0}
|
||||
class:list={[{ large: item.i === 0 }, className]}
|
||||
{...({})}
|
||||
>
|
||||
<span>{item.i}</span>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
${Array.from({ length: 1000 })
|
||||
.map(() => `<p>${loremIpsumHtml}</p>`)
|
||||
.join('\n')}
|
||||
</body>
|
||||
</html>`,
|
||||
'pages/md.md': `\
|
||||
# List
|
||||
|
||||
${Array.from({ length: 1000 }, (_, i) => i)
|
||||
.map((v) => `- ${v}`)
|
||||
.join('\n')}
|
||||
|
||||
${Array.from({ length: 1000 })
|
||||
.map(() => loremIpsumMd)
|
||||
.join('\n\n')}
|
||||
`,
|
||||
'pages/mdx.mdx': `\
|
||||
export const className = "text-red-500";
|
||||
export const style = { color: "red" };
|
||||
export const items = Array.from({ length: 1000 }, (_, i) => i);
|
||||
|
||||
# List
|
||||
|
||||
<ul style={style}>
|
||||
{items.map((item) => (
|
||||
<li class={className}>{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
${Array.from({ length: 1000 })
|
||||
.map(() => loremIpsumMd)
|
||||
.join('\n\n')}
|
||||
`,
|
||||
};
|
||||
|
||||
export const renderPages = [];
|
||||
for (const file of Object.keys(renderFiles)) {
|
||||
if (file.startsWith('pages/')) {
|
||||
renderPages.push(file.replace('pages/', ''));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {URL} projectDir
|
||||
*/
|
||||
export async function run(projectDir) {
|
||||
await fs.rm(projectDir, { recursive: true, force: true });
|
||||
await fs.mkdir(new URL('./src/pages', projectDir), { recursive: true });
|
||||
await fs.mkdir(new URL('./src/components', projectDir), { recursive: true });
|
||||
|
||||
await Promise.all(
|
||||
Object.entries(renderFiles).map(([name, content]) => {
|
||||
return fs.writeFile(new URL(`./src/${name}`, projectDir), content, 'utf-8');
|
||||
})
|
||||
);
|
||||
|
||||
await fs.writeFile(
|
||||
new URL('./astro.config.js', projectDir),
|
||||
`\
|
||||
import { defineConfig } from 'astro/config';
|
||||
import adapter from '@benchmark/adapter';
|
||||
import mdx from '@astrojs/mdx';
|
||||
|
||||
export default defineConfig({
|
||||
integrations: [mdx()],
|
||||
output: 'server',
|
||||
adapter: adapter(),
|
||||
});`,
|
||||
'utf-8'
|
||||
);
|
||||
}
|
|
@ -10,6 +10,7 @@
|
|||
"@astrojs/mdx": "workspace:*",
|
||||
"@astrojs/node": "^8.3.4",
|
||||
"@benchmark/timer": "workspace:*",
|
||||
"@benchmark/adapter": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"autocannon": "^7.15.0",
|
||||
"markdown-table": "^3.0.4",
|
||||
|
@ -18,5 +19,9 @@
|
|||
"pretty-bytes": "^6.1.1",
|
||||
"sharp": "^0.33.3",
|
||||
"tinyexec": "^0.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@codspeed/tinybench-plugin": "^3.1.1",
|
||||
"tinybench": "^2.9.0"
|
||||
}
|
||||
}
|
||||
|
|
3
benchmark/packages/adapter/README.md
Normal file
3
benchmark/packages/adapter/README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# @benchmark/timer
|
||||
|
||||
Like `@astrojs/node`, but returns the rendered time in milliseconds for the page instead of the page content itself. This is used for internal benchmarks only.
|
35
benchmark/packages/adapter/package.json
Normal file
35
benchmark/packages/adapter/package.json
Normal file
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"name": "@benchmark/adapter",
|
||||
"description": "Bench adapter",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"types": "./dist/index.d.ts",
|
||||
"author": "withastro",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"withastro",
|
||||
"astro-adapter"
|
||||
],
|
||||
"exports": {
|
||||
".": "./dist/index.js",
|
||||
"./server.js": "./dist/server.js",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
|
||||
"build:ci": "astro-scripts build \"src/**/*.ts\"",
|
||||
"dev": "astro-scripts dev \"src/**/*.ts\""
|
||||
},
|
||||
"dependencies": {
|
||||
"server-destroy": "^1.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"astro": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/server-destroy": "^1.0.4",
|
||||
"astro": "workspace:*",
|
||||
"astro-scripts": "workspace:*"
|
||||
}
|
||||
}
|
32
benchmark/packages/adapter/src/index.ts
Normal file
32
benchmark/packages/adapter/src/index.ts
Normal file
|
@ -0,0 +1,32 @@
|
|||
import type { AstroAdapter, AstroIntegration } from 'astro';
|
||||
|
||||
export default function createIntegration(): AstroIntegration {
|
||||
return {
|
||||
name: '@benchmark/timer',
|
||||
hooks: {
|
||||
'astro:config:setup': ({ updateConfig }) => {
|
||||
updateConfig({
|
||||
vite: {
|
||||
ssr: {
|
||||
noExternal: ['@benchmark/timer'],
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
'astro:config:done': ({ setAdapter }) => {
|
||||
setAdapter({
|
||||
name: '@benchmark/adapter',
|
||||
serverEntrypoint: '@benchmark/adapter/server.js',
|
||||
exports: ['manifest', 'createApp'],
|
||||
supportedAstroFeatures: {
|
||||
serverOutput: 'stable',
|
||||
envGetSecret: 'experimental',
|
||||
staticOutput: 'stable',
|
||||
hybridOutput: 'stable',
|
||||
i18nDomains: 'stable',
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
34
benchmark/packages/adapter/src/server.ts
Normal file
34
benchmark/packages/adapter/src/server.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
import * as fs from 'node:fs';
|
||||
import type { SSRManifest } from 'astro';
|
||||
import { App } from 'astro/app';
|
||||
import { applyPolyfills } from 'astro/app/node';
|
||||
|
||||
applyPolyfills();
|
||||
|
||||
class MyApp extends App {
|
||||
#manifest: SSRManifest | undefined;
|
||||
#streaming: boolean;
|
||||
constructor(manifest: SSRManifest, streaming = false) {
|
||||
super(manifest, streaming);
|
||||
this.#manifest = manifest;
|
||||
this.#streaming = streaming;
|
||||
}
|
||||
|
||||
async render(request: Request) {
|
||||
const url = new URL(request.url);
|
||||
if (this.#manifest?.assets.has(url.pathname)) {
|
||||
const filePath = new URL('../../client/' + this.removeBase(url.pathname), import.meta.url);
|
||||
const data = await fs.promises.readFile(filePath);
|
||||
return new Response(data);
|
||||
}
|
||||
|
||||
return super.render(request);
|
||||
}
|
||||
}
|
||||
|
||||
export function createExports(manifest: SSRManifest) {
|
||||
return {
|
||||
manifest,
|
||||
createApp: (streaming: boolean) => new MyApp(manifest, streaming),
|
||||
};
|
||||
}
|
7
benchmark/packages/adapter/tsconfig.json
Normal file
7
benchmark/packages/adapter/tsconfig.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"include": ["src"],
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist"
|
||||
}
|
||||
}
|
|
@ -6,7 +6,9 @@ export function getAdapter(): AstroAdapter {
|
|||
serverEntrypoint: '@benchmark/timer/server.js',
|
||||
previewEntrypoint: '@benchmark/timer/preview.js',
|
||||
exports: ['handler'],
|
||||
supportedAstroFeatures: {},
|
||||
supportedAstroFeatures: {
|
||||
serverOutput: 'stable',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
13
biome.jsonc
13
biome.jsonc
|
@ -9,20 +9,17 @@
|
|||
"**/_temp-fixtures/**",
|
||||
"**/vendor/**",
|
||||
"**/.vercel/**",
|
||||
"benchmark/projects/",
|
||||
"benchmark/results/",
|
||||
"benchmark/bench/_template.js",
|
||||
],
|
||||
"include": ["test/**", "e2e/**", "packages/**", "/scripts/**"],
|
||||
"include": ["test/**", "e2e/**", "packages/**", "/scripts/**", "benchmark/bench"],
|
||||
},
|
||||
"formatter": {
|
||||
"indentStyle": "tab",
|
||||
"indentWidth": 2,
|
||||
"lineWidth": 100,
|
||||
"ignore": [
|
||||
"benchmark/projects/",
|
||||
"benchmark/results/",
|
||||
".changeset",
|
||||
"pnpm-lock.yaml",
|
||||
"*.astro",
|
||||
],
|
||||
"ignore": [".changeset", "pnpm-lock.yaml", "*.astro"],
|
||||
},
|
||||
"organizeImports": {
|
||||
"enabled": true,
|
||||
|
|
|
@ -10,6 +10,6 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^5.0.0-beta.6"
|
||||
"astro": "^5.0.0-beta.7"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,6 @@
|
|||
"@astrojs/mdx": "^4.0.0-beta.3",
|
||||
"@astrojs/rss": "^4.0.9",
|
||||
"@astrojs/sitemap": "^3.2.1",
|
||||
"astro": "^5.0.0-beta.6"
|
||||
"astro": "^5.0.0-beta.7"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
],
|
||||
"scripts": {},
|
||||
"devDependencies": {
|
||||
"astro": "^5.0.0-beta.6"
|
||||
"astro": "^5.0.0-beta.7"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"astro": "^4.0.0 || ^5.0.0"
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"test": "vitest run"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^5.0.0-beta.6",
|
||||
"astro": "^5.0.0-beta.7",
|
||||
"@astrojs/react": "^3.6.2",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
|
|
|
@ -13,6 +13,6 @@
|
|||
"@astrojs/alpinejs": "^0.4.0",
|
||||
"@types/alpinejs": "^3.13.10",
|
||||
"alpinejs": "^3.14.3",
|
||||
"astro": "^5.0.0-beta.6"
|
||||
"astro": "^5.0.0-beta.7"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
"@astrojs/preact": "^3.5.3",
|
||||
"@astrojs/react": "^3.6.2",
|
||||
"@astrojs/solid-js": "^4.4.2",
|
||||
"@astrojs/svelte": "^6.0.0-beta.1",
|
||||
"@astrojs/svelte": "^6.0.0-beta.2",
|
||||
"@astrojs/vue": "^5.0.0-beta.1",
|
||||
"@types/react": "^18.3.12",
|
||||
"@types/react-dom": "^18.3.1",
|
||||
"astro": "^5.0.0-beta.6",
|
||||
"astro": "^5.0.0-beta.7",
|
||||
"preact": "^10.24.3",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"dependencies": {
|
||||
"@astrojs/preact": "^3.5.3",
|
||||
"@preact/signals": "^1.3.0",
|
||||
"astro": "^5.0.0-beta.6",
|
||||
"astro": "^5.0.0-beta.7",
|
||||
"preact": "^10.24.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"@astrojs/react": "^3.6.2",
|
||||
"@types/react": "^18.3.12",
|
||||
"@types/react-dom": "^18.3.1",
|
||||
"astro": "^5.0.0-beta.6",
|
||||
"astro": "^5.0.0-beta.7",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@astrojs/solid-js": "^4.4.2",
|
||||
"astro": "^5.0.0-beta.6",
|
||||
"astro": "^5.0.0-beta.7",
|
||||
"solid-js": "^1.9.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/svelte": "^6.0.0-beta.1",
|
||||
"astro": "^5.0.0-beta.6",
|
||||
"@astrojs/svelte": "^6.0.0-beta.2",
|
||||
"astro": "^5.0.0-beta.7",
|
||||
"svelte": "^4.2.19"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@astrojs/vue": "^5.0.0-beta.1",
|
||||
"astro": "^5.0.0-beta.6",
|
||||
"astro": "^5.0.0-beta.7",
|
||||
"vue": "^3.5.12"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@astrojs/node": "^9.0.0-alpha.1",
|
||||
"astro": "^5.0.0-beta.6"
|
||||
"astro": "^5.0.0-beta.7"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
],
|
||||
"scripts": {},
|
||||
"devDependencies": {
|
||||
"astro": "^5.0.0-beta.6"
|
||||
"astro": "^5.0.0-beta.7"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"astro": "^4.0.0"
|
||||
|
|
|
@ -10,6 +10,6 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^5.0.0-beta.6"
|
||||
"astro": "^5.0.0-beta.7"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,6 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^5.0.0-beta.6"
|
||||
"astro": "^5.0.0-beta.7"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@astrojs/node": "^9.0.0-alpha.1",
|
||||
"@astrojs/svelte": "^6.0.0-beta.1",
|
||||
"astro": "^5.0.0-beta.6",
|
||||
"@astrojs/svelte": "^6.0.0-beta.2",
|
||||
"astro": "^5.0.0-beta.7",
|
||||
"svelte": "^4.2.19"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^5.0.0-beta.6",
|
||||
"sass": "^1.80.3",
|
||||
"astro": "^5.0.0-beta.7",
|
||||
"sass": "^1.80.6",
|
||||
"sharp": "^0.33.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,6 @@
|
|||
"./app": "./dist/app.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "^5.0.0-beta.6"
|
||||
"astro": "^5.0.0-beta.7"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@astrojs/markdoc": "^0.12.0-beta.0",
|
||||
"astro": "^5.0.0-beta.6"
|
||||
"astro": "^5.0.0-beta.7"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"dependencies": {
|
||||
"@astrojs/mdx": "^4.0.0-beta.3",
|
||||
"@astrojs/preact": "^3.5.3",
|
||||
"astro": "^5.0.0-beta.6",
|
||||
"astro": "^5.0.0-beta.7",
|
||||
"preact": "^10.24.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"dependencies": {
|
||||
"@astrojs/preact": "^3.5.3",
|
||||
"@nanostores/preact": "^0.5.2",
|
||||
"astro": "^5.0.0-beta.6",
|
||||
"astro": "^5.0.0-beta.7",
|
||||
"nanostores": "^0.11.3",
|
||||
"preact": "^10.24.3"
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"@astrojs/mdx": "^4.0.0-beta.3",
|
||||
"@astrojs/tailwind": "^5.1.2",
|
||||
"@types/canvas-confetti": "^1.6.4",
|
||||
"astro": "^5.0.0-beta.6",
|
||||
"astro": "^5.0.0-beta.7",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"canvas-confetti": "^1.9.3",
|
||||
"postcss": "^8.4.47",
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"test": "vitest"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^5.0.0-beta.6",
|
||||
"vitest": "^2.1.3"
|
||||
"astro": "^5.0.0-beta.7",
|
||||
"vitest": "^2.1.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
"@changesets/cli": "^2.27.9",
|
||||
"@types/node": "^18.17.8",
|
||||
"esbuild": "^0.21.5",
|
||||
"eslint": "^9.13.0",
|
||||
"eslint": "^9.14.0",
|
||||
"eslint-plugin-regexp": "^2.6.0",
|
||||
"globby": "^14.0.2",
|
||||
"only-allow": "^1.2.1",
|
||||
|
@ -67,12 +67,12 @@
|
|||
"prettier-plugin-astro": "^0.14.1",
|
||||
"turbo": "^2.2.3",
|
||||
"typescript": "~5.6.3",
|
||||
"typescript-eslint": "^8.11.0"
|
||||
"typescript-eslint": "^8.13.0"
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"vitest>vite": "6.0.0-beta.2",
|
||||
"vite-node>vite": "6.0.0-beta.2"
|
||||
"vitest>vite": "6.0.0-beta.6",
|
||||
"vite-node>vite": "6.0.0-beta.6"
|
||||
},
|
||||
"peerDependencyRules": {
|
||||
"allowAny": [
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
# astro
|
||||
|
||||
## 5.0.0-beta.7
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#12323](https://github.com/withastro/astro/pull/12323) [`c280655`](https://github.com/withastro/astro/commit/c280655655cc6c22121f32c5f7c76836adf17230) Thanks [@bluwy](https://github.com/bluwy)! - Updates to Vite 6.0.0-beta.6
|
||||
|
||||
- [#12379](https://github.com/withastro/astro/pull/12379) [`94f4fe8`](https://github.com/withastro/astro/commit/94f4fe8180f02cf19fb617dde7d67d4f7bee8dac) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Adds a new components exported from `astro/components`: Welcome, to be used by the new Basics template
|
||||
|
||||
## 5.0.0-beta.6
|
||||
|
||||
### Major Changes
|
||||
|
@ -1118,6 +1126,34 @@
|
|||
- Updated dependencies [[`83a2a64`](https://github.com/withastro/astro/commit/83a2a648418ad30f4eb781d1c1b5f2d8a8ac846e)]:
|
||||
- @astrojs/markdown-remark@6.0.0-alpha.0
|
||||
|
||||
## 4.16.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#12311](https://github.com/withastro/astro/pull/12311) [`bf2723e`](https://github.com/withastro/astro/commit/bf2723e83140099914b29c6d51eb147a065be460) Thanks [@dinesh-58](https://github.com/dinesh-58)! - Adds `checked` to the list of boolean attributes.
|
||||
|
||||
- [#12363](https://github.com/withastro/astro/pull/12363) [`222f718`](https://github.com/withastro/astro/commit/222f71894cc7118319ce83b3b29fa61a9dbebb75) Thanks [@Fryuni](https://github.com/Fryuni)! - Fixes code generated by `astro add` command when adding a version of an integration other than the default `latest`.
|
||||
|
||||
- [#12368](https://github.com/withastro/astro/pull/12368) [`493fe43`](https://github.com/withastro/astro/commit/493fe43cd3ef94b087b8958031ecc964ae73463b) Thanks [@bluwy](https://github.com/bluwy)! - Improves error logs when executing commands
|
||||
|
||||
- [#12355](https://github.com/withastro/astro/pull/12355) [`c4726d7`](https://github.com/withastro/astro/commit/c4726d7ba8cc93157390ce64d5c8b718ed5cac29) Thanks [@apatel369](https://github.com/apatel369)! - Improves error reporting for invalid frontmatter in MDX files during the `astro build` command. The error message now includes the file path where the frontmatter parsing failed.
|
||||
|
||||
## 4.16.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#12333](https://github.com/withastro/astro/pull/12333) [`836cd91`](https://github.com/withastro/astro/commit/836cd91c37cea8ae58dd04a326435fcb2c88f358) Thanks [@imattacus](https://github.com/imattacus)! - Destroy the server response stream if async error is thrown
|
||||
|
||||
- [#12358](https://github.com/withastro/astro/pull/12358) [`7680349`](https://github.com/withastro/astro/commit/76803498738f9e86e7948ce81e01e63607e03549) Thanks [@spacedawwwg](https://github.com/spacedawwwg)! - Honors `inlineAstroConfig` parameter in `getViteConfig` when creating a logger
|
||||
|
||||
- [#12353](https://github.com/withastro/astro/pull/12353) [`35795a1`](https://github.com/withastro/astro/commit/35795a1a54b2bfaf331c58ca91b47e5672e08c4e) Thanks [@hippotastic](https://github.com/hippotastic)! - Fixes an issue in dev server watch file handling that could cause multiple restarts for a single file change.
|
||||
|
||||
- [#12351](https://github.com/withastro/astro/pull/12351) [`5751488`](https://github.com/withastro/astro/commit/57514881655b62a0bc39ace1e1ed4b89b96f74ca) Thanks [@florian-lefebvre](https://github.com/florian-lefebvre)! - Reverts a change made in `4.16.6` that prevented usage of `astro:env` secrets inside middleware in SSR
|
||||
|
||||
- [#12346](https://github.com/withastro/astro/pull/12346) [`20e5a84`](https://github.com/withastro/astro/commit/20e5a843c86e9328814615edf3e8a6fb5e4696cc) Thanks [@bluwy](https://github.com/bluwy)! - Fixes sourcemap generation when prefetch is enabled
|
||||
|
||||
- [#12349](https://github.com/withastro/astro/pull/12349) [`1fc83d3`](https://github.com/withastro/astro/commit/1fc83d3ba8315c31b2a3aadc77b20b1615d261a0) Thanks [@norskeld](https://github.com/norskeld)! - Fixes the `getImage` options type so it properly extends `ImageTransform`
|
||||
|
||||
## 4.16.8
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// The `ts-ignore` comments here are necessary because we're importing this file inside the `astro:components`
|
||||
// virtual module's types, which means that `tsc` will try to resolve these imports.
|
||||
// @ts-ignore
|
||||
export { default as Code } from "./Code.astro";
|
||||
export { default as Code } from './Code.astro';
|
||||
// @ts-ignore
|
||||
export { default as Debug } from "./Debug.astro";
|
||||
export { default as Debug } from './Debug.astro';
|
||||
// @ts-ignore
|
||||
export { default as Welcome } from "./Welcome.astro";
|
||||
export { default as Welcome } from './Welcome.astro';
|
||||
|
|
|
@ -81,7 +81,8 @@ test.describe('Error display', () => {
|
|||
expect(fileLocation).toMatch(/^vue\/VueRuntimeError.vue/);
|
||||
});
|
||||
|
||||
test('shows correct line when a style preprocess has an error', async ({ page, astro }) => {
|
||||
// TODO: unskip when upgrading to Vite 6.0.0-beta.7 or above
|
||||
test.skip('shows correct line when a style preprocess has an error', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/astro-sass-error'), { waitUntil: 'networkidle' });
|
||||
|
||||
const { fileLocation, absoluteFileLocation } = await getErrorOverlayContent(page);
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
"private": true,
|
||||
"dependencies": {
|
||||
"astro": "workspace:*",
|
||||
"sass": "^1.80.4"
|
||||
"sass": "^1.80.6"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"preact": "^10.24.3",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"sass": "^1.80.4",
|
||||
"sass": "^1.80.6",
|
||||
"solid-js": "^1.9.3",
|
||||
"svelte": "^4.2.19",
|
||||
"vue": "^3.5.12"
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
"private": true,
|
||||
"devDependencies": {
|
||||
"astro": "workspace:*",
|
||||
"sass": "^1.80.4"
|
||||
"sass": "^1.80.6"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "astro",
|
||||
"version": "5.0.0-beta.6",
|
||||
"version": "5.0.0-beta.7",
|
||||
"description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
|
||||
"type": "module",
|
||||
"author": "withastro",
|
||||
|
@ -165,7 +165,7 @@
|
|||
"tsconfck": "^3.1.4",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"vfile": "^6.0.3",
|
||||
"vite": "6.0.0-beta.2",
|
||||
"vite": "6.0.0-beta.6",
|
||||
"vitefu": "^1.0.3",
|
||||
"which-pm": "^3.0.0",
|
||||
"xxhash-wasm": "^1.0.2",
|
||||
|
@ -200,7 +200,7 @@
|
|||
"eol": "^0.10.0",
|
||||
"execa": "^8.0.1",
|
||||
"expect-type": "^1.1.0",
|
||||
"fs-fixture": "^2.5.0",
|
||||
"fs-fixture": "^2.6.0",
|
||||
"mdast-util-mdx": "^3.0.0",
|
||||
"mdast-util-mdx-jsx": "^3.1.3",
|
||||
"node-mocks-http": "^1.16.1",
|
||||
|
@ -209,8 +209,8 @@
|
|||
"rehype-slug": "^6.0.0",
|
||||
"rehype-toc": "^3.0.2",
|
||||
"remark-code-titles": "^0.1.2",
|
||||
"rollup": "^4.24.2",
|
||||
"sass": "^1.80.4",
|
||||
"rollup": "^4.24.4",
|
||||
"sass": "^1.80.6",
|
||||
"undici": "^6.20.1",
|
||||
"unified": "^11.0.5",
|
||||
"vitest": "^2.1.1"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type { WithRequired } from '../type-utils.js';
|
||||
import type { ImageLayout } from '../types/public/index.js';
|
||||
import type { OmitPreservingIndexSignature, Simplify, WithRequired } from '../type-utils.js';
|
||||
import type { VALID_INPUT_FORMATS, VALID_OUTPUT_FORMATS } from './consts.js';
|
||||
import type { ImageService } from './services/service.js';
|
||||
|
||||
|
@ -67,10 +67,12 @@ export type SrcSetValue = UnresolvedSrcSetValue & {
|
|||
/**
|
||||
* A yet to be resolved image transform. Used by `getImage`
|
||||
*/
|
||||
export type UnresolvedImageTransform = Omit<ImageTransform, 'src'> & {
|
||||
src: ImageMetadata | string | Promise<{ default: ImageMetadata }>;
|
||||
inferSize?: boolean;
|
||||
} & {
|
||||
export type UnresolvedImageTransform = Simplify<
|
||||
OmitPreservingIndexSignature<ImageTransform, 'src'> & {
|
||||
src: ImageMetadata | string | Promise<{ default: ImageMetadata }>;
|
||||
inferSize?: boolean;
|
||||
}
|
||||
> & {
|
||||
[isESMImport]?: never;
|
||||
};
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import { getDefaultExportOptions } from 'magicast/helpers';
|
|||
import preferredPM from 'preferred-pm';
|
||||
import prompts from 'prompts';
|
||||
import maxSatisfying from 'semver/ranges/max-satisfying.js';
|
||||
import { exec } from 'tinyexec';
|
||||
import yoctoSpinner from 'yocto-spinner';
|
||||
import {
|
||||
loadTSConfig,
|
||||
|
@ -30,6 +29,7 @@ import { appendForwardSlash } from '../../core/path.js';
|
|||
import { apply as applyPolyfill } from '../../core/polyfill.js';
|
||||
import { ensureProcessNodeEnv, parseNpmName } from '../../core/util.js';
|
||||
import { eventCliSession, telemetry } from '../../events/index.js';
|
||||
import { exec } from '../exec.js';
|
||||
import { type Flags, createLoggerFromFlags, flagsToAstroInlineConfig } from '../flags.js';
|
||||
import { fetchPackageJson, fetchPackageVersions } from '../install-package.js';
|
||||
|
||||
|
@ -344,7 +344,11 @@ export async function add(names: string[], { flags }: AddOptions) {
|
|||
logger.info('SKIP_FORMAT', msg.success(`Configuration up-to-date.`));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// NOTE: failure shouldn't happen in practice because `updateAstroConfig` doesn't return that.
|
||||
// Pipe this to the same handling as `UpdateResult.updated` for now.
|
||||
case UpdateResult.failure:
|
||||
case UpdateResult.updated:
|
||||
case undefined: {
|
||||
const list = integrations.map((integration) => ` - ${integration.packageName}`).join('\n');
|
||||
logger.info(
|
||||
'SKIP_FORMAT',
|
||||
|
@ -375,7 +379,7 @@ export async function add(names: string[], { flags }: AddOptions) {
|
|||
`Unknown error parsing tsconfig.json or jsconfig.json. Could not update TypeScript settings.`,
|
||||
);
|
||||
}
|
||||
default:
|
||||
case UpdateResult.updated:
|
||||
logger.info('SKIP_FORMAT', msg.success(`Successfully updated TypeScript settings`));
|
||||
}
|
||||
}
|
||||
|
@ -390,13 +394,16 @@ function isAdapter(
|
|||
// Some examples:
|
||||
// - @astrojs/image => image
|
||||
// - @astrojs/markdown-component => markdownComponent
|
||||
// - @astrojs/image@beta => image
|
||||
// - astro-cast => cast
|
||||
// - astro-cast@next => cast
|
||||
// - markdown-astro => markdown
|
||||
// - some-package => somePackage
|
||||
// - example.com => exampleCom
|
||||
// - under_score => underScore
|
||||
// - 123numeric => numeric
|
||||
// - @npm/thingy => npmThingy
|
||||
// - @npm/thingy@1.2.3 => npmThingy
|
||||
// - @jane/foo.js => janeFoo
|
||||
// - @tokencss/astro => tokencss
|
||||
const toIdent = (name: string) => {
|
||||
|
@ -409,7 +416,9 @@ const toIdent = (name: string) => {
|
|||
// convert to camel case
|
||||
.replace(/[.\-_/]+([a-zA-Z])/g, (_, w) => w.toUpperCase())
|
||||
// drop invalid first characters
|
||||
.replace(/^[^a-zA-Z$_]+/, '');
|
||||
.replace(/^[^a-zA-Z$_]+/, '')
|
||||
// drop version or tag
|
||||
.replace(/@.*$/, '');
|
||||
return `${ident[0].toLowerCase()}${ident.slice(1)}`;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { type Result, exec } from 'tinyexec';
|
||||
import type { Result } from 'tinyexec';
|
||||
import { exec } from '../exec.js';
|
||||
|
||||
/**
|
||||
* Credit: Azhar22
|
||||
|
@ -8,6 +9,7 @@ const getPlatformSpecificCommand = (): [string] | [string, string[]] => {
|
|||
const isGitPod = Boolean(process.env.GITPOD_REPO_ROOT);
|
||||
const platform = isGitPod ? 'gitpod' : process.platform;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
||||
switch (platform) {
|
||||
case 'android':
|
||||
case 'linux':
|
||||
|
|
26
packages/astro/src/cli/exec.ts
Normal file
26
packages/astro/src/cli/exec.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { NonZeroExitError, type Options, x } from 'tinyexec';
|
||||
|
||||
/**
|
||||
* Improve tinyexec error logging and set `throwOnError` to `true` by default
|
||||
*/
|
||||
export function exec(command: string, args?: string[], options?: Partial<Options>) {
|
||||
return x(command, args, {
|
||||
throwOnError: true,
|
||||
...options,
|
||||
}).then(
|
||||
(o) => o,
|
||||
(e) => {
|
||||
if (e instanceof NonZeroExitError) {
|
||||
const fullCommand = args?.length
|
||||
? `${command} ${args.map((a) => (a.includes(' ') ? `"${a}"` : a)).join(' ')}`
|
||||
: command;
|
||||
const message = `The command \`${fullCommand}\` exited with code ${e.exitCode}`;
|
||||
const newError = new Error(message, e.cause ? { cause: e.cause } : undefined);
|
||||
(newError as any).stderr = e.output?.stderr;
|
||||
(newError as any).stdout = e.output?.stdout;
|
||||
throw newError;
|
||||
}
|
||||
throw e;
|
||||
},
|
||||
);
|
||||
}
|
|
@ -133,8 +133,8 @@ async function runCommand(cmd: string, flags: yargs.Arguments) {
|
|||
}
|
||||
case 'sync': {
|
||||
const { sync } = await import('./sync/index.js');
|
||||
const exitCode = await sync({ flags });
|
||||
return process.exit(exitCode);
|
||||
await sync({ flags });
|
||||
return;
|
||||
}
|
||||
case 'preferences': {
|
||||
const { preferences } = await import('./preferences/index.js');
|
||||
|
|
|
@ -4,10 +4,10 @@ import ci from 'ci-info';
|
|||
import { bold, cyan, dim, magenta } from 'kleur/colors';
|
||||
import preferredPM from 'preferred-pm';
|
||||
import prompts from 'prompts';
|
||||
import { exec } from 'tinyexec';
|
||||
import whichPm from 'which-pm';
|
||||
import yoctoSpinner from 'yocto-spinner';
|
||||
import type { Logger } from '../core/logger/core.js';
|
||||
import { exec } from './exec.js';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
|
|
|
@ -22,10 +22,5 @@ export async function sync({ flags }: SyncOptions) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
await _sync(flagsToAstroInlineConfig(flags), { telemetry: true });
|
||||
return 0;
|
||||
} catch (_) {
|
||||
return 1;
|
||||
}
|
||||
await _sync(flagsToAstroInlineConfig(flags), { telemetry: true });
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import type { UserConfig as ViteUserConfig, UserConfigFn as ViteUserConfigFn } from 'vite';
|
||||
import { Logger } from '../core/logger/core.js';
|
||||
import { createRouteManifest } from '../core/routing/index.js';
|
||||
import type { AstroInlineConfig, AstroUserConfig, Locales } from '../types/public/config.js';
|
||||
import { createDevelopmentManifest } from '../vite-plugin-astro-server/plugin.js';
|
||||
|
@ -30,7 +29,7 @@ export function getViteConfig(
|
|||
const [
|
||||
fs,
|
||||
{ mergeConfig },
|
||||
{ nodeLogDestination },
|
||||
{ createNodeLogger },
|
||||
{ resolveConfig, createSettings },
|
||||
{ createVite },
|
||||
{ runHookConfigSetup, runHookConfigDone },
|
||||
|
@ -38,16 +37,13 @@ export function getViteConfig(
|
|||
] = await Promise.all([
|
||||
import('node:fs'),
|
||||
import('vite'),
|
||||
import('../core/logger/node.js'),
|
||||
import('../core/config/logging.js'),
|
||||
import('../core/config/index.js'),
|
||||
import('../core/create-vite.js'),
|
||||
import('../integrations/hooks.js'),
|
||||
import('./vite-plugin-content-listen.js'),
|
||||
]);
|
||||
const logger = new Logger({
|
||||
dest: nodeLogDestination,
|
||||
level: 'info',
|
||||
});
|
||||
const logger = createNodeLogger(inlineAstroConfig);
|
||||
const { astroConfig: config } = await resolveConfig(inlineAstroConfig, cmd);
|
||||
let settings = await createSettings(config, userViteConfig.root);
|
||||
settings = await runHookConfigSetup({ settings, command: cmd, logger });
|
||||
|
|
|
@ -122,14 +122,10 @@ export class App {
|
|||
throw new Error(`Unable to resolve [${specifier}]`);
|
||||
}
|
||||
const bundlePath = this.#manifest.entryModules[specifier];
|
||||
switch (true) {
|
||||
case bundlePath.startsWith('data:'):
|
||||
case bundlePath.length === 0: {
|
||||
return bundlePath;
|
||||
}
|
||||
default: {
|
||||
return createAssetLink(bundlePath, this.#manifest.base, this.#manifest.assetsPrefix);
|
||||
}
|
||||
if (bundlePath.startsWith('data:') || bundlePath.length === 0) {
|
||||
return bundlePath;
|
||||
} else {
|
||||
return createAssetLink(bundlePath, this.#manifest.base, this.#manifest.assetsPrefix);
|
||||
}
|
||||
},
|
||||
serverLike: true,
|
||||
|
|
|
@ -153,8 +153,10 @@ export class NodeApp extends App {
|
|||
}
|
||||
destination.end();
|
||||
// the error will be logged by the "on end" callback above
|
||||
} catch {
|
||||
destination.end('Internal server error');
|
||||
} catch (err) {
|
||||
destination.write('Internal server error', () => {
|
||||
err instanceof Error ? destination.destroy(err) : destination.destroy();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -370,6 +370,7 @@ function getUrlForPath(
|
|||
ending = trailingSlash === 'never' ? '' : '/';
|
||||
break;
|
||||
}
|
||||
case 'file':
|
||||
default: {
|
||||
ending = '.html';
|
||||
break;
|
||||
|
|
|
@ -122,24 +122,17 @@ export async function staticBuild(
|
|||
contentFileNames?: string[],
|
||||
) {
|
||||
const { settings } = opts;
|
||||
switch (settings.buildOutput) {
|
||||
case 'static': {
|
||||
settings.timer.start('Static generate');
|
||||
await generatePages(opts, internals);
|
||||
await cleanServerOutput(opts, ssrOutputChunkNames, contentFileNames, internals);
|
||||
settings.timer.end('Static generate');
|
||||
return;
|
||||
}
|
||||
case 'server': {
|
||||
settings.timer.start('Server generate');
|
||||
await generatePages(opts, internals);
|
||||
await cleanStaticOutput(opts, internals);
|
||||
await ssrMoveAssets(opts);
|
||||
settings.timer.end('Server generate');
|
||||
return;
|
||||
}
|
||||
default: // `settings.buildOutput` will always be one of the above at this point, but TS doesn't know that
|
||||
return;
|
||||
if (settings.buildOutput === 'static') {
|
||||
settings.timer.start('Static generate');
|
||||
await generatePages(opts, internals);
|
||||
await cleanServerOutput(opts, ssrOutputChunkNames, contentFileNames, internals);
|
||||
settings.timer.end('Static generate');
|
||||
} else if (settings.buildOutput === 'server') {
|
||||
settings.timer.start('Server generate');
|
||||
await generatePages(opts, internals);
|
||||
await cleanStaticOutput(opts, internals);
|
||||
await ssrMoveAssets(opts);
|
||||
settings.timer.end('Server generate');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -176,8 +176,11 @@ export async function createContainerWithAutomaticRestart({
|
|||
|
||||
// Restart the Astro dev server instead of Vite's when the API is called by plugins.
|
||||
// Ignore the `forceOptimize` parameter for now.
|
||||
restart.container.viteServer.restart = () =>
|
||||
handleServerRestart('', restart.container.viteServer);
|
||||
restart.container.viteServer.restart = async () => {
|
||||
if (!restart.container.restartInFlight) {
|
||||
await handleServerRestart('', restart.container.viteServer);
|
||||
}
|
||||
};
|
||||
|
||||
// Set up shortcuts
|
||||
|
||||
|
|
|
@ -1429,7 +1429,7 @@ export const GenerateContentTypesError = {
|
|||
title: 'Failed to generate content types.',
|
||||
message: (errorMessage: string) =>
|
||||
`\`astro sync\` command failed to generate content collection types: ${errorMessage}`,
|
||||
hint: 'Check your `src/content/config.*` file for typos.',
|
||||
hint: 'This error is often caused by a syntax error inside your content, or your content configuration file. Check your `src/content/config.*` file for typos.',
|
||||
} satisfies ErrorData;
|
||||
/**
|
||||
* @docs
|
||||
|
|
|
@ -298,6 +298,11 @@ export function formatErrorMessage(err: ErrorWithMetadata, showFullStacktrace: b
|
|||
output.push(` ${cyan(underline(docsLink))}`);
|
||||
}
|
||||
|
||||
if (showFullStacktrace && err.loc) {
|
||||
output.push(` ${bold('Location:')}`);
|
||||
output.push(` ${underline(`${err.loc.file}:${err.loc.line ?? 0}:${err.loc.column ?? 0}`)}`);
|
||||
}
|
||||
|
||||
if (err.stack) {
|
||||
output.push(` ${bold('Stack trace:')}`);
|
||||
output.push(dim(formatErrorStackTrace(err, showFullStacktrace)));
|
||||
|
|
|
@ -26,6 +26,7 @@ import {
|
|||
AstroError,
|
||||
AstroErrorData,
|
||||
AstroUserError,
|
||||
type ErrorWithMetadata,
|
||||
createSafeError,
|
||||
isAstroError,
|
||||
} from '../errors/index.js';
|
||||
|
@ -68,17 +69,7 @@ export default async function sync(
|
|||
});
|
||||
const manifest = await createRouteManifest({ settings, fsMod: fs }, logger);
|
||||
|
||||
// Run `astro:config:done`
|
||||
// Actions will throw if there is misconfiguration, so catch here.
|
||||
try {
|
||||
await runHookConfigDone({ settings, logger });
|
||||
} catch (err) {
|
||||
if (err instanceof Error) {
|
||||
const errorMessage = err.toString();
|
||||
logger.error('sync', errorMessage);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
await runHookConfigDone({ settings, logger });
|
||||
|
||||
return await syncInternal({
|
||||
settings,
|
||||
|
@ -127,51 +118,41 @@ export async function syncInternal({
|
|||
|
||||
const timerStart = performance.now();
|
||||
|
||||
try {
|
||||
if (!skip?.content) {
|
||||
await syncContentCollections(settings, { mode, fs, logger, manifest });
|
||||
settings.timer.start('Sync content layer');
|
||||
let store: MutableDataStore | undefined;
|
||||
try {
|
||||
const dataStoreFile = getDataStoreFile(settings);
|
||||
if (existsSync(dataStoreFile)) {
|
||||
store = await MutableDataStore.fromFile(dataStoreFile);
|
||||
}
|
||||
} catch (err: any) {
|
||||
logger.error('content', err.message);
|
||||
if (!skip?.content) {
|
||||
await syncContentCollections(settings, { mode, fs, logger, manifest });
|
||||
settings.timer.start('Sync content layer');
|
||||
let store: MutableDataStore | undefined;
|
||||
try {
|
||||
const dataStoreFile = getDataStoreFile(settings);
|
||||
if (existsSync(dataStoreFile)) {
|
||||
store = await MutableDataStore.fromFile(dataStoreFile);
|
||||
}
|
||||
if (!store) {
|
||||
store = new MutableDataStore();
|
||||
}
|
||||
const contentLayer = globalContentLayer.init({
|
||||
settings,
|
||||
logger,
|
||||
store,
|
||||
});
|
||||
await contentLayer.sync();
|
||||
settings.timer.end('Sync content layer');
|
||||
} else if (fs.existsSync(fileURLToPath(getContentPaths(settings.config, fs).contentDir))) {
|
||||
// Content is synced after writeFiles. That means references are not created
|
||||
// To work around it, we create a stub so the reference is created and content
|
||||
// sync will override the empty file
|
||||
settings.injectedTypes.push({
|
||||
filename: CONTENT_TYPES_FILE,
|
||||
content: '',
|
||||
});
|
||||
} catch (err: any) {
|
||||
logger.error('content', err.message);
|
||||
}
|
||||
syncAstroEnv(settings);
|
||||
|
||||
writeInjectedTypes(settings, fs);
|
||||
logger.info('types', `Generated ${dim(getTimeStat(timerStart, performance.now()))}`);
|
||||
} catch (err) {
|
||||
const error = createSafeError(err);
|
||||
logger.error(
|
||||
'types',
|
||||
formatErrorMessage(collectErrorMetadata(error), logger.level() === 'debug') + '\n',
|
||||
);
|
||||
// Will return exit code 1 in CLI
|
||||
throw error;
|
||||
if (!store) {
|
||||
store = new MutableDataStore();
|
||||
}
|
||||
const contentLayer = globalContentLayer.init({
|
||||
settings,
|
||||
logger,
|
||||
store,
|
||||
});
|
||||
await contentLayer.sync();
|
||||
settings.timer.end('Sync content layer');
|
||||
} else if (fs.existsSync(fileURLToPath(getContentPaths(settings.config, fs).contentDir))) {
|
||||
// Content is synced after writeFiles. That means references are not created
|
||||
// To work around it, we create a stub so the reference is created and content
|
||||
// sync will override the empty file
|
||||
settings.injectedTypes.push({
|
||||
filename: CONTENT_TYPES_FILE,
|
||||
content: '',
|
||||
});
|
||||
}
|
||||
syncAstroEnv(settings);
|
||||
|
||||
writeInjectedTypes(settings, fs);
|
||||
logger.info('types', `Generated ${dim(getTimeStat(timerStart, performance.now()))}`);
|
||||
}
|
||||
|
||||
function getTsReference(type: 'path' | 'types', value: string) {
|
||||
|
@ -270,7 +251,7 @@ async function syncContentCollections(
|
|||
}
|
||||
}
|
||||
} catch (e) {
|
||||
const safeError = createSafeError(e);
|
||||
const safeError = createSafeError(e) as ErrorWithMetadata;
|
||||
if (isAstroError(e)) {
|
||||
throw e;
|
||||
}
|
||||
|
@ -280,6 +261,7 @@ async function syncContentCollections(
|
|||
...AstroErrorData.GenerateContentTypesError,
|
||||
hint,
|
||||
message: AstroErrorData.GenerateContentTypesError.message(safeError.message),
|
||||
location: safeError.loc,
|
||||
},
|
||||
{ cause: e },
|
||||
);
|
||||
|
|
1
packages/astro/src/env/runtime-constants.ts
vendored
1
packages/astro/src/env/runtime-constants.ts
vendored
|
@ -1 +0,0 @@
|
|||
export const ENV_SYMBOL = Symbol.for('astro:env/dev');
|
6
packages/astro/src/env/runtime.ts
vendored
6
packages/astro/src/env/runtime.ts
vendored
|
@ -1,16 +1,12 @@
|
|||
import { AstroError, AstroErrorData } from '../core/errors/index.js';
|
||||
import { invalidVariablesToError } from './errors.js';
|
||||
import { ENV_SYMBOL } from './runtime-constants.js';
|
||||
import type { ValidationResultInvalid } from './validators.js';
|
||||
export { validateEnvVariable, getEnvFieldType } from './validators.js';
|
||||
|
||||
export type GetEnv = (key: string) => string | undefined;
|
||||
type OnSetGetEnv = (reset: boolean) => void;
|
||||
|
||||
let _getEnv: GetEnv = (key) => {
|
||||
const env = (globalThis as any)[ENV_SYMBOL] ?? {};
|
||||
return env[key];
|
||||
};
|
||||
let _getEnv: GetEnv = (key) => process.env[key];
|
||||
|
||||
export function setGetEnv(fn: GetEnv, reset = false) {
|
||||
_getEnv = fn;
|
||||
|
|
7
packages/astro/src/env/vite-plugin-env.ts
vendored
7
packages/astro/src/env/vite-plugin-env.ts
vendored
|
@ -9,7 +9,6 @@ import {
|
|||
VIRTUAL_MODULES_IDS_VALUES,
|
||||
} from './constants.js';
|
||||
import { type InvalidVariable, invalidVariablesToError } from './errors.js';
|
||||
import { ENV_SYMBOL } from './runtime-constants.js';
|
||||
import type { EnvSchema } from './schema.js';
|
||||
import { getEnvFieldType, validateEnvVariable } from './validators.js';
|
||||
|
||||
|
@ -29,7 +28,11 @@ export function astroEnv({ settings, mode, sync }: AstroEnvPluginParams): Plugin
|
|||
enforce: 'pre',
|
||||
buildStart() {
|
||||
const loadedEnv = loadEnv(mode, fileURLToPath(settings.config.root), '');
|
||||
(globalThis as any)[ENV_SYMBOL] = loadedEnv;
|
||||
for (const [key, value] of Object.entries(loadedEnv)) {
|
||||
if (value !== undefined) {
|
||||
process.env[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
const validatedVariables = validatePublicVariables({
|
||||
schema,
|
||||
|
|
|
@ -65,6 +65,7 @@ export function isValidKey(key: string): key is PreferenceKey {
|
|||
}
|
||||
export function coerce(key: string, value: unknown) {
|
||||
const type = typeof dget(DEFAULT_PREFERENCES, key);
|
||||
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
||||
switch (type) {
|
||||
case 'string':
|
||||
return value;
|
||||
|
@ -142,6 +143,7 @@ function getGlobalPreferenceDir() {
|
|||
const { XDG_CONFIG_HOME = path.join(homedir, '.config') } = process.env;
|
||||
return path.join(XDG_CONFIG_HOME, name);
|
||||
};
|
||||
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
||||
switch (process.platform) {
|
||||
case 'darwin':
|
||||
return macos();
|
||||
|
|
|
@ -45,15 +45,25 @@ export default function astroPrefetch({ settings }: { settings: AstroSettings })
|
|||
},
|
||||
transform(code, id) {
|
||||
// NOTE: Handle replacing the specifiers even if prefetch is disabled so View Transitions
|
||||
// can import the internal module as not hit runtime issues.
|
||||
// can import the internal module and not hit runtime issues.
|
||||
if (id.includes(prefetchInternalModuleFsSubpath)) {
|
||||
return code
|
||||
.replace('__PREFETCH_PREFETCH_ALL__', JSON.stringify(prefetch?.prefetchAll))
|
||||
.replace('__PREFETCH_DEFAULT_STRATEGY__', JSON.stringify(prefetch?.defaultStrategy))
|
||||
// We perform a simple replacement with padding so that the code offset is not changed and
|
||||
// we don't have to generate a sourcemap. This has the assumption that the replaced string
|
||||
// will always be shorter than the search string to work.
|
||||
code = code
|
||||
.replace(
|
||||
'__EXPERIMENTAL_CLIENT_PRERENDER__',
|
||||
JSON.stringify(settings.config.experimental.clientPrerender),
|
||||
'__PREFETCH_PREFETCH_ALL__', // length: 25
|
||||
`${JSON.stringify(prefetch?.prefetchAll)}`.padEnd(25),
|
||||
)
|
||||
.replace(
|
||||
'__PREFETCH_DEFAULT_STRATEGY__', // length: 29
|
||||
`${JSON.stringify(prefetch?.defaultStrategy)}`.padEnd(29),
|
||||
)
|
||||
.replace(
|
||||
'__EXPERIMENTAL_CLIENT_PRERENDER__', // length: 33
|
||||
`${JSON.stringify(settings.config.experimental.clientPrerender)}`.padEnd(33),
|
||||
);
|
||||
return { code, map: null };
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -204,6 +204,8 @@ export default {
|
|||
label.append(astroSelect);
|
||||
break;
|
||||
}
|
||||
case 'number':
|
||||
case 'text':
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ function guessRenderers(componentUrl?: string): string[] {
|
|||
case 'jsx':
|
||||
case 'tsx':
|
||||
return ['@astrojs/react', '@astrojs/preact', '@astrojs/solid-js', '@astrojs/vue (jsx)'];
|
||||
case undefined:
|
||||
default:
|
||||
return [
|
||||
'@astrojs/react',
|
||||
|
|
|
@ -7,7 +7,7 @@ import { HTMLString, markHTMLString } from '../escape.js';
|
|||
export const voidElementNames =
|
||||
/^(area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/i;
|
||||
const htmlBooleanAttributes =
|
||||
/^(?:allowfullscreen|async|autofocus|autoplay|controls|default|defer|disabled|disablepictureinpicture|disableremoteplayback|formnovalidate|hidden|loop|nomodule|novalidate|open|playsinline|readonly|required|reversed|scoped|seamless|selected|itemscope)$/i;
|
||||
/^(?:allowfullscreen|async|autofocus|autoplay|checked|controls|default|defer|disabled|disablepictureinpicture|disableremoteplayback|formnovalidate|hidden|loop|nomodule|novalidate|open|playsinline|readonly|required|reversed|scoped|seamless|selected|itemscope)$/i;
|
||||
|
||||
const AMPERSAND_REGEX = /&/g;
|
||||
const DOUBLE_QUOTE_REGEX = /"/g;
|
||||
|
|
|
@ -16,6 +16,11 @@ export type OmitIndexSignature<ObjectType> = {
|
|||
: KeyType]: ObjectType[KeyType];
|
||||
};
|
||||
|
||||
// This is an alternative `Omit<T, K>` implementation that _doesn't_ remove the index signature of an object.
|
||||
export type OmitPreservingIndexSignature<T, K extends PropertyKey> = {
|
||||
[P in keyof T as Exclude<P, K>]: T[P];
|
||||
};
|
||||
|
||||
// Transform a string into its kebab case equivalent (camelCase -> kebab-case). Useful for CSS-in-JS to CSS.
|
||||
export type Kebab<T extends string, A extends string = ''> = T extends `${infer F}${infer R}`
|
||||
? Kebab<R, `${A}${F extends Lowercase<F> ? '' : '-'}${Lowercase<F>}`>
|
||||
|
|
|
@ -189,6 +189,9 @@ export default function astro({ settings, logger }: AstroPluginOptions): vite.Pl
|
|||
|
||||
return result;
|
||||
}
|
||||
case 'custom':
|
||||
case 'template':
|
||||
case undefined:
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,6 @@
|
|||
"vue": "^3.5.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"postcss-preset-env": "^10.0.8"
|
||||
"postcss-preset-env": "^10.0.9"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"private": true,
|
||||
"dependencies": {
|
||||
"@astrojs/solid-js": "workspace:*",
|
||||
"@solidjs/router": "^0.14.10",
|
||||
"@solidjs/router": "^0.15.1",
|
||||
"@test/solid-jsx-component": "file:./deps/solid-jsx-component",
|
||||
"astro": "workspace:*",
|
||||
"solid-js": "^1.9.3"
|
||||
|
|
|
@ -1,5 +1,16 @@
|
|||
# create-astro
|
||||
|
||||
## 4.11.0-beta.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#12083](https://github.com/withastro/astro/pull/12083) [`9263e96`](https://github.com/withastro/astro/commit/9263e965932b9a6a116801c063c6b7105c39643e) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Reworks the experience of creating a new Astro project using the `create astro` CLI command.
|
||||
|
||||
- Updates the list of templates to include Starlight and combines the "minimal" and "basics" templates into a new, refreshed "Basics" template to serve as the single, minimal Astro project starter.
|
||||
- Removes the TypeScript question. Astro is TypeScript-only, so this question was often misleading. The "Strict" preset is now the default, but it can still be changed manually in `tsconfig.json`.
|
||||
- `astro check` is no longer automatically added to the build script.
|
||||
- Added a new `--add` flag to install additional integrations after creating a project. For example, `pnpm create astro --add react` will create a new Astro project and install the React integration.
|
||||
|
||||
## 4.10.0
|
||||
|
||||
### Minor Changes
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "create-astro",
|
||||
"version": "4.10.0",
|
||||
"version": "4.11.0-beta.0",
|
||||
"type": "module",
|
||||
"author": "withastro",
|
||||
"license": "MIT",
|
||||
|
|
|
@ -27,7 +27,10 @@ export async function dependencies(
|
|||
ctx.add = ctx.add?.reduce<string[]>((acc, item) => acc.concat(item.split(',')), []);
|
||||
|
||||
if (ctx.dryRun) {
|
||||
await info('--dry-run', `Skipping dependency installation${ ctx.add ? ` and adding ${ctx.add.join(', ')}` : '' }`);
|
||||
await info(
|
||||
'--dry-run',
|
||||
`Skipping dependency installation${ctx.add ? ` and adding ${ctx.add.join(', ')}` : ''}`,
|
||||
);
|
||||
} else if (deps) {
|
||||
ctx.tasks.push({
|
||||
pending: 'Dependencies',
|
||||
|
|
|
@ -57,6 +57,7 @@ export default function getSeasonalHouston({ fancy }: { fancy?: boolean }): Seas
|
|||
`Your creativity is the gift that keeps on giving!`,
|
||||
],
|
||||
};
|
||||
case undefined:
|
||||
default:
|
||||
return {
|
||||
hats: fancy ? ['🎩', '🎩', '🎩', '🎩', '🎓', '👑', '🧢', '🍦'] : undefined,
|
||||
|
|
|
@ -30,7 +30,9 @@ describe('integrations', () => {
|
|||
|
||||
await dependencies(context);
|
||||
|
||||
assert.ok(fixture.hasMessage('--dry-run Skipping dependency installation and adding node, react'));
|
||||
assert.ok(
|
||||
fixture.hasMessage('--dry-run Skipping dependency installation and adding node, react'),
|
||||
);
|
||||
});
|
||||
|
||||
it('--add node,react', async () => {
|
||||
|
@ -39,12 +41,14 @@ describe('integrations', () => {
|
|||
yes: true,
|
||||
packageManager: 'npm',
|
||||
dryRun: true,
|
||||
add: ['node,react']
|
||||
add: ['node,react'],
|
||||
};
|
||||
|
||||
await dependencies(context);
|
||||
|
||||
assert.ok(fixture.hasMessage('--dry-run Skipping dependency installation and adding node, react'));
|
||||
assert.ok(
|
||||
fixture.hasMessage('--dry-run Skipping dependency installation and adding node, react'),
|
||||
);
|
||||
});
|
||||
|
||||
it('-y', async () => {
|
||||
|
|
|
@ -91,6 +91,6 @@
|
|||
"astro-scripts": "workspace:*",
|
||||
"cheerio": "1.0.0",
|
||||
"typescript": "^5.6.3",
|
||||
"vite": "6.0.0-beta.2"
|
||||
"vite": "6.0.0-beta.6"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
"@playwright/test": "1.48.2",
|
||||
"astro": "workspace:*",
|
||||
"astro-scripts": "workspace:*",
|
||||
"vite": "6.0.0-beta.2"
|
||||
"vite": "6.0.0-beta.6"
|
||||
},
|
||||
"publishConfig": {
|
||||
"provenance": true
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
"astro-scripts": "workspace:*",
|
||||
"devalue": "^5.1.1",
|
||||
"linkedom": "^0.18.5",
|
||||
"vite": "6.0.0-beta.2"
|
||||
"vite": "6.0.0-beta.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.1 || ^20.3.0 || >=21.0.0"
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
"remark-toc": "^9.0.0",
|
||||
"shiki": "^1.22.2",
|
||||
"unified": "^11.0.5",
|
||||
"vite": "6.0.0-beta.2"
|
||||
"vite": "6.0.0-beta.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.1 || ^20.3.0 || >=21.0.0"
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
"cheerio": "1.0.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"vite": "6.0.0-beta.2"
|
||||
"vite": "6.0.0-beta.6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^17.0.50 || ^18.0.21",
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
"astro": "workspace:*",
|
||||
"astro-scripts": "workspace:*",
|
||||
"solid-js": "^1.9.3",
|
||||
"vite": "6.0.0-beta.2"
|
||||
"vite": "6.0.0-beta.6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"solid-devtools": "^0.30.1",
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
# @astrojs/svelte
|
||||
|
||||
## 6.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`b21a075`](https://github.com/withastro/astro/commit/b21a07500284a3621be4d509f5aa67c0a8fcbf07) Thanks [@bluwy](https://github.com/bluwy)! - New release to include changes from 5.7.3
|
||||
|
||||
## 6.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
@ -19,6 +25,12 @@
|
|||
- Updated dependencies [[`b6fbdaa`](https://github.com/withastro/astro/commit/b6fbdaa94a9ecec706a99e1938fbf5cd028c72e0), [`89bab1e`](https://github.com/withastro/astro/commit/89bab1e70786123fbe933a9d7a1b80c9334dcc5f), [`d74617c`](https://github.com/withastro/astro/commit/d74617cbd3278feba05909ec83db2d73d57a153e), [`e90f559`](https://github.com/withastro/astro/commit/e90f5593d23043579611452a84b9e18ad2407ef9), [`2df49a6`](https://github.com/withastro/astro/commit/2df49a6fb4f6d92fe45f7429430abe63defeacd6), [`8a53517`](https://github.com/withastro/astro/commit/8a5351737d6a14fc55f1dafad8f3b04079e81af6)]:
|
||||
- astro@5.0.0-alpha.0
|
||||
|
||||
## 5.7.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#12390](https://github.com/withastro/astro/pull/12390) [`6fd3d59`](https://github.com/withastro/astro/commit/6fd3d5960f5ab16591bfdb94d1f9b9a9b72006cf) Thanks [@bluwy](https://github.com/bluwy)! - Adds support for Svelte 5's new `@render` syntax while maintaining backward compatibility with traditional slots.
|
||||
|
||||
## 5.7.2
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
@ -8,7 +8,10 @@ export default (element) => {
|
|||
|
||||
let children = undefined;
|
||||
let $$slots = undefined;
|
||||
let renderFns = {};
|
||||
|
||||
for (const [key, value] of Object.entries(slotted)) {
|
||||
// Legacy slot support
|
||||
$$slots ??= {};
|
||||
if (key === 'default') {
|
||||
$$slots.default = true;
|
||||
|
@ -20,6 +23,16 @@ export default (element) => {
|
|||
render: () => `<astro-slot name="${key}">${value}</astro-slot>`,
|
||||
}));
|
||||
}
|
||||
// @render support for Svelte ^5.0
|
||||
if (key === 'default') {
|
||||
renderFns.children = createRawSnippet(() => ({
|
||||
render: () => `<astro-slot>${value}</astro-slot>`,
|
||||
}));
|
||||
} else {
|
||||
renderFns[key] = createRawSnippet(() => ({
|
||||
render: () => `<astro-slot name="${key}">${value}</astro-slot>`,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
const bootstrap = client !== 'only' ? hydrate : mount;
|
||||
|
@ -28,6 +41,7 @@ export default (element) => {
|
|||
...props,
|
||||
children,
|
||||
$$slots,
|
||||
...renderFns,
|
||||
});
|
||||
} else {
|
||||
const component = bootstrap(Component, {
|
||||
|
@ -36,6 +50,7 @@ export default (element) => {
|
|||
...props,
|
||||
children,
|
||||
$$slots,
|
||||
...renderFns,
|
||||
},
|
||||
});
|
||||
existingApplications.set(element, component);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@astrojs/svelte",
|
||||
"version": "6.0.0-beta.1",
|
||||
"version": "6.0.0-beta.2",
|
||||
"description": "Use Svelte components within Astro",
|
||||
"type": "module",
|
||||
"types": "./dist/index.d.ts",
|
||||
|
@ -57,7 +57,7 @@
|
|||
"astro": "workspace:*",
|
||||
"astro-scripts": "workspace:*",
|
||||
"svelte": "^4.2.19",
|
||||
"vite": "6.0.0-beta.2"
|
||||
"vite": "6.0.0-beta.6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"astro": "^5.0.0-alpha.0",
|
||||
|
|
|
@ -17,7 +17,10 @@ async function renderToStaticMarkup(Component, props, slotted, metadata) {
|
|||
|
||||
let children = undefined;
|
||||
let $$slots = undefined;
|
||||
const renderProps = {};
|
||||
|
||||
for (const [key, value] of Object.entries(slotted)) {
|
||||
// Legacy slot support
|
||||
$$slots ??= {};
|
||||
if (key === 'default') {
|
||||
$$slots.default = true;
|
||||
|
@ -29,6 +32,11 @@ async function renderToStaticMarkup(Component, props, slotted, metadata) {
|
|||
render: () => `<${tagName} name="${key}">${value}</${tagName}>`,
|
||||
}));
|
||||
}
|
||||
// @render support for Svelte ^5.0
|
||||
const slotName = key === 'default' ? 'children' : key;
|
||||
renderProps[slotName] = createRawSnippet(() => ({
|
||||
render: () => `<${tagName}${key !== 'default' ? ` name="${key}"` : ''}>${value}</${tagName}>`,
|
||||
}));
|
||||
}
|
||||
|
||||
const result = render(Component, {
|
||||
|
@ -36,6 +44,7 @@ async function renderToStaticMarkup(Component, props, slotted, metadata) {
|
|||
...props,
|
||||
children,
|
||||
$$slots,
|
||||
...renderProps,
|
||||
},
|
||||
});
|
||||
return { html: result.body };
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
"astro": "workspace:*",
|
||||
"astro-scripts": "workspace:*",
|
||||
"tailwindcss": "^3.4.14",
|
||||
"vite": "6.0.0-beta.2"
|
||||
"vite": "6.0.0-beta.6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"astro": "^3.0.0 || ^4.0.0 || ^5.0.0-beta.0",
|
||||
|
|
|
@ -48,14 +48,14 @@
|
|||
"@vitejs/plugin-vue": "^5.1.4",
|
||||
"@vitejs/plugin-vue-jsx": "^4.0.1",
|
||||
"@vue/compiler-sfc": "^3.5.12",
|
||||
"vite-plugin-vue-devtools": "^7.5.4"
|
||||
"vite-plugin-vue-devtools": "^7.6.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "workspace:*",
|
||||
"astro-scripts": "workspace:*",
|
||||
"cheerio": "1.0.0",
|
||||
"linkedom": "^0.18.5",
|
||||
"vite": "6.0.0-beta.2",
|
||||
"vite": "6.0.0-beta.6",
|
||||
"vue": "^3.5.12"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
|
|
@ -42,6 +42,6 @@
|
|||
"astro": "workspace:*",
|
||||
"astro-scripts": "workspace:*",
|
||||
"typescript": "^5.6.3",
|
||||
"vite": "6.0.0-beta.2"
|
||||
"vite": "6.0.0-beta.6"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ function getConfigDir(name: string) {
|
|||
const { XDG_CONFIG_HOME = path.join(homedir, '.config') } = process.env;
|
||||
return path.join(XDG_CONFIG_HOME, name);
|
||||
};
|
||||
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
||||
switch (process.platform) {
|
||||
case 'darwin':
|
||||
return macos();
|
||||
|
|
1224
pnpm-lock.yaml
generated
1224
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue