diff --git a/.changeset/green-pillows-hammer.md b/.changeset/green-pillows-hammer.md new file mode 100644 index 000000000..ca3bef981 --- /dev/null +++ b/.changeset/green-pillows-hammer.md @@ -0,0 +1,5 @@ +--- +'@astrojs/vue': patch +--- + +Fix Vue `script setup` with other renderers applied diff --git a/.changeset/orange-llamas-play.md b/.changeset/orange-llamas-play.md deleted file mode 100644 index 04c0e5ae4..000000000 --- a/.changeset/orange-llamas-play.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@astrojs/react': patch ---- - -Prevent decoder from leaking diff --git a/.changeset/proud-gifts-explain.md b/.changeset/proud-gifts-explain.md deleted file mode 100644 index 0c75aab9a..000000000 --- a/.changeset/proud-gifts-explain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@astrojs/image': patch ---- - -Updates the integration to build all optimized images to `dist/assets` during SSG builds diff --git a/.changeset/tasty-owls-watch.md b/.changeset/tasty-owls-watch.md deleted file mode 100644 index 8d0eb53f4..000000000 --- a/.changeset/tasty-owls-watch.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'astro': patch -'@astrojs/react': patch ---- - -Fix framework components on Vercel Edge diff --git a/examples/basics/package.json b/examples/basics/package.json index 36b26f934..d1ea84594 100644 --- a/examples/basics/package.json +++ b/examples/basics/package.json @@ -10,6 +10,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^1.1.7" + "astro": "^1.2.1" } } diff --git a/examples/blog/package.json b/examples/blog/package.json index 920624ff8..aed49334d 100644 --- a/examples/blog/package.json +++ b/examples/blog/package.json @@ -10,7 +10,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^1.1.7", + "astro": "^1.2.1", "@astrojs/mdx": "^0.11.1", "@astrojs/rss": "^1.0.0", "@astrojs/sitemap": "^1.0.0" diff --git a/examples/component/package.json b/examples/component/package.json index 80f78ef8d..fd70c4293 100644 --- a/examples/component/package.json +++ b/examples/component/package.json @@ -15,9 +15,9 @@ ], "scripts": {}, "devDependencies": { - "astro": "^1.1.7" + "astro": "^1.2.1" }, "peerDependencies": { - "astro": "^1.1.7" + "astro": "^1.2.1" } } diff --git a/examples/docs/README.md b/examples/docs/README.md index 8bf8e6ca5..b88fb0808 100644 --- a/examples/docs/README.md +++ b/examples/docs/README.md @@ -47,14 +47,14 @@ Welcome! Check out [our documentation](https://docs.astro.build) or jump into ou ### 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. 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 -/* public/theme.css */ +/* src/styles/theme.css */ :root { color-scheme: light; - --theme-accent: hsla(var(--color-blue), 1); diff --git a/examples/docs/package.json b/examples/docs/package.json index 96a7aa29c..1632052d3 100644 --- a/examples/docs/package.json +++ b/examples/docs/package.json @@ -11,11 +11,11 @@ "astro": "astro" }, "dependencies": { - "astro": "^1.1.7", + "astro": "^1.2.1", "preact": "^10.7.3", "react": "^18.1.0", "react-dom": "^18.1.0", - "@astrojs/react": "^1.1.0", + "@astrojs/react": "^1.1.2", "@astrojs/preact": "^1.1.0", "@algolia/client-search": "^4.13.1", "@docsearch/css": "^3.1.0", diff --git a/examples/framework-alpine/package.json b/examples/framework-alpine/package.json index ecead3157..15d4931eb 100644 --- a/examples/framework-alpine/package.json +++ b/examples/framework-alpine/package.json @@ -10,7 +10,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^1.1.7", + "astro": "^1.2.1", "alpinejs": "^3.10.2", "@astrojs/alpinejs": "^0.1.2", "@types/alpinejs": "^3.7.0" diff --git a/examples/framework-lit/package.json b/examples/framework-lit/package.json index d9ea200a7..d46f1d96a 100644 --- a/examples/framework-lit/package.json +++ b/examples/framework-lit/package.json @@ -10,7 +10,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^1.1.7", + "astro": "^1.2.1", "lit": "^2.2.5", "@astrojs/lit": "^1.0.0", "@webcomponents/template-shadowroot": "^0.1.0" diff --git a/examples/framework-multiple/package.json b/examples/framework-multiple/package.json index 63bff5342..8b23093b2 100644 --- a/examples/framework-multiple/package.json +++ b/examples/framework-multiple/package.json @@ -10,7 +10,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^1.1.7", + "astro": "^1.2.1", "preact": "^10.7.3", "react": "^18.1.0", "react-dom": "^18.1.0", @@ -18,7 +18,7 @@ "svelte": "^3.48.0", "vue": "^3.2.37", "@astrojs/preact": "^1.1.0", - "@astrojs/react": "^1.1.0", + "@astrojs/react": "^1.1.2", "@astrojs/solid-js": "^1.1.0", "@astrojs/svelte": "^1.0.0", "@astrojs/vue": "^1.0.1" diff --git a/examples/framework-preact/package.json b/examples/framework-preact/package.json index 86fa870bd..5f3f9338b 100644 --- a/examples/framework-preact/package.json +++ b/examples/framework-preact/package.json @@ -10,7 +10,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^1.1.7", + "astro": "^1.2.1", "preact": "^10.7.3", "@astrojs/preact": "^1.1.0" } diff --git a/examples/framework-react/package.json b/examples/framework-react/package.json index a68fbd845..18805c079 100644 --- a/examples/framework-react/package.json +++ b/examples/framework-react/package.json @@ -10,10 +10,10 @@ "astro": "astro" }, "dependencies": { - "astro": "^1.1.7", + "astro": "^1.2.1", "react": "^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-dom": "^18.0.5" } diff --git a/examples/framework-solid/package.json b/examples/framework-solid/package.json index 55392d4df..a7cbdad9b 100644 --- a/examples/framework-solid/package.json +++ b/examples/framework-solid/package.json @@ -10,7 +10,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^1.1.7", + "astro": "^1.2.1", "solid-js": "^1.4.3", "@astrojs/solid-js": "^1.1.0" } diff --git a/examples/framework-svelte/package.json b/examples/framework-svelte/package.json index 25c5252d7..86422d9a1 100644 --- a/examples/framework-svelte/package.json +++ b/examples/framework-svelte/package.json @@ -12,6 +12,6 @@ "dependencies": { "svelte": "^3.48.0", "@astrojs/svelte": "^1.0.0", - "astro": "^1.1.7" + "astro": "^1.2.1" } } diff --git a/examples/framework-vue/package.json b/examples/framework-vue/package.json index b14317693..d0eceaf0e 100644 --- a/examples/framework-vue/package.json +++ b/examples/framework-vue/package.json @@ -10,7 +10,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^1.1.7", + "astro": "^1.2.1", "vue": "^3.2.37", "@astrojs/vue": "^1.0.1" } diff --git a/examples/minimal/package.json b/examples/minimal/package.json index 05284048d..904f4f60b 100644 --- a/examples/minimal/package.json +++ b/examples/minimal/package.json @@ -10,6 +10,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^1.1.7" + "astro": "^1.2.1" } } diff --git a/examples/non-html-pages/package.json b/examples/non-html-pages/package.json index 83d238c44..9d4a244f7 100644 --- a/examples/non-html-pages/package.json +++ b/examples/non-html-pages/package.json @@ -10,6 +10,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^1.1.7" + "astro": "^1.2.1" } } diff --git a/examples/portfolio/package.json b/examples/portfolio/package.json index 69f7a343e..12f47762c 100644 --- a/examples/portfolio/package.json +++ b/examples/portfolio/package.json @@ -10,6 +10,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^1.1.7" + "astro": "^1.2.1" } } diff --git a/examples/ssr/package.json b/examples/ssr/package.json index ef957afc8..74087dcfc 100644 --- a/examples/ssr/package.json +++ b/examples/ssr/package.json @@ -12,7 +12,7 @@ }, "devDependencies": {}, "dependencies": { - "astro": "^1.1.7", + "astro": "^1.2.1", "svelte": "^3.48.0", "@astrojs/svelte": "^1.0.0", "@astrojs/node": "^1.0.1", diff --git a/examples/with-markdown-plugins/package.json b/examples/with-markdown-plugins/package.json index 7262a8b2e..0039219ae 100644 --- a/examples/with-markdown-plugins/package.json +++ b/examples/with-markdown-plugins/package.json @@ -10,7 +10,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^1.1.7", + "astro": "^1.2.1", "@astrojs/markdown-remark": "^1.1.0", "hast-util-select": "5.0.1", "rehype-autolink-headings": "^6.1.1", diff --git a/examples/with-markdown-shiki/package.json b/examples/with-markdown-shiki/package.json index 1a7936dc7..c4ae2e551 100644 --- a/examples/with-markdown-shiki/package.json +++ b/examples/with-markdown-shiki/package.json @@ -10,6 +10,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^1.1.7" + "astro": "^1.2.1" } } diff --git a/examples/with-mdx/package.json b/examples/with-mdx/package.json index 22446d4d4..b507f7dcd 100644 --- a/examples/with-mdx/package.json +++ b/examples/with-mdx/package.json @@ -10,7 +10,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^1.1.7", + "astro": "^1.2.1", "preact": "^10.6.5", "@astrojs/preact": "^1.1.0", "@astrojs/mdx": "^0.11.1" diff --git a/examples/with-nanostores/package.json b/examples/with-nanostores/package.json index 81f93325a..d99d027ad 100644 --- a/examples/with-nanostores/package.json +++ b/examples/with-nanostores/package.json @@ -10,7 +10,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^1.1.7", + "astro": "^1.2.1", "preact": "^10.7.3", "@astrojs/preact": "^1.1.0", "nanostores": "^0.5.12", diff --git a/examples/with-tailwindcss/package.json b/examples/with-tailwindcss/package.json index 7688bf6eb..13738f090 100644 --- a/examples/with-tailwindcss/package.json +++ b/examples/with-tailwindcss/package.json @@ -10,7 +10,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^1.1.7", + "astro": "^1.2.1", "@astrojs/tailwind": "^1.0.0", "autoprefixer": "^10.4.7", "canvas-confetti": "^1.5.1", diff --git a/examples/with-vite-plugin-pwa/package.json b/examples/with-vite-plugin-pwa/package.json index 8c72a34e8..0014742b8 100644 --- a/examples/with-vite-plugin-pwa/package.json +++ b/examples/with-vite-plugin-pwa/package.json @@ -10,7 +10,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^1.1.7", + "astro": "^1.2.1", "vite-plugin-pwa": "0.11.11", "workbox-window": "^6.5.3" } diff --git a/examples/with-vitest/package.json b/examples/with-vitest/package.json index c7edbeac6..494abf392 100644 --- a/examples/with-vitest/package.json +++ b/examples/with-vitest/package.json @@ -12,7 +12,7 @@ "test": "vitest" }, "dependencies": { - "astro": "^1.1.7", + "astro": "^1.2.1", "vitest": "^0.20.3" } } diff --git a/packages/astro/CHANGELOG.md b/packages/astro/CHANGELOG.md index 27b36d8d3..0d8781cab 100644 --- a/packages/astro/CHANGELOG.md +++ b/packages/astro/CHANGELOG.md @@ -1,5 +1,39 @@ # 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 ### Patch Changes diff --git a/packages/astro/e2e/astro-component.test.js b/packages/astro/e2e/astro-component.test.js index 8d6151f07..8ebbcd3a6 100644 --- a/packages/astro/e2e/astro-component.test.js +++ b/packages/astro/e2e/astro-component.test.js @@ -36,10 +36,7 @@ test.describe('Astro component HMR', () => { ); }); - // TODO: Re-enable this test on windows when #3424 is fixed - // https://github.com/withastro/astro/issues/3424 - const it = os.platform() === 'win32' ? test.skip : test; - it('hoisted scripts', async ({ page, astro }) => { + test('hoisted scripts', async ({ page, astro }) => { const initialLog = page.waitForEvent( 'console', (message) => message.text() === 'Hello, Astro!' @@ -60,4 +57,26 @@ test.describe('Astro component HMR', () => { 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; + }); }); diff --git a/packages/astro/e2e/fixtures/astro-component/src/pages/index.astro b/packages/astro/e2e/fixtures/astro-component/src/pages/index.astro index 76221b040..c7522dc54 100644 --- a/packages/astro/e2e/fixtures/astro-component/src/pages/index.astro +++ b/packages/astro/e2e/fixtures/astro-component/src/pages/index.astro @@ -18,3 +18,7 @@ import Hero from '../components/Hero.astro'; + + diff --git a/packages/astro/package.json b/packages/astro/package.json index 82c848ad3..8d3158788 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -1,6 +1,6 @@ { "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.", "type": "module", "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\"", "postbuild": "astro-scripts copy \"src/**/*.astro\"", "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:e2e": "playwright test", "test:e2e:match": "playwright test -g" }, "dependencies": { - "@astrojs/compiler": "^0.23.5", + "@astrojs/compiler": "^0.24.0", "@astrojs/language-server": "^0.23.0", "@astrojs/markdown-remark": "^1.1.1", "@astrojs/telemetry": "^1.0.0", @@ -105,8 +106,11 @@ "@babel/plugin-transform-react-jsx": "^7.17.12", "@babel/traverse": "^7.18.2", "@babel/types": "^7.18.4", - "@proload/core": "^0.3.2", + "@proload/core": "^0.3.3", "@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", "ci-info": "^3.3.1", "common-ancestor-path": "^1.0.1", @@ -151,7 +155,6 @@ }, "devDependencies": { "@playwright/test": "^1.22.2", - "@types/babel__core": "^7.1.19", "@types/babel__generator": "^7.6.4", "@types/babel__traverse": "^7.17.1", "@types/chai": "^4.3.1", @@ -160,7 +163,6 @@ "@types/debug": "^4.1.7", "@types/diff": "^5.0.2", "@types/estree": "^0.0.51", - "@types/html-escaper": "^3.0.0", "@types/mime": "^2.0.3", "@types/mocha": "^9.1.1", "@types/parse5": "^6.0.3", @@ -170,7 +172,6 @@ "@types/rimraf": "^3.0.2", "@types/send": "^0.17.1", "@types/unist": "^2.0.6", - "@types/yargs-parser": "^21.0.0", "ast-types": "^0.14.2", "astro-scripts": "workspace:*", "chai": "^4.3.6", diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts index 5cd7abe24..c358d63e7 100644 --- a/packages/astro/src/@types/astro.ts +++ b/packages/astro/src/@types/astro.ts @@ -924,7 +924,7 @@ export interface MarkdownInstance> { default: AstroComponentFactory; } -export interface MDXInstance +export interface MDXInstance> extends Omit, '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 */ rawContent: never; @@ -944,7 +944,10 @@ export interface MarkdownLayoutProps> { compiledContent: MarkdownInstance['compiledContent']; } -export type MDXLayoutProps = Omit, 'rawContent' | 'compiledContent'>; +export type MDXLayoutProps> = Omit< + MarkdownLayoutProps, + 'rawContent' | 'compiledContent' +>; export type GetHydrateCallback = () => Promise<() => void | Promise>; @@ -1082,6 +1085,7 @@ export interface APIContext { export interface EndpointOutput { body: Body; + encoding?: BufferEncoding; } export type APIRoute = ( diff --git a/packages/astro/src/cli/index.ts b/packages/astro/src/cli/index.ts index 2511ada86..622505700 100644 --- a/packages/astro/src/cli/index.ts +++ b/packages/astro/src/cli/index.ts @@ -1,16 +1,19 @@ /* eslint-disable no-console */ - 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 { z } from 'zod'; import add from '../core/add/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 { 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 { formatConfigErrorMessage, formatErrorMessage, printHelp } from '../core/messages.js'; +import { appendForwardSlash } from '../core/path.js'; import preview from '../core/preview/index.js'; import { ASTRO_VERSION, createSafeError } from '../core/util.js'; import * as event from '../events/index.js'; @@ -81,6 +84,21 @@ function resolveCommand(flags: Arguments): CLICommand { 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. * 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, flags, cmd, logging, + }).catch(async (e) => { + await handleConfigError(e, { cwd: root, flags, logging }); + return {} as any; }); + if (!astroConfig) return; telemetry.record(event.eventCliSession(cmd, userConfig, flags)); // Common CLI Commands: @@ -145,33 +167,55 @@ async function runCommand(cmd: string, flags: yargs.Arguments) { // by the end of this switch statement. switch (cmd) { case 'dev': { - async function startDevServer() { - const { watcher, stop } = await devServer(astroConfig, { logging, telemetry }); + async function startDevServer({ isRestart = false }: { isRestart?: boolean } = {}) { + 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); - watcher.on('unlink', logRestartServerOnConfigChange); - function logRestartServerOnConfigChange(changedFile: string) { - if (userConfigPath === changedFile) { - warn(logging, 'astro', 'Astro config updated. Restart server to see changes!'); - } - } - - watcher.on('add', async function restartServerOnNewConfigFile(addedFile: string) { - // if there was not a config before, attempt to resolve - if (!userConfigPath && addedFile.includes('astro.config')) { - const addedConfig = await openConfig({ cwd: root, flags, cmd, logging }); - if (addedConfig.userConfigPath) { - info(logging, 'astro', 'Astro config detected. Restarting server...'); - astroConfig = addedConfig.astroConfig; - userConfig = addedConfig.userConfig; - userConfigPath = addedConfig.userConfigPath; - await stop(); - await startDevServer(); + const handleServerRestart = (logMsg: string) => + async function (changedFile: string) { + if ( + !restartInFlight && + (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 + new RegExp( + `${normalizePath(resolvedRoot)}.*astro\.config\.((mjs)|(cjs)|(js)|(ts))$` + ).test(normalizePath(changedFile))) + ) { + restartInFlight = true; + console.clear(); + try { + const newConfig = await openConfig({ + cwd: root, + flags, + 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 } diff --git a/packages/astro/src/core/add/index.ts b/packages/astro/src/core/add/index.ts index fa56fa1d2..c655dab5d 100644 --- a/packages/astro/src/core/add/index.ts +++ b/packages/astro/src/core/add/index.ts @@ -10,7 +10,7 @@ import preferredPM from 'preferred-pm'; import prompts from 'prompts'; import { fileURLToPath, pathToFileURL } from 'url'; 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 * as msg from '../messages.js'; import { printHelp } from '../messages.js'; @@ -57,6 +57,7 @@ const OFFICIAL_ADAPTER_TO_IMPORT_MAP: Record = { }; export default async function add(names: string[], { cwd, flags, logging, telemetry }: AddOptions) { + applyPolyfill(); if (flags.help || names.length === 0) { printHelp({ commandName: 'astro add', @@ -95,16 +96,76 @@ export default async function add(names: string[], { cwd, flags, logging, teleme }); 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()); - configURL = await resolveConfigURL({ cwd, flags }); - applyPolyfill(); + // Append forward slash to compute relative paths + 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) { debug('add', `Found config at ${configURL}`); } else { 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' }); } @@ -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.` ); } - - // 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; try { ast = await parseAstroConfig(configURL); @@ -164,7 +220,6 @@ export default async function add(names: string[], { cwd, flags, logging, teleme } let configResult: UpdateResult | undefined; - let installResult: UpdateResult | undefined; if (ast) { 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.`)); - break; + return; } - } - - 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`); - } - } + default: { const list = integrations.map((integration) => ` - ${integration.packageName}`).join('\n'); info( logging, null, 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) { case 'npm': - return { pm: 'npm', command: 'install', flags: ['--save-dev'], dependencies }; + return { pm: 'npm', command: 'install', flags: [], dependencies }; case 'yarn': - return { pm: 'yarn', command: 'add', flags: ['--dev'], dependencies }; + return { pm: 'yarn', command: 'add', flags: [], dependencies }; case 'pnpm': - return { pm: 'pnpm', command: 'install', flags: ['--save-dev'], dependencies }; + return { pm: 'pnpm', command: 'install', flags: [], dependencies }; default: return null; } @@ -577,9 +580,10 @@ async function tryToInstallIntegrations({ if (installCommand === null) { return UpdateResult.none; } else { - const coloredOutput = `${bold(installCommand.pm)} ${ - installCommand.command - } ${installCommand.flags.join(' ')} ${cyan(installCommand.dependencies.join(' '))}`; + const coloredOutput = `${bold(installCommand.pm)} ${installCommand.command}${[ + '', + ...installCommand.flags, + ].join(' ')} ${cyan(installCommand.dependencies.join(' '))}`; const message = `\n${boxen(coloredOutput, { margin: 0.5, padding: 0.5, diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts index 406186a21..b6ebf4697 100644 --- a/packages/astro/src/core/build/generate.ts +++ b/packages/astro/src/core/build/generate.ts @@ -391,6 +391,7 @@ async function generatePath( }; let body: string; + let encoding: BufferEncoding | undefined; if (pageData.route.type === 'endpoint') { 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.`); } body = result.body; + encoding = result.encoding; } else { const response = await render(options); @@ -413,5 +415,5 @@ async function generatePath( const outFile = getOutFile(astroConfig, outFolder, pathname, pageData.route.type); pageData.route.distURL = outFile; await fs.promises.mkdir(outFolder, { recursive: true }); - await fs.promises.writeFile(outFile, body, 'utf-8'); + await fs.promises.writeFile(outFile, body, encoding ?? 'utf-8'); } diff --git a/packages/astro/src/core/build/vite-plugin-analyzer.ts b/packages/astro/src/core/build/vite-plugin-analyzer.ts index e25ee42aa..65da4fd0f 100644 --- a/packages/astro/src/core/build/vite-plugin-analyzer.ts +++ b/packages/astro/src/core/build/vite-plugin-analyzer.ts @@ -70,7 +70,7 @@ export function vitePluginAnalyzer(internals: BuildInternals): VitePlugin { return { name: '@astro/rollup-plugin-astro-analyzer', - generateBundle() { + async generateBundle() { const hoistScanner = hoistedScriptScanner(); const ids = this.getModuleIds(); @@ -95,6 +95,14 @@ export function vitePluginAnalyzer(internals: BuildInternals): VitePlugin { const cid = c.resolvedPath ? decodeURI(c.resolvedPath) : c.specifier; internals.discoveredClientOnlyComponents.add(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)) { diff --git a/packages/astro/src/vite-plugin-astro/compile.ts b/packages/astro/src/core/compile/compile.ts similarity index 53% rename from packages/astro/src/vite-plugin-astro/compile.ts rename to packages/astro/src/core/compile/compile.ts index 368e310fc..10411860e 100644 --- a/packages/astro/src/vite-plugin-astro/compile.ts +++ b/packages/astro/src/core/compile/compile.ts @@ -1,14 +1,12 @@ import type { TransformResult } from '@astrojs/compiler'; -import type { PluginContext, SourceMapInput } from 'rollup'; -import type { ViteDevServer } from 'vite'; -import type { AstroConfig } from '../@types/astro'; -import type { TransformStyleWithVite } from './styles'; +import type { AstroConfig } from '../../@types/astro'; +import type { TransformStyle } from './types'; import { transform } from '@astrojs/compiler'; -import { fileURLToPath } from 'url'; -import { AstroErrorCodes } from '../core/errors.js'; -import { prependForwardSlash } from '../core/path.js'; -import { viteID } from '../core/util.js'; +import { AstroErrorCodes } from '../errors.js'; +import { prependForwardSlash } from '../path.js'; +import { AggregateError, viteID } from '../util.js'; +import { createStylePreprocessor } from './style.js'; type CompilationCache = Map; type CompileResult = TransformResult & { @@ -23,20 +21,7 @@ export interface CompileProps { filename: string; moduleId: string; source: string; - ssr: boolean; - 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; - } + transformStyle: TransformStyle; } async function compile({ @@ -44,19 +29,10 @@ async function compile({ filename, moduleId, source, - ssr, - transformStyleWithVite, - viteDevServer, - pluginContext, + transformStyle, }: CompileProps): Promise { - const normalizedID = getNormalizedID(filename); let cssDeps = new Set(); - let cssTransformError: Error | undefined; - - // handleHotUpdate doesn't have `addWatchFile` used by transformStyleWithVite. - if (!pluginContext.addWatchFile) { - pluginContext.addWatchFile = () => {}; - } + let cssTransformErrors: Error[] = []; // Transform from `.astro` to valid `.ts` // use `sourcemap: "both"` so that sourcemap is included in the code @@ -69,44 +45,11 @@ async function compile({ sourcefile: filename, sourcemap: 'both', 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 experimentalStaticExtraction: true, - preprocessStyle: async (value: string, attrs: Record) => { - 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; - } - }, + preprocessStyle: createStylePreprocessor(transformStyle, cssDeps, cssTransformErrors), }) .catch((err) => { // throw compiler errors here if encountered @@ -114,13 +57,22 @@ async function compile({ throw err; }) .then((result) => { - // throw CSS transform errors here if encountered - if (cssTransformError) { - (cssTransformError as any).code = - (cssTransformError as any).code || AstroErrorCodes.UnknownCompilerCSSError; - throw cssTransformError; + switch (cssTransformErrors.length) { + case 0: + return result; + case 1: { + 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, { diff --git a/packages/astro/src/core/compile/index.ts b/packages/astro/src/core/compile/index.ts new file mode 100644 index 000000000..1ee6af06a --- /dev/null +++ b/packages/astro/src/core/compile/index.ts @@ -0,0 +1,3 @@ +export type { CompileProps } from './compile'; +export { cachedCompilation, getCachedSource, invalidateCompilation, isCached } from './compile.js'; +export type { TransformStyle } from './types'; diff --git a/packages/astro/src/core/compile/style.ts b/packages/astro/src/core/compile/style.ts new file mode 100644 index 000000000..20079cede --- /dev/null +++ b/packages/astro/src/core/compile/style.ts @@ -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, + errors: Error[] +): PreprocessStyle { + const preprocessStyle: PreprocessStyle = async (value: string, attrs: Record) => { + 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; +} diff --git a/packages/astro/src/core/compile/types.ts b/packages/astro/src/core/compile/types.ts new file mode 100644 index 000000000..1ef4bdfdc --- /dev/null +++ b/packages/astro/src/core/compile/types.ts @@ -0,0 +1,12 @@ +import type { SourceMap } from 'rollup'; + +export type TransformStyleResult = null | { + code: string; + map: SourceMap | null; + deps: Set; +}; + +export type TransformStyle = ( + source: string, + lang: string +) => TransformStyleResult | Promise; diff --git a/packages/astro/src/core/config.ts b/packages/astro/src/core/config.ts index aa8d701e7..611584b76 100644 --- a/packages/astro/src/core/config.ts +++ b/packages/astro/src/core/config.ts @@ -1,4 +1,5 @@ import type { RehypePlugin, RemarkPlugin, RemarkRehype } from '@astrojs/markdown-remark'; +import fs from 'fs'; import type * as Postcss from 'postcss'; import type { ILanguageRegistration, IThemeRegistration, Theme } from 'shiki'; 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. */ -function resolveFlags(flags: Partial): CLIFlags { +export function resolveFlags(flags: Partial): CLIFlags { return { root: typeof flags.root === 'string' ? flags.root : undefined, site: typeof flags.site === 'string' ? flags.site : undefined, @@ -373,6 +374,10 @@ function resolveFlags(flags: Partial): CLIFlags { }; } +export function resolveRoot(cwd?: string): string { + return cwd ? path.resolve(cwd) : process.cwd(); +} + /** Merge CLI flags & user config object (CLI flags take priority) */ function mergeCLIFlags(astroConfig: AstroUserConfig, flags: CLIFlags, cmd: string) { astroConfig.server = astroConfig.server || {}; @@ -398,6 +403,8 @@ interface LoadConfigOptions { cmd: string; validate?: boolean; 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` * instead of the resolved config */ -export async function resolveConfigURL( +export async function resolveConfigPath( configOptions: Pick -): Promise { - const root = configOptions.cwd ? path.resolve(configOptions.cwd) : process.cwd(); +): Promise { + const root = resolveRoot(configOptions.cwd); const flags = resolveFlags(configOptions.flags || {}); let userConfigPath: string | undefined; @@ -419,19 +426,23 @@ export async function resolveConfigURL( // Resolve config file path using Proload // If `userConfigPath` is `undefined`, Proload will search for `astro.config.[cm]?[jt]s` - const configPath = await resolve('astro', { - mustExist: false, - cwd: root, - filePath: userConfigPath, - }); - if (configPath) { - return pathToFileURL(configPath); + try { + const configPath = await resolve('astro', { + mustExist: !!userConfigPath, + cwd: root, + filePath: userConfigPath, + }); + 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 { userConfig: AstroUserConfig; - userConfigPath: string | undefined; astroConfig: AstroConfig; flags: CLIFlags; root: string; @@ -439,22 +450,13 @@ interface OpenConfigResult { /** Load a configuration file, returning both the userConfig and astroConfig */ export async function openConfig(configOptions: LoadConfigOptions): Promise { - const root = configOptions.cwd ? path.resolve(configOptions.cwd) : process.cwd(); + const root = resolveRoot(configOptions.cwd); const flags = resolveFlags(configOptions.flags || {}); let userConfig: AstroUserConfig = {}; - let userConfigPath: string | undefined; - if (flags?.config) { - 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); + const config = await tryLoadConfig(configOptions, flags, root); if (config) { userConfig = config.value; - userConfigPath = config.filePath; } const astroConfig = await resolveConfig( userConfig, @@ -467,7 +469,6 @@ export async function openConfig(configOptions: LoadConfigOptions): Promise { + let finallyCleanup = async () => {}; try { - // Automatically load config file using Proload - // If `userConfigPath` is `undefined`, Proload will search for `astro.config.[cm]?[jt]s` + let configPath = await resolveConfigPath({ + 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', { - mustExist: !!userConfigPath, + mustExist: !!configPath, cwd: root, - filePath: userConfigPath, + filePath: configPath, }); return config as TryLoadConfigResult; @@ -499,28 +521,32 @@ async function tryLoadConfig( throw new Error(`Unable to resolve --config "${flags.config}"! Does the file exist?`); } - const configURL = await resolveConfigURL(configOptions); - if (!configURL) { + const configPath = await resolveConfigPath(configOptions); + if (!configPath) { throw e; } // Fallback to use Vite DevServer const viteServer = await vite.createServer({ server: { middlewareMode: true, hmr: false }, + optimizeDeps: { entries: [] }, + clearScreen: false, appType: 'custom', }); try { - const mod = await viteServer.ssrLoadModule(fileURLToPath(configURL)); + const mod = await viteServer.ssrLoadModule(configPath); if (mod?.default) { return { value: mod.default, - filePath: fileURLToPath(configURL), + filePath: configPath, }; } } finally { await viteServer.close(); } + } finally { + await finallyCleanup(); } } @@ -529,19 +555,11 @@ async function tryLoadConfig( * @deprecated */ export async function loadConfig(configOptions: LoadConfigOptions): Promise { - const root = configOptions.cwd ? path.resolve(configOptions.cwd) : process.cwd(); + const root = resolveRoot(configOptions.cwd); const flags = resolveFlags(configOptions.flags || {}); let userConfig: AstroUserConfig = {}; - let userConfigPath: string | undefined; - if (flags?.config) { - 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); + const config = await tryLoadConfig(configOptions, flags, root); if (config) { userConfig = config.value; } diff --git a/packages/astro/src/core/dev/index.ts b/packages/astro/src/core/dev/index.ts index b768093ed..e8069db90 100644 --- a/packages/astro/src/core/dev/index.ts +++ b/packages/astro/src/core/dev/index.ts @@ -18,6 +18,7 @@ import { apply as applyPolyfill } from '../polyfill.js'; export interface DevOptions { logging: LogOptions; telemetry: AstroTelemetry; + isRestart?: boolean; } export interface DevServer { @@ -33,6 +34,7 @@ export default async function dev(config: AstroConfig, options: DevOptions): Pro await options.telemetry.record([]); config = await runHookConfigSetup({ config, command: 'dev', logging: options.logging }); const { host, port } = config.server; + const { isRestart = false } = options; // The client entrypoint for renderers. Since these are imported dynamically // we need to tell Vite to preoptimize them. @@ -66,6 +68,7 @@ export default async function dev(config: AstroConfig, options: DevOptions): Pro devServerAddressInfo, site, https: !!viteConfig.server?.https, + isRestart, }) ); diff --git a/packages/astro/src/core/endpoint/index.ts b/packages/astro/src/core/endpoint/index.ts index 9e974ee36..73c96ae64 100644 --- a/packages/astro/src/core/endpoint/index.ts +++ b/packages/astro/src/core/endpoint/index.ts @@ -21,6 +21,7 @@ type EndpointCallResult = | { type: 'simple'; body: string; + encoding?: BufferEncoding; } | { type: 'response'; @@ -52,5 +53,6 @@ export async function call( return { type: 'simple', body: response.body, + encoding: response.encoding, }; } diff --git a/packages/astro/src/core/messages.ts b/packages/astro/src/core/messages.ts index 0c74f8cbe..f140e052f 100644 --- a/packages/astro/src/core/messages.ts +++ b/packages/astro/src/core/messages.ts @@ -58,12 +58,14 @@ export function devStart({ config, https, site, + isRestart = false, }: { startupTime: number; devServerAddressInfo: AddressInfo; config: AstroConfig; https: boolean; site: URL | undefined; + isRestart?: boolean; }): string { // PACKAGE_VERSION is injected at build-time const version = process.env.PACKAGE_VERSION ?? '0.0.0'; @@ -106,7 +108,7 @@ export function devStart({ const messages = [ `${emoji('🚀 ', '')}${bgGreen(black(` astro `))} ${green(`v${version}`)} ${dim( - `started in ${Math.round(startupTime)}ms` + `${isRestart ? 're' : ''}started in ${Math.round(startupTime)}ms` )}`, '', local, diff --git a/packages/astro/src/core/util.ts b/packages/astro/src/core/util.ts index 3c74b5580..0abc9b40b 100644 --- a/packages/astro/src/core/util.ts +++ b/packages/astro/src/core/util.ts @@ -126,7 +126,7 @@ export function resolveDependency(dep: string, projectRoot: URL) { * Windows: C:/Users/astro/code/my-project/src/pages/index.astro */ export function viteID(filePath: URL): string { - return slash(fileURLToPath(filePath)); + return slash(fileURLToPath(filePath) + filePath.search); } export const VALID_ID_PREFIX = `/@id/`; @@ -226,3 +226,14 @@ export async function resolveIdToUrl(viteServer: ViteDevServer, id: string) { } return VALID_ID_PREFIX + result.id; } + +export const AggregateError = + typeof globalThis.AggregateError !== 'undefined' + ? globalThis.AggregateError + : class extends Error { + errors: Array = []; + constructor(errors: Iterable, message?: string | undefined) { + super(message); + this.errors = Array.from(errors); + } + }; diff --git a/packages/astro/src/runtime/server/render/head.ts b/packages/astro/src/runtime/server/render/head.ts index bb0fffc2e..ed4b73f3e 100644 --- a/packages/astro/src/runtime/server/render/head.ts +++ b/packages/astro/src/runtime/server/render/head.ts @@ -32,7 +32,7 @@ export function renderHead(result: SSRResult): Promise { } // This function is called by Astro components that do not contain a component -// This accomodates the fact that using a is optional in Astro, so this +// This accommodates the fact that using a is optional in Astro, so this // is called before a component's first non-head HTML element. If the head was // already injected it is a noop. export async function* maybeRenderHead(result: SSRResult): AsyncIterable { diff --git a/packages/astro/src/runtime/server/serialize.ts b/packages/astro/src/runtime/server/serialize.ts index 10812ab75..021c050da 100644 --- a/packages/astro/src/runtime/server/serialize.ts +++ b/packages/astro/src/runtime/server/serialize.ts @@ -13,30 +13,48 @@ const PROP_TYPE = { URL: 7, }; -function serializeArray(value: any[], metadata: AstroComponentMetadata): any[] { - return value.map((v) => convertToSerializedForm(v, metadata)); -} - -function serializeObject( - value: Record, - metadata: AstroComponentMetadata -): Record { - if (cyclicRefs.has(value)) { +function serializeArray( + value: any[], + metadata: AstroComponentMetadata | Record = {}, + parents = new WeakSet() +): 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.`); } - cyclicRefs.add(value); - return Object.fromEntries( + parents.add(value); + const serialized = value.map((v) => { + return convertToSerializedForm(v, metadata, parents); + }); + parents.delete(value); + return serialized; +} + +function serializeObject( + value: Record, + metadata: AstroComponentMetadata | Record = {}, + parents = new WeakSet() +): Record { + 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]) => { - return [k, convertToSerializedForm(v, metadata)]; + return [k, convertToSerializedForm(v, metadata, parents)]; }) ); + parents.delete(value); + return serialized; } function convertToSerializedForm( value: any, - metadata: AstroComponentMetadata + metadata: AstroComponentMetadata | Record = {}, + parents = new WeakSet() ): [ValueOf, any] { const tag = Object.prototype.toString.call(value); switch (tag) { @@ -49,13 +67,13 @@ function convertToSerializedForm( case '[object Map]': { return [ PROP_TYPE.Map, - JSON.stringify(serializeArray(Array.from(value as Map), metadata)), + JSON.stringify(serializeArray(Array.from(value as Map), metadata, parents)), ]; } case '[object Set]': { return [ PROP_TYPE.Set, - JSON.stringify(serializeArray(Array.from(value as Set), metadata)), + JSON.stringify(serializeArray(Array.from(value as Set), metadata, parents)), ]; } case '[object BigInt]': { @@ -65,11 +83,11 @@ function convertToSerializedForm( return [PROP_TYPE.URL, (value as URL).toString()]; } case '[object Array]': { - return [PROP_TYPE.JSON, JSON.stringify(serializeArray(value, metadata))]; + return [PROP_TYPE.JSON, JSON.stringify(serializeArray(value, metadata, parents))]; } default: { if (value !== null && typeof value === 'object') { - return [PROP_TYPE.Value, serializeObject(value, metadata)]; + return [PROP_TYPE.Value, serializeObject(value, metadata, parents)]; } else { return [PROP_TYPE.Value, value]; } @@ -77,9 +95,7 @@ function convertToSerializedForm( } } -let cyclicRefs = new WeakSet(); export function serializeProps(props: any, metadata: AstroComponentMetadata) { const serialized = JSON.stringify(serializeObject(props, metadata)); - cyclicRefs = new WeakSet(); return serialized; } diff --git a/packages/astro/src/vite-plugin-astro/hmr.ts b/packages/astro/src/vite-plugin-astro/hmr.ts index 6ee123e07..a91874240 100644 --- a/packages/astro/src/vite-plugin-astro/hmr.ts +++ b/packages/astro/src/vite-plugin-astro/hmr.ts @@ -1,10 +1,10 @@ import { fileURLToPath } from 'node:url'; import type { HmrContext, ModuleNode } from 'vite'; import type { AstroConfig } from '../@types/astro'; +import { cachedCompilation, invalidateCompilation, isCached } from '../core/compile/index.js'; import type { LogOptions } from '../core/logger/core.js'; import { info } from '../core/logger/core.js'; import * as msg from '../core/messages.js'; -import { cachedCompilation, invalidateCompilation, isCached } from './compile.js'; import { isAstroScript } from './query.js'; 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 const isSelfAccepting = mods.every((m) => m.isSelfAccepting || m.url.endsWith('.svelte')); if (isSelfAccepting) { + if (/astro\.config\.[cm][jt]s$/.test(file)) return mods; info(logging, 'astro', msg.hmr({ file })); } else { info(logging, 'astro', msg.reload({ file })); diff --git a/packages/astro/src/vite-plugin-astro/index.ts b/packages/astro/src/vite-plugin-astro/index.ts index ccfba7af7..d946dd256 100644 --- a/packages/astro/src/vite-plugin-astro/index.ts +++ b/packages/astro/src/vite-plugin-astro/index.ts @@ -2,18 +2,23 @@ import type { PluginContext, SourceDescription } from 'rollup'; import type * as vite from 'vite'; import type { AstroConfig } from '../@types/astro'; import type { LogOptions } from '../core/logger/core.js'; +import type { ViteStyleTransformer } from '../vite-style-transform'; import type { PluginMetadata as AstroPluginMetadata } from './types'; import ancestor from 'common-ancestor-path'; import esbuild from 'esbuild'; import slash from 'slash'; 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 { cachedCompilation, CompileProps, getCachedSource } from './compile.js'; +import { + createTransformStyles, + createViteStyleTransformer, +} from '../vite-style-transform/index.js'; import { handleHotUpdate } from './hmr.js'; import { parseAstroRequest, ParsedRequestResult } from './query.js'; -import { createTransformStyleWithViteFn, TransformStyleWithVite } from './styles.js'; const FRONTMATTER_PARSE_REGEXP = /^\-\-\-(.*)^\-\-\-/ms; interface AstroPluginOptions { @@ -38,12 +43,14 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu } let resolvedConfig: vite.ResolvedConfig; - let transformStyleWithVite: TransformStyleWithVite; + let styleTransformer: ViteStyleTransformer; let viteDevServer: vite.ViteDevServer | undefined; // Variables for determining if an id starts with /src... const srcRootWeb = config.srcDir.pathname.slice(config.root.pathname.length - 1); 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 { 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 configResolved(_resolvedConfig) { resolvedConfig = _resolvedConfig; - transformStyleWithVite = createTransformStyleWithViteFn(_resolvedConfig); + styleTransformer = createViteStyleTransformer(_resolvedConfig); }, configureServer(server) { viteDevServer = server; + styleTransformer.viteDevServer = server; }, // note: don’t claim .astro files with resolveId() — it prevents Vite from transpiling the final JS (import.meta.glob, etc.) async resolveId(id, from, opts) { @@ -89,7 +97,10 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu if (query.type === 'style' && isBrowserPath(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; } }, @@ -117,10 +128,7 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu filename, moduleId: id, source, - ssr: Boolean(opts?.ssr), - transformStyleWithVite, - viteDevServer, - pluginContext: this, + transformStyle: createTransformStyles(styleTransformer, filename, Boolean(opts?.ssr), this), }; switch (query.type) { @@ -216,10 +224,7 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu filename, moduleId: id, source, - ssr: Boolean(opts?.ssr), - transformStyleWithVite, - viteDevServer, - pluginContext: this, + transformStyle: createTransformStyles(styleTransformer, filename, Boolean(opts?.ssr), this), }; try { @@ -246,18 +251,8 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu )};export { $$file as file, $$url as url };\n`; // Add HMR handling in dev mode. 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; 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";`; i++; } @@ -352,10 +347,7 @@ ${source} filename: context.file, moduleId: context.file, source: await context.read(), - ssr: true, - transformStyleWithVite, - viteDevServer, - pluginContext: this, + transformStyle: createTransformStyles(styleTransformer, context.file, true, this), }; const compile = () => cachedCompilation(compileProps); return handleHotUpdate.call(this, context, { diff --git a/packages/astro/src/vite-plugin-markdown-legacy/index.ts b/packages/astro/src/vite-plugin-markdown-legacy/index.ts index 1bfb8546b..dd7259e2c 100644 --- a/packages/astro/src/vite-plugin-markdown-legacy/index.ts +++ b/packages/astro/src/vite-plugin-markdown-legacy/index.ts @@ -7,15 +7,16 @@ import { fileURLToPath } from 'url'; import type { Plugin, ViteDevServer } from 'vite'; import type { AstroConfig } from '../@types/astro'; import { pagesVirtualModuleId } from '../core/app/index.js'; +import { cachedCompilation, CompileProps } from '../core/compile/index.js'; import { collectErrorMetadata } from '../core/errors.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 { getFileInfo } from '../vite-plugin-utils/index.js'; +import { + createTransformStyles, + createViteStyleTransformer, + ViteStyleTransformer, +} from '../vite-style-transform/index.js'; interface AstroPluginOptions { config: AstroConfig; @@ -64,14 +65,17 @@ export default function markdown({ config, logging }: AstroPluginOptions): Plugi return false; } - let transformStyleWithVite: TransformStyleWithVite; + let styleTransformer: ViteStyleTransformer; let viteDevServer: ViteDevServer | undefined; return { name: 'astro:markdown', enforce: 'pre', configResolved(_resolvedConfig) { - transformStyleWithVite = createTransformStyleWithViteFn(_resolvedConfig); + styleTransformer = createViteStyleTransformer(_resolvedConfig); + }, + configureServer(server) { + styleTransformer.viteDevServer = server; }, async resolveId(id, importer, options) { // Resolve any .md files with the `?content` cache buster. This should only come from @@ -208,10 +212,12 @@ ${setup}`.trim(); filename, moduleId: id, source: astroResult, - ssr: Boolean(opts?.ssr), - transformStyleWithVite, - viteDevServer, - pluginContext: this, + transformStyle: createTransformStyles( + styleTransformer, + filename, + Boolean(opts?.ssr), + this + ), }; let transformResult = await cachedCompilation(compileProps); diff --git a/packages/astro/src/vite-style-transform/index.ts b/packages/astro/src/vite-style-transform/index.ts new file mode 100644 index 000000000..8e03caca6 --- /dev/null +++ b/packages/astro/src/vite-style-transform/index.ts @@ -0,0 +1,2 @@ +export type { ViteStyleTransformer } from './style-transform'; +export { createTransformStyles, createViteStyleTransformer } from './style-transform.js'; diff --git a/packages/astro/src/vite-style-transform/style-transform.ts b/packages/astro/src/vite-style-transform/style-transform.ts new file mode 100644 index 000000000..276a52246 --- /dev/null +++ b/packages/astro/src/vite-style-transform/style-transform.ts @@ -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; + }; +} diff --git a/packages/astro/src/vite-plugin-astro/styles.ts b/packages/astro/src/vite-style-transform/transform-with-vite.ts similarity index 100% rename from packages/astro/src/vite-plugin-astro/styles.ts rename to packages/astro/src/vite-style-transform/transform-with-vite.ts diff --git a/packages/astro/test/astro-client-only.test.js b/packages/astro/test/astro-client-only.test.js index 90e4b083d..0600b4950 100644 --- a/packages/astro/test/astro-client-only.test.js +++ b/packages/astro/test/astro-client-only.test.js @@ -3,6 +3,7 @@ import { load as cheerioLoad } from 'cheerio'; import { loadFixture } from './test-utils.js'; describe('Client only components', () => { + /** @type {import('./test-utils').Fixture} */ let fixture; before(async () => { @@ -39,6 +40,12 @@ describe('Client only components', () => { const $ = cheerioLoad(html); 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', () => { diff --git a/packages/astro/test/fixtures/astro-client-only/package.json b/packages/astro/test/fixtures/astro-client-only/package.json index dd987f6c2..69bef83c6 100644 --- a/packages/astro/test/fixtures/astro-client-only/package.json +++ b/packages/astro/test/fixtures/astro-client-only/package.json @@ -7,6 +7,7 @@ "@astrojs/react": "workspace:*", "astro": "workspace:*", "react": "^18.1.0", - "react-dom": "^18.1.0" + "react-dom": "^18.1.0", + "@test/astro-client-only-pkg": "file:./pkg" } } diff --git a/packages/astro/test/fixtures/astro-client-only/pkg/index.svelte b/packages/astro/test/fixtures/astro-client-only/pkg/index.svelte new file mode 100644 index 000000000..3e81de564 --- /dev/null +++ b/packages/astro/test/fixtures/astro-client-only/pkg/index.svelte @@ -0,0 +1,6 @@ +

Testing

+ diff --git a/packages/astro/test/fixtures/astro-client-only/pkg/package.json b/packages/astro/test/fixtures/astro-client-only/pkg/package.json new file mode 100644 index 000000000..03e6121e6 --- /dev/null +++ b/packages/astro/test/fixtures/astro-client-only/pkg/package.json @@ -0,0 +1,4 @@ +{ + "name": "@test/astro-client-only-pkg", + "main": "index.svelte" +} diff --git a/packages/astro/test/fixtures/astro-client-only/src/pages/pkg.astro b/packages/astro/test/fixtures/astro-client-only/src/pages/pkg.astro new file mode 100644 index 000000000..dbf693ef8 --- /dev/null +++ b/packages/astro/test/fixtures/astro-client-only/src/pages/pkg.astro @@ -0,0 +1,12 @@ +--- +import IndexSvelte from '@test/astro-client-only-pkg'; +--- + + + Testing + + +

Testing

+ + + diff --git a/packages/astro/test/fixtures/non-html-pages/package.json b/packages/astro/test/fixtures/non-html-pages/package.json new file mode 100644 index 000000000..c3a215d98 --- /dev/null +++ b/packages/astro/test/fixtures/non-html-pages/package.json @@ -0,0 +1,8 @@ +{ + "name": "@test/non-html-pages", + "version": "0.0.0", + "private": true, + "dependencies": { + "astro": "workspace:*" + } +} diff --git a/packages/astro/test/fixtures/non-html-pages/src/images/placeholder.png b/packages/astro/test/fixtures/non-html-pages/src/images/placeholder.png new file mode 100644 index 000000000..62841efdb Binary files /dev/null and b/packages/astro/test/fixtures/non-html-pages/src/images/placeholder.png differ diff --git a/packages/astro/test/fixtures/non-html-pages/src/pages/about.json.ts b/packages/astro/test/fixtures/non-html-pages/src/pages/about.json.ts new file mode 100644 index 000000000..af61847f3 --- /dev/null +++ b/packages/astro/test/fixtures/non-html-pages/src/pages/about.json.ts @@ -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/', + }), + }; +} diff --git a/packages/astro/test/fixtures/non-html-pages/src/pages/placeholder.png.ts b/packages/astro/test/fixtures/non-html-pages/src/pages/placeholder.png.ts new file mode 100644 index 000000000..0c2d3806b --- /dev/null +++ b/packages/astro/test/fixtures/non-html-pages/src/pages/placeholder.png.ts @@ -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}`); + } +}; diff --git a/packages/astro/test/fixtures/vue-with-multi-renderer/astro.config.mjs b/packages/astro/test/fixtures/vue-with-multi-renderer/astro.config.mjs new file mode 100644 index 000000000..3c67ad965 --- /dev/null +++ b/packages/astro/test/fixtures/vue-with-multi-renderer/astro.config.mjs @@ -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()], +}); diff --git a/packages/astro/test/fixtures/vue-with-multi-renderer/package.json b/packages/astro/test/fixtures/vue-with-multi-renderer/package.json new file mode 100644 index 000000000..e36b012a6 --- /dev/null +++ b/packages/astro/test/fixtures/vue-with-multi-renderer/package.json @@ -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:*" + } +} diff --git a/packages/astro/test/fixtures/vue-with-multi-renderer/src/components/Counter.vue b/packages/astro/test/fixtures/vue-with-multi-renderer/src/components/Counter.vue new file mode 100644 index 000000000..ed6fb5fb4 --- /dev/null +++ b/packages/astro/test/fixtures/vue-with-multi-renderer/src/components/Counter.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/packages/astro/test/fixtures/vue-with-multi-renderer/src/components/CounterWithScriptSetup.vue b/packages/astro/test/fixtures/vue-with-multi-renderer/src/components/CounterWithScriptSetup.vue new file mode 100644 index 000000000..1b63df0d6 --- /dev/null +++ b/packages/astro/test/fixtures/vue-with-multi-renderer/src/components/CounterWithScriptSetup.vue @@ -0,0 +1,15 @@ + + + diff --git a/packages/astro/test/fixtures/vue-with-multi-renderer/src/pages/index.astro b/packages/astro/test/fixtures/vue-with-multi-renderer/src/pages/index.astro new file mode 100644 index 000000000..12cd7bb54 --- /dev/null +++ b/packages/astro/test/fixtures/vue-with-multi-renderer/src/pages/index.astro @@ -0,0 +1,55 @@ +--- +import Counter from '../components/Counter.vue'; +import CounterWithScriptSetup from '../components/CounterWithScriptSetup.vue'; + +const someProps = { + count: 0, +}; +--- + + + + + + + +

Hello, server!

+
+ + +

Hello, client:idle!

+
+ + +

Hello, client:load!

+
+ + +

Hello, client:visible!

+
+ + +

Hello, client:media!

+
+ + +

Hello, server!

+
+ + +

Hello, client:idle!

+
+ + +

Hello, client:load!

+
+ + +

Hello, client:visible!

+
+ + +

Hello, client:media!

+
+ + diff --git a/packages/astro/test/non-html-pages.test.js b/packages/astro/test/non-html-pages.test.js new file mode 100644 index 000000000..e1b89ee6a --- /dev/null +++ b/packages/astro/test/non-html-pages.test.js @@ -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=' + ); + }); + }); +}); diff --git a/packages/astro/test/serialize.test.js b/packages/astro/test/serialize.test.js new file mode 100644 index 000000000..0646edfd7 --- /dev/null +++ b/packages/astro/test/serialize.test.js @@ -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(); + }); +}); diff --git a/packages/astro/test/test-utils.js b/packages/astro/test/test-utils.js index c6150b26b..59a925314 100644 --- a/packages/astro/test/test-utils.js +++ b/packages/astro/test/test-utils.js @@ -146,8 +146,8 @@ export async function loadFixture(inlineConfig) { const previewServer = await preview(config, { logging, telemetry, ...opts }); return previewServer; }, - readFile: (filePath) => - fs.promises.readFile(new URL(filePath.replace(/^\//, ''), config.outDir), 'utf8'), + readFile: (filePath, encoding) => + fs.promises.readFile(new URL(filePath.replace(/^\//, ''), config.outDir), encoding ?? 'utf8'), readdir: (fp) => fs.promises.readdir(new URL(fp.replace(/^\//, ''), config.outDir)), glob: (p) => fastGlob(p, { diff --git a/packages/astro/test/units/compile/invalid-css.test.js b/packages/astro/test/units/compile/invalid-css.test.js new file mode 100644 index 000000000..00d4fb7f6 --- /dev/null +++ b/packages/astro/test/units/compile/invalid-css.test.js @@ -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: ` + --- + --- + + + `, + 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'); + }); + }); +}); diff --git a/packages/astro/test/vue-with-multi-renderer.test.js b/packages/astro/test/vue-with-multi-renderer.test.js new file mode 100644 index 000000000..62ad96491 --- /dev/null +++ b/packages/astro/test/vue-with-multi-renderer.test.js @@ -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`); + } + }); +}); diff --git a/packages/integrations/alpinejs/README.md b/packages/integrations/alpinejs/README.md index 9eaf45382..7e7484767 100644 --- a/packages/integrations/alpinejs/README.md +++ b/packages/integrations/alpinejs/README.md @@ -25,8 +25,6 @@ yarn 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. ### Manual Install @@ -56,8 +54,6 @@ export default defineConfig({ }); ``` -Finally, restart the dev server. - ## 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. diff --git a/packages/integrations/image/CHANGELOG.md b/packages/integrations/image/CHANGELOG.md index 8e79766bc..8bdb6ee6e 100644 --- a/packages/integrations/image/CHANGELOG.md +++ b/packages/integrations/image/CHANGELOG.md @@ -1,5 +1,17 @@ # @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 ### Minor Changes diff --git a/packages/integrations/image/README.md b/packages/integrations/image/README.md index fda9727e6..fe3a69901 100644 --- a/packages/integrations/image/README.md +++ b/packages/integrations/image/README.md @@ -36,8 +36,6 @@ yarn 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. ### Manual Install @@ -58,7 +56,6 @@ export default { integrations: [image()], } ``` -Then, restart the dev server. ### 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 `rgb(100,100,100)`. -### ` +#### fit + +

+ +**Type:** `'cover' | 'contain' | 'fill' | 'inside' | 'outside'`
+**Default:** `'cover'` +

+ +How the image should be resized to fit both `height` and `width`. + +#### position + +

+ +**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'`
+**Default:** `'centre'` +

+ +Position of the crop when fit is `cover` or `contain`. + +### `` #### 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 `rgb(100,100,100)`. +#### fit + +

+ +**Type:** `'cover' | 'contain' | 'fill' | 'inside' | 'outside'`
+**Default:** `'cover'` +

+ +How the image should be resized to fit both `height` and `width`. + +#### position + +

+ +**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'`
+**Default:** `'centre'` +

+ +Position of the crop when fit is `cover` or `contain`. + ### `getImage` This is the helper function used by the `` component to build `` attributes for the transformed image. This helper can be used directly for more complex use cases that aren't currently supported by the `` component. @@ -469,7 +508,7 @@ const imageUrl = 'https://www.google.com/images/branding/googlelogo/2x/googlelog ``` ## 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 refreshing the page doesn't update your preview, or if a new installation doesn't seem to be working, then restart the dev server. diff --git a/packages/integrations/image/components/Picture.astro b/packages/integrations/image/components/Picture.astro index e28f5bf40..a2d80354a 100644 --- a/packages/integrations/image/components/Picture.astro +++ b/packages/integrations/image/components/Picture.astro @@ -38,7 +38,9 @@ const { sizes, widths, aspectRatio, + fit, background, + position, formats = ['avif', 'webp'], loading = 'lazy', decoding = 'async', @@ -49,7 +51,15 @@ if (alt === undefined || alt === null) { warnForMissingAlt(); } -const { image, sources } = await getPicture({ src, widths, formats, aspectRatio, background }); +const { image, sources } = await getPicture({ + src, + widths, + formats, + aspectRatio, + fit, + background, + position, +}); --- diff --git a/packages/integrations/image/package.json b/packages/integrations/image/package.json index 250c5cc5e..08e0447d0 100644 --- a/packages/integrations/image/package.json +++ b/packages/integrations/image/package.json @@ -1,7 +1,7 @@ { "name": "@astrojs/image", "description": "Load and transform images in your Astro site.", - "version": "0.6.0", + "version": "0.7.0", "type": "module", "types": "./dist/index.d.ts", "author": "withastro", diff --git a/packages/integrations/image/src/lib/get-picture.ts b/packages/integrations/image/src/lib/get-picture.ts index 2476686b7..132d93ee1 100644 --- a/packages/integrations/image/src/lib/get-picture.ts +++ b/packages/integrations/image/src/lib/get-picture.ts @@ -10,7 +10,9 @@ export interface GetPictureParams { widths: number[]; formats: OutputFormat[]; aspectRatio?: TransformOptions['aspectRatio']; + fit?: TransformOptions['fit']; background?: TransformOptions['background']; + position?: TransformOptions['position']; } export interface GetPictureResult { @@ -41,7 +43,7 @@ async function resolveFormats({ src, formats }: GetPictureParams) { } export async function getPicture(params: GetPictureParams): Promise { - const { src, widths } = params; + const { src, widths, fit, position, background } = params; if (!src) { throw new Error('[@astrojs/image] `src` is required'); @@ -64,8 +66,10 @@ export async function getPicture(params: GetPictureParams): Promise getSource(format))); diff --git a/packages/integrations/image/src/loaders/index.ts b/packages/integrations/image/src/loaders/index.ts index c031b60f0..069491702 100644 --- a/packages/integrations/image/src/loaders/index.ts +++ b/packages/integrations/image/src/loaders/index.ts @@ -21,6 +21,31 @@ export type ColorDefinition = | `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 { return ['avif', 'jpeg', 'jpg', 'png', 'webp'].includes(value); } @@ -105,6 +130,18 @@ export interface TransformOptions { * @example "rgb(255, 255, 255)" - an rgb color */ 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 { @@ -191,10 +228,18 @@ export abstract class BaseSSRService implements SSRImageService { searchParams.append('ar', transform.aspectRatio.toString()); } + if (transform.fit) { + searchParams.append('fit', transform.fit); + } + if (transform.background) { searchParams.append('bg', transform.background); } + if (transform.position) { + searchParams.append('p', encodeURI(transform.position)); + } + searchParams.append('href', transform.src); 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')) { transform.background = searchParams.get('bg') as ColorDefinition; } diff --git a/packages/integrations/image/src/loaders/sharp.ts b/packages/integrations/image/src/loaders/sharp.ts index 7d5e9973c..cf838ddb2 100644 --- a/packages/integrations/image/src/loaders/sharp.ts +++ b/packages/integrations/image/src/loaders/sharp.ts @@ -13,7 +13,14 @@ class SharpService extends BaseSSRService { if (transform.width || transform.height) { const width = transform.width && Math.round(transform.width); 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 diff --git a/packages/integrations/image/test/sharp.test.js b/packages/integrations/image/test/sharp.test.js index 81172504b..4d4005770 100644 --- a/packages/integrations/image/test/sharp.test.js +++ b/packages/integrations/image/test/sharp.test.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; import sharp from '../dist/loaders/sharp.js'; -describe('Sharp service', () => { +describe.only('Sharp service', () => { describe('serializeTransform', () => { const src = '/assets/image.png'; @@ -15,6 +15,8 @@ describe('Sharp service', () => { ['aspect ratio string', { src, aspectRatio: '16:9' }], ['aspect ratio float', { src, aspectRatio: 1.7 }], ['background color', { src, format: 'jpeg', background: '#333333' }], + ['crop fit', { src, fit: 'cover' }], + ['crop position', { src, position: 'center' }], ].forEach(([description, props]) => { it(description, async () => { const { searchParams } = await sharp.serializeTransform(props); @@ -32,6 +34,8 @@ describe('Sharp service', () => { verifyProp(props.width, 'w'); verifyProp(props.height, 'h'); verifyProp(props.aspectRatio, 'ar'); + verifyProp(props.fit, 'fit'); + verifyProp(props.position, 'p'); verifyProp(props.background, 'bg'); }); }); @@ -55,6 +59,8 @@ describe('Sharp service', () => { `f=jpeg&bg=%23333333&href=${href}`, { 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]) => { it(description, async () => { const searchParams = new URLSearchParams(params); diff --git a/packages/integrations/lit/README.md b/packages/integrations/lit/README.md index 97b836bc0..af3f78238 100644 --- a/packages/integrations/lit/README.md +++ b/packages/integrations/lit/README.md @@ -23,8 +23,6 @@ yarn 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. ### Install dependencies manually diff --git a/packages/integrations/mdx/README.md b/packages/integrations/mdx/README.md index 2ce12d9cd..181e55faa 100644 --- a/packages/integrations/mdx/README.md +++ b/packages/integrations/mdx/README.md @@ -33,8 +33,6 @@ yarn 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. ### Manual Install @@ -61,6 +59,16 @@ export default defineConfig({ 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 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. diff --git a/packages/integrations/node/README.md b/packages/integrations/node/README.md index cb2297081..3ab5f0b17 100644 --- a/packages/integrations/node/README.md +++ b/packages/integrations/node/README.md @@ -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} import { defineConfig } from 'astro/config'; - import netlify from '@astrojs/node'; + import node from '@astrojs/node'; export default defineConfig({ output: 'server', diff --git a/packages/integrations/partytown/README.md b/packages/integrations/partytown/README.md index 6ff8dd200..ab1f15eb0 100644 --- a/packages/integrations/partytown/README.md +++ b/packages/integrations/partytown/README.md @@ -35,8 +35,6 @@ yarn 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. ### Manual Install @@ -59,7 +57,6 @@ export default defineConfig({ }) ``` -Then, restart the dev server. ## Usage diff --git a/packages/integrations/preact/README.md b/packages/integrations/preact/README.md index 2a8779737..742d3654b 100644 --- a/packages/integrations/preact/README.md +++ b/packages/integrations/preact/README.md @@ -35,8 +35,6 @@ yarn 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. ### Manual Install @@ -67,8 +65,6 @@ export default defineConfig({ }); ``` -Finally, restart the dev server. - ## Usage To use your first Preact component in Astro, head to our [UI framework documentation][astro-ui-frameworks]. You'll explore: diff --git a/packages/integrations/prefetch/README.md b/packages/integrations/prefetch/README.md index e3ae6e72a..009cd5fda 100644 --- a/packages/integrations/prefetch/README.md +++ b/packages/integrations/prefetch/README.md @@ -29,8 +29,6 @@ yarn 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. ### Manual Install @@ -52,7 +50,6 @@ export default { } ``` -Then, restart the dev server. ## Usage @@ -94,7 +91,7 @@ export default { ``` ## 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. For help, check out the `#support-threads` channel on [Discord](https://astro.build/chat). Our friendly Support Squad members are here to help! diff --git a/packages/integrations/react/CHANGELOG.md b/packages/integrations/react/CHANGELOG.md index 0971832ec..d029111a5 100644 --- a/packages/integrations/react/CHANGELOG.md +++ b/packages/integrations/react/CHANGELOG.md @@ -1,5 +1,13 @@ # @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 ### Patch Changes diff --git a/packages/integrations/react/README.md b/packages/integrations/react/README.md index 1e502b6c0..e254ee901 100644 --- a/packages/integrations/react/README.md +++ b/packages/integrations/react/README.md @@ -23,8 +23,6 @@ yarn 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. ### Install dependencies manually diff --git a/packages/integrations/react/package.json b/packages/integrations/react/package.json index 042c01567..46a907c30 100644 --- a/packages/integrations/react/package.json +++ b/packages/integrations/react/package.json @@ -1,7 +1,7 @@ { "name": "@astrojs/react", "description": "Use React components within Astro", - "version": "1.1.1", + "version": "1.1.2", "type": "module", "types": "./dist/index.d.ts", "author": "withastro", diff --git a/packages/integrations/sitemap/README.md b/packages/integrations/sitemap/README.md index 58a3cc1d6..b05c5aac2 100644 --- a/packages/integrations/sitemap/README.md +++ b/packages/integrations/sitemap/README.md @@ -35,8 +35,6 @@ yarn 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. ### Manual Install @@ -59,7 +57,6 @@ export default defineConfig({ }) ``` -Then, restart the dev server. ## Usage diff --git a/packages/integrations/solid/README.md b/packages/integrations/solid/README.md index 5afe62c11..63daaefdf 100644 --- a/packages/integrations/solid/README.md +++ b/packages/integrations/solid/README.md @@ -23,8 +23,6 @@ yarn 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. ### Install dependencies manually diff --git a/packages/integrations/svelte/README.md b/packages/integrations/svelte/README.md index 8acd41a6f..9c48177e8 100644 --- a/packages/integrations/svelte/README.md +++ b/packages/integrations/svelte/README.md @@ -23,8 +23,6 @@ yarn 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. ### Install dependencies manually diff --git a/packages/integrations/tailwind/README.md b/packages/integrations/tailwind/README.md index df1002038..9eaf95452 100644 --- a/packages/integrations/tailwind/README.md +++ b/packages/integrations/tailwind/README.md @@ -38,8 +38,6 @@ yarn 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. ### Manual Install @@ -61,7 +59,6 @@ export default { } ``` -Then, restart the dev server. ## 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! ## 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 refreshing the page doesn't update your preview, or if a new installation doesn't seem to be working, then restart the dev server. diff --git a/packages/integrations/turbolinks/README.md b/packages/integrations/turbolinks/README.md index 15ece4721..569015d85 100644 --- a/packages/integrations/turbolinks/README.md +++ b/packages/integrations/turbolinks/README.md @@ -33,8 +33,6 @@ yarn 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. ### Install dependencies manually diff --git a/packages/integrations/vue/README.md b/packages/integrations/vue/README.md index 66b320629..9666bf394 100644 --- a/packages/integrations/vue/README.md +++ b/packages/integrations/vue/README.md @@ -23,8 +23,6 @@ yarn 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. ### Install dependencies manually diff --git a/packages/integrations/vue/server.js b/packages/integrations/vue/server.js index 883aa4de0..8d4c6df9e 100644 --- a/packages/integrations/vue/server.js +++ b/packages/integrations/vue/server.js @@ -3,7 +3,7 @@ import { renderToString } from 'vue/server-renderer'; import StaticHtml from './static-html.js'; function check(Component) { - return !!Component['ssrRender']; + return !!Component['ssrRender'] || !!Component['__ssrInlineRender']; } async function renderToStaticMarkup(Component, props, slotted) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 376f6293e..407a5bc6e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -56,7 +56,7 @@ importers: examples/basics: specifiers: - astro: ^1.1.7 + astro: ^1.2.1 dependencies: astro: link:../../packages/astro @@ -65,7 +65,7 @@ importers: '@astrojs/mdx': ^0.11.1 '@astrojs/rss': ^1.0.0 '@astrojs/sitemap': ^1.0.0 - astro: ^1.1.7 + astro: ^1.2.1 dependencies: '@astrojs/mdx': link:../../packages/integrations/mdx '@astrojs/rss': link:../../packages/astro-rss @@ -74,7 +74,7 @@ importers: examples/component: specifiers: - astro: ^1.1.7 + astro: ^1.2.1 devDependencies: astro: link:../../packages/astro @@ -82,13 +82,13 @@ importers: specifiers: '@algolia/client-search': ^4.13.1 '@astrojs/preact': ^1.1.0 - '@astrojs/react': ^1.1.0 + '@astrojs/react': ^1.1.2 '@docsearch/css': ^3.1.0 '@docsearch/react': ^3.1.0 '@types/node': ^18.0.0 '@types/react': ^17.0.45 '@types/react-dom': ^18.0.0 - astro: ^1.1.7 + astro: ^1.2.1 preact: ^10.7.3 react: ^18.1.0 react-dom: ^18.1.0 @@ -111,7 +111,7 @@ importers: '@astrojs/alpinejs': ^0.1.2 '@types/alpinejs': ^3.7.0 alpinejs: ^3.10.2 - astro: ^1.1.7 + astro: ^1.2.1 dependencies: '@astrojs/alpinejs': link:../../packages/integrations/alpinejs '@types/alpinejs': 3.7.0 @@ -122,7 +122,7 @@ importers: specifiers: '@astrojs/lit': ^1.0.0 '@webcomponents/template-shadowroot': ^0.1.0 - astro: ^1.1.7 + astro: ^1.2.1 lit: ^2.2.5 dependencies: '@astrojs/lit': link:../../packages/integrations/lit @@ -133,11 +133,11 @@ importers: examples/framework-multiple: specifiers: '@astrojs/preact': ^1.1.0 - '@astrojs/react': ^1.1.0 + '@astrojs/react': ^1.1.2 '@astrojs/solid-js': ^1.1.0 '@astrojs/svelte': ^1.0.0 '@astrojs/vue': ^1.0.1 - astro: ^1.1.7 + astro: ^1.2.1 preact: ^10.7.3 react: ^18.1.0 react-dom: ^18.1.0 @@ -155,13 +155,13 @@ importers: react: 18.2.0 react-dom: 18.2.0_react@18.2.0 solid-js: 1.5.4 - svelte: 3.50.0 + svelte: 3.50.1 vue: 3.2.39 examples/framework-preact: specifiers: '@astrojs/preact': ^1.1.0 - astro: ^1.1.7 + astro: ^1.2.1 preact: ^10.7.3 dependencies: '@astrojs/preact': link:../../packages/integrations/preact @@ -170,10 +170,10 @@ importers: examples/framework-react: specifiers: - '@astrojs/react': ^1.1.0 + '@astrojs/react': ^1.1.2 '@types/react': ^18.0.10 '@types/react-dom': ^18.0.5 - astro: ^1.1.7 + astro: ^1.2.1 react: ^18.1.0 react-dom: ^18.1.0 dependencies: @@ -187,7 +187,7 @@ importers: examples/framework-solid: specifiers: '@astrojs/solid-js': ^1.1.0 - astro: ^1.1.7 + astro: ^1.2.1 solid-js: ^1.4.3 dependencies: '@astrojs/solid-js': link:../../packages/integrations/solid @@ -197,17 +197,17 @@ importers: examples/framework-svelte: specifiers: '@astrojs/svelte': ^1.0.0 - astro: ^1.1.7 + astro: ^1.2.1 svelte: ^3.48.0 dependencies: '@astrojs/svelte': link:../../packages/integrations/svelte astro: link:../../packages/astro - svelte: 3.50.0 + svelte: 3.50.1 examples/framework-vue: specifiers: '@astrojs/vue': ^1.0.1 - astro: ^1.1.7 + astro: ^1.2.1 vue: ^3.2.37 dependencies: '@astrojs/vue': link:../../packages/integrations/vue @@ -216,19 +216,19 @@ importers: examples/minimal: specifiers: - astro: ^1.1.7 + astro: ^1.2.1 dependencies: astro: link:../../packages/astro examples/non-html-pages: specifiers: - astro: ^1.1.7 + astro: ^1.2.1 dependencies: astro: link:../../packages/astro examples/portfolio: specifiers: - astro: ^1.1.7 + astro: ^1.2.1 dependencies: astro: link:../../packages/astro @@ -236,7 +236,7 @@ importers: specifiers: '@astrojs/node': ^1.0.1 '@astrojs/svelte': ^1.0.0 - astro: ^1.1.7 + astro: ^1.2.1 concurrently: ^7.2.1 lightcookie: ^1.0.25 svelte: ^3.48.0 @@ -248,14 +248,14 @@ importers: astro: link:../../packages/astro concurrently: 7.4.0 lightcookie: 1.0.25 - svelte: 3.50.0 + svelte: 3.50.1 unocss: 0.15.6 vite-imagetools: 4.0.9 examples/with-markdown-plugins: specifiers: '@astrojs/markdown-remark': ^1.1.0 - astro: ^1.1.7 + astro: ^1.2.1 hast-util-select: 5.0.1 rehype-autolink-headings: ^6.1.1 rehype-slug: ^5.0.1 @@ -272,7 +272,7 @@ importers: examples/with-markdown-shiki: specifiers: - astro: ^1.1.7 + astro: ^1.2.1 dependencies: astro: link:../../packages/astro @@ -280,7 +280,7 @@ importers: specifiers: '@astrojs/mdx': ^0.11.1 '@astrojs/preact': ^1.1.0 - astro: ^1.1.7 + astro: ^1.2.1 preact: ^10.6.5 dependencies: '@astrojs/mdx': link:../../packages/integrations/mdx @@ -292,7 +292,7 @@ importers: specifiers: '@astrojs/preact': ^1.1.0 '@nanostores/preact': ^0.1.3 - astro: ^1.1.7 + astro: ^1.2.1 nanostores: ^0.5.12 preact: ^10.7.3 dependencies: @@ -305,7 +305,7 @@ importers: examples/with-tailwindcss: specifiers: '@astrojs/tailwind': ^1.0.0 - astro: ^1.1.7 + astro: ^1.2.1 autoprefixer: ^10.4.7 canvas-confetti: ^1.5.1 postcss: ^8.4.14 @@ -320,7 +320,7 @@ importers: examples/with-vite-plugin-pwa: specifiers: - astro: ^1.1.7 + astro: ^1.2.1 vite-plugin-pwa: 0.11.11 workbox-window: ^6.5.3 dependencies: @@ -330,7 +330,7 @@ importers: examples/with-vitest: specifiers: - astro: ^1.1.7 + astro: ^1.2.1 vitest: ^0.20.3 dependencies: astro: link:../../packages/astro @@ -338,7 +338,7 @@ importers: packages/astro: specifiers: - '@astrojs/compiler': ^0.23.5 + '@astrojs/compiler': ^0.24.0 '@astrojs/language-server': ^0.23.0 '@astrojs/markdown-remark': ^1.1.1 '@astrojs/telemetry': ^1.0.0 @@ -350,7 +350,7 @@ importers: '@babel/traverse': ^7.18.2 '@babel/types': ^7.18.4 '@playwright/test': ^1.22.2 - '@proload/core': ^0.3.2 + '@proload/core': ^0.3.3 '@proload/plugin-tsm': ^0.2.1 '@types/babel__core': ^7.1.19 '@types/babel__generator': ^7.6.4 @@ -421,7 +421,7 @@ importers: yargs-parser: ^21.0.1 zod: ^3.17.3 dependencies: - '@astrojs/compiler': 0.23.5 + '@astrojs/compiler': 0.24.0 '@astrojs/language-server': 0.23.3 '@astrojs/markdown-remark': link:../markdown/remark '@astrojs/telemetry': link:../telemetry @@ -434,6 +434,9 @@ importers: '@babel/types': 7.19.0 '@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 ci-info: 3.3.2 common-ancestor-path: 1.0.1 @@ -443,7 +446,7 @@ importers: es-module-lexer: 0.10.5 esbuild: 0.14.54 execa: 6.1.0 - fast-glob: 3.2.11 + fast-glob: 3.2.12 github-slugger: 1.4.0 gray-matter: 4.0.3 html-entities: 2.3.3 @@ -471,13 +474,12 @@ importers: supports-esm: 1.0.0 tsconfig-resolver: 3.0.1 unist-util-visit: 4.1.1 - vfile: 5.3.4 + vfile: 5.3.5 vite: 3.0.9_sass@1.54.9 yargs-parser: 21.1.1 zod: 3.19.0 devDependencies: '@playwright/test': 1.25.2 - '@types/babel__core': 7.1.19 '@types/babel__generator': 7.6.4 '@types/babel__traverse': 7.18.1 '@types/chai': 4.3.3 @@ -486,7 +488,6 @@ importers: '@types/debug': 4.1.7 '@types/diff': 5.0.2 '@types/estree': 0.0.51 - '@types/html-escaper': 3.0.0 '@types/mime': 2.0.3 '@types/mocha': 9.1.1 '@types/parse5': 6.0.3 @@ -496,7 +497,6 @@ importers: '@types/rimraf': 3.0.2 '@types/send': 0.17.1 '@types/unist': 2.0.6 - '@types/yargs-parser': 21.0.0 ast-types: 0.14.2 astro-scripts: link:../../scripts chai: 4.3.6 @@ -564,7 +564,7 @@ importers: react: 18.2.0 react-dom: 18.2.0_react@18.2.0 solid-js: 1.5.4 - svelte: 3.50.0 + svelte: 3.50.1 vue: 3.2.39 devDependencies: '@astrojs/preact': link:../../../../integrations/preact @@ -674,7 +674,7 @@ importers: react: 18.2.0 react-dom: 18.2.0_react@18.2.0 solid-js: 1.5.4 - svelte: 3.50.0 + svelte: 3.50.1 vue: 3.2.39 devDependencies: '@astrojs/lit': link:../../../../integrations/lit @@ -717,7 +717,7 @@ importers: react: 18.2.0 react-dom: 18.2.0_react@18.2.0 solid-js: 1.5.4 - svelte: 3.50.0 + svelte: 3.50.1 vue: 3.2.39 devDependencies: '@astrojs/preact': link:../../../../integrations/preact @@ -746,7 +746,7 @@ importers: react: 18.2.0 react-dom: 18.2.0_react@18.2.0 solid-js: 1.5.4 - svelte: 3.50.0 + svelte: 3.50.1 vue: 3.2.39 devDependencies: '@astrojs/preact': link:../../../../integrations/preact @@ -775,7 +775,7 @@ importers: react: 18.2.0 react-dom: 18.2.0_react@18.2.0 solid-js: 1.5.4 - svelte: 3.50.0 + svelte: 3.50.1 vue: 3.2.39 devDependencies: '@astrojs/preact': link:../../../../integrations/preact @@ -804,7 +804,7 @@ importers: react: 18.2.0 react-dom: 18.2.0_react@18.2.0 solid-js: 1.5.4 - svelte: 3.50.0 + svelte: 3.50.1 vue: 3.2.39 devDependencies: '@astrojs/preact': link:../../../../integrations/preact @@ -833,7 +833,7 @@ importers: react: 18.2.0 react-dom: 18.2.0_react@18.2.0 solid-js: 1.5.4 - svelte: 3.50.0 + svelte: 3.50.1 vue: 3.2.39 devDependencies: '@astrojs/preact': link:../../../../integrations/preact @@ -862,7 +862,7 @@ importers: react: 18.2.0 react-dom: 18.2.0_react@18.2.0 solid-js: 1.5.4 - svelte: 3.50.0 + svelte: 3.50.1 vue: 3.2.39 devDependencies: '@astrojs/preact': link:../../../../integrations/preact @@ -961,7 +961,7 @@ importers: '@astrojs/mdx': link:../../../../integrations/mdx '@astrojs/svelte': link:../../../../integrations/svelte astro: link:../../.. - svelte: 3.50.0 + svelte: 3.50.1 packages/astro/e2e/fixtures/tailwindcss: specifiers: @@ -1097,16 +1097,21 @@ importers: specifiers: '@astrojs/react': workspace:* '@astrojs/svelte': workspace:* + '@test/astro-client-only-pkg': file:./pkg astro: workspace:* react: ^18.1.0 react-dom: ^18.1.0 dependencies: '@astrojs/react': link:../../../../integrations/react '@astrojs/svelte': link:../../../../integrations/svelte + '@test/astro-client-only-pkg': file:packages/astro/test/fixtures/astro-client-only/pkg astro: link:../../.. 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: specifiers: astro: workspace:* @@ -1596,7 +1601,7 @@ importers: react: 18.2.0 react-dom: 18.2.0_react@18.2.0 solid-js: 1.5.4 - svelte: 3.50.0 + svelte: 3.50.1 vue: 3.2.39 devDependencies: '@astrojs/preact': link:../../../../integrations/preact @@ -1666,6 +1671,12 @@ importers: packages/astro/test/fixtures/multiple-renderers/renderers/two: specifiers: {} + packages/astro/test/fixtures/non-html-pages: + specifiers: + astro: workspace:* + dependencies: + astro: link:../../.. + packages/astro/test/fixtures/page-format: specifiers: astro: workspace:* @@ -2062,6 +2073,16 @@ importers: '@astrojs/vue': link:../../../../integrations/vue 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: specifiers: astro: workspace:* @@ -2351,7 +2372,7 @@ importers: remark-smartypants: 2.0.0 shiki: 0.11.1 unist-util-visit: 4.1.1 - vfile: 5.3.4 + vfile: 5.3.5 devDependencies: '@types/chai': 4.3.3 '@types/mocha': 9.1.1 @@ -2605,15 +2626,15 @@ importers: svelte2tsx: ^0.5.11 vite: ^3.0.0 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 - svelte-preprocess: 4.10.7_5llrep7g7lww57fglza6pzz77u - svelte2tsx: 0.5.16_svelte@3.50.0 + svelte-preprocess: 4.10.7_dnlyed3grtnuceggogyodrmgvm + svelte2tsx: 0.5.16_svelte@3.50.1 vite: 3.1.0 devDependencies: astro: link:../../astro astro-scripts: link:../../../scripts - svelte: 3.50.0 + svelte: 3.50.1 packages/integrations/tailwind: specifiers: @@ -2837,7 +2858,7 @@ importers: unified: 10.1.2 unist-util-map: 3.1.1 unist-util-visit: 4.1.1 - vfile: 5.3.4 + vfile: 5.3.5 devDependencies: '@types/chai': 4.3.3 '@types/github-slugger': 1.3.0 @@ -2945,7 +2966,7 @@ importers: esbuild: 0.14.54 globby: 12.2.0 kleur: 4.1.5 - svelte: 3.50.0 + svelte: 3.50.1 tar: 6.1.11 packages: @@ -3234,6 +3255,10 @@ packages: resolution: {integrity: sha512-vBMPy9ok4iLapSyCCT1qsZ9dK7LkVFl9mObtLEmWiec9myGHS9h2kQY2xzPeFNJiWXUf9O6tSyQpQTy5As/p3g==} dev: false + /@astrojs/compiler/0.24.0: + resolution: {integrity: sha512-xZ81C/oMfExdF18I1Tyd2BKKzBqO+qYYctSy4iCwH4UWSo/4Y8A8MAzV1hG67uuE7hFRourSl6H5KUbhyChv/A==} + dev: false + /@astrojs/language-server/0.23.3: resolution: {integrity: sha512-ROoMKo37NZ76pE/A2xHfjDlgfsNnFmkhL4+Wifs0L855n73SUCbnXz7ZaQktIGAq2Te2TpSjAawiOx0q9L5qeg==} hasBin: true @@ -5371,7 +5396,7 @@ packages: unist-util-position-from-estree: 1.1.1 unist-util-stringify-position: 3.0.2 unist-util-visit: 4.1.1 - vfile: 5.3.4 + vfile: 5.3.5 transitivePeerDependencies: - supports-color dev: false @@ -5387,7 +5412,7 @@ packages: '@mdx-js/mdx': 2.1.3 '@rollup/pluginutils': 4.2.1 source-map: 0.7.4 - vfile: 5.3.4 + vfile: 5.3.5 transitivePeerDependencies: - supports-color dev: false @@ -8769,7 +8794,7 @@ packages: string.prototype.matchall: 4.0.7 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==} engines: {node: ^14.18.0 || >= 16} peerDependencies: @@ -8787,8 +8812,8 @@ packages: deepmerge: 4.2.2 kleur: 4.1.5 magic-string: 0.26.3 - svelte: 3.50.0 - svelte-hmr: 0.14.12_svelte@3.50.0 + svelte: 3.50.1 + svelte-hmr: 0.14.12_svelte@3.50.1 vite: 3.1.0 transitivePeerDependencies: - supports-color @@ -8802,7 +8827,7 @@ packages: /@ts-morph/common/0.16.0: resolution: {integrity: sha512-SgJpzkTgZKLKqQniCjLaE3c2L2sdL7UShvmTmPBejAKd2OKV/yfMpQ2IWpAuA+VY5wy7PkSUaEObIqEK6afFuw==} dependencies: - fast-glob: 3.2.11 + fast-glob: 3.2.12 minimatch: 5.1.0 mkdirp: 1.0.4 path-browserify: 1.0.1 @@ -8828,26 +8853,24 @@ packages: '@types/babel__generator': 7.6.4 '@types/babel__template': 7.4.1 '@types/babel__traverse': 7.18.1 - dev: true + dev: false /@types/babel__generator/7.6.4: resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} dependencies: '@babel/types': 7.19.0 - dev: true /@types/babel__template/7.4.1: resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} dependencies: '@babel/parser': 7.19.0 '@babel/types': 7.19.0 - dev: true + dev: false /@types/babel__traverse/7.18.1: resolution: {integrity: sha512-FSdLaZh2UxaMuLp9lixWaHq/golWTRWOnRsAXzDTDSDOQLuZb1nsdCt6pJSPWSEQt2eFZ2YVk3oYhn+1kLMeMA==} dependencies: '@babel/types': 7.19.0 - dev: true /@types/chai-as-promised/7.1.5: resolution: {integrity: sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==} @@ -8936,7 +8959,7 @@ packages: /@types/html-escaper/3.0.0: resolution: {integrity: sha512-OcJcvP3Yk8mjYwf/IdXZtTE1tb/u0WF0qa29ER07ZHCYUBZXSN29Z1mBS+/96+kNMGTFUAbSz9X+pHmHpZrTCw==} - dev: true + dev: false /@types/is-ci/3.0.0: resolution: {integrity: sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ==} @@ -9147,7 +9170,6 @@ packages: /@types/yargs-parser/21.0.0: resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} - dev: true /@typescript-eslint/eslint-plugin/5.36.2_kou65mzxaniwtkb2mhvaghdcyi: resolution: {integrity: sha512-OwwR8LRwSnI98tdc2z7mJYgY60gf7I9ZfGjN5EjCwwns9bdTuQfAXcsjSB2wSQ/TVNYSGKf4kzVXbNGaZvwiXw==} @@ -9322,7 +9344,7 @@ packages: chokidar: 3.5.3 colorette: 2.0.19 consola: 2.15.3 - fast-glob: 3.2.11 + fast-glob: 3.2.12 pathe: 0.2.0 dev: false @@ -10022,7 +10044,7 @@ packages: hasBin: true dependencies: caniuse-lite: 1.0.30001393 - electron-to-chromium: 1.4.244 + electron-to-chromium: 1.4.246 node-releases: 2.0.6 update-browserslist-db: 1.0.7_browserslist@4.21.3 @@ -10839,8 +10861,8 @@ packages: jake: 10.8.5 dev: false - /electron-to-chromium/1.4.244: - resolution: {integrity: sha512-E21saXLt2eTDaTxgUtiJtBUqanF9A32wZasAwDZ8gvrqXoxrBrbwtDCx7c/PQTLp81wj4X0OLDeoGQg7eMo3+w==} + /electron-to-chromium/1.4.246: + resolution: {integrity: sha512-/wFCHUE+Hocqr/LlVGsuKLIw4P2lBWwFIDcNMDpJGzyIysQV4aycpoOitAs32FT94EHKnNqDR/CVZJFbXEufJA==} /emmet/2.3.6: resolution: {integrity: sha512-pLS4PBPDdxuUAmw7Me7+TcHbykTsBKN/S9XJbUOMFQrNv9MoshzyMFK/R57JBm94/6HSL4vHnDeEmxlC82NQ4A==} @@ -11847,8 +11869,8 @@ packages: resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==} dev: true - /fast-glob/3.2.11: - resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==} + /fast-glob/3.2.12: + resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} engines: {node: '>=8.6.0'} dependencies: '@nodelib/fs.stat': 2.0.5 @@ -12212,7 +12234,7 @@ packages: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.2.11 + fast-glob: 3.2.12 ignore: 5.2.0 merge2: 1.4.1 slash: 3.0.0 @@ -12224,7 +12246,7 @@ packages: dependencies: array-union: 3.0.1 dir-glob: 3.0.1 - fast-glob: 3.2.11 + fast-glob: 3.2.12 ignore: 5.2.0 merge2: 1.4.1 slash: 4.0.0 @@ -12334,7 +12356,7 @@ packages: '@types/unist': 2.0.6 hastscript: 7.0.2 property-information: 6.1.1 - vfile: 5.3.4 + vfile: 5.3.5 vfile-location: 4.0.1 web-namespaces: 2.0.1 dev: false @@ -12373,7 +12395,7 @@ packages: parse5: 6.0.1 unist-util-position: 4.0.3 unist-util-visit: 4.1.1 - vfile: 5.3.4 + vfile: 5.3.5 web-namespaces: 2.0.1 zwitch: 2.0.2 dev: false @@ -15640,7 +15662,7 @@ packages: shiki: 0.10.1 shiki-twoslash: 3.1.0 tslib: 2.1.0 - typescript: 4.8.2 + typescript: 4.8.3 unist-util-visit: 2.0.3 transitivePeerDependencies: - supports-color @@ -16000,7 +16022,7 @@ packages: '@typescript/twoslash': 3.1.0 '@typescript/vfs': 1.3.4 shiki: 0.10.1 - typescript: 4.8.2 + typescript: 4.8.3 transitivePeerDependencies: - supports-color dev: true @@ -16431,16 +16453,16 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 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==} engines: {node: ^12.20 || ^14.13.1 || >= 16} peerDependencies: svelte: '>=3.19.0' dependencies: - svelte: 3.50.0 + svelte: 3.50.1 dev: false - /svelte-preprocess/4.10.7_5llrep7g7lww57fglza6pzz77u: + /svelte-preprocess/4.10.7_dnlyed3grtnuceggogyodrmgvm: resolution: {integrity: sha512-sNPBnqYD6FnmdBrUmBCaqS00RyCsCpj2BG58A1JBswNF7b0OKviwxqVrOL/CKyJrLSClrSeqQv5BXNg2RUbPOw==} engines: {node: '>= 9.11.2'} requiresBuild: true @@ -16488,14 +16510,14 @@ packages: postcss-load-config: 3.1.4 sorcery: 0.10.0 strip-indent: 3.0.0 - svelte: 3.50.0 + svelte: 3.50.1 dev: false - /svelte/3.50.0: - resolution: {integrity: sha512-zXeOUDS7+85i+RxLN+0iB6PMbGH7OhEgjETcD1fD8ZrhuhNFxYxYEHU41xuhkHIulJavcu3PKbPyuCrBxdxskQ==} + /svelte/3.50.1: + resolution: {integrity: sha512-bS4odcsdj5D5jEg6riZuMg5NKelzPtmsCbD9RG+8umU03TeNkdWnP6pqbCm0s8UQNBkqk29w/Bdubn3C+HWSwA==} engines: {node: '>= 8'} - /svelte2tsx/0.5.16_svelte@3.50.0: + /svelte2tsx/0.5.16_svelte@3.50.1: resolution: {integrity: sha512-MwgpeRHfzP8T7NkFNT1JPhe9pCF4Dml2oSdjL2zNqvSprjA2BFgQuCNUg4R5qSz7AxVDJsiL/2hciCtVbXAT3A==} peerDependencies: svelte: ^3.24 @@ -16506,7 +16528,7 @@ packages: dependencies: dedent-js: 1.0.1 pascal-case: 3.1.2 - svelte: 3.50.0 + svelte: 3.50.1 dev: false /synckit/0.7.3: @@ -16529,7 +16551,7 @@ packages: detective: 5.2.1 didyoumean: 1.2.2 dlv: 1.1.3 - fast-glob: 3.2.11 + fast-glob: 3.2.12 glob-parent: 6.0.2 is-glob: 4.0.3 lilconfig: 2.0.6 @@ -16969,8 +16991,8 @@ packages: hasBin: true dev: true - /typescript/4.8.2: - resolution: {integrity: sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==} + /typescript/4.8.3: + resolution: {integrity: sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==} engines: {node: '>=4.2.0'} hasBin: true dev: true @@ -17036,7 +17058,7 @@ packages: is-buffer: 2.0.5 is-plain-obj: 4.1.0 trough: 2.1.0 - vfile: 5.3.4 + vfile: 5.3.5 /unique-string/2.0.0: resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} @@ -17259,7 +17281,7 @@ packages: resolution: {integrity: sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==} dependencies: '@types/unist': 2.0.6 - vfile: 5.3.4 + vfile: 5.3.5 dev: false /vfile-message/3.1.2: @@ -17268,8 +17290,8 @@ packages: '@types/unist': 2.0.6 unist-util-stringify-position: 3.0.2 - /vfile/5.3.4: - resolution: {integrity: sha512-KI+7cnst03KbEyN1+JE504zF5bJBZa+J+CrevLeyIMq0aPU681I2rQ5p4PlnQ6exFtWiUrg26QUdFMnAKR6PIw==} + /vfile/5.3.5: + resolution: {integrity: sha512-U1ho2ga33eZ8y8pkbQLH54uKqGhFJ6GYIHnnG5AhRpAh3OWjkrRHKa/KogbmQn8We+c0KVV3rTOgR9V/WowbXQ==} dependencies: '@types/unist': 2.0.6 is-buffer: 2.0.5 @@ -17295,7 +17317,7 @@ packages: optional: true dependencies: debug: 4.3.4 - fast-glob: 3.2.11 + fast-glob: 3.2.12 pretty-bytes: 5.6.0 rollup: 2.79.0 workbox-build: 6.5.4 @@ -17941,6 +17963,11 @@ packages: resolution: {integrity: sha512-JZxotl7SxAJH0j7dN4pxsTV6ZLXoLdGME+PsjkL/DaBrVryK9kTGq06GfKrwcSOqypP+fdXGoCHE36b99fWVoA==} 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: resolution: {directory: packages/astro/test/fixtures/css-assets/packages/font-awesome, type: directory} name: '@astrojs/test-font-awesome-package'