Merge branch 'main' into feat/squoosh-lib

This commit is contained in:
Tony Sullivan 2022-09-12 09:34:46 -05:00
commit 6d1eecb2b1
99 changed files with 1235 additions and 489 deletions

View file

@ -0,0 +1,5 @@
---
'@astrojs/vue': patch
---
Fix Vue `script setup` with other renderers applied

View file

@ -1,5 +0,0 @@
---
'@astrojs/react': patch
---
Prevent decoder from leaking

View file

@ -1,5 +0,0 @@
---
'@astrojs/image': patch
---
Updates the integration to build all optimized images to `dist/assets` during SSG builds

View file

@ -1,6 +0,0 @@
---
'astro': patch
'@astrojs/react': patch
---
Fix framework components on Vercel Edge

View file

@ -10,6 +10,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7" "astro": "^1.2.1"
} }
} }

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7", "astro": "^1.2.1",
"@astrojs/mdx": "^0.11.1", "@astrojs/mdx": "^0.11.1",
"@astrojs/rss": "^1.0.0", "@astrojs/rss": "^1.0.0",
"@astrojs/sitemap": "^1.0.0" "@astrojs/sitemap": "^1.0.0"

View file

@ -15,9 +15,9 @@
], ],
"scripts": {}, "scripts": {},
"devDependencies": { "devDependencies": {
"astro": "^1.1.7" "astro": "^1.2.1"
}, },
"peerDependencies": { "peerDependencies": {
"astro": "^1.1.7" "astro": "^1.2.1"
} }
} }

View file

@ -47,14 +47,14 @@ Welcome! Check out [our documentation](https://docs.astro.build) or jump into ou
### CSS styling ### CSS styling
The theme's look and feel is controlled by a few key variables that you can customize yourself. You'll find them in the `public/theme.css` CSS file. The theme's look and feel is controlled by a few key variables that you can customize yourself. You'll find them in the `src/styles/theme.css` CSS file.
If you've never worked with CSS variables before, give [MDN's guide on CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) a quick read. If you've never worked with CSS variables before, give [MDN's guide on CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) a quick read.
This theme uses a "cool blue" accent color by default. To customize this for your project, change the `--theme-accent` variable to whatever color you'd like: This theme uses a "cool blue" accent color by default. To customize this for your project, change the `--theme-accent` variable to whatever color you'd like:
```diff ```diff
/* public/theme.css */ /* src/styles/theme.css */
:root { :root {
color-scheme: light; color-scheme: light;
- --theme-accent: hsla(var(--color-blue), 1); - --theme-accent: hsla(var(--color-blue), 1);

View file

@ -11,11 +11,11 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7", "astro": "^1.2.1",
"preact": "^10.7.3", "preact": "^10.7.3",
"react": "^18.1.0", "react": "^18.1.0",
"react-dom": "^18.1.0", "react-dom": "^18.1.0",
"@astrojs/react": "^1.1.0", "@astrojs/react": "^1.1.2",
"@astrojs/preact": "^1.1.0", "@astrojs/preact": "^1.1.0",
"@algolia/client-search": "^4.13.1", "@algolia/client-search": "^4.13.1",
"@docsearch/css": "^3.1.0", "@docsearch/css": "^3.1.0",

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7", "astro": "^1.2.1",
"alpinejs": "^3.10.2", "alpinejs": "^3.10.2",
"@astrojs/alpinejs": "^0.1.2", "@astrojs/alpinejs": "^0.1.2",
"@types/alpinejs": "^3.7.0" "@types/alpinejs": "^3.7.0"

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7", "astro": "^1.2.1",
"lit": "^2.2.5", "lit": "^2.2.5",
"@astrojs/lit": "^1.0.0", "@astrojs/lit": "^1.0.0",
"@webcomponents/template-shadowroot": "^0.1.0" "@webcomponents/template-shadowroot": "^0.1.0"

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7", "astro": "^1.2.1",
"preact": "^10.7.3", "preact": "^10.7.3",
"react": "^18.1.0", "react": "^18.1.0",
"react-dom": "^18.1.0", "react-dom": "^18.1.0",
@ -18,7 +18,7 @@
"svelte": "^3.48.0", "svelte": "^3.48.0",
"vue": "^3.2.37", "vue": "^3.2.37",
"@astrojs/preact": "^1.1.0", "@astrojs/preact": "^1.1.0",
"@astrojs/react": "^1.1.0", "@astrojs/react": "^1.1.2",
"@astrojs/solid-js": "^1.1.0", "@astrojs/solid-js": "^1.1.0",
"@astrojs/svelte": "^1.0.0", "@astrojs/svelte": "^1.0.0",
"@astrojs/vue": "^1.0.1" "@astrojs/vue": "^1.0.1"

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7", "astro": "^1.2.1",
"preact": "^10.7.3", "preact": "^10.7.3",
"@astrojs/preact": "^1.1.0" "@astrojs/preact": "^1.1.0"
} }

View file

@ -10,10 +10,10 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7", "astro": "^1.2.1",
"react": "^18.1.0", "react": "^18.1.0",
"react-dom": "^18.1.0", "react-dom": "^18.1.0",
"@astrojs/react": "^1.1.0", "@astrojs/react": "^1.1.2",
"@types/react": "^18.0.10", "@types/react": "^18.0.10",
"@types/react-dom": "^18.0.5" "@types/react-dom": "^18.0.5"
} }

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7", "astro": "^1.2.1",
"solid-js": "^1.4.3", "solid-js": "^1.4.3",
"@astrojs/solid-js": "^1.1.0" "@astrojs/solid-js": "^1.1.0"
} }

View file

@ -12,6 +12,6 @@
"dependencies": { "dependencies": {
"svelte": "^3.48.0", "svelte": "^3.48.0",
"@astrojs/svelte": "^1.0.0", "@astrojs/svelte": "^1.0.0",
"astro": "^1.1.7" "astro": "^1.2.1"
} }
} }

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7", "astro": "^1.2.1",
"vue": "^3.2.37", "vue": "^3.2.37",
"@astrojs/vue": "^1.0.1" "@astrojs/vue": "^1.0.1"
} }

View file

@ -10,6 +10,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7" "astro": "^1.2.1"
} }
} }

View file

@ -10,6 +10,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7" "astro": "^1.2.1"
} }
} }

View file

@ -10,6 +10,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7" "astro": "^1.2.1"
} }
} }

View file

@ -12,7 +12,7 @@
}, },
"devDependencies": {}, "devDependencies": {},
"dependencies": { "dependencies": {
"astro": "^1.1.7", "astro": "^1.2.1",
"svelte": "^3.48.0", "svelte": "^3.48.0",
"@astrojs/svelte": "^1.0.0", "@astrojs/svelte": "^1.0.0",
"@astrojs/node": "^1.0.1", "@astrojs/node": "^1.0.1",

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7", "astro": "^1.2.1",
"@astrojs/markdown-remark": "^1.1.0", "@astrojs/markdown-remark": "^1.1.0",
"hast-util-select": "5.0.1", "hast-util-select": "5.0.1",
"rehype-autolink-headings": "^6.1.1", "rehype-autolink-headings": "^6.1.1",

View file

@ -10,6 +10,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7" "astro": "^1.2.1"
} }
} }

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7", "astro": "^1.2.1",
"preact": "^10.6.5", "preact": "^10.6.5",
"@astrojs/preact": "^1.1.0", "@astrojs/preact": "^1.1.0",
"@astrojs/mdx": "^0.11.1" "@astrojs/mdx": "^0.11.1"

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7", "astro": "^1.2.1",
"preact": "^10.7.3", "preact": "^10.7.3",
"@astrojs/preact": "^1.1.0", "@astrojs/preact": "^1.1.0",
"nanostores": "^0.5.12", "nanostores": "^0.5.12",

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7", "astro": "^1.2.1",
"@astrojs/tailwind": "^1.0.0", "@astrojs/tailwind": "^1.0.0",
"autoprefixer": "^10.4.7", "autoprefixer": "^10.4.7",
"canvas-confetti": "^1.5.1", "canvas-confetti": "^1.5.1",

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7", "astro": "^1.2.1",
"vite-plugin-pwa": "0.11.11", "vite-plugin-pwa": "0.11.11",
"workbox-window": "^6.5.3" "workbox-window": "^6.5.3"
} }

View file

@ -12,7 +12,7 @@
"test": "vitest" "test": "vitest"
}, },
"dependencies": { "dependencies": {
"astro": "^1.1.7", "astro": "^1.2.1",
"vitest": "^0.20.3" "vitest": "^0.20.3"
} }
} }

View file

@ -1,5 +1,39 @@
# astro # astro
## 1.2.1
### Patch Changes
- [#4703](https://github.com/withastro/astro/pull/4703) [`d28f7013c`](https://github.com/withastro/astro/commit/d28f7013c2b415cbf6b640f17c9678ef0ac53253) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Fix: [astro add] Apply fetch polyfill before running
## 1.2.0
### Minor Changes
- [#4682](https://github.com/withastro/astro/pull/4682) [`d1e695914`](https://github.com/withastro/astro/commit/d1e69591479741022eecc122c43afb05985a94fd) Thanks [@bholmesdev](https://github.com/bholmesdev)! - astro add - move configuration updates to final step
- [#4549](https://github.com/withastro/astro/pull/4549) [`255636cc7`](https://github.com/withastro/astro/commit/255636cc7b4ed5f72045f75a2411ebd84a2bdb0d) Thanks [@altano](https://github.com/altano)! - Allow specifying custom encoding when using a non-html route. Only option before was 'utf-8' and now that is just the default.
- [#4578](https://github.com/withastro/astro/pull/4578) [`c706d845e`](https://github.com/withastro/astro/commit/c706d845ebf4786c33d2295954a98df8c5a7f183) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Restart dev server when config file is added, updated, or removed
### Patch Changes
- [#4699](https://github.com/withastro/astro/pull/4699) [`b85d05a84`](https://github.com/withastro/astro/commit/b85d05a841538b6a995808b6422b234f3e746804) Thanks [@matthewp](https://github.com/matthewp)! - Fix missing CSS in client:only in child packages
## 1.1.8
### Patch Changes
- [#4675](https://github.com/withastro/astro/pull/4675) [`63e49c3b6`](https://github.com/withastro/astro/commit/63e49c3b642274835cf99e2c0816a5bb655971c9) Thanks [@matthewp](https://github.com/matthewp)! - Prevent locking up when encountering invalid CSS
- [#4684](https://github.com/withastro/astro/pull/4684) [`919df13b9`](https://github.com/withastro/astro/commit/919df13b91eb561ae939e9be51e5a76ca97d8512) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Fixes regression introduced in [#4646](https://github.com/withastro/astro/pull/4646) with better cyclic reference detection
- [#4683](https://github.com/withastro/astro/pull/4683) [`cc242d3af`](https://github.com/withastro/astro/commit/cc242d3af2cc39731cc40b07ac0aa1db687b2920) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Fix `tsc` compilation errors when `skipLibCheck` wasn't enabled
- [#4667](https://github.com/withastro/astro/pull/4667) [`9290b2414`](https://github.com/withastro/astro/commit/9290b24143d753edd3daf25945990c25a58e5bde) Thanks [@Holben888](https://github.com/Holben888)! - Fix framework components on Vercel Edge
- [#4645](https://github.com/withastro/astro/pull/4645) [`f27ca6ab3`](https://github.com/withastro/astro/commit/f27ca6ab3edbf0ef55e213ffd09aac454ce07995) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Fix client-side scripts reloads on dev server in windows
## 1.1.7 ## 1.1.7
### Patch Changes ### Patch Changes

View file

@ -36,10 +36,7 @@ test.describe('Astro component HMR', () => {
); );
}); });
// TODO: Re-enable this test on windows when #3424 is fixed test('hoisted scripts', async ({ page, astro }) => {
// https://github.com/withastro/astro/issues/3424
const it = os.platform() === 'win32' ? test.skip : test;
it('hoisted scripts', async ({ page, astro }) => {
const initialLog = page.waitForEvent( const initialLog = page.waitForEvent(
'console', 'console',
(message) => message.text() === 'Hello, Astro!' (message) => message.text() === 'Hello, Astro!'
@ -60,4 +57,26 @@ test.describe('Astro component HMR', () => {
await updatedLog; await updatedLog;
}); });
test('inline scripts', async ({ page, astro }) => {
const initialLog = page.waitForEvent(
'console',
(message) => message.text() === 'Hello, inline Astro!'
);
await page.goto(astro.resolveUrl('/'));
await initialLog;
const updatedLog = page.waitForEvent(
'console',
(message) => message.text() === 'Hello, updated inline Astro!'
);
// Edit the inline script on the page
await astro.editFile('./src/pages/index.astro', (content) =>
content.replace('Hello, inline Astro!', 'Hello, updated inline Astro!')
);
await updatedLog;
});
}); });

View file

@ -18,3 +18,7 @@ import Hero from '../components/Hero.astro';
<script> <script>
console.log('Hello, Astro!'); console.log('Hello, Astro!');
</script> </script>
<script is:inline>
console.log('Hello, inline Astro!');
</script>

View file

@ -1,6 +1,6 @@
{ {
"name": "astro", "name": "astro",
"version": "1.1.7", "version": "1.2.1",
"description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.", "description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
"type": "module", "type": "module",
"author": "withastro", "author": "withastro",
@ -88,13 +88,14 @@
"dev": "astro-scripts dev --prebuild \"src/runtime/server/astro-island.ts\" --prebuild \"src/runtime/client/{idle,load,media,only,visible}.ts\" \"src/**/*.ts\"", "dev": "astro-scripts dev --prebuild \"src/runtime/server/astro-island.ts\" --prebuild \"src/runtime/client/{idle,load,media,only,visible}.ts\" \"src/**/*.ts\"",
"postbuild": "astro-scripts copy \"src/**/*.astro\"", "postbuild": "astro-scripts copy \"src/**/*.astro\"",
"benchmark": "node test/benchmark/dev.bench.js && node test/benchmark/build.bench.js", "benchmark": "node test/benchmark/dev.bench.js && node test/benchmark/build.bench.js",
"test": "mocha --exit --timeout 20000 --ignore **/lit-element.test.js && mocha --timeout 20000 **/lit-element.test.js", "test:unit": "mocha --exit --timeout 2000 ./test/units/**/*.test.js",
"test": "pnpm run test:unit && mocha --exit --timeout 20000 --ignore **/lit-element.test.js && mocha --timeout 20000 **/lit-element.test.js",
"test:match": "mocha --timeout 20000 -g", "test:match": "mocha --timeout 20000 -g",
"test:e2e": "playwright test", "test:e2e": "playwright test",
"test:e2e:match": "playwright test -g" "test:e2e:match": "playwright test -g"
}, },
"dependencies": { "dependencies": {
"@astrojs/compiler": "^0.23.5", "@astrojs/compiler": "^0.24.0",
"@astrojs/language-server": "^0.23.0", "@astrojs/language-server": "^0.23.0",
"@astrojs/markdown-remark": "^1.1.1", "@astrojs/markdown-remark": "^1.1.1",
"@astrojs/telemetry": "^1.0.0", "@astrojs/telemetry": "^1.0.0",
@ -105,8 +106,11 @@
"@babel/plugin-transform-react-jsx": "^7.17.12", "@babel/plugin-transform-react-jsx": "^7.17.12",
"@babel/traverse": "^7.18.2", "@babel/traverse": "^7.18.2",
"@babel/types": "^7.18.4", "@babel/types": "^7.18.4",
"@proload/core": "^0.3.2", "@proload/core": "^0.3.3",
"@proload/plugin-tsm": "^0.2.1", "@proload/plugin-tsm": "^0.2.1",
"@types/babel__core": "^7.1.19",
"@types/html-escaper": "^3.0.0",
"@types/yargs-parser": "^21.0.0",
"boxen": "^6.2.1", "boxen": "^6.2.1",
"ci-info": "^3.3.1", "ci-info": "^3.3.1",
"common-ancestor-path": "^1.0.1", "common-ancestor-path": "^1.0.1",
@ -151,7 +155,6 @@
}, },
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.22.2", "@playwright/test": "^1.22.2",
"@types/babel__core": "^7.1.19",
"@types/babel__generator": "^7.6.4", "@types/babel__generator": "^7.6.4",
"@types/babel__traverse": "^7.17.1", "@types/babel__traverse": "^7.17.1",
"@types/chai": "^4.3.1", "@types/chai": "^4.3.1",
@ -160,7 +163,6 @@
"@types/debug": "^4.1.7", "@types/debug": "^4.1.7",
"@types/diff": "^5.0.2", "@types/diff": "^5.0.2",
"@types/estree": "^0.0.51", "@types/estree": "^0.0.51",
"@types/html-escaper": "^3.0.0",
"@types/mime": "^2.0.3", "@types/mime": "^2.0.3",
"@types/mocha": "^9.1.1", "@types/mocha": "^9.1.1",
"@types/parse5": "^6.0.3", "@types/parse5": "^6.0.3",
@ -170,7 +172,6 @@
"@types/rimraf": "^3.0.2", "@types/rimraf": "^3.0.2",
"@types/send": "^0.17.1", "@types/send": "^0.17.1",
"@types/unist": "^2.0.6", "@types/unist": "^2.0.6",
"@types/yargs-parser": "^21.0.0",
"ast-types": "^0.14.2", "ast-types": "^0.14.2",
"astro-scripts": "workspace:*", "astro-scripts": "workspace:*",
"chai": "^4.3.6", "chai": "^4.3.6",

View file

@ -924,7 +924,7 @@ export interface MarkdownInstance<T extends Record<string, any>> {
default: AstroComponentFactory; default: AstroComponentFactory;
} }
export interface MDXInstance<T> export interface MDXInstance<T extends Record<string, any>>
extends Omit<MarkdownInstance<T>, 'rawContent' | 'compiledContent'> { extends Omit<MarkdownInstance<T>, 'rawContent' | 'compiledContent'> {
/** MDX does not support rawContent! If you need to read the Markdown contents to calculate values (ex. reading time), we suggest injecting frontmatter via remark plugins. Learn more on our docs: https://docs.astro.build/en/guides/integrations-guide/mdx/#inject-frontmatter-via-remark-or-rehype-plugins */ /** MDX does not support rawContent! If you need to read the Markdown contents to calculate values (ex. reading time), we suggest injecting frontmatter via remark plugins. Learn more on our docs: https://docs.astro.build/en/guides/integrations-guide/mdx/#inject-frontmatter-via-remark-or-rehype-plugins */
rawContent: never; rawContent: never;
@ -944,7 +944,10 @@ export interface MarkdownLayoutProps<T extends Record<string, any>> {
compiledContent: MarkdownInstance<T>['compiledContent']; compiledContent: MarkdownInstance<T>['compiledContent'];
} }
export type MDXLayoutProps<T> = Omit<MarkdownLayoutProps<T>, 'rawContent' | 'compiledContent'>; export type MDXLayoutProps<T extends Record<string, any>> = Omit<
MarkdownLayoutProps<T>,
'rawContent' | 'compiledContent'
>;
export type GetHydrateCallback = () => Promise<() => void | Promise<void>>; export type GetHydrateCallback = () => Promise<() => void | Promise<void>>;
@ -1082,6 +1085,7 @@ export interface APIContext {
export interface EndpointOutput { export interface EndpointOutput {
body: Body; body: Body;
encoding?: BufferEncoding;
} }
export type APIRoute = ( export type APIRoute = (

View file

@ -1,16 +1,19 @@
/* eslint-disable no-console */ /* eslint-disable no-console */
import * as colors from 'kleur/colors'; import * as colors from 'kleur/colors';
import { pathToFileURL } from 'url';
import { normalizePath } from 'vite';
import type { Arguments as Flags } from 'yargs-parser';
import yargs from 'yargs-parser'; import yargs from 'yargs-parser';
import { z } from 'zod'; import { z } from 'zod';
import add from '../core/add/index.js'; import add from '../core/add/index.js';
import build from '../core/build/index.js'; import build from '../core/build/index.js';
import { openConfig } from '../core/config.js'; import { openConfig, resolveConfigPath, resolveFlags, resolveRoot } from '../core/config.js';
import devServer from '../core/dev/index.js'; import devServer from '../core/dev/index.js';
import { collectErrorMetadata } from '../core/errors.js'; import { collectErrorMetadata } from '../core/errors.js';
import { debug, info, LogOptions, warn } from '../core/logger/core.js'; import { debug, error, info, LogOptions } from '../core/logger/core.js';
import { enableVerboseLogging, nodeLogDestination } from '../core/logger/node.js'; import { enableVerboseLogging, nodeLogDestination } from '../core/logger/node.js';
import { formatConfigErrorMessage, formatErrorMessage, printHelp } from '../core/messages.js'; import { formatConfigErrorMessage, formatErrorMessage, printHelp } from '../core/messages.js';
import { appendForwardSlash } from '../core/path.js';
import preview from '../core/preview/index.js'; import preview from '../core/preview/index.js';
import { ASTRO_VERSION, createSafeError } from '../core/util.js'; import { ASTRO_VERSION, createSafeError } from '../core/util.js';
import * as event from '../events/index.js'; import * as event from '../events/index.js';
@ -81,6 +84,21 @@ function resolveCommand(flags: Arguments): CLICommand {
return 'help'; return 'help';
} }
async function handleConfigError(
e: any,
{ cwd, flags, logging }: { cwd?: string; flags?: Flags; logging: LogOptions }
) {
const path = await resolveConfigPath({ cwd, flags });
if (e instanceof Error) {
if (path) {
error(logging, 'astro', `Unable to load ${colors.bold(path)}\n`);
}
console.error(
formatErrorMessage(collectErrorMetadata(e, path ? pathToFileURL(path) : undefined)) + '\n'
);
}
}
/** /**
* Run the given command with the given flags. * Run the given command with the given flags.
* NOTE: This function provides no error handling, so be sure * NOTE: This function provides no error handling, so be sure
@ -132,12 +150,16 @@ async function runCommand(cmd: string, flags: yargs.Arguments) {
} }
} }
let { astroConfig, userConfig, userConfigPath } = await openConfig({ let { astroConfig, userConfig } = await openConfig({
cwd: root, cwd: root,
flags, flags,
cmd, cmd,
logging, logging,
}).catch(async (e) => {
await handleConfigError(e, { cwd: root, flags, logging });
return {} as any;
}); });
if (!astroConfig) return;
telemetry.record(event.eventCliSession(cmd, userConfig, flags)); telemetry.record(event.eventCliSession(cmd, userConfig, flags));
// Common CLI Commands: // Common CLI Commands:
@ -145,33 +167,55 @@ async function runCommand(cmd: string, flags: yargs.Arguments) {
// by the end of this switch statement. // by the end of this switch statement.
switch (cmd) { switch (cmd) {
case 'dev': { case 'dev': {
async function startDevServer() { async function startDevServer({ isRestart = false }: { isRestart?: boolean } = {}) {
const { watcher, stop } = await devServer(astroConfig, { logging, telemetry }); const { watcher, stop } = await devServer(astroConfig, { logging, telemetry, isRestart });
let restartInFlight = false;
const configFlag = resolveFlags(flags).config;
const configFlagPath = configFlag
? await resolveConfigPath({ cwd: root, flags })
: undefined;
const resolvedRoot = appendForwardSlash(resolveRoot(root));
watcher.on('change', logRestartServerOnConfigChange); const handleServerRestart = (logMsg: string) =>
watcher.on('unlink', logRestartServerOnConfigChange); async function (changedFile: string) {
function logRestartServerOnConfigChange(changedFile: string) { if (
if (userConfigPath === changedFile) { !restartInFlight &&
warn(logging, 'astro', 'Astro config updated. Restart server to see changes!'); (configFlag
} ? // If --config is specified, only watch changes for this file
} configFlagPath && normalizePath(configFlagPath) === normalizePath(changedFile)
: // Otherwise, watch for any astro.config.* file changes in project root
watcher.on('add', async function restartServerOnNewConfigFile(addedFile: string) { new RegExp(
// if there was not a config before, attempt to resolve `${normalizePath(resolvedRoot)}.*astro\.config\.((mjs)|(cjs)|(js)|(ts))$`
if (!userConfigPath && addedFile.includes('astro.config')) { ).test(normalizePath(changedFile)))
const addedConfig = await openConfig({ cwd: root, flags, cmd, logging }); ) {
if (addedConfig.userConfigPath) { restartInFlight = true;
info(logging, 'astro', 'Astro config detected. Restarting server...'); console.clear();
astroConfig = addedConfig.astroConfig; try {
userConfig = addedConfig.userConfig; const newConfig = await openConfig({
userConfigPath = addedConfig.userConfigPath; cwd: root,
await stop(); flags,
await startDevServer(); cmd,
logging,
isConfigReload: true,
});
info(logging, 'astro', logMsg + '\n');
astroConfig = newConfig.astroConfig;
await stop();
await startDevServer({ isRestart: true });
} catch (e) {
await handleConfigError(e, { cwd: root, flags, logging });
await stop();
info(logging, 'astro', 'Continuing with previous valid configuration\n');
await startDevServer({ isRestart: true });
}
} }
} };
});
watcher.on('change', handleServerRestart('Configuration updated. Restarting...'));
watcher.on('unlink', handleServerRestart('Configuration removed. Restarting...'));
watcher.on('add', handleServerRestart('Configuration added. Restarting...'));
} }
await startDevServer(); await startDevServer({ isRestart: false });
return await new Promise(() => {}); // lives forever return await new Promise(() => {}); // lives forever
} }

View file

@ -10,7 +10,7 @@ import preferredPM from 'preferred-pm';
import prompts from 'prompts'; import prompts from 'prompts';
import { fileURLToPath, pathToFileURL } from 'url'; import { fileURLToPath, pathToFileURL } from 'url';
import type yargs from 'yargs-parser'; import type yargs from 'yargs-parser';
import { resolveConfigURL } from '../config.js'; import { resolveConfigPath } from '../config.js';
import { debug, info, LogOptions } from '../logger/core.js'; import { debug, info, LogOptions } from '../logger/core.js';
import * as msg from '../messages.js'; import * as msg from '../messages.js';
import { printHelp } from '../messages.js'; import { printHelp } from '../messages.js';
@ -57,6 +57,7 @@ const OFFICIAL_ADAPTER_TO_IMPORT_MAP: Record<string, string> = {
}; };
export default async function add(names: string[], { cwd, flags, logging, telemetry }: AddOptions) { export default async function add(names: string[], { cwd, flags, logging, telemetry }: AddOptions) {
applyPolyfill();
if (flags.help || names.length === 0) { if (flags.help || names.length === 0) {
printHelp({ printHelp({
commandName: 'astro add', commandName: 'astro add',
@ -95,16 +96,76 @@ export default async function add(names: string[], { cwd, flags, logging, teleme
}); });
return; return;
} }
let configURL: URL | undefined;
// Some packages might have a common alias! We normalize those here.
const integrationNames = names.map((name) => (ALIASES.has(name) ? ALIASES.get(name)! : name));
const integrations = await validateIntegrations(integrationNames);
let installResult = await tryToInstallIntegrations({ integrations, cwd, flags, logging });
const root = pathToFileURL(cwd ? path.resolve(cwd) : process.cwd()); const root = pathToFileURL(cwd ? path.resolve(cwd) : process.cwd());
configURL = await resolveConfigURL({ cwd, flags }); // Append forward slash to compute relative paths
applyPolyfill(); root.href = appendForwardSlash(root.href);
switch (installResult) {
case UpdateResult.updated: {
if (integrations.find((integration) => integration.id === 'tailwind')) {
const possibleConfigFiles = [
'./tailwind.config.cjs',
'./tailwind.config.mjs',
'./tailwind.config.js',
].map((p) => fileURLToPath(new URL(p, root)));
let alreadyConfigured = false;
for (const possibleConfigPath of possibleConfigFiles) {
if (existsSync(possibleConfigPath)) {
alreadyConfigured = true;
break;
}
}
if (!alreadyConfigured) {
info(
logging,
null,
`\n ${magenta(
`Astro will generate a minimal ${bold('./tailwind.config.cjs')} file.`
)}\n`
);
if (await askToContinue({ flags })) {
await fs.writeFile(
fileURLToPath(new URL('./tailwind.config.cjs', root)),
TAILWIND_CONFIG_STUB,
{ encoding: 'utf-8' }
);
debug('add', `Generated default ./tailwind.config.cjs file`);
}
} else {
debug('add', `Using existing Tailwind configuration`);
}
}
break;
}
case UpdateResult.cancelled: {
info(
logging,
null,
msg.cancelled(
`Dependencies ${bold('NOT')} installed.`,
`Be sure to install them manually before continuing!`
)
);
break;
}
case UpdateResult.failure: {
throw createPrettyError(new Error(`Unable to install dependencies`));
}
}
const rawConfigPath = await resolveConfigPath({ cwd, flags });
let configURL = rawConfigPath ? pathToFileURL(rawConfigPath) : undefined;
if (configURL) { if (configURL) {
debug('add', `Found config at ${configURL}`); debug('add', `Found config at ${configURL}`);
} else { } else {
info(logging, 'add', `Unable to locate a config file, generating one for you.`); info(logging, 'add', `Unable to locate a config file, generating one for you.`);
configURL = new URL('./astro.config.mjs', appendForwardSlash(root.href)); configURL = new URL('./astro.config.mjs', root);
await fs.writeFile(fileURLToPath(configURL), ASTRO_CONFIG_STUB, { encoding: 'utf-8' }); await fs.writeFile(fileURLToPath(configURL), ASTRO_CONFIG_STUB, { encoding: 'utf-8' });
} }
@ -114,11 +175,6 @@ export default async function add(names: string[], { cwd, flags, logging, teleme
`Unable to use "astro add" with package.json configuration. Try migrating to \`astro.config.mjs\` and try again.` `Unable to use "astro add" with package.json configuration. Try migrating to \`astro.config.mjs\` and try again.`
); );
} }
// Some packages might have a common alias! We normalize those here.
const integrationNames = names.map((name) => (ALIASES.has(name) ? ALIASES.get(name)! : name));
const integrations = await validateIntegrations(integrationNames);
let ast: t.File | null = null; let ast: t.File | null = null;
try { try {
ast = await parseAstroConfig(configURL); ast = await parseAstroConfig(configURL);
@ -164,7 +220,6 @@ export default async function add(names: string[], { cwd, flags, logging, teleme
} }
let configResult: UpdateResult | undefined; let configResult: UpdateResult | undefined;
let installResult: UpdateResult | undefined;
if (ast) { if (ast) {
try { try {
@ -203,71 +258,19 @@ export default async function add(names: string[], { cwd, flags, logging, teleme
} }
info(logging, null, msg.success(`Configuration up-to-date.`)); info(logging, null, msg.success(`Configuration up-to-date.`));
break; return;
} }
} default: {
installResult = await tryToInstallIntegrations({ integrations, cwd, flags, logging });
switch (installResult) {
case UpdateResult.updated: {
const len = integrations.length;
if (integrations.find((integration) => integration.id === 'tailwind')) {
const possibleConfigFiles = [
'./tailwind.config.cjs',
'./tailwind.config.mjs',
'./tailwind.config.js',
].map((p) => fileURLToPath(new URL(p, configURL)));
let alreadyConfigured = false;
for (const possibleConfigPath of possibleConfigFiles) {
if (existsSync(possibleConfigPath)) {
alreadyConfigured = true;
break;
}
}
if (!alreadyConfigured) {
info(
logging,
null,
`\n ${magenta(
`Astro will generate a minimal ${bold('./tailwind.config.cjs')} file.`
)}\n`
);
if (await askToContinue({ flags })) {
await fs.writeFile(
fileURLToPath(new URL('./tailwind.config.cjs', configURL)),
TAILWIND_CONFIG_STUB,
{ encoding: 'utf-8' }
);
debug('add', `Generated default ./tailwind.config.cjs file`);
}
} else {
debug('add', `Using existing Tailwind configuration`);
}
}
const list = integrations.map((integration) => ` - ${integration.packageName}`).join('\n'); const list = integrations.map((integration) => ` - ${integration.packageName}`).join('\n');
info( info(
logging, logging,
null, null,
msg.success( msg.success(
`Added the following integration${len === 1 ? '' : 's'} to your project:\n${list}` `Added the following integration${
integrations.length === 1 ? '' : 's'
} to your project:\n${list}`
) )
); );
return;
}
case UpdateResult.cancelled: {
info(
logging,
null,
msg.cancelled(
`Dependencies ${bold('NOT')} installed.`,
`Be sure to install them manually before continuing!`
)
);
return;
}
case UpdateResult.failure: {
throw createPrettyError(new Error(`Unable to install dependencies`));
} }
} }
} }
@ -551,11 +554,11 @@ async function getInstallIntegrationsCommand({
switch (pm.name) { switch (pm.name) {
case 'npm': case 'npm':
return { pm: 'npm', command: 'install', flags: ['--save-dev'], dependencies }; return { pm: 'npm', command: 'install', flags: [], dependencies };
case 'yarn': case 'yarn':
return { pm: 'yarn', command: 'add', flags: ['--dev'], dependencies }; return { pm: 'yarn', command: 'add', flags: [], dependencies };
case 'pnpm': case 'pnpm':
return { pm: 'pnpm', command: 'install', flags: ['--save-dev'], dependencies }; return { pm: 'pnpm', command: 'install', flags: [], dependencies };
default: default:
return null; return null;
} }
@ -577,9 +580,10 @@ async function tryToInstallIntegrations({
if (installCommand === null) { if (installCommand === null) {
return UpdateResult.none; return UpdateResult.none;
} else { } else {
const coloredOutput = `${bold(installCommand.pm)} ${ const coloredOutput = `${bold(installCommand.pm)} ${installCommand.command}${[
installCommand.command '',
} ${installCommand.flags.join(' ')} ${cyan(installCommand.dependencies.join(' '))}`; ...installCommand.flags,
].join(' ')} ${cyan(installCommand.dependencies.join(' '))}`;
const message = `\n${boxen(coloredOutput, { const message = `\n${boxen(coloredOutput, {
margin: 0.5, margin: 0.5,
padding: 0.5, padding: 0.5,

View file

@ -391,6 +391,7 @@ async function generatePath(
}; };
let body: string; let body: string;
let encoding: BufferEncoding | undefined;
if (pageData.route.type === 'endpoint') { if (pageData.route.type === 'endpoint') {
const result = await callEndpoint(mod as unknown as EndpointHandler, options); const result = await callEndpoint(mod as unknown as EndpointHandler, options);
@ -398,6 +399,7 @@ async function generatePath(
throw new Error(`Returning a Response from an endpoint is not supported in SSG mode.`); throw new Error(`Returning a Response from an endpoint is not supported in SSG mode.`);
} }
body = result.body; body = result.body;
encoding = result.encoding;
} else { } else {
const response = await render(options); const response = await render(options);
@ -413,5 +415,5 @@ async function generatePath(
const outFile = getOutFile(astroConfig, outFolder, pathname, pageData.route.type); const outFile = getOutFile(astroConfig, outFolder, pathname, pageData.route.type);
pageData.route.distURL = outFile; pageData.route.distURL = outFile;
await fs.promises.mkdir(outFolder, { recursive: true }); await fs.promises.mkdir(outFolder, { recursive: true });
await fs.promises.writeFile(outFile, body, 'utf-8'); await fs.promises.writeFile(outFile, body, encoding ?? 'utf-8');
} }

View file

@ -70,7 +70,7 @@ export function vitePluginAnalyzer(internals: BuildInternals): VitePlugin {
return { return {
name: '@astro/rollup-plugin-astro-analyzer', name: '@astro/rollup-plugin-astro-analyzer',
generateBundle() { async generateBundle() {
const hoistScanner = hoistedScriptScanner(); const hoistScanner = hoistedScriptScanner();
const ids = this.getModuleIds(); const ids = this.getModuleIds();
@ -95,6 +95,14 @@ export function vitePluginAnalyzer(internals: BuildInternals): VitePlugin {
const cid = c.resolvedPath ? decodeURI(c.resolvedPath) : c.specifier; const cid = c.resolvedPath ? decodeURI(c.resolvedPath) : c.specifier;
internals.discoveredClientOnlyComponents.add(cid); internals.discoveredClientOnlyComponents.add(cid);
clientOnlys.push(cid); clientOnlys.push(cid);
// Bare module specifiers need to be resolved so that the CSS
// plugin can walk up the graph to find which page they belong to.
if (c.resolvedPath === c.specifier) {
const resolvedId = await this.resolve(c.specifier, id);
if (resolvedId) {
clientOnlys.push(resolvedId.id);
}
}
} }
for (const [pageInfo] of getTopLevelPages(id, this)) { for (const [pageInfo] of getTopLevelPages(id, this)) {

View file

@ -1,14 +1,12 @@
import type { TransformResult } from '@astrojs/compiler'; import type { TransformResult } from '@astrojs/compiler';
import type { PluginContext, SourceMapInput } from 'rollup'; import type { AstroConfig } from '../../@types/astro';
import type { ViteDevServer } from 'vite'; import type { TransformStyle } from './types';
import type { AstroConfig } from '../@types/astro';
import type { TransformStyleWithVite } from './styles';
import { transform } from '@astrojs/compiler'; import { transform } from '@astrojs/compiler';
import { fileURLToPath } from 'url'; import { AstroErrorCodes } from '../errors.js';
import { AstroErrorCodes } from '../core/errors.js'; import { prependForwardSlash } from '../path.js';
import { prependForwardSlash } from '../core/path.js'; import { AggregateError, viteID } from '../util.js';
import { viteID } from '../core/util.js'; import { createStylePreprocessor } from './style.js';
type CompilationCache = Map<string, CompileResult>; type CompilationCache = Map<string, CompileResult>;
type CompileResult = TransformResult & { type CompileResult = TransformResult & {
@ -23,20 +21,7 @@ export interface CompileProps {
filename: string; filename: string;
moduleId: string; moduleId: string;
source: string; source: string;
ssr: boolean; transformStyle: TransformStyle;
transformStyleWithVite: TransformStyleWithVite;
viteDevServer?: ViteDevServer;
pluginContext: PluginContext;
}
function getNormalizedID(filename: string): string {
try {
const filenameURL = new URL(`file://${filename}`);
return fileURLToPath(filenameURL);
} catch (err) {
// Not a real file, so just use the provided filename as the normalized id
return filename;
}
} }
async function compile({ async function compile({
@ -44,19 +29,10 @@ async function compile({
filename, filename,
moduleId, moduleId,
source, source,
ssr, transformStyle,
transformStyleWithVite,
viteDevServer,
pluginContext,
}: CompileProps): Promise<CompileResult> { }: CompileProps): Promise<CompileResult> {
const normalizedID = getNormalizedID(filename);
let cssDeps = new Set<string>(); let cssDeps = new Set<string>();
let cssTransformError: Error | undefined; let cssTransformErrors: Error[] = [];
// handleHotUpdate doesn't have `addWatchFile` used by transformStyleWithVite.
if (!pluginContext.addWatchFile) {
pluginContext.addWatchFile = () => {};
}
// Transform from `.astro` to valid `.ts` // Transform from `.astro` to valid `.ts`
// use `sourcemap: "both"` so that sourcemap is included in the code // use `sourcemap: "both"` so that sourcemap is included in the code
@ -69,44 +45,11 @@ async function compile({
sourcefile: filename, sourcefile: filename,
sourcemap: 'both', sourcemap: 'both',
internalURL: `/@fs${prependForwardSlash( internalURL: `/@fs${prependForwardSlash(
viteID(new URL('../runtime/server/index.js', import.meta.url)) viteID(new URL('../../runtime/server/index.js', import.meta.url))
)}`, )}`,
// TODO: baseline flag // TODO: baseline flag
experimentalStaticExtraction: true, experimentalStaticExtraction: true,
preprocessStyle: async (value: string, attrs: Record<string, string>) => { preprocessStyle: createStylePreprocessor(transformStyle, cssDeps, cssTransformErrors),
const lang = `.${attrs?.lang || 'css'}`.toLowerCase();
try {
const result = await transformStyleWithVite.call(pluginContext, {
id: normalizedID,
source: value,
lang,
ssr,
viteDevServer,
});
if (!result) return null as any; // TODO: add type in compiler to fix "any"
for (const dep of result.deps) {
cssDeps.add(dep);
}
let map: SourceMapInput | undefined;
if (result.map) {
if (typeof result.map === 'string') {
map = result.map;
} else if (result.map.mappings) {
map = result.map.toString();
}
}
return { code: result.code, map };
} catch (err) {
// save error to throw in plugin context
cssTransformError = err as any;
return null;
}
},
}) })
.catch((err) => { .catch((err) => {
// throw compiler errors here if encountered // throw compiler errors here if encountered
@ -114,13 +57,22 @@ async function compile({
throw err; throw err;
}) })
.then((result) => { .then((result) => {
// throw CSS transform errors here if encountered switch (cssTransformErrors.length) {
if (cssTransformError) { case 0:
(cssTransformError as any).code = return result;
(cssTransformError as any).code || AstroErrorCodes.UnknownCompilerCSSError; case 1: {
throw cssTransformError; let error = cssTransformErrors[0];
if (!(error as any).code) {
(error as any).code = AstroErrorCodes.UnknownCompilerCSSError;
}
throw cssTransformErrors[0];
}
default: {
const aggregateError = new AggregateError(cssTransformErrors);
(aggregateError as any).code = AstroErrorCodes.UnknownCompilerCSSError;
throw aggregateError;
}
} }
return result;
}); });
const compileResult: CompileResult = Object.create(transformResult, { const compileResult: CompileResult = Object.create(transformResult, {

View file

@ -0,0 +1,3 @@
export type { CompileProps } from './compile';
export { cachedCompilation, getCachedSource, invalidateCompilation, isCached } from './compile.js';
export type { TransformStyle } from './types';

View file

@ -0,0 +1,43 @@
import type { TransformOptions } from '@astrojs/compiler';
import type { SourceMapInput } from 'rollup';
import type { TransformStyle } from './types';
type PreprocessStyle = TransformOptions['preprocessStyle'];
export function createStylePreprocessor(
transformStyle: TransformStyle,
cssDeps: Set<string>,
errors: Error[]
): PreprocessStyle {
const preprocessStyle: PreprocessStyle = async (value: string, attrs: Record<string, string>) => {
const lang = `.${attrs?.lang || 'css'}`.toLowerCase();
try {
const result = await transformStyle(value, lang);
if (!result) return null as any; // TODO: add type in compiler to fix "any"
for (const dep of result.deps) {
cssDeps.add(dep);
}
let map: SourceMapInput | undefined;
if (result.map) {
if (typeof result.map === 'string') {
map = result.map;
} else if (result.map.mappings) {
map = result.map.toString();
}
}
return { code: result.code, map };
} catch (err) {
errors.push(err as unknown as Error);
return {
error: err + '',
};
}
};
return preprocessStyle;
}

View file

@ -0,0 +1,12 @@
import type { SourceMap } from 'rollup';
export type TransformStyleResult = null | {
code: string;
map: SourceMap | null;
deps: Set<string>;
};
export type TransformStyle = (
source: string,
lang: string
) => TransformStyleResult | Promise<TransformStyleResult>;

View file

@ -1,4 +1,5 @@
import type { RehypePlugin, RemarkPlugin, RemarkRehype } from '@astrojs/markdown-remark'; import type { RehypePlugin, RemarkPlugin, RemarkRehype } from '@astrojs/markdown-remark';
import fs from 'fs';
import type * as Postcss from 'postcss'; import type * as Postcss from 'postcss';
import type { ILanguageRegistration, IThemeRegistration, Theme } from 'shiki'; import type { ILanguageRegistration, IThemeRegistration, Theme } from 'shiki';
import type { Arguments as Flags } from 'yargs-parser'; import type { Arguments as Flags } from 'yargs-parser';
@ -361,7 +362,7 @@ export async function validateConfig(
} }
/** Convert the generic "yargs" flag object into our own, custom TypeScript object. */ /** Convert the generic "yargs" flag object into our own, custom TypeScript object. */
function resolveFlags(flags: Partial<Flags>): CLIFlags { export function resolveFlags(flags: Partial<Flags>): CLIFlags {
return { return {
root: typeof flags.root === 'string' ? flags.root : undefined, root: typeof flags.root === 'string' ? flags.root : undefined,
site: typeof flags.site === 'string' ? flags.site : undefined, site: typeof flags.site === 'string' ? flags.site : undefined,
@ -373,6 +374,10 @@ function resolveFlags(flags: Partial<Flags>): CLIFlags {
}; };
} }
export function resolveRoot(cwd?: string): string {
return cwd ? path.resolve(cwd) : process.cwd();
}
/** Merge CLI flags & user config object (CLI flags take priority) */ /** Merge CLI flags & user config object (CLI flags take priority) */
function mergeCLIFlags(astroConfig: AstroUserConfig, flags: CLIFlags, cmd: string) { function mergeCLIFlags(astroConfig: AstroUserConfig, flags: CLIFlags, cmd: string) {
astroConfig.server = astroConfig.server || {}; astroConfig.server = astroConfig.server || {};
@ -398,6 +403,8 @@ interface LoadConfigOptions {
cmd: string; cmd: string;
validate?: boolean; validate?: boolean;
logging: LogOptions; logging: LogOptions;
/** Invalidate when reloading a previously loaded config */
isConfigReload?: boolean;
} }
/** /**
@ -405,10 +412,10 @@ interface LoadConfigOptions {
* Note: currently the same as loadConfig but only returns the `filePath` * Note: currently the same as loadConfig but only returns the `filePath`
* instead of the resolved config * instead of the resolved config
*/ */
export async function resolveConfigURL( export async function resolveConfigPath(
configOptions: Pick<LoadConfigOptions, 'cwd' | 'flags'> configOptions: Pick<LoadConfigOptions, 'cwd' | 'flags'>
): Promise<URL | undefined> { ): Promise<string | undefined> {
const root = configOptions.cwd ? path.resolve(configOptions.cwd) : process.cwd(); const root = resolveRoot(configOptions.cwd);
const flags = resolveFlags(configOptions.flags || {}); const flags = resolveFlags(configOptions.flags || {});
let userConfigPath: string | undefined; let userConfigPath: string | undefined;
@ -419,19 +426,23 @@ export async function resolveConfigURL(
// Resolve config file path using Proload // Resolve config file path using Proload
// If `userConfigPath` is `undefined`, Proload will search for `astro.config.[cm]?[jt]s` // If `userConfigPath` is `undefined`, Proload will search for `astro.config.[cm]?[jt]s`
const configPath = await resolve('astro', { try {
mustExist: false, const configPath = await resolve('astro', {
cwd: root, mustExist: !!userConfigPath,
filePath: userConfigPath, cwd: root,
}); filePath: userConfigPath,
if (configPath) { });
return pathToFileURL(configPath); return configPath;
} catch (e) {
if (e instanceof ProloadError && flags.config) {
throw new Error(`Unable to resolve --config "${flags.config}"! Does the file exist?`);
}
throw e;
} }
} }
interface OpenConfigResult { interface OpenConfigResult {
userConfig: AstroUserConfig; userConfig: AstroUserConfig;
userConfigPath: string | undefined;
astroConfig: AstroConfig; astroConfig: AstroConfig;
flags: CLIFlags; flags: CLIFlags;
root: string; root: string;
@ -439,22 +450,13 @@ interface OpenConfigResult {
/** Load a configuration file, returning both the userConfig and astroConfig */ /** Load a configuration file, returning both the userConfig and astroConfig */
export async function openConfig(configOptions: LoadConfigOptions): Promise<OpenConfigResult> { export async function openConfig(configOptions: LoadConfigOptions): Promise<OpenConfigResult> {
const root = configOptions.cwd ? path.resolve(configOptions.cwd) : process.cwd(); const root = resolveRoot(configOptions.cwd);
const flags = resolveFlags(configOptions.flags || {}); const flags = resolveFlags(configOptions.flags || {});
let userConfig: AstroUserConfig = {}; let userConfig: AstroUserConfig = {};
let userConfigPath: string | undefined;
if (flags?.config) { const config = await tryLoadConfig(configOptions, flags, root);
userConfigPath = /^\.*\//.test(flags.config) ? flags.config : `./${flags.config}`;
userConfigPath = fileURLToPath(
new URL(userConfigPath, appendForwardSlash(pathToFileURL(root).toString()))
);
}
const config = await tryLoadConfig(configOptions, flags, userConfigPath, root);
if (config) { if (config) {
userConfig = config.value; userConfig = config.value;
userConfigPath = config.filePath;
} }
const astroConfig = await resolveConfig( const astroConfig = await resolveConfig(
userConfig, userConfig,
@ -467,7 +469,6 @@ export async function openConfig(configOptions: LoadConfigOptions): Promise<Open
return { return {
astroConfig, astroConfig,
userConfig, userConfig,
userConfigPath,
flags, flags,
root, root,
}; };
@ -481,16 +482,37 @@ interface TryLoadConfigResult {
async function tryLoadConfig( async function tryLoadConfig(
configOptions: LoadConfigOptions, configOptions: LoadConfigOptions,
flags: CLIFlags, flags: CLIFlags,
userConfigPath: string | undefined,
root: string root: string
): Promise<TryLoadConfigResult | undefined> { ): Promise<TryLoadConfigResult | undefined> {
let finallyCleanup = async () => {};
try { try {
// Automatically load config file using Proload let configPath = await resolveConfigPath({
// If `userConfigPath` is `undefined`, Proload will search for `astro.config.[cm]?[jt]s` cwd: configOptions.cwd,
flags: configOptions.flags,
});
if (!configPath) return undefined;
if (configOptions.isConfigReload) {
// Hack: Write config to temporary file at project root
// This invalidates and reloads file contents when using ESM imports or "resolve"
const tempConfigPath = path.join(
root,
`.temp.${Date.now()}.config${path.extname(configPath)}`
);
await fs.promises.writeFile(tempConfigPath, await fs.promises.readFile(configPath));
finallyCleanup = async () => {
try {
await fs.promises.unlink(tempConfigPath);
} catch {
/** file already removed */
}
};
configPath = tempConfigPath;
}
const config = await load('astro', { const config = await load('astro', {
mustExist: !!userConfigPath, mustExist: !!configPath,
cwd: root, cwd: root,
filePath: userConfigPath, filePath: configPath,
}); });
return config as TryLoadConfigResult; return config as TryLoadConfigResult;
@ -499,28 +521,32 @@ async function tryLoadConfig(
throw new Error(`Unable to resolve --config "${flags.config}"! Does the file exist?`); throw new Error(`Unable to resolve --config "${flags.config}"! Does the file exist?`);
} }
const configURL = await resolveConfigURL(configOptions); const configPath = await resolveConfigPath(configOptions);
if (!configURL) { if (!configPath) {
throw e; throw e;
} }
// Fallback to use Vite DevServer // Fallback to use Vite DevServer
const viteServer = await vite.createServer({ const viteServer = await vite.createServer({
server: { middlewareMode: true, hmr: false }, server: { middlewareMode: true, hmr: false },
optimizeDeps: { entries: [] },
clearScreen: false,
appType: 'custom', appType: 'custom',
}); });
try { try {
const mod = await viteServer.ssrLoadModule(fileURLToPath(configURL)); const mod = await viteServer.ssrLoadModule(configPath);
if (mod?.default) { if (mod?.default) {
return { return {
value: mod.default, value: mod.default,
filePath: fileURLToPath(configURL), filePath: configPath,
}; };
} }
} finally { } finally {
await viteServer.close(); await viteServer.close();
} }
} finally {
await finallyCleanup();
} }
} }
@ -529,19 +555,11 @@ async function tryLoadConfig(
* @deprecated * @deprecated
*/ */
export async function loadConfig(configOptions: LoadConfigOptions): Promise<AstroConfig> { export async function loadConfig(configOptions: LoadConfigOptions): Promise<AstroConfig> {
const root = configOptions.cwd ? path.resolve(configOptions.cwd) : process.cwd(); const root = resolveRoot(configOptions.cwd);
const flags = resolveFlags(configOptions.flags || {}); const flags = resolveFlags(configOptions.flags || {});
let userConfig: AstroUserConfig = {}; let userConfig: AstroUserConfig = {};
let userConfigPath: string | undefined;
if (flags?.config) { const config = await tryLoadConfig(configOptions, flags, root);
userConfigPath = /^\.*\//.test(flags.config) ? flags.config : `./${flags.config}`;
userConfigPath = fileURLToPath(
new URL(userConfigPath, appendForwardSlash(pathToFileURL(root).toString()))
);
}
const config = await tryLoadConfig(configOptions, flags, userConfigPath, root);
if (config) { if (config) {
userConfig = config.value; userConfig = config.value;
} }

View file

@ -18,6 +18,7 @@ import { apply as applyPolyfill } from '../polyfill.js';
export interface DevOptions { export interface DevOptions {
logging: LogOptions; logging: LogOptions;
telemetry: AstroTelemetry; telemetry: AstroTelemetry;
isRestart?: boolean;
} }
export interface DevServer { export interface DevServer {
@ -33,6 +34,7 @@ export default async function dev(config: AstroConfig, options: DevOptions): Pro
await options.telemetry.record([]); await options.telemetry.record([]);
config = await runHookConfigSetup({ config, command: 'dev', logging: options.logging }); config = await runHookConfigSetup({ config, command: 'dev', logging: options.logging });
const { host, port } = config.server; const { host, port } = config.server;
const { isRestart = false } = options;
// The client entrypoint for renderers. Since these are imported dynamically // The client entrypoint for renderers. Since these are imported dynamically
// we need to tell Vite to preoptimize them. // we need to tell Vite to preoptimize them.
@ -66,6 +68,7 @@ export default async function dev(config: AstroConfig, options: DevOptions): Pro
devServerAddressInfo, devServerAddressInfo,
site, site,
https: !!viteConfig.server?.https, https: !!viteConfig.server?.https,
isRestart,
}) })
); );

View file

@ -21,6 +21,7 @@ type EndpointCallResult =
| { | {
type: 'simple'; type: 'simple';
body: string; body: string;
encoding?: BufferEncoding;
} }
| { | {
type: 'response'; type: 'response';
@ -52,5 +53,6 @@ export async function call(
return { return {
type: 'simple', type: 'simple',
body: response.body, body: response.body,
encoding: response.encoding,
}; };
} }

View file

@ -58,12 +58,14 @@ export function devStart({
config, config,
https, https,
site, site,
isRestart = false,
}: { }: {
startupTime: number; startupTime: number;
devServerAddressInfo: AddressInfo; devServerAddressInfo: AddressInfo;
config: AstroConfig; config: AstroConfig;
https: boolean; https: boolean;
site: URL | undefined; site: URL | undefined;
isRestart?: boolean;
}): string { }): string {
// PACKAGE_VERSION is injected at build-time // PACKAGE_VERSION is injected at build-time
const version = process.env.PACKAGE_VERSION ?? '0.0.0'; const version = process.env.PACKAGE_VERSION ?? '0.0.0';
@ -106,7 +108,7 @@ export function devStart({
const messages = [ const messages = [
`${emoji('🚀 ', '')}${bgGreen(black(` astro `))} ${green(`v${version}`)} ${dim( `${emoji('🚀 ', '')}${bgGreen(black(` astro `))} ${green(`v${version}`)} ${dim(
`started in ${Math.round(startupTime)}ms` `${isRestart ? 're' : ''}started in ${Math.round(startupTime)}ms`
)}`, )}`,
'', '',
local, local,

View file

@ -126,7 +126,7 @@ export function resolveDependency(dep: string, projectRoot: URL) {
* Windows: C:/Users/astro/code/my-project/src/pages/index.astro * Windows: C:/Users/astro/code/my-project/src/pages/index.astro
*/ */
export function viteID(filePath: URL): string { export function viteID(filePath: URL): string {
return slash(fileURLToPath(filePath)); return slash(fileURLToPath(filePath) + filePath.search);
} }
export const VALID_ID_PREFIX = `/@id/`; export const VALID_ID_PREFIX = `/@id/`;
@ -226,3 +226,14 @@ export async function resolveIdToUrl(viteServer: ViteDevServer, id: string) {
} }
return VALID_ID_PREFIX + result.id; return VALID_ID_PREFIX + result.id;
} }
export const AggregateError =
typeof globalThis.AggregateError !== 'undefined'
? globalThis.AggregateError
: class extends Error {
errors: Array<any> = [];
constructor(errors: Iterable<any>, message?: string | undefined) {
super(message);
this.errors = Array.from(errors);
}
};

View file

@ -32,7 +32,7 @@ export function renderHead(result: SSRResult): Promise<string> {
} }
// This function is called by Astro components that do not contain a <head> component // This function is called by Astro components that do not contain a <head> component
// This accomodates the fact that using a <head> is optional in Astro, so this // This accommodates the fact that using a <head> is optional in Astro, so this
// is called before a component's first non-head HTML element. If the head was // is called before a component's first non-head HTML element. If the head was
// already injected it is a noop. // already injected it is a noop.
export async function* maybeRenderHead(result: SSRResult): AsyncIterable<string> { export async function* maybeRenderHead(result: SSRResult): AsyncIterable<string> {

View file

@ -13,30 +13,48 @@ const PROP_TYPE = {
URL: 7, URL: 7,
}; };
function serializeArray(value: any[], metadata: AstroComponentMetadata): any[] { function serializeArray(
return value.map((v) => convertToSerializedForm(v, metadata)); value: any[],
} metadata: AstroComponentMetadata | Record<string, any> = {},
parents = new WeakSet<any>()
function serializeObject( ): any[] {
value: Record<any, any>, if (parents.has(value)) {
metadata: AstroComponentMetadata
): Record<any, any> {
if (cyclicRefs.has(value)) {
throw new Error(`Cyclic reference detected while serializing props for <${metadata.displayName} client:${metadata.hydrate}>! throw new Error(`Cyclic reference detected while serializing props for <${metadata.displayName} client:${metadata.hydrate}>!
Cyclic references cannot be safely serialized for client-side usage. Please remove the cyclic reference.`); Cyclic references cannot be safely serialized for client-side usage. Please remove the cyclic reference.`);
} }
cyclicRefs.add(value); parents.add(value);
return Object.fromEntries( const serialized = value.map((v) => {
return convertToSerializedForm(v, metadata, parents);
});
parents.delete(value);
return serialized;
}
function serializeObject(
value: Record<any, any>,
metadata: AstroComponentMetadata | Record<string, any> = {},
parents = new WeakSet<any>()
): Record<any, any> {
if (parents.has(value)) {
throw new Error(`Cyclic reference detected while serializing props for <${metadata.displayName} client:${metadata.hydrate}>!
Cyclic references cannot be safely serialized for client-side usage. Please remove the cyclic reference.`);
}
parents.add(value);
const serialized = Object.fromEntries(
Object.entries(value).map(([k, v]) => { Object.entries(value).map(([k, v]) => {
return [k, convertToSerializedForm(v, metadata)]; return [k, convertToSerializedForm(v, metadata, parents)];
}) })
); );
parents.delete(value);
return serialized;
} }
function convertToSerializedForm( function convertToSerializedForm(
value: any, value: any,
metadata: AstroComponentMetadata metadata: AstroComponentMetadata | Record<string, any> = {},
parents = new WeakSet<any>()
): [ValueOf<typeof PROP_TYPE>, any] { ): [ValueOf<typeof PROP_TYPE>, any] {
const tag = Object.prototype.toString.call(value); const tag = Object.prototype.toString.call(value);
switch (tag) { switch (tag) {
@ -49,13 +67,13 @@ function convertToSerializedForm(
case '[object Map]': { case '[object Map]': {
return [ return [
PROP_TYPE.Map, PROP_TYPE.Map,
JSON.stringify(serializeArray(Array.from(value as Map<any, any>), metadata)), JSON.stringify(serializeArray(Array.from(value as Map<any, any>), metadata, parents)),
]; ];
} }
case '[object Set]': { case '[object Set]': {
return [ return [
PROP_TYPE.Set, PROP_TYPE.Set,
JSON.stringify(serializeArray(Array.from(value as Set<any>), metadata)), JSON.stringify(serializeArray(Array.from(value as Set<any>), metadata, parents)),
]; ];
} }
case '[object BigInt]': { case '[object BigInt]': {
@ -65,11 +83,11 @@ function convertToSerializedForm(
return [PROP_TYPE.URL, (value as URL).toString()]; return [PROP_TYPE.URL, (value as URL).toString()];
} }
case '[object Array]': { case '[object Array]': {
return [PROP_TYPE.JSON, JSON.stringify(serializeArray(value, metadata))]; return [PROP_TYPE.JSON, JSON.stringify(serializeArray(value, metadata, parents))];
} }
default: { default: {
if (value !== null && typeof value === 'object') { if (value !== null && typeof value === 'object') {
return [PROP_TYPE.Value, serializeObject(value, metadata)]; return [PROP_TYPE.Value, serializeObject(value, metadata, parents)];
} else { } else {
return [PROP_TYPE.Value, value]; return [PROP_TYPE.Value, value];
} }
@ -77,9 +95,7 @@ function convertToSerializedForm(
} }
} }
let cyclicRefs = new WeakSet<any>();
export function serializeProps(props: any, metadata: AstroComponentMetadata) { export function serializeProps(props: any, metadata: AstroComponentMetadata) {
const serialized = JSON.stringify(serializeObject(props, metadata)); const serialized = JSON.stringify(serializeObject(props, metadata));
cyclicRefs = new WeakSet<any>();
return serialized; return serialized;
} }

View file

@ -1,10 +1,10 @@
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import type { HmrContext, ModuleNode } from 'vite'; import type { HmrContext, ModuleNode } from 'vite';
import type { AstroConfig } from '../@types/astro'; import type { AstroConfig } from '../@types/astro';
import { cachedCompilation, invalidateCompilation, isCached } from '../core/compile/index.js';
import type { LogOptions } from '../core/logger/core.js'; import type { LogOptions } from '../core/logger/core.js';
import { info } from '../core/logger/core.js'; import { info } from '../core/logger/core.js';
import * as msg from '../core/messages.js'; import * as msg from '../core/messages.js';
import { cachedCompilation, invalidateCompilation, isCached } from './compile.js';
import { isAstroScript } from './query.js'; import { isAstroScript } from './query.js';
const PKG_PREFIX = new URL('../../', import.meta.url); const PKG_PREFIX = new URL('../../', import.meta.url);
@ -125,6 +125,7 @@ export async function handleHotUpdate(
// TODO: Svelte files should be marked as `isSelfAccepting` but they don't appear to be // TODO: Svelte files should be marked as `isSelfAccepting` but they don't appear to be
const isSelfAccepting = mods.every((m) => m.isSelfAccepting || m.url.endsWith('.svelte')); const isSelfAccepting = mods.every((m) => m.isSelfAccepting || m.url.endsWith('.svelte'));
if (isSelfAccepting) { if (isSelfAccepting) {
if (/astro\.config\.[cm][jt]s$/.test(file)) return mods;
info(logging, 'astro', msg.hmr({ file })); info(logging, 'astro', msg.hmr({ file }));
} else { } else {
info(logging, 'astro', msg.reload({ file })); info(logging, 'astro', msg.reload({ file }));

View file

@ -2,18 +2,23 @@ import type { PluginContext, SourceDescription } from 'rollup';
import type * as vite from 'vite'; import type * as vite from 'vite';
import type { AstroConfig } from '../@types/astro'; import type { AstroConfig } from '../@types/astro';
import type { LogOptions } from '../core/logger/core.js'; import type { LogOptions } from '../core/logger/core.js';
import type { ViteStyleTransformer } from '../vite-style-transform';
import type { PluginMetadata as AstroPluginMetadata } from './types'; import type { PluginMetadata as AstroPluginMetadata } from './types';
import ancestor from 'common-ancestor-path'; import ancestor from 'common-ancestor-path';
import esbuild from 'esbuild'; import esbuild from 'esbuild';
import slash from 'slash'; import slash from 'slash';
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
import { isRelativePath, startsWithForwardSlash } from '../core/path.js'; import { cachedCompilation, CompileProps, getCachedSource } from '../core/compile/index.js';
import { isRelativePath, prependForwardSlash, startsWithForwardSlash } from '../core/path.js';
import { viteID } from '../core/util.js';
import { getFileInfo } from '../vite-plugin-utils/index.js'; import { getFileInfo } from '../vite-plugin-utils/index.js';
import { cachedCompilation, CompileProps, getCachedSource } from './compile.js'; import {
createTransformStyles,
createViteStyleTransformer,
} from '../vite-style-transform/index.js';
import { handleHotUpdate } from './hmr.js'; import { handleHotUpdate } from './hmr.js';
import { parseAstroRequest, ParsedRequestResult } from './query.js'; import { parseAstroRequest, ParsedRequestResult } from './query.js';
import { createTransformStyleWithViteFn, TransformStyleWithVite } from './styles.js';
const FRONTMATTER_PARSE_REGEXP = /^\-\-\-(.*)^\-\-\-/ms; const FRONTMATTER_PARSE_REGEXP = /^\-\-\-(.*)^\-\-\-/ms;
interface AstroPluginOptions { interface AstroPluginOptions {
@ -38,12 +43,14 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu
} }
let resolvedConfig: vite.ResolvedConfig; let resolvedConfig: vite.ResolvedConfig;
let transformStyleWithVite: TransformStyleWithVite; let styleTransformer: ViteStyleTransformer;
let viteDevServer: vite.ViteDevServer | undefined; let viteDevServer: vite.ViteDevServer | undefined;
// Variables for determining if an id starts with /src... // Variables for determining if an id starts with /src...
const srcRootWeb = config.srcDir.pathname.slice(config.root.pathname.length - 1); const srcRootWeb = config.srcDir.pathname.slice(config.root.pathname.length - 1);
const isBrowserPath = (path: string) => path.startsWith(srcRootWeb); const isBrowserPath = (path: string) => path.startsWith(srcRootWeb);
const isFullFilePath = (path: string) =>
path.startsWith(prependForwardSlash(slash(fileURLToPath(config.root))));
function resolveRelativeFromAstroParent(id: string, parsedFrom: ParsedRequestResult): string { function resolveRelativeFromAstroParent(id: string, parsedFrom: ParsedRequestResult): string {
const filename = normalizeFilename(parsedFrom.filename); const filename = normalizeFilename(parsedFrom.filename);
@ -60,10 +67,11 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu
enforce: 'pre', // run transforms before other plugins can enforce: 'pre', // run transforms before other plugins can
configResolved(_resolvedConfig) { configResolved(_resolvedConfig) {
resolvedConfig = _resolvedConfig; resolvedConfig = _resolvedConfig;
transformStyleWithVite = createTransformStyleWithViteFn(_resolvedConfig); styleTransformer = createViteStyleTransformer(_resolvedConfig);
}, },
configureServer(server) { configureServer(server) {
viteDevServer = server; viteDevServer = server;
styleTransformer.viteDevServer = server;
}, },
// note: dont claim .astro files with resolveId() — it prevents Vite from transpiling the final JS (import.meta.glob, etc.) // note: dont claim .astro files with resolveId() — it prevents Vite from transpiling the final JS (import.meta.glob, etc.)
async resolveId(id, from, opts) { async resolveId(id, from, opts) {
@ -89,7 +97,10 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu
if (query.type === 'style' && isBrowserPath(id)) { if (query.type === 'style' && isBrowserPath(id)) {
return relativeToRoot(id); return relativeToRoot(id);
} }
// Convert file paths to ViteID, meaning on Windows it omits the leading slash
if (isFullFilePath(id)) {
return viteID(new URL('file://' + id));
}
return id; return id;
} }
}, },
@ -117,10 +128,7 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu
filename, filename,
moduleId: id, moduleId: id,
source, source,
ssr: Boolean(opts?.ssr), transformStyle: createTransformStyles(styleTransformer, filename, Boolean(opts?.ssr), this),
transformStyleWithVite,
viteDevServer,
pluginContext: this,
}; };
switch (query.type) { switch (query.type) {
@ -216,10 +224,7 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu
filename, filename,
moduleId: id, moduleId: id,
source, source,
ssr: Boolean(opts?.ssr), transformStyle: createTransformStyles(styleTransformer, filename, Boolean(opts?.ssr), this),
transformStyleWithVite,
viteDevServer,
pluginContext: this,
}; };
try { try {
@ -246,18 +251,8 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu
)};export { $$file as file, $$url as url };\n`; )};export { $$file as file, $$url as url };\n`;
// Add HMR handling in dev mode. // Add HMR handling in dev mode.
if (!resolvedConfig.isProduction) { if (!resolvedConfig.isProduction) {
// HACK: extract dependencies from metadata until compiler static extraction handles them
const metadata = transformResult.code.split('$$createMetadata(')[1].split('});\n')[0];
const pattern = /specifier:\s*'([^']*)'/g;
const deps = new Set();
let match;
while ((match = pattern.exec(metadata)?.[1])) {
deps.add(match);
}
let i = 0; let i = 0;
while (i < transformResult.scripts.length) { while (i < transformResult.scripts.length) {
deps.add(`${id}?astro&type=script&index=${i}&lang.ts`);
SUFFIX += `import "${id}?astro&type=script&index=${i}&lang.ts";`; SUFFIX += `import "${id}?astro&type=script&index=${i}&lang.ts";`;
i++; i++;
} }
@ -352,10 +347,7 @@ ${source}
filename: context.file, filename: context.file,
moduleId: context.file, moduleId: context.file,
source: await context.read(), source: await context.read(),
ssr: true, transformStyle: createTransformStyles(styleTransformer, context.file, true, this),
transformStyleWithVite,
viteDevServer,
pluginContext: this,
}; };
const compile = () => cachedCompilation(compileProps); const compile = () => cachedCompilation(compileProps);
return handleHotUpdate.call(this, context, { return handleHotUpdate.call(this, context, {

View file

@ -7,15 +7,16 @@ import { fileURLToPath } from 'url';
import type { Plugin, ViteDevServer } from 'vite'; import type { Plugin, ViteDevServer } from 'vite';
import type { AstroConfig } from '../@types/astro'; import type { AstroConfig } from '../@types/astro';
import { pagesVirtualModuleId } from '../core/app/index.js'; import { pagesVirtualModuleId } from '../core/app/index.js';
import { cachedCompilation, CompileProps } from '../core/compile/index.js';
import { collectErrorMetadata } from '../core/errors.js'; import { collectErrorMetadata } from '../core/errors.js';
import type { LogOptions } from '../core/logger/core.js'; import type { LogOptions } from '../core/logger/core.js';
import { cachedCompilation, CompileProps } from '../vite-plugin-astro/compile.js';
import {
createTransformStyleWithViteFn,
TransformStyleWithVite,
} from '../vite-plugin-astro/styles.js';
import type { PluginMetadata as AstroPluginMetadata } from '../vite-plugin-astro/types'; import type { PluginMetadata as AstroPluginMetadata } from '../vite-plugin-astro/types';
import { getFileInfo } from '../vite-plugin-utils/index.js'; import { getFileInfo } from '../vite-plugin-utils/index.js';
import {
createTransformStyles,
createViteStyleTransformer,
ViteStyleTransformer,
} from '../vite-style-transform/index.js';
interface AstroPluginOptions { interface AstroPluginOptions {
config: AstroConfig; config: AstroConfig;
@ -64,14 +65,17 @@ export default function markdown({ config, logging }: AstroPluginOptions): Plugi
return false; return false;
} }
let transformStyleWithVite: TransformStyleWithVite; let styleTransformer: ViteStyleTransformer;
let viteDevServer: ViteDevServer | undefined; let viteDevServer: ViteDevServer | undefined;
return { return {
name: 'astro:markdown', name: 'astro:markdown',
enforce: 'pre', enforce: 'pre',
configResolved(_resolvedConfig) { configResolved(_resolvedConfig) {
transformStyleWithVite = createTransformStyleWithViteFn(_resolvedConfig); styleTransformer = createViteStyleTransformer(_resolvedConfig);
},
configureServer(server) {
styleTransformer.viteDevServer = server;
}, },
async resolveId(id, importer, options) { async resolveId(id, importer, options) {
// Resolve any .md files with the `?content` cache buster. This should only come from // Resolve any .md files with the `?content` cache buster. This should only come from
@ -208,10 +212,12 @@ ${setup}`.trim();
filename, filename,
moduleId: id, moduleId: id,
source: astroResult, source: astroResult,
ssr: Boolean(opts?.ssr), transformStyle: createTransformStyles(
transformStyleWithVite, styleTransformer,
viteDevServer, filename,
pluginContext: this, Boolean(opts?.ssr),
this
),
}; };
let transformResult = await cachedCompilation(compileProps); let transformResult = await cachedCompilation(compileProps);

View file

@ -0,0 +1,2 @@
export type { ViteStyleTransformer } from './style-transform';
export { createTransformStyles, createViteStyleTransformer } from './style-transform.js';

View file

@ -0,0 +1,54 @@
import type { PluginContext } from 'rollup';
import { fileURLToPath } from 'url';
import type { TransformStyle } from '../core/compile/index';
import { createTransformStyleWithViteFn, TransformStyleWithVite } from './transform-with-vite.js';
import type * as vite from 'vite';
export type ViteStyleTransformer = {
viteDevServer?: vite.ViteDevServer;
transformStyleWithVite: TransformStyleWithVite;
};
export function createViteStyleTransformer(viteConfig: vite.ResolvedConfig): ViteStyleTransformer {
return {
transformStyleWithVite: createTransformStyleWithViteFn(viteConfig),
};
}
function getNormalizedIDForPostCSS(filename: string): string {
try {
const filenameURL = new URL(`file://${filename}`);
return fileURLToPath(filenameURL);
} catch (err) {
// Not a real file, so just use the provided filename as the normalized id
return filename;
}
}
export function createTransformStyles(
viteStyleTransformer: ViteStyleTransformer,
filename: string,
ssr: boolean,
pluginContext: PluginContext
): TransformStyle {
// handleHotUpdate doesn't have `addWatchFile` used by transformStyleWithVite.
// TODO, refactor, why is this happening *here* ?
if (!pluginContext.addWatchFile) {
pluginContext.addWatchFile = () => {};
}
const normalizedID = getNormalizedIDForPostCSS(filename);
return async function (styleSource, lang) {
const result = await viteStyleTransformer.transformStyleWithVite.call(pluginContext, {
id: normalizedID,
source: styleSource,
lang,
ssr,
viteDevServer: viteStyleTransformer.viteDevServer,
});
return result;
};
}

View file

@ -3,6 +3,7 @@ import { load as cheerioLoad } from 'cheerio';
import { loadFixture } from './test-utils.js'; import { loadFixture } from './test-utils.js';
describe('Client only components', () => { describe('Client only components', () => {
/** @type {import('./test-utils').Fixture} */
let fixture; let fixture;
before(async () => { before(async () => {
@ -39,6 +40,12 @@ describe('Client only components', () => {
const $ = cheerioLoad(html); const $ = cheerioLoad(html);
expect($('link[rel=stylesheet]')).to.have.a.lengthOf(1); expect($('link[rel=stylesheet]')).to.have.a.lengthOf(1);
}); });
it('Includes CSS from package components', async () => {
const html = await fixture.readFile('/pkg/index.html');
const $ = cheerioLoad(html);
expect($('link[rel=stylesheet]')).to.have.a.lengthOf(1);
});
}); });
describe('Client only components subpath', () => { describe('Client only components subpath', () => {

View file

@ -7,6 +7,7 @@
"@astrojs/react": "workspace:*", "@astrojs/react": "workspace:*",
"astro": "workspace:*", "astro": "workspace:*",
"react": "^18.1.0", "react": "^18.1.0",
"react-dom": "^18.1.0" "react-dom": "^18.1.0",
"@test/astro-client-only-pkg": "file:./pkg"
} }
} }

View file

@ -0,0 +1,6 @@
<h1>Testing</h1>
<style>
h1 {
background: green;
}
</style>

View file

@ -0,0 +1,4 @@
{
"name": "@test/astro-client-only-pkg",
"main": "index.svelte"
}

View file

@ -0,0 +1,12 @@
---
import IndexSvelte from '@test/astro-client-only-pkg';
---
<html>
<head>
<title>Testing</title>
</head>
<body>
<h1>Testing</h1>
<IndexSvelte client:only="svelte" />
</body>
</html>

View file

@ -0,0 +1,8 @@
{
"name": "@test/non-html-pages",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -0,0 +1,11 @@
// Returns the file body for this non-HTML file.
// The content type is based off of the extension in the filename,
// in this case: about.json.
export async function get() {
return {
body: JSON.stringify({
name: 'Astro',
url: 'https://astro.build/',
}),
};
}

View file

@ -0,0 +1,17 @@
import { promises as fs } from 'node:fs';
import type { APIRoute } from 'astro';
export const get: APIRoute = async function get() {
try {
// Image is in the public domain. Sourced from
// https://en.wikipedia.org/wiki/File:Portrait_placeholder.png
const buffer = await fs.readFile('./test/fixtures/non-html-pages/src/images/placeholder.png');
return {
body: buffer.toString('binary'),
encoding: 'binary',
} as const;
} catch (error: unknown) {
throw new Error(`Something went wrong in placeholder.png route!: ${error as string}`);
}
};

View file

@ -0,0 +1,8 @@
import { defineConfig } from 'astro/config';
import svelte from '@astrojs/svelte';
import vue from '@astrojs/vue';
// https://astro.build/config
export default defineConfig({
integrations: [vue(), svelte()],
});

View file

@ -0,0 +1,10 @@
{
"name": "@test/vue-with-multi-renderer",
"version": "0.0.0",
"private": true,
"dependencies": {
"@astrojs/vue": "workspace:*",
"@astrojs/svelte": "workspace:*",
"astro": "workspace:*"
}
}

View file

@ -0,0 +1,54 @@
<template>
<div :id="id" class="counter">
<button class="decrement" @click="subtract()">-</button>
<pre>{{count}}</pre>
<button class="increment" @click="add()">+</button>
</div>
<div :id="messageId" class="message">
<slot />
</div>
</template>
<script>
import { ref } from 'vue';
export default {
props: {
id: {
type: String,
required: true
},
count: {
type: Number,
default: 0
}
},
setup(props) {
const id = props.id;
const count = ref(props.count);
const messageId = `${id}-message`;
const add = () => (count.value = count.value + 1);
const subtract = () => (count.value = count.value - 1);
return {
count,
id,
messageId,
add,
subtract,
};
},
};
</script>
<style>
.counter {
display: grid;
font-size: 2em;
grid-template-columns: repeat(3, minmax(0, 1fr));
margin-top: 2em;
place-items: center;
}
.message {
text-align: center;
}
</style>

View file

@ -0,0 +1,15 @@
<template>
<div :id="id" class="counter">
<button class="decrement" @click="subtract()">-</button>
<pre>{{count}}</pre>
<button class="increment" @click="add()">+</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const count = ref(0);
const add = () => (count.value = count.value + 1);
const subtract = () => (count.value = count.value - 1);
</script>

View file

@ -0,0 +1,55 @@
---
import Counter from '../components/Counter.vue';
import CounterWithScriptSetup from '../components/CounterWithScriptSetup.vue';
const someProps = {
count: 0,
};
---
<html>
<head>
<!-- Head Stuff -->
</head>
<body>
<Counter id="server-only" {...someProps}>
<h1>Hello, server!</h1>
</Counter>
<Counter id="client-idle" {...someProps} client:idle>
<h1>Hello, client:idle!</h1>
</Counter>
<Counter id="client-load" {...someProps} client:load>
<h1>Hello, client:load!</h1>
</Counter>
<Counter id="client-visible" {...someProps} client:visible>
<h1>Hello, client:visible!</h1>
</Counter>
<Counter id="client-media" {...someProps} client:media="(max-width: 50em)">
<h1>Hello, client:media!</h1>
</Counter>
<CounterWithScriptSetup id="server-only" {...someProps}>
<h1>Hello, server!</h1>
</CounterWithScriptSetup>
<CounterWithScriptSetup id="client-idle" {...someProps} client:idle>
<h1>Hello, client:idle!</h1>
</CounterWithScriptSetup>
<CounterWithScriptSetup id="client-load" {...someProps} client:load>
<h1>Hello, client:load!</h1>
</CounterWithScriptSetup>
<CounterWithScriptSetup id="client-visible" {...someProps} client:visible>
<h1>Hello, client:visible!</h1>
</CounterWithScriptSetup>
<CounterWithScriptSetup id="client-media" {...someProps} client:media="(max-width: 50em)">
<h1>Hello, client:media!</h1>
</CounterWithScriptSetup>
</body>
</html>

View file

@ -0,0 +1,38 @@
import { expect } from 'chai';
import { loadFixture } from './test-utils.js';
describe('Non-HTML Pages', () => {
let fixture;
before(async () => {
fixture = await loadFixture({ root: './fixtures/non-html-pages/' });
await fixture.build();
});
describe('json', () => {
it('should match contents', async () => {
const json = JSON.parse(await fixture.readFile('/about.json'));
expect(json).to.have.property('name', 'Astro');
expect(json).to.have.property('url', 'https://astro.build/');
});
});
describe('png', () => {
it('should not have had its encoding mangled', async () => {
const buffer = await fixture.readFile('/placeholder.png', 'base64');
// Sanity check the first byte
const hex = Buffer.from(buffer, 'base64').toString('hex');
const firstHexByte = hex.slice(0, 2);
// If we accidentally utf8 encode the png, the first byte (in hex) will be 'c2'
expect(firstHexByte).to.not.equal('c2');
// and if correctly encoded in binary, it should be '89'
expect(firstHexByte).to.equal('89');
// Make sure the whole buffer (in base64) matches this snapshot
expect(buffer).to.equal(
'iVBORw0KGgoAAAANSUhEUgAAAGQAAACWCAYAAAAouC1GAAAD10lEQVR4Xu3ZbW4iMRCE4c1RuP+ZEEfZFZHIAgHGH9Xtsv3m94yx6qHaM+HrfD7//cOfTQJfgNhYfG8EEC8PQMw8AAHELQGz/XCGAGKWgNl2aAggZgmYbYeGAGKWgNl2aAggZgmYbYeGAGKWgNl2aAggZgmYbYeGAGKWgNl2aAggZgmYbYeGAGKWgNl2aAggZgmYbYeGAGKWgNl2aAggZgmYbWe6hpxOp6oIL5dL1fWjL54CpBbhXagz4FiDqCCegZxhLEGiIGaAsQPJwrjhuLXFBiQbwrUtFiCjMZzaMhzEBcMFZSiIG4YDyjAQV4zRKENA3DFGoqSDzIIxCgWQgn9eZb6rpILM1o57qyyUNJCZMTLHFyAFI2s5kBXakYWS0hBAymsYDrISRkZLACn/8j5cGfXUFQqyYjuiWwJIY0Out0W0JAxk5XZEtgQQGtKRgOGt6rEV0pAdxlXU2AKks3U0pDPAiNuVKDREIGQNstP5EXGOyBsCSF/lAOnL7/tuRpYgRPUSKhQaIpIBRBSkahlAVEmK1gFEFKRqGUuQHR951e8i0kMdkP6+SUGu29kVxXJkAUJD+hMQrUBDREGqlgFElaRgHRXGdSsc6oAIEjBbgoYAUpfAbu8i1g3Z7V1EiRFyqANSN02er5Y/Zd0+YJexNUVDdmmJGiNsZAHSPrbCRtYOKFM1ZHWQCIzQkbX64Q5I+1iW3xmFkdKQFUcXIPLvePuCkRhpDVmpJcuArIASjZHakNmfujIwAKk4SpYFmXF0ZWEMachsoysTYyjIDE3JxhgO4owyAsMCxBFlFIYNiBPKSAxAnh57R2PYgLj9/j4SJvQXw5L3LjeM+z2PgBkG4gzx/EXKhEkHmQliRFvSQGaFyEZJAVkB4wYTPb7CQVbCyEAJA1kRImN8hYCsjhHZFDnILhhRKICUvL0eXKM86KUgu7Uj4kyRgeyMoRxfEhAw/neld3x1g4Dx+4DpQQFEcKi/WqIVpQuEdrzXTAcB47haLSjNDQHkGOR6RS1KEwgYZRgtj8PVIGDUYdS2BJD6fJvuKB1dVSC0o8ni56YSFED6Mq66WwpCO6qyf3vxEUpxQwAxAgFDg1HyGFzUEECMQMDQYhy15LAhgBiBgBGD8ent/WNDAIkDeYcCSGzmH1d/9U7yFoR25Eg9owCSk3vxmzsgM4AwrnKV7sfWy4YAAkhuAmaf9rEhtCNfC5D8zA8/8Yby6wyhIYfZhVwASEis7Yu+BKEd7YH23glIb4IB919RHs4QGhKQcsWSgFSElXEpIBkpV3zGAwjjqiK5oEsBCQq2Z9l/4WuAC09sfQEAAAAASUVORK5CYII='
);
});
});
});

View file

@ -0,0 +1,67 @@
import { expect } from 'chai';
import { serializeProps } from '../dist/runtime/server/serialize.js';
describe('serialize', () => {
it('serializes a plain value', () => {
const input = { a: 1 };
const output = `{"a":[0,1]}`;
expect(serializeProps(input)).to.equal(output);
});
it('serializes an array', () => {
const input = { a: [0] };
const output = `{"a":[1,"[[0,0]]"]}`;
expect(serializeProps(input)).to.equal(output);
});
it('serializes a regular expression', () => {
const input = { a: /b/ };
const output = `{"a":[2,"b"]}`;
expect(serializeProps(input)).to.equal(output);
});
it('serializes a Date', () => {
const input = { a: new Date(0) };
const output = `{"a":[3,"1970-01-01T00:00:00.000Z"]}`;
expect(serializeProps(input)).to.equal(output);
});
it('serializes a Map', () => {
const input = { a: new Map([[0, 1]]) };
const output = `{"a":[4,"[[1,\\"[[0,0],[0,1]]\\"]]"]}`;
expect(serializeProps(input)).to.equal(output);
});
it('serializes a Set', () => {
const input = { a: new Set([0, 1, 2, 3]) };
const output = `{"a":[5,"[[0,0],[0,1],[0,2],[0,3]]"]}`;
expect(serializeProps(input)).to.equal(output);
});
it('serializes a BigInt', () => {
const input = { a: BigInt('1') };
const output = `{"a":[6,"1"]}`;
expect(serializeProps(input)).to.equal(output);
});
it('serializes a URL', () => {
const input = { a: new URL('https://example.com/') };
const output = `{"a":[7,"https://example.com/"]}`;
expect(serializeProps(input)).to.equal(output);
});
it('cannot serialize a cyclic reference', () => {
const a = {};
a.b = a;
const input = { a };
expect(() => serializeProps(input)).to.throw(/cyclic/);
});
it('cannot serialize a cyclic array', () => {
const input = { foo: ['bar'] };
input.foo.push(input);
expect(() => serializeProps(input)).to.throw(/cyclic/);
});
it('cannot serialize a deep cyclic reference', () => {
const a = { b: {} };
a.b.c = a;
const input = { a };
expect(() => serializeProps(input)).to.throw(/cyclic/);
});
it('can serialize shared references that are not cyclic', () => {
const b = {};
const input = { a: { b, b }, b };
expect(() => serializeProps(input)).not.to.throw();
});
});

View file

@ -146,8 +146,8 @@ export async function loadFixture(inlineConfig) {
const previewServer = await preview(config, { logging, telemetry, ...opts }); const previewServer = await preview(config, { logging, telemetry, ...opts });
return previewServer; return previewServer;
}, },
readFile: (filePath) => readFile: (filePath, encoding) =>
fs.promises.readFile(new URL(filePath.replace(/^\//, ''), config.outDir), 'utf8'), fs.promises.readFile(new URL(filePath.replace(/^\//, ''), config.outDir), encoding ?? 'utf8'),
readdir: (fp) => fs.promises.readdir(new URL(fp.replace(/^\//, ''), config.outDir)), readdir: (fp) => fs.promises.readdir(new URL(fp.replace(/^\//, ''), config.outDir)),
glob: (p) => glob: (p) =>
fastGlob(p, { fastGlob(p, {

View file

@ -0,0 +1,42 @@
import { expect } from 'chai';
import { cachedCompilation } from '../../../dist/core/compile/index.js';
import { AggregateError } from '../../../dist/core/util.js';
describe('astro/src/core/compile', () => {
describe('Invalid CSS', () => {
it('throws an aggregate error with the errors', async () => {
let error;
try {
let r = await cachedCompilation({
config: /** @type {any} */ ({
root: '/',
}),
filename: '/src/pages/index.astro',
moduleId: '/src/pages/index.astro',
source: `
---
---
<style lang="scss">
article:global(:is(h1, h2, h3, h4, h5, h6):hover {
color: purple;
}
</style>
<style lang="scss">
article:is(h1, h2, h3, h4, h5, h6:hover {
color: purple;
}
</style>
`,
transformStyle(source, lang) {
throw new Error('Invalid css');
},
});
} catch (err) {
error = err;
}
expect(error).to.be.an.instanceOf(AggregateError);
expect(error.errors[0].message).to.contain('Invalid css');
});
});
});

View file

@ -0,0 +1,21 @@
import { expect } from 'chai';
import * as cheerio from 'cheerio';
import { loadFixture } from './test-utils.js';
describe('Vue with multi-renderer', () => {
let fixture;
before(async () => {
fixture = await loadFixture({
root: './fixtures/vue-with-multi-renderer/',
});
});
it('builds with another renderer present', async () => {
try {
await fixture.build();
} catch (e) {
expect(e).to.equal(undefined, `Should not throw`);
}
});
});

View file

@ -25,8 +25,6 @@ yarn astro add alpinejs
pnpm astro add alpinejs pnpm astro add alpinejs
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Manual Install ### Manual Install
@ -56,8 +54,6 @@ export default defineConfig({
}); });
``` ```
Finally, restart the dev server.
## Usage ## Usage
Once the integration is installed, you can use [Alpine.js](https://alpinejs.dev/) directives and syntax inside any Astro component. The Alpine.js script is automatically added and enabled on every page of your website. Once the integration is installed, you can use [Alpine.js](https://alpinejs.dev/) directives and syntax inside any Astro component. The Alpine.js script is automatically added and enabled on every page of your website.

View file

@ -1,5 +1,17 @@
# @astrojs/image # @astrojs/image
## 0.7.0
### Minor Changes
- [#4438](https://github.com/withastro/astro/pull/4438) [`1e5d8ba9a`](https://github.com/withastro/astro/commit/1e5d8ba9af4eb017382263653216e5247d96ab79) Thanks [@obennaci](https://github.com/obennaci)! - Support additional Sharp resize options
## 0.6.1
### Patch Changes
- [#4678](https://github.com/withastro/astro/pull/4678) [`4c05c65a3`](https://github.com/withastro/astro/commit/4c05c65a3df5bae935afebc8a15ff52d5b912d8b) Thanks [@tony-sull](https://github.com/tony-sull)! - Updates the integration to build all optimized images to `dist/assets` during SSG builds
## 0.6.0 ## 0.6.0
### Minor Changes ### Minor Changes

View file

@ -36,8 +36,6 @@ yarn astro add image
pnpm astro add image pnpm astro add image
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Manual Install ### Manual Install
@ -58,7 +56,6 @@ export default {
integrations: [image()], integrations: [image()],
} }
``` ```
Then, restart the dev server.
### Update `env.d.ts` ### Update `env.d.ts`
@ -208,7 +205,27 @@ The parameter can be a [named HTML color](https://www.w3schools.com/tags/ref_col
color representation with 3 or 6 hexadecimal characters in the form `#123[abc]`, or an RGB definition in the form color representation with 3 or 6 hexadecimal characters in the form `#123[abc]`, or an RGB definition in the form
`rgb(100,100,100)`. `rgb(100,100,100)`.
### `<Picture /`> #### fit
<p>
**Type:** `'cover' | 'contain' | 'fill' | 'inside' | 'outside'` <br>
**Default:** `'cover'`
</p>
How the image should be resized to fit both `height` and `width`.
#### position
<p>
**Type:** `'top' | 'right top' | 'right' | 'right bottom' | 'bottom' | 'left bottom' | 'left' | 'left top' | 'north' | 'northeast' | 'east' | 'southeast' | 'south' | 'southwest' | 'west' | 'northwest' | 'center' | 'centre' | 'cover' | 'entropy' | 'attention'` <br>
**Default:** `'centre'`
</p>
Position of the crop when fit is `cover` or `contain`.
### `<Picture />`
#### src #### src
@ -307,6 +324,28 @@ The parameter can be a [named HTML color](https://www.w3schools.com/tags/ref_col
color representation with 3 or 6 hexadecimal characters in the form `#123[abc]`, or an RGB definition in the form color representation with 3 or 6 hexadecimal characters in the form `#123[abc]`, or an RGB definition in the form
`rgb(100,100,100)`. `rgb(100,100,100)`.
#### fit
<p>
**Type:** `'cover' | 'contain' | 'fill' | 'inside' | 'outside'` <br>
**Default:** `'cover'`
</p>
How the image should be resized to fit both `height` and `width`.
#### position
<p>
**Type:** `'top' | 'right top' | 'right' | 'right bottom' | 'bottom' | 'left bottom' | 'left' | 'left top' |
'north' | 'northeast' | 'east' | 'southeast' | 'south' | 'southwest' | 'west' | 'northwest' |
'center' | 'centre' | 'cover' | 'entropy' | 'attention'` <br>
**Default:** `'centre'`
</p>
Position of the crop when fit is `cover` or `contain`.
### `getImage` ### `getImage`
This is the helper function used by the `<Image />` component to build `<img />` attributes for the transformed image. This helper can be used directly for more complex use cases that aren't currently supported by the `<Image />` component. This is the helper function used by the `<Image />` component to build `<img />` attributes for the transformed image. This helper can be used directly for more complex use cases that aren't currently supported by the `<Image />` component.
@ -469,7 +508,7 @@ const imageUrl = 'https://www.google.com/images/branding/googlelogo/2x/googlelog
``` ```
## Troubleshooting ## Troubleshooting
- If your installation doesn't seem to be working, make sure to restart the dev server. - If your installation doesn't seem to be working, try restarting the dev server.
- If you edit and save a file and don't see your site update accordingly, try refreshing the page. - If you edit and save a file and don't see your site update accordingly, try refreshing the page.
- If refreshing the page doesn't update your preview, or if a new installation doesn't seem to be working, then restart the dev server. - If refreshing the page doesn't update your preview, or if a new installation doesn't seem to be working, then restart the dev server.

View file

@ -38,7 +38,9 @@ const {
sizes, sizes,
widths, widths,
aspectRatio, aspectRatio,
fit,
background, background,
position,
formats = ['avif', 'webp'], formats = ['avif', 'webp'],
loading = 'lazy', loading = 'lazy',
decoding = 'async', decoding = 'async',
@ -49,7 +51,15 @@ if (alt === undefined || alt === null) {
warnForMissingAlt(); warnForMissingAlt();
} }
const { image, sources } = await getPicture({ src, widths, formats, aspectRatio, background }); const { image, sources } = await getPicture({
src,
widths,
formats,
aspectRatio,
fit,
background,
position,
});
--- ---
<picture {...attrs}> <picture {...attrs}>

View file

@ -1,7 +1,7 @@
{ {
"name": "@astrojs/image", "name": "@astrojs/image",
"description": "Load and transform images in your Astro site.", "description": "Load and transform images in your Astro site.",
"version": "0.6.0", "version": "0.7.0",
"type": "module", "type": "module",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
"author": "withastro", "author": "withastro",

View file

@ -10,7 +10,9 @@ export interface GetPictureParams {
widths: number[]; widths: number[];
formats: OutputFormat[]; formats: OutputFormat[];
aspectRatio?: TransformOptions['aspectRatio']; aspectRatio?: TransformOptions['aspectRatio'];
fit?: TransformOptions['fit'];
background?: TransformOptions['background']; background?: TransformOptions['background'];
position?: TransformOptions['position'];
} }
export interface GetPictureResult { export interface GetPictureResult {
@ -41,7 +43,7 @@ async function resolveFormats({ src, formats }: GetPictureParams) {
} }
export async function getPicture(params: GetPictureParams): Promise<GetPictureResult> { export async function getPicture(params: GetPictureParams): Promise<GetPictureResult> {
const { src, widths } = params; const { src, widths, fit, position, background } = params;
if (!src) { if (!src) {
throw new Error('[@astrojs/image] `src` is required'); throw new Error('[@astrojs/image] `src` is required');
@ -64,8 +66,10 @@ export async function getPicture(params: GetPictureParams): Promise<GetPictureRe
src, src,
format, format,
width, width,
fit,
position,
background,
height: Math.round(width / aspectRatio!), height: Math.round(width / aspectRatio!),
background: params.background,
}); });
return `${img.src} ${width}w`; return `${img.src} ${width}w`;
}) })
@ -84,8 +88,10 @@ export async function getPicture(params: GetPictureParams): Promise<GetPictureRe
src, src,
width: Math.max(...widths), width: Math.max(...widths),
aspectRatio, aspectRatio,
fit,
position,
background,
format: allFormats[allFormats.length - 1], format: allFormats[allFormats.length - 1],
background: params.background,
}); });
const sources = await Promise.all(allFormats.map((format) => getSource(format))); const sources = await Promise.all(allFormats.map((format) => getSource(format)));

View file

@ -21,6 +21,31 @@ export type ColorDefinition =
| `rgb(${number}, ${number}, ${number})` | `rgb(${number}, ${number}, ${number})`
| `rgb(${number},${number},${number})`; | `rgb(${number},${number},${number})`;
export type CropFit = 'cover' | 'contain' | 'fill' | 'inside' | 'outside';
export type CropPosition =
| 'top'
| 'right top'
| 'right'
| 'right bottom'
| 'bottom'
| 'left bottom'
| 'left'
| 'left top'
| 'north'
| 'northeast'
| 'east'
| 'southeast'
| 'south'
| 'southwest'
| 'west'
| 'northwest'
| 'center'
| 'centre'
| 'cover'
| 'entropy'
| 'attention';
export function isOutputFormat(value: string): value is OutputFormat { export function isOutputFormat(value: string): value is OutputFormat {
return ['avif', 'jpeg', 'jpg', 'png', 'webp'].includes(value); return ['avif', 'jpeg', 'jpg', 'png', 'webp'].includes(value);
} }
@ -105,6 +130,18 @@ export interface TransformOptions {
* @example "rgb(255, 255, 255)" - an rgb color * @example "rgb(255, 255, 255)" - an rgb color
*/ */
background?: ColorDefinition; background?: ColorDefinition;
/**
* How the image should be resized to fit both `height` and `width`.
*
* @default 'cover'
*/
fit?: CropFit;
/**
* Position of the crop when fit is `cover` or `contain`.
*
* @default 'centre'
*/
position?: CropPosition;
} }
export interface HostedImageService<T extends TransformOptions = TransformOptions> { export interface HostedImageService<T extends TransformOptions = TransformOptions> {
@ -191,10 +228,18 @@ export abstract class BaseSSRService implements SSRImageService {
searchParams.append('ar', transform.aspectRatio.toString()); searchParams.append('ar', transform.aspectRatio.toString());
} }
if (transform.fit) {
searchParams.append('fit', transform.fit);
}
if (transform.background) { if (transform.background) {
searchParams.append('bg', transform.background); searchParams.append('bg', transform.background);
} }
if (transform.position) {
searchParams.append('p', encodeURI(transform.position));
}
searchParams.append('href', transform.src); searchParams.append('href', transform.src);
return { searchParams }; return { searchParams };
@ -236,6 +281,14 @@ export abstract class BaseSSRService implements SSRImageService {
} }
} }
if (searchParams.has('fit')) {
transform.fit = searchParams.get('fit') as typeof transform.fit;
}
if (searchParams.has('p')) {
transform.position = decodeURI(searchParams.get('p')!) as typeof transform.position;
}
if (searchParams.has('bg')) { if (searchParams.has('bg')) {
transform.background = searchParams.get('bg') as ColorDefinition; transform.background = searchParams.get('bg') as ColorDefinition;
} }

View file

@ -13,7 +13,14 @@ class SharpService extends BaseSSRService {
if (transform.width || transform.height) { if (transform.width || transform.height) {
const width = transform.width && Math.round(transform.width); const width = transform.width && Math.round(transform.width);
const height = transform.height && Math.round(transform.height); const height = transform.height && Math.round(transform.height);
sharpImage.resize(width, height);
sharpImage.resize({
width,
height,
fit: transform.fit,
position: transform.position,
background: transform.background,
});
} }
// remove alpha channel and replace with background color if requested // remove alpha channel and replace with background color if requested

View file

@ -1,7 +1,7 @@
import { expect } from 'chai'; import { expect } from 'chai';
import sharp from '../dist/loaders/sharp.js'; import sharp from '../dist/loaders/sharp.js';
describe('Sharp service', () => { describe.only('Sharp service', () => {
describe('serializeTransform', () => { describe('serializeTransform', () => {
const src = '/assets/image.png'; const src = '/assets/image.png';
@ -15,6 +15,8 @@ describe('Sharp service', () => {
['aspect ratio string', { src, aspectRatio: '16:9' }], ['aspect ratio string', { src, aspectRatio: '16:9' }],
['aspect ratio float', { src, aspectRatio: 1.7 }], ['aspect ratio float', { src, aspectRatio: 1.7 }],
['background color', { src, format: 'jpeg', background: '#333333' }], ['background color', { src, format: 'jpeg', background: '#333333' }],
['crop fit', { src, fit: 'cover' }],
['crop position', { src, position: 'center' }],
].forEach(([description, props]) => { ].forEach(([description, props]) => {
it(description, async () => { it(description, async () => {
const { searchParams } = await sharp.serializeTransform(props); const { searchParams } = await sharp.serializeTransform(props);
@ -32,6 +34,8 @@ describe('Sharp service', () => {
verifyProp(props.width, 'w'); verifyProp(props.width, 'w');
verifyProp(props.height, 'h'); verifyProp(props.height, 'h');
verifyProp(props.aspectRatio, 'ar'); verifyProp(props.aspectRatio, 'ar');
verifyProp(props.fit, 'fit');
verifyProp(props.position, 'p');
verifyProp(props.background, 'bg'); verifyProp(props.background, 'bg');
}); });
}); });
@ -55,6 +59,8 @@ describe('Sharp service', () => {
`f=jpeg&bg=%23333333&href=${href}`, `f=jpeg&bg=%23333333&href=${href}`,
{ src, format: 'jpeg', background: '#333333' }, { src, format: 'jpeg', background: '#333333' },
], ],
['crop fit', `fit=contain&href=${href}`, { src, fit: 'contain' }],
['crop position', `p=right%20top&href=${href}`, { src, position: 'right top' }],
].forEach(([description, params, expected]) => { ].forEach(([description, params, expected]) => {
it(description, async () => { it(description, async () => {
const searchParams = new URLSearchParams(params); const searchParams = new URLSearchParams(params);

View file

@ -23,8 +23,6 @@ yarn astro add lit
pnpm astro add lit pnpm astro add lit
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Install dependencies manually ### Install dependencies manually

View file

@ -33,8 +33,6 @@ yarn astro add mdx
pnpm astro add mdx pnpm astro add mdx
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Manual Install ### Manual Install
@ -61,6 +59,16 @@ export default defineConfig({
Finally, restart the dev server. Finally, restart the dev server.
### Editor Integration
[VS Code](https://code.visualstudio.com/) supports Markdown by default. However, for MDX editor support, you may wish to add the following setting in your VSCode config. This ensures authoring MDX files provides a Markdown-like editor experience.
```json title=".vscode/settings.json"
"files.associations": {
"*.mdx": "markdown"
}
```
## Usage ## Usage
You can [add MDX pages to your project](https://docs.astro.build/en/guides/markdown-content/#markdown-and-mdx-pages) by adding `.mdx` files within your `src/pages/` directory. You can [add MDX pages to your project](https://docs.astro.build/en/guides/markdown-content/#markdown-and-mdx-pages) by adding `.mdx` files within your `src/pages/` directory.

View file

@ -39,7 +39,7 @@ If you prefer to install the adapter manually instead, complete the following tw
```js title="astro.config.mjs" ins={2, 5-6} ```js title="astro.config.mjs" ins={2, 5-6}
import { defineConfig } from 'astro/config'; import { defineConfig } from 'astro/config';
import netlify from '@astrojs/node'; import node from '@astrojs/node';
export default defineConfig({ export default defineConfig({
output: 'server', output: 'server',

View file

@ -35,8 +35,6 @@ yarn astro add partytown
pnpm astro add partytown pnpm astro add partytown
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Manual Install ### Manual Install
@ -59,7 +57,6 @@ export default defineConfig({
}) })
``` ```
Then, restart the dev server.
## Usage ## Usage

View file

@ -35,8 +35,6 @@ yarn astro add preact
pnpm astro add preact pnpm astro add preact
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Manual Install ### Manual Install
@ -67,8 +65,6 @@ export default defineConfig({
}); });
``` ```
Finally, restart the dev server.
## Usage ## Usage
To use your first Preact component in Astro, head to our [UI framework documentation][astro-ui-frameworks]. You'll explore: To use your first Preact component in Astro, head to our [UI framework documentation][astro-ui-frameworks]. You'll explore:

View file

@ -29,8 +29,6 @@ yarn astro add prefetch
pnpm astro add prefetch pnpm astro add prefetch
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Manual Install ### Manual Install
@ -52,7 +50,6 @@ export default {
} }
``` ```
Then, restart the dev server.
## Usage ## Usage
@ -94,7 +91,7 @@ export default {
``` ```
## Troubleshooting ## Troubleshooting
- If your installation doesn't seem to be working, make sure to restart the dev server. - If your installation doesn't seem to be working, try restarting the dev server.
- If a link doesn't seem to be prefetching, make sure that the link is pointing to a page on the same domain and matches the integration's `selector` option. - If a link doesn't seem to be prefetching, make sure that the link is pointing to a page on the same domain and matches the integration's `selector` option.
For help, check out the `#support-threads` channel on [Discord](https://astro.build/chat). Our friendly Support Squad members are here to help! For help, check out the `#support-threads` channel on [Discord](https://astro.build/chat). Our friendly Support Squad members are here to help!

View file

@ -1,5 +1,13 @@
# @astrojs/react # @astrojs/react
## 1.1.2
### Patch Changes
- [#4679](https://github.com/withastro/astro/pull/4679) [`5986517b4`](https://github.com/withastro/astro/commit/5986517b4f29af90fcfe333d4bb69ac09d4f8778) Thanks [@matthewp](https://github.com/matthewp)! - Prevent decoder from leaking
- [#4667](https://github.com/withastro/astro/pull/4667) [`9290b2414`](https://github.com/withastro/astro/commit/9290b24143d753edd3daf25945990c25a58e5bde) Thanks [@Holben888](https://github.com/Holben888)! - Fix framework components on Vercel Edge
## 1.1.1 ## 1.1.1
### Patch Changes ### Patch Changes

View file

@ -23,8 +23,6 @@ yarn astro add react
pnpm astro add react pnpm astro add react
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Install dependencies manually ### Install dependencies manually

View file

@ -1,7 +1,7 @@
{ {
"name": "@astrojs/react", "name": "@astrojs/react",
"description": "Use React components within Astro", "description": "Use React components within Astro",
"version": "1.1.1", "version": "1.1.2",
"type": "module", "type": "module",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
"author": "withastro", "author": "withastro",

View file

@ -35,8 +35,6 @@ yarn astro add sitemap
pnpm astro add sitemap pnpm astro add sitemap
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Manual Install ### Manual Install
@ -59,7 +57,6 @@ export default defineConfig({
}) })
``` ```
Then, restart the dev server.
## Usage ## Usage

View file

@ -23,8 +23,6 @@ yarn astro add solid
pnpm astro add solid pnpm astro add solid
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Install dependencies manually ### Install dependencies manually

View file

@ -23,8 +23,6 @@ yarn astro add svelte
pnpm astro add svelte pnpm astro add svelte
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Install dependencies manually ### Install dependencies manually

View file

@ -38,8 +38,6 @@ yarn astro add tailwind
pnpm astro add tailwind pnpm astro add tailwind
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Manual Install ### Manual Install
@ -61,7 +59,6 @@ export default {
} }
``` ```
Then, restart the dev server.
## Usage ## Usage
@ -154,7 +151,7 @@ module.exports = {
- [Browse Astro Tailwind projects on GitHub](https://github.com/search?q=%22%40astrojs%2Ftailwind%22+filename%3Apackage.json&type=Code) for more examples! - [Browse Astro Tailwind projects on GitHub](https://github.com/search?q=%22%40astrojs%2Ftailwind%22+filename%3Apackage.json&type=Code) for more examples!
## Troubleshooting ## Troubleshooting
- If your installation doesn't seem to be working, make sure to restart the dev server. - If your installation doesn't seem to be working, try restarting the dev server.
- If you edit and save a file and don't see your site update accordingly, try refreshing the page. - If you edit and save a file and don't see your site update accordingly, try refreshing the page.
- If refreshing the page doesn't update your preview, or if a new installation doesn't seem to be working, then restart the dev server. - If refreshing the page doesn't update your preview, or if a new installation doesn't seem to be working, then restart the dev server.

View file

@ -33,8 +33,6 @@ yarn astro add turbolinks
pnpm astro add turbolinks pnpm astro add turbolinks
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Install dependencies manually ### Install dependencies manually

View file

@ -23,8 +23,6 @@ yarn astro add vue
pnpm astro add vue pnpm astro add vue
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Install dependencies manually ### Install dependencies manually

View file

@ -3,7 +3,7 @@ import { renderToString } from 'vue/server-renderer';
import StaticHtml from './static-html.js'; import StaticHtml from './static-html.js';
function check(Component) { function check(Component) {
return !!Component['ssrRender']; return !!Component['ssrRender'] || !!Component['__ssrInlineRender'];
} }
async function renderToStaticMarkup(Component, props, slotted) { async function renderToStaticMarkup(Component, props, slotted) {

View file

@ -56,7 +56,7 @@ importers:
examples/basics: examples/basics:
specifiers: specifiers:
astro: ^1.1.7 astro: ^1.2.1
dependencies: dependencies:
astro: link:../../packages/astro astro: link:../../packages/astro
@ -65,7 +65,7 @@ importers:
'@astrojs/mdx': ^0.11.1 '@astrojs/mdx': ^0.11.1
'@astrojs/rss': ^1.0.0 '@astrojs/rss': ^1.0.0
'@astrojs/sitemap': ^1.0.0 '@astrojs/sitemap': ^1.0.0
astro: ^1.1.7 astro: ^1.2.1
dependencies: dependencies:
'@astrojs/mdx': link:../../packages/integrations/mdx '@astrojs/mdx': link:../../packages/integrations/mdx
'@astrojs/rss': link:../../packages/astro-rss '@astrojs/rss': link:../../packages/astro-rss
@ -74,7 +74,7 @@ importers:
examples/component: examples/component:
specifiers: specifiers:
astro: ^1.1.7 astro: ^1.2.1
devDependencies: devDependencies:
astro: link:../../packages/astro astro: link:../../packages/astro
@ -82,13 +82,13 @@ importers:
specifiers: specifiers:
'@algolia/client-search': ^4.13.1 '@algolia/client-search': ^4.13.1
'@astrojs/preact': ^1.1.0 '@astrojs/preact': ^1.1.0
'@astrojs/react': ^1.1.0 '@astrojs/react': ^1.1.2
'@docsearch/css': ^3.1.0 '@docsearch/css': ^3.1.0
'@docsearch/react': ^3.1.0 '@docsearch/react': ^3.1.0
'@types/node': ^18.0.0 '@types/node': ^18.0.0
'@types/react': ^17.0.45 '@types/react': ^17.0.45
'@types/react-dom': ^18.0.0 '@types/react-dom': ^18.0.0
astro: ^1.1.7 astro: ^1.2.1
preact: ^10.7.3 preact: ^10.7.3
react: ^18.1.0 react: ^18.1.0
react-dom: ^18.1.0 react-dom: ^18.1.0
@ -111,7 +111,7 @@ importers:
'@astrojs/alpinejs': ^0.1.2 '@astrojs/alpinejs': ^0.1.2
'@types/alpinejs': ^3.7.0 '@types/alpinejs': ^3.7.0
alpinejs: ^3.10.2 alpinejs: ^3.10.2
astro: ^1.1.7 astro: ^1.2.1
dependencies: dependencies:
'@astrojs/alpinejs': link:../../packages/integrations/alpinejs '@astrojs/alpinejs': link:../../packages/integrations/alpinejs
'@types/alpinejs': 3.7.0 '@types/alpinejs': 3.7.0
@ -122,7 +122,7 @@ importers:
specifiers: specifiers:
'@astrojs/lit': ^1.0.0 '@astrojs/lit': ^1.0.0
'@webcomponents/template-shadowroot': ^0.1.0 '@webcomponents/template-shadowroot': ^0.1.0
astro: ^1.1.7 astro: ^1.2.1
lit: ^2.2.5 lit: ^2.2.5
dependencies: dependencies:
'@astrojs/lit': link:../../packages/integrations/lit '@astrojs/lit': link:../../packages/integrations/lit
@ -133,11 +133,11 @@ importers:
examples/framework-multiple: examples/framework-multiple:
specifiers: specifiers:
'@astrojs/preact': ^1.1.0 '@astrojs/preact': ^1.1.0
'@astrojs/react': ^1.1.0 '@astrojs/react': ^1.1.2
'@astrojs/solid-js': ^1.1.0 '@astrojs/solid-js': ^1.1.0
'@astrojs/svelte': ^1.0.0 '@astrojs/svelte': ^1.0.0
'@astrojs/vue': ^1.0.1 '@astrojs/vue': ^1.0.1
astro: ^1.1.7 astro: ^1.2.1
preact: ^10.7.3 preact: ^10.7.3
react: ^18.1.0 react: ^18.1.0
react-dom: ^18.1.0 react-dom: ^18.1.0
@ -155,13 +155,13 @@ importers:
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0_react@18.2.0 react-dom: 18.2.0_react@18.2.0
solid-js: 1.5.4 solid-js: 1.5.4
svelte: 3.50.0 svelte: 3.50.1
vue: 3.2.39 vue: 3.2.39
examples/framework-preact: examples/framework-preact:
specifiers: specifiers:
'@astrojs/preact': ^1.1.0 '@astrojs/preact': ^1.1.0
astro: ^1.1.7 astro: ^1.2.1
preact: ^10.7.3 preact: ^10.7.3
dependencies: dependencies:
'@astrojs/preact': link:../../packages/integrations/preact '@astrojs/preact': link:../../packages/integrations/preact
@ -170,10 +170,10 @@ importers:
examples/framework-react: examples/framework-react:
specifiers: specifiers:
'@astrojs/react': ^1.1.0 '@astrojs/react': ^1.1.2
'@types/react': ^18.0.10 '@types/react': ^18.0.10
'@types/react-dom': ^18.0.5 '@types/react-dom': ^18.0.5
astro: ^1.1.7 astro: ^1.2.1
react: ^18.1.0 react: ^18.1.0
react-dom: ^18.1.0 react-dom: ^18.1.0
dependencies: dependencies:
@ -187,7 +187,7 @@ importers:
examples/framework-solid: examples/framework-solid:
specifiers: specifiers:
'@astrojs/solid-js': ^1.1.0 '@astrojs/solid-js': ^1.1.0
astro: ^1.1.7 astro: ^1.2.1
solid-js: ^1.4.3 solid-js: ^1.4.3
dependencies: dependencies:
'@astrojs/solid-js': link:../../packages/integrations/solid '@astrojs/solid-js': link:../../packages/integrations/solid
@ -197,17 +197,17 @@ importers:
examples/framework-svelte: examples/framework-svelte:
specifiers: specifiers:
'@astrojs/svelte': ^1.0.0 '@astrojs/svelte': ^1.0.0
astro: ^1.1.7 astro: ^1.2.1
svelte: ^3.48.0 svelte: ^3.48.0
dependencies: dependencies:
'@astrojs/svelte': link:../../packages/integrations/svelte '@astrojs/svelte': link:../../packages/integrations/svelte
astro: link:../../packages/astro astro: link:../../packages/astro
svelte: 3.50.0 svelte: 3.50.1
examples/framework-vue: examples/framework-vue:
specifiers: specifiers:
'@astrojs/vue': ^1.0.1 '@astrojs/vue': ^1.0.1
astro: ^1.1.7 astro: ^1.2.1
vue: ^3.2.37 vue: ^3.2.37
dependencies: dependencies:
'@astrojs/vue': link:../../packages/integrations/vue '@astrojs/vue': link:../../packages/integrations/vue
@ -216,19 +216,19 @@ importers:
examples/minimal: examples/minimal:
specifiers: specifiers:
astro: ^1.1.7 astro: ^1.2.1
dependencies: dependencies:
astro: link:../../packages/astro astro: link:../../packages/astro
examples/non-html-pages: examples/non-html-pages:
specifiers: specifiers:
astro: ^1.1.7 astro: ^1.2.1
dependencies: dependencies:
astro: link:../../packages/astro astro: link:../../packages/astro
examples/portfolio: examples/portfolio:
specifiers: specifiers:
astro: ^1.1.7 astro: ^1.2.1
dependencies: dependencies:
astro: link:../../packages/astro astro: link:../../packages/astro
@ -236,7 +236,7 @@ importers:
specifiers: specifiers:
'@astrojs/node': ^1.0.1 '@astrojs/node': ^1.0.1
'@astrojs/svelte': ^1.0.0 '@astrojs/svelte': ^1.0.0
astro: ^1.1.7 astro: ^1.2.1
concurrently: ^7.2.1 concurrently: ^7.2.1
lightcookie: ^1.0.25 lightcookie: ^1.0.25
svelte: ^3.48.0 svelte: ^3.48.0
@ -248,14 +248,14 @@ importers:
astro: link:../../packages/astro astro: link:../../packages/astro
concurrently: 7.4.0 concurrently: 7.4.0
lightcookie: 1.0.25 lightcookie: 1.0.25
svelte: 3.50.0 svelte: 3.50.1
unocss: 0.15.6 unocss: 0.15.6
vite-imagetools: 4.0.9 vite-imagetools: 4.0.9
examples/with-markdown-plugins: examples/with-markdown-plugins:
specifiers: specifiers:
'@astrojs/markdown-remark': ^1.1.0 '@astrojs/markdown-remark': ^1.1.0
astro: ^1.1.7 astro: ^1.2.1
hast-util-select: 5.0.1 hast-util-select: 5.0.1
rehype-autolink-headings: ^6.1.1 rehype-autolink-headings: ^6.1.1
rehype-slug: ^5.0.1 rehype-slug: ^5.0.1
@ -272,7 +272,7 @@ importers:
examples/with-markdown-shiki: examples/with-markdown-shiki:
specifiers: specifiers:
astro: ^1.1.7 astro: ^1.2.1
dependencies: dependencies:
astro: link:../../packages/astro astro: link:../../packages/astro
@ -280,7 +280,7 @@ importers:
specifiers: specifiers:
'@astrojs/mdx': ^0.11.1 '@astrojs/mdx': ^0.11.1
'@astrojs/preact': ^1.1.0 '@astrojs/preact': ^1.1.0
astro: ^1.1.7 astro: ^1.2.1
preact: ^10.6.5 preact: ^10.6.5
dependencies: dependencies:
'@astrojs/mdx': link:../../packages/integrations/mdx '@astrojs/mdx': link:../../packages/integrations/mdx
@ -292,7 +292,7 @@ importers:
specifiers: specifiers:
'@astrojs/preact': ^1.1.0 '@astrojs/preact': ^1.1.0
'@nanostores/preact': ^0.1.3 '@nanostores/preact': ^0.1.3
astro: ^1.1.7 astro: ^1.2.1
nanostores: ^0.5.12 nanostores: ^0.5.12
preact: ^10.7.3 preact: ^10.7.3
dependencies: dependencies:
@ -305,7 +305,7 @@ importers:
examples/with-tailwindcss: examples/with-tailwindcss:
specifiers: specifiers:
'@astrojs/tailwind': ^1.0.0 '@astrojs/tailwind': ^1.0.0
astro: ^1.1.7 astro: ^1.2.1
autoprefixer: ^10.4.7 autoprefixer: ^10.4.7
canvas-confetti: ^1.5.1 canvas-confetti: ^1.5.1
postcss: ^8.4.14 postcss: ^8.4.14
@ -320,7 +320,7 @@ importers:
examples/with-vite-plugin-pwa: examples/with-vite-plugin-pwa:
specifiers: specifiers:
astro: ^1.1.7 astro: ^1.2.1
vite-plugin-pwa: 0.11.11 vite-plugin-pwa: 0.11.11
workbox-window: ^6.5.3 workbox-window: ^6.5.3
dependencies: dependencies:
@ -330,7 +330,7 @@ importers:
examples/with-vitest: examples/with-vitest:
specifiers: specifiers:
astro: ^1.1.7 astro: ^1.2.1
vitest: ^0.20.3 vitest: ^0.20.3
dependencies: dependencies:
astro: link:../../packages/astro astro: link:../../packages/astro
@ -338,7 +338,7 @@ importers:
packages/astro: packages/astro:
specifiers: specifiers:
'@astrojs/compiler': ^0.23.5 '@astrojs/compiler': ^0.24.0
'@astrojs/language-server': ^0.23.0 '@astrojs/language-server': ^0.23.0
'@astrojs/markdown-remark': ^1.1.1 '@astrojs/markdown-remark': ^1.1.1
'@astrojs/telemetry': ^1.0.0 '@astrojs/telemetry': ^1.0.0
@ -350,7 +350,7 @@ importers:
'@babel/traverse': ^7.18.2 '@babel/traverse': ^7.18.2
'@babel/types': ^7.18.4 '@babel/types': ^7.18.4
'@playwright/test': ^1.22.2 '@playwright/test': ^1.22.2
'@proload/core': ^0.3.2 '@proload/core': ^0.3.3
'@proload/plugin-tsm': ^0.2.1 '@proload/plugin-tsm': ^0.2.1
'@types/babel__core': ^7.1.19 '@types/babel__core': ^7.1.19
'@types/babel__generator': ^7.6.4 '@types/babel__generator': ^7.6.4
@ -421,7 +421,7 @@ importers:
yargs-parser: ^21.0.1 yargs-parser: ^21.0.1
zod: ^3.17.3 zod: ^3.17.3
dependencies: dependencies:
'@astrojs/compiler': 0.23.5 '@astrojs/compiler': 0.24.0
'@astrojs/language-server': 0.23.3 '@astrojs/language-server': 0.23.3
'@astrojs/markdown-remark': link:../markdown/remark '@astrojs/markdown-remark': link:../markdown/remark
'@astrojs/telemetry': link:../telemetry '@astrojs/telemetry': link:../telemetry
@ -434,6 +434,9 @@ importers:
'@babel/types': 7.19.0 '@babel/types': 7.19.0
'@proload/core': 0.3.3 '@proload/core': 0.3.3
'@proload/plugin-tsm': 0.2.1_@proload+core@0.3.3 '@proload/plugin-tsm': 0.2.1_@proload+core@0.3.3
'@types/babel__core': 7.1.19
'@types/html-escaper': 3.0.0
'@types/yargs-parser': 21.0.0
boxen: 6.2.1 boxen: 6.2.1
ci-info: 3.3.2 ci-info: 3.3.2
common-ancestor-path: 1.0.1 common-ancestor-path: 1.0.1
@ -443,7 +446,7 @@ importers:
es-module-lexer: 0.10.5 es-module-lexer: 0.10.5
esbuild: 0.14.54 esbuild: 0.14.54
execa: 6.1.0 execa: 6.1.0
fast-glob: 3.2.11 fast-glob: 3.2.12
github-slugger: 1.4.0 github-slugger: 1.4.0
gray-matter: 4.0.3 gray-matter: 4.0.3
html-entities: 2.3.3 html-entities: 2.3.3
@ -471,13 +474,12 @@ importers:
supports-esm: 1.0.0 supports-esm: 1.0.0
tsconfig-resolver: 3.0.1 tsconfig-resolver: 3.0.1
unist-util-visit: 4.1.1 unist-util-visit: 4.1.1
vfile: 5.3.4 vfile: 5.3.5
vite: 3.0.9_sass@1.54.9 vite: 3.0.9_sass@1.54.9
yargs-parser: 21.1.1 yargs-parser: 21.1.1
zod: 3.19.0 zod: 3.19.0
devDependencies: devDependencies:
'@playwright/test': 1.25.2 '@playwright/test': 1.25.2
'@types/babel__core': 7.1.19
'@types/babel__generator': 7.6.4 '@types/babel__generator': 7.6.4
'@types/babel__traverse': 7.18.1 '@types/babel__traverse': 7.18.1
'@types/chai': 4.3.3 '@types/chai': 4.3.3
@ -486,7 +488,6 @@ importers:
'@types/debug': 4.1.7 '@types/debug': 4.1.7
'@types/diff': 5.0.2 '@types/diff': 5.0.2
'@types/estree': 0.0.51 '@types/estree': 0.0.51
'@types/html-escaper': 3.0.0
'@types/mime': 2.0.3 '@types/mime': 2.0.3
'@types/mocha': 9.1.1 '@types/mocha': 9.1.1
'@types/parse5': 6.0.3 '@types/parse5': 6.0.3
@ -496,7 +497,6 @@ importers:
'@types/rimraf': 3.0.2 '@types/rimraf': 3.0.2
'@types/send': 0.17.1 '@types/send': 0.17.1
'@types/unist': 2.0.6 '@types/unist': 2.0.6
'@types/yargs-parser': 21.0.0
ast-types: 0.14.2 ast-types: 0.14.2
astro-scripts: link:../../scripts astro-scripts: link:../../scripts
chai: 4.3.6 chai: 4.3.6
@ -564,7 +564,7 @@ importers:
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0_react@18.2.0 react-dom: 18.2.0_react@18.2.0
solid-js: 1.5.4 solid-js: 1.5.4
svelte: 3.50.0 svelte: 3.50.1
vue: 3.2.39 vue: 3.2.39
devDependencies: devDependencies:
'@astrojs/preact': link:../../../../integrations/preact '@astrojs/preact': link:../../../../integrations/preact
@ -674,7 +674,7 @@ importers:
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0_react@18.2.0 react-dom: 18.2.0_react@18.2.0
solid-js: 1.5.4 solid-js: 1.5.4
svelte: 3.50.0 svelte: 3.50.1
vue: 3.2.39 vue: 3.2.39
devDependencies: devDependencies:
'@astrojs/lit': link:../../../../integrations/lit '@astrojs/lit': link:../../../../integrations/lit
@ -717,7 +717,7 @@ importers:
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0_react@18.2.0 react-dom: 18.2.0_react@18.2.0
solid-js: 1.5.4 solid-js: 1.5.4
svelte: 3.50.0 svelte: 3.50.1
vue: 3.2.39 vue: 3.2.39
devDependencies: devDependencies:
'@astrojs/preact': link:../../../../integrations/preact '@astrojs/preact': link:../../../../integrations/preact
@ -746,7 +746,7 @@ importers:
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0_react@18.2.0 react-dom: 18.2.0_react@18.2.0
solid-js: 1.5.4 solid-js: 1.5.4
svelte: 3.50.0 svelte: 3.50.1
vue: 3.2.39 vue: 3.2.39
devDependencies: devDependencies:
'@astrojs/preact': link:../../../../integrations/preact '@astrojs/preact': link:../../../../integrations/preact
@ -775,7 +775,7 @@ importers:
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0_react@18.2.0 react-dom: 18.2.0_react@18.2.0
solid-js: 1.5.4 solid-js: 1.5.4
svelte: 3.50.0 svelte: 3.50.1
vue: 3.2.39 vue: 3.2.39
devDependencies: devDependencies:
'@astrojs/preact': link:../../../../integrations/preact '@astrojs/preact': link:../../../../integrations/preact
@ -804,7 +804,7 @@ importers:
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0_react@18.2.0 react-dom: 18.2.0_react@18.2.0
solid-js: 1.5.4 solid-js: 1.5.4
svelte: 3.50.0 svelte: 3.50.1
vue: 3.2.39 vue: 3.2.39
devDependencies: devDependencies:
'@astrojs/preact': link:../../../../integrations/preact '@astrojs/preact': link:../../../../integrations/preact
@ -833,7 +833,7 @@ importers:
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0_react@18.2.0 react-dom: 18.2.0_react@18.2.0
solid-js: 1.5.4 solid-js: 1.5.4
svelte: 3.50.0 svelte: 3.50.1
vue: 3.2.39 vue: 3.2.39
devDependencies: devDependencies:
'@astrojs/preact': link:../../../../integrations/preact '@astrojs/preact': link:../../../../integrations/preact
@ -862,7 +862,7 @@ importers:
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0_react@18.2.0 react-dom: 18.2.0_react@18.2.0
solid-js: 1.5.4 solid-js: 1.5.4
svelte: 3.50.0 svelte: 3.50.1
vue: 3.2.39 vue: 3.2.39
devDependencies: devDependencies:
'@astrojs/preact': link:../../../../integrations/preact '@astrojs/preact': link:../../../../integrations/preact
@ -961,7 +961,7 @@ importers:
'@astrojs/mdx': link:../../../../integrations/mdx '@astrojs/mdx': link:../../../../integrations/mdx
'@astrojs/svelte': link:../../../../integrations/svelte '@astrojs/svelte': link:../../../../integrations/svelte
astro: link:../../.. astro: link:../../..
svelte: 3.50.0 svelte: 3.50.1
packages/astro/e2e/fixtures/tailwindcss: packages/astro/e2e/fixtures/tailwindcss:
specifiers: specifiers:
@ -1097,16 +1097,21 @@ importers:
specifiers: specifiers:
'@astrojs/react': workspace:* '@astrojs/react': workspace:*
'@astrojs/svelte': workspace:* '@astrojs/svelte': workspace:*
'@test/astro-client-only-pkg': file:./pkg
astro: workspace:* astro: workspace:*
react: ^18.1.0 react: ^18.1.0
react-dom: ^18.1.0 react-dom: ^18.1.0
dependencies: dependencies:
'@astrojs/react': link:../../../../integrations/react '@astrojs/react': link:../../../../integrations/react
'@astrojs/svelte': link:../../../../integrations/svelte '@astrojs/svelte': link:../../../../integrations/svelte
'@test/astro-client-only-pkg': file:packages/astro/test/fixtures/astro-client-only/pkg
astro: link:../../.. astro: link:../../..
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0_react@18.2.0 react-dom: 18.2.0_react@18.2.0
packages/astro/test/fixtures/astro-client-only/pkg:
specifiers: {}
packages/astro/test/fixtures/astro-component-code: packages/astro/test/fixtures/astro-component-code:
specifiers: specifiers:
astro: workspace:* astro: workspace:*
@ -1596,7 +1601,7 @@ importers:
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0_react@18.2.0 react-dom: 18.2.0_react@18.2.0
solid-js: 1.5.4 solid-js: 1.5.4
svelte: 3.50.0 svelte: 3.50.1
vue: 3.2.39 vue: 3.2.39
devDependencies: devDependencies:
'@astrojs/preact': link:../../../../integrations/preact '@astrojs/preact': link:../../../../integrations/preact
@ -1666,6 +1671,12 @@ importers:
packages/astro/test/fixtures/multiple-renderers/renderers/two: packages/astro/test/fixtures/multiple-renderers/renderers/two:
specifiers: {} specifiers: {}
packages/astro/test/fixtures/non-html-pages:
specifiers:
astro: workspace:*
dependencies:
astro: link:../../..
packages/astro/test/fixtures/page-format: packages/astro/test/fixtures/page-format:
specifiers: specifiers:
astro: workspace:* astro: workspace:*
@ -2062,6 +2073,16 @@ importers:
'@astrojs/vue': link:../../../../integrations/vue '@astrojs/vue': link:../../../../integrations/vue
astro: link:../../.. astro: link:../../..
packages/astro/test/fixtures/vue-with-multi-renderer:
specifiers:
'@astrojs/svelte': workspace:*
'@astrojs/vue': workspace:*
astro: workspace:*
dependencies:
'@astrojs/svelte': link:../../../../integrations/svelte
'@astrojs/vue': link:../../../../integrations/vue
astro: link:../../..
packages/astro/test/fixtures/with-endpoint-routes: packages/astro/test/fixtures/with-endpoint-routes:
specifiers: specifiers:
astro: workspace:* astro: workspace:*
@ -2351,7 +2372,7 @@ importers:
remark-smartypants: 2.0.0 remark-smartypants: 2.0.0
shiki: 0.11.1 shiki: 0.11.1
unist-util-visit: 4.1.1 unist-util-visit: 4.1.1
vfile: 5.3.4 vfile: 5.3.5
devDependencies: devDependencies:
'@types/chai': 4.3.3 '@types/chai': 4.3.3
'@types/mocha': 9.1.1 '@types/mocha': 9.1.1
@ -2605,15 +2626,15 @@ importers:
svelte2tsx: ^0.5.11 svelte2tsx: ^0.5.11
vite: ^3.0.0 vite: ^3.0.0
dependencies: dependencies:
'@sveltejs/vite-plugin-svelte': 1.0.5_svelte@3.50.0+vite@3.1.0 '@sveltejs/vite-plugin-svelte': 1.0.5_svelte@3.50.1+vite@3.1.0
postcss-load-config: 3.1.4 postcss-load-config: 3.1.4
svelte-preprocess: 4.10.7_5llrep7g7lww57fglza6pzz77u svelte-preprocess: 4.10.7_dnlyed3grtnuceggogyodrmgvm
svelte2tsx: 0.5.16_svelte@3.50.0 svelte2tsx: 0.5.16_svelte@3.50.1
vite: 3.1.0 vite: 3.1.0
devDependencies: devDependencies:
astro: link:../../astro astro: link:../../astro
astro-scripts: link:../../../scripts astro-scripts: link:../../../scripts
svelte: 3.50.0 svelte: 3.50.1
packages/integrations/tailwind: packages/integrations/tailwind:
specifiers: specifiers:
@ -2837,7 +2858,7 @@ importers:
unified: 10.1.2 unified: 10.1.2
unist-util-map: 3.1.1 unist-util-map: 3.1.1
unist-util-visit: 4.1.1 unist-util-visit: 4.1.1
vfile: 5.3.4 vfile: 5.3.5
devDependencies: devDependencies:
'@types/chai': 4.3.3 '@types/chai': 4.3.3
'@types/github-slugger': 1.3.0 '@types/github-slugger': 1.3.0
@ -2945,7 +2966,7 @@ importers:
esbuild: 0.14.54 esbuild: 0.14.54
globby: 12.2.0 globby: 12.2.0
kleur: 4.1.5 kleur: 4.1.5
svelte: 3.50.0 svelte: 3.50.1
tar: 6.1.11 tar: 6.1.11
packages: packages:
@ -3234,6 +3255,10 @@ packages:
resolution: {integrity: sha512-vBMPy9ok4iLapSyCCT1qsZ9dK7LkVFl9mObtLEmWiec9myGHS9h2kQY2xzPeFNJiWXUf9O6tSyQpQTy5As/p3g==} resolution: {integrity: sha512-vBMPy9ok4iLapSyCCT1qsZ9dK7LkVFl9mObtLEmWiec9myGHS9h2kQY2xzPeFNJiWXUf9O6tSyQpQTy5As/p3g==}
dev: false dev: false
/@astrojs/compiler/0.24.0:
resolution: {integrity: sha512-xZ81C/oMfExdF18I1Tyd2BKKzBqO+qYYctSy4iCwH4UWSo/4Y8A8MAzV1hG67uuE7hFRourSl6H5KUbhyChv/A==}
dev: false
/@astrojs/language-server/0.23.3: /@astrojs/language-server/0.23.3:
resolution: {integrity: sha512-ROoMKo37NZ76pE/A2xHfjDlgfsNnFmkhL4+Wifs0L855n73SUCbnXz7ZaQktIGAq2Te2TpSjAawiOx0q9L5qeg==} resolution: {integrity: sha512-ROoMKo37NZ76pE/A2xHfjDlgfsNnFmkhL4+Wifs0L855n73SUCbnXz7ZaQktIGAq2Te2TpSjAawiOx0q9L5qeg==}
hasBin: true hasBin: true
@ -5371,7 +5396,7 @@ packages:
unist-util-position-from-estree: 1.1.1 unist-util-position-from-estree: 1.1.1
unist-util-stringify-position: 3.0.2 unist-util-stringify-position: 3.0.2
unist-util-visit: 4.1.1 unist-util-visit: 4.1.1
vfile: 5.3.4 vfile: 5.3.5
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: false dev: false
@ -5387,7 +5412,7 @@ packages:
'@mdx-js/mdx': 2.1.3 '@mdx-js/mdx': 2.1.3
'@rollup/pluginutils': 4.2.1 '@rollup/pluginutils': 4.2.1
source-map: 0.7.4 source-map: 0.7.4
vfile: 5.3.4 vfile: 5.3.5
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: false dev: false
@ -8769,7 +8794,7 @@ packages:
string.prototype.matchall: 4.0.7 string.prototype.matchall: 4.0.7
dev: false dev: false
/@sveltejs/vite-plugin-svelte/1.0.5_svelte@3.50.0+vite@3.1.0: /@sveltejs/vite-plugin-svelte/1.0.5_svelte@3.50.1+vite@3.1.0:
resolution: {integrity: sha512-CmSdSow0Dr5ua1A11BQMtreWnE0JZmkVIcRU/yG3PKbycKUpXjNdgYTWFSbStLB0vdlGnBbm2+Y4sBVj+C+TIw==} resolution: {integrity: sha512-CmSdSow0Dr5ua1A11BQMtreWnE0JZmkVIcRU/yG3PKbycKUpXjNdgYTWFSbStLB0vdlGnBbm2+Y4sBVj+C+TIw==}
engines: {node: ^14.18.0 || >= 16} engines: {node: ^14.18.0 || >= 16}
peerDependencies: peerDependencies:
@ -8787,8 +8812,8 @@ packages:
deepmerge: 4.2.2 deepmerge: 4.2.2
kleur: 4.1.5 kleur: 4.1.5
magic-string: 0.26.3 magic-string: 0.26.3
svelte: 3.50.0 svelte: 3.50.1
svelte-hmr: 0.14.12_svelte@3.50.0 svelte-hmr: 0.14.12_svelte@3.50.1
vite: 3.1.0 vite: 3.1.0
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -8802,7 +8827,7 @@ packages:
/@ts-morph/common/0.16.0: /@ts-morph/common/0.16.0:
resolution: {integrity: sha512-SgJpzkTgZKLKqQniCjLaE3c2L2sdL7UShvmTmPBejAKd2OKV/yfMpQ2IWpAuA+VY5wy7PkSUaEObIqEK6afFuw==} resolution: {integrity: sha512-SgJpzkTgZKLKqQniCjLaE3c2L2sdL7UShvmTmPBejAKd2OKV/yfMpQ2IWpAuA+VY5wy7PkSUaEObIqEK6afFuw==}
dependencies: dependencies:
fast-glob: 3.2.11 fast-glob: 3.2.12
minimatch: 5.1.0 minimatch: 5.1.0
mkdirp: 1.0.4 mkdirp: 1.0.4
path-browserify: 1.0.1 path-browserify: 1.0.1
@ -8828,26 +8853,24 @@ packages:
'@types/babel__generator': 7.6.4 '@types/babel__generator': 7.6.4
'@types/babel__template': 7.4.1 '@types/babel__template': 7.4.1
'@types/babel__traverse': 7.18.1 '@types/babel__traverse': 7.18.1
dev: true dev: false
/@types/babel__generator/7.6.4: /@types/babel__generator/7.6.4:
resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==}
dependencies: dependencies:
'@babel/types': 7.19.0 '@babel/types': 7.19.0
dev: true
/@types/babel__template/7.4.1: /@types/babel__template/7.4.1:
resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==}
dependencies: dependencies:
'@babel/parser': 7.19.0 '@babel/parser': 7.19.0
'@babel/types': 7.19.0 '@babel/types': 7.19.0
dev: true dev: false
/@types/babel__traverse/7.18.1: /@types/babel__traverse/7.18.1:
resolution: {integrity: sha512-FSdLaZh2UxaMuLp9lixWaHq/golWTRWOnRsAXzDTDSDOQLuZb1nsdCt6pJSPWSEQt2eFZ2YVk3oYhn+1kLMeMA==} resolution: {integrity: sha512-FSdLaZh2UxaMuLp9lixWaHq/golWTRWOnRsAXzDTDSDOQLuZb1nsdCt6pJSPWSEQt2eFZ2YVk3oYhn+1kLMeMA==}
dependencies: dependencies:
'@babel/types': 7.19.0 '@babel/types': 7.19.0
dev: true
/@types/chai-as-promised/7.1.5: /@types/chai-as-promised/7.1.5:
resolution: {integrity: sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==} resolution: {integrity: sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==}
@ -8936,7 +8959,7 @@ packages:
/@types/html-escaper/3.0.0: /@types/html-escaper/3.0.0:
resolution: {integrity: sha512-OcJcvP3Yk8mjYwf/IdXZtTE1tb/u0WF0qa29ER07ZHCYUBZXSN29Z1mBS+/96+kNMGTFUAbSz9X+pHmHpZrTCw==} resolution: {integrity: sha512-OcJcvP3Yk8mjYwf/IdXZtTE1tb/u0WF0qa29ER07ZHCYUBZXSN29Z1mBS+/96+kNMGTFUAbSz9X+pHmHpZrTCw==}
dev: true dev: false
/@types/is-ci/3.0.0: /@types/is-ci/3.0.0:
resolution: {integrity: sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ==} resolution: {integrity: sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ==}
@ -9147,7 +9170,6 @@ packages:
/@types/yargs-parser/21.0.0: /@types/yargs-parser/21.0.0:
resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==}
dev: true
/@typescript-eslint/eslint-plugin/5.36.2_kou65mzxaniwtkb2mhvaghdcyi: /@typescript-eslint/eslint-plugin/5.36.2_kou65mzxaniwtkb2mhvaghdcyi:
resolution: {integrity: sha512-OwwR8LRwSnI98tdc2z7mJYgY60gf7I9ZfGjN5EjCwwns9bdTuQfAXcsjSB2wSQ/TVNYSGKf4kzVXbNGaZvwiXw==} resolution: {integrity: sha512-OwwR8LRwSnI98tdc2z7mJYgY60gf7I9ZfGjN5EjCwwns9bdTuQfAXcsjSB2wSQ/TVNYSGKf4kzVXbNGaZvwiXw==}
@ -9322,7 +9344,7 @@ packages:
chokidar: 3.5.3 chokidar: 3.5.3
colorette: 2.0.19 colorette: 2.0.19
consola: 2.15.3 consola: 2.15.3
fast-glob: 3.2.11 fast-glob: 3.2.12
pathe: 0.2.0 pathe: 0.2.0
dev: false dev: false
@ -10022,7 +10044,7 @@ packages:
hasBin: true hasBin: true
dependencies: dependencies:
caniuse-lite: 1.0.30001393 caniuse-lite: 1.0.30001393
electron-to-chromium: 1.4.244 electron-to-chromium: 1.4.246
node-releases: 2.0.6 node-releases: 2.0.6
update-browserslist-db: 1.0.7_browserslist@4.21.3 update-browserslist-db: 1.0.7_browserslist@4.21.3
@ -10839,8 +10861,8 @@ packages:
jake: 10.8.5 jake: 10.8.5
dev: false dev: false
/electron-to-chromium/1.4.244: /electron-to-chromium/1.4.246:
resolution: {integrity: sha512-E21saXLt2eTDaTxgUtiJtBUqanF9A32wZasAwDZ8gvrqXoxrBrbwtDCx7c/PQTLp81wj4X0OLDeoGQg7eMo3+w==} resolution: {integrity: sha512-/wFCHUE+Hocqr/LlVGsuKLIw4P2lBWwFIDcNMDpJGzyIysQV4aycpoOitAs32FT94EHKnNqDR/CVZJFbXEufJA==}
/emmet/2.3.6: /emmet/2.3.6:
resolution: {integrity: sha512-pLS4PBPDdxuUAmw7Me7+TcHbykTsBKN/S9XJbUOMFQrNv9MoshzyMFK/R57JBm94/6HSL4vHnDeEmxlC82NQ4A==} resolution: {integrity: sha512-pLS4PBPDdxuUAmw7Me7+TcHbykTsBKN/S9XJbUOMFQrNv9MoshzyMFK/R57JBm94/6HSL4vHnDeEmxlC82NQ4A==}
@ -11847,8 +11869,8 @@ packages:
resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==} resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==}
dev: true dev: true
/fast-glob/3.2.11: /fast-glob/3.2.12:
resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==} resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==}
engines: {node: '>=8.6.0'} engines: {node: '>=8.6.0'}
dependencies: dependencies:
'@nodelib/fs.stat': 2.0.5 '@nodelib/fs.stat': 2.0.5
@ -12212,7 +12234,7 @@ packages:
dependencies: dependencies:
array-union: 2.1.0 array-union: 2.1.0
dir-glob: 3.0.1 dir-glob: 3.0.1
fast-glob: 3.2.11 fast-glob: 3.2.12
ignore: 5.2.0 ignore: 5.2.0
merge2: 1.4.1 merge2: 1.4.1
slash: 3.0.0 slash: 3.0.0
@ -12224,7 +12246,7 @@ packages:
dependencies: dependencies:
array-union: 3.0.1 array-union: 3.0.1
dir-glob: 3.0.1 dir-glob: 3.0.1
fast-glob: 3.2.11 fast-glob: 3.2.12
ignore: 5.2.0 ignore: 5.2.0
merge2: 1.4.1 merge2: 1.4.1
slash: 4.0.0 slash: 4.0.0
@ -12334,7 +12356,7 @@ packages:
'@types/unist': 2.0.6 '@types/unist': 2.0.6
hastscript: 7.0.2 hastscript: 7.0.2
property-information: 6.1.1 property-information: 6.1.1
vfile: 5.3.4 vfile: 5.3.5
vfile-location: 4.0.1 vfile-location: 4.0.1
web-namespaces: 2.0.1 web-namespaces: 2.0.1
dev: false dev: false
@ -12373,7 +12395,7 @@ packages:
parse5: 6.0.1 parse5: 6.0.1
unist-util-position: 4.0.3 unist-util-position: 4.0.3
unist-util-visit: 4.1.1 unist-util-visit: 4.1.1
vfile: 5.3.4 vfile: 5.3.5
web-namespaces: 2.0.1 web-namespaces: 2.0.1
zwitch: 2.0.2 zwitch: 2.0.2
dev: false dev: false
@ -15640,7 +15662,7 @@ packages:
shiki: 0.10.1 shiki: 0.10.1
shiki-twoslash: 3.1.0 shiki-twoslash: 3.1.0
tslib: 2.1.0 tslib: 2.1.0
typescript: 4.8.2 typescript: 4.8.3
unist-util-visit: 2.0.3 unist-util-visit: 2.0.3
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -16000,7 +16022,7 @@ packages:
'@typescript/twoslash': 3.1.0 '@typescript/twoslash': 3.1.0
'@typescript/vfs': 1.3.4 '@typescript/vfs': 1.3.4
shiki: 0.10.1 shiki: 0.10.1
typescript: 4.8.2 typescript: 4.8.3
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
@ -16431,16 +16453,16 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
/svelte-hmr/0.14.12_svelte@3.50.0: /svelte-hmr/0.14.12_svelte@3.50.1:
resolution: {integrity: sha512-4QSW/VvXuqVcFZ+RhxiR8/newmwOCTlbYIezvkeN6302YFRE8cXy0naamHcjz8Y9Ce3ITTZtrHrIL0AGfyo61w==} resolution: {integrity: sha512-4QSW/VvXuqVcFZ+RhxiR8/newmwOCTlbYIezvkeN6302YFRE8cXy0naamHcjz8Y9Ce3ITTZtrHrIL0AGfyo61w==}
engines: {node: ^12.20 || ^14.13.1 || >= 16} engines: {node: ^12.20 || ^14.13.1 || >= 16}
peerDependencies: peerDependencies:
svelte: '>=3.19.0' svelte: '>=3.19.0'
dependencies: dependencies:
svelte: 3.50.0 svelte: 3.50.1
dev: false dev: false
/svelte-preprocess/4.10.7_5llrep7g7lww57fglza6pzz77u: /svelte-preprocess/4.10.7_dnlyed3grtnuceggogyodrmgvm:
resolution: {integrity: sha512-sNPBnqYD6FnmdBrUmBCaqS00RyCsCpj2BG58A1JBswNF7b0OKviwxqVrOL/CKyJrLSClrSeqQv5BXNg2RUbPOw==} resolution: {integrity: sha512-sNPBnqYD6FnmdBrUmBCaqS00RyCsCpj2BG58A1JBswNF7b0OKviwxqVrOL/CKyJrLSClrSeqQv5BXNg2RUbPOw==}
engines: {node: '>= 9.11.2'} engines: {node: '>= 9.11.2'}
requiresBuild: true requiresBuild: true
@ -16488,14 +16510,14 @@ packages:
postcss-load-config: 3.1.4 postcss-load-config: 3.1.4
sorcery: 0.10.0 sorcery: 0.10.0
strip-indent: 3.0.0 strip-indent: 3.0.0
svelte: 3.50.0 svelte: 3.50.1
dev: false dev: false
/svelte/3.50.0: /svelte/3.50.1:
resolution: {integrity: sha512-zXeOUDS7+85i+RxLN+0iB6PMbGH7OhEgjETcD1fD8ZrhuhNFxYxYEHU41xuhkHIulJavcu3PKbPyuCrBxdxskQ==} resolution: {integrity: sha512-bS4odcsdj5D5jEg6riZuMg5NKelzPtmsCbD9RG+8umU03TeNkdWnP6pqbCm0s8UQNBkqk29w/Bdubn3C+HWSwA==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
/svelte2tsx/0.5.16_svelte@3.50.0: /svelte2tsx/0.5.16_svelte@3.50.1:
resolution: {integrity: sha512-MwgpeRHfzP8T7NkFNT1JPhe9pCF4Dml2oSdjL2zNqvSprjA2BFgQuCNUg4R5qSz7AxVDJsiL/2hciCtVbXAT3A==} resolution: {integrity: sha512-MwgpeRHfzP8T7NkFNT1JPhe9pCF4Dml2oSdjL2zNqvSprjA2BFgQuCNUg4R5qSz7AxVDJsiL/2hciCtVbXAT3A==}
peerDependencies: peerDependencies:
svelte: ^3.24 svelte: ^3.24
@ -16506,7 +16528,7 @@ packages:
dependencies: dependencies:
dedent-js: 1.0.1 dedent-js: 1.0.1
pascal-case: 3.1.2 pascal-case: 3.1.2
svelte: 3.50.0 svelte: 3.50.1
dev: false dev: false
/synckit/0.7.3: /synckit/0.7.3:
@ -16529,7 +16551,7 @@ packages:
detective: 5.2.1 detective: 5.2.1
didyoumean: 1.2.2 didyoumean: 1.2.2
dlv: 1.1.3 dlv: 1.1.3
fast-glob: 3.2.11 fast-glob: 3.2.12
glob-parent: 6.0.2 glob-parent: 6.0.2
is-glob: 4.0.3 is-glob: 4.0.3
lilconfig: 2.0.6 lilconfig: 2.0.6
@ -16969,8 +16991,8 @@ packages:
hasBin: true hasBin: true
dev: true dev: true
/typescript/4.8.2: /typescript/4.8.3:
resolution: {integrity: sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==} resolution: {integrity: sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==}
engines: {node: '>=4.2.0'} engines: {node: '>=4.2.0'}
hasBin: true hasBin: true
dev: true dev: true
@ -17036,7 +17058,7 @@ packages:
is-buffer: 2.0.5 is-buffer: 2.0.5
is-plain-obj: 4.1.0 is-plain-obj: 4.1.0
trough: 2.1.0 trough: 2.1.0
vfile: 5.3.4 vfile: 5.3.5
/unique-string/2.0.0: /unique-string/2.0.0:
resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==}
@ -17259,7 +17281,7 @@ packages:
resolution: {integrity: sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==} resolution: {integrity: sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==}
dependencies: dependencies:
'@types/unist': 2.0.6 '@types/unist': 2.0.6
vfile: 5.3.4 vfile: 5.3.5
dev: false dev: false
/vfile-message/3.1.2: /vfile-message/3.1.2:
@ -17268,8 +17290,8 @@ packages:
'@types/unist': 2.0.6 '@types/unist': 2.0.6
unist-util-stringify-position: 3.0.2 unist-util-stringify-position: 3.0.2
/vfile/5.3.4: /vfile/5.3.5:
resolution: {integrity: sha512-KI+7cnst03KbEyN1+JE504zF5bJBZa+J+CrevLeyIMq0aPU681I2rQ5p4PlnQ6exFtWiUrg26QUdFMnAKR6PIw==} resolution: {integrity: sha512-U1ho2ga33eZ8y8pkbQLH54uKqGhFJ6GYIHnnG5AhRpAh3OWjkrRHKa/KogbmQn8We+c0KVV3rTOgR9V/WowbXQ==}
dependencies: dependencies:
'@types/unist': 2.0.6 '@types/unist': 2.0.6
is-buffer: 2.0.5 is-buffer: 2.0.5
@ -17295,7 +17317,7 @@ packages:
optional: true optional: true
dependencies: dependencies:
debug: 4.3.4 debug: 4.3.4
fast-glob: 3.2.11 fast-glob: 3.2.12
pretty-bytes: 5.6.0 pretty-bytes: 5.6.0
rollup: 2.79.0 rollup: 2.79.0
workbox-build: 6.5.4 workbox-build: 6.5.4
@ -17941,6 +17963,11 @@ packages:
resolution: {integrity: sha512-JZxotl7SxAJH0j7dN4pxsTV6ZLXoLdGME+PsjkL/DaBrVryK9kTGq06GfKrwcSOqypP+fdXGoCHE36b99fWVoA==} resolution: {integrity: sha512-JZxotl7SxAJH0j7dN4pxsTV6ZLXoLdGME+PsjkL/DaBrVryK9kTGq06GfKrwcSOqypP+fdXGoCHE36b99fWVoA==}
dev: false dev: false
file:packages/astro/test/fixtures/astro-client-only/pkg:
resolution: {directory: packages/astro/test/fixtures/astro-client-only/pkg, type: directory}
name: '@test/astro-client-only-pkg'
dev: false
file:packages/astro/test/fixtures/css-assets/packages/font-awesome: file:packages/astro/test/fixtures/css-assets/packages/font-awesome:
resolution: {directory: packages/astro/test/fixtures/css-assets/packages/font-awesome, type: directory} resolution: {directory: packages/astro/test/fixtures/css-assets/packages/font-awesome, type: directory}
name: '@astrojs/test-font-awesome-package' name: '@astrojs/test-font-awesome-package'