diff --git a/.changeset/curly-icons-watch.md b/.changeset/curly-icons-watch.md new file mode 100644 index 000000000..8c2561904 --- /dev/null +++ b/.changeset/curly-icons-watch.md @@ -0,0 +1,5 @@ +--- +'@astrojs/node': patch +--- + +The node adapter now logs uncaught errors encountered during rendering a page. diff --git a/.changeset/eighty-trainers-accept.md b/.changeset/eighty-trainers-accept.md deleted file mode 100644 index c4bb890a1..000000000 --- a/.changeset/eighty-trainers-accept.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -add hide to style & script generated for island diff --git a/.changeset/fair-teachers-protect.md b/.changeset/fair-teachers-protect.md deleted file mode 100644 index df8215b9f..000000000 --- a/.changeset/fair-teachers-protect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -Fix small types issues related to `astro:assets`'s AVIF support and `getImage` diff --git a/.changeset/fifty-weeks-bake.md b/.changeset/fifty-weeks-bake.md new file mode 100644 index 000000000..714be802e --- /dev/null +++ b/.changeset/fifty-weeks-bake.md @@ -0,0 +1,20 @@ +--- +'@astrojs/cloudflare': minor +--- + +Add support for the following Node.js Runtime APIs, which are availabe in [Cloudflare](https://developers.cloudflare.com/workers/runtime-apis/nodejs) using the `node:` syntax. + +- assert +- AsyncLocalStorage +- Buffer +- Diagnostics Channel +- EventEmitter +- path +- process +- Streams +- StringDecoder +- util + +```js +import { Buffer } from 'node:buffer'; +``` diff --git a/.changeset/fluffy-dodos-rule.md b/.changeset/fluffy-dodos-rule.md deleted file mode 100644 index 7ec2f5bcc..000000000 --- a/.changeset/fluffy-dodos-rule.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@astrojs/vercel': patch ---- - -log only once in serverless adapter diff --git a/.changeset/large-shoes-hammer.md b/.changeset/large-shoes-hammer.md new file mode 100644 index 000000000..442b83ce2 --- /dev/null +++ b/.changeset/large-shoes-hammer.md @@ -0,0 +1,6 @@ +--- +'@astrojs/telemetry': patch +'astro': patch +--- + +Improve config info telemetry diff --git a/.changeset/serious-wolves-breathe.md b/.changeset/serious-wolves-breathe.md new file mode 100644 index 000000000..cc1fcc420 --- /dev/null +++ b/.changeset/serious-wolves-breathe.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fix alias plugin causing CSS ordering issue diff --git a/.changeset/thin-pigs-mate.md b/.changeset/thin-pigs-mate.md deleted file mode 100644 index 6a764cf18..000000000 --- a/.changeset/thin-pigs-mate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@astrojs/cloudflare': patch ---- - -add the option to type environment variables using a generic diff --git a/.changeset/two-jeans-serve.md b/.changeset/two-jeans-serve.md deleted file mode 100644 index 8312b82b1..000000000 --- a/.changeset/two-jeans-serve.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -show redirect symbol as of the page diff --git a/.changeset/warm-turkeys-develop.md b/.changeset/warm-turkeys-develop.md new file mode 100644 index 000000000..844232254 --- /dev/null +++ b/.changeset/warm-turkeys-develop.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Prevent body scripts from re-executing on navigation diff --git a/examples/basics/package.json b/examples/basics/package.json index 3ff333ea2..85b886d4b 100644 --- a/examples/basics/package.json +++ b/examples/basics/package.json @@ -11,6 +11,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^3.1.0" + "astro": "^3.1.1" } } diff --git a/examples/blog/package.json b/examples/blog/package.json index ef2a4c143..b2ad50da8 100644 --- a/examples/blog/package.json +++ b/examples/blog/package.json @@ -14,6 +14,6 @@ "@astrojs/mdx": "^1.1.0", "@astrojs/rss": "^3.0.0", "@astrojs/sitemap": "^3.0.0", - "astro": "^3.1.0" + "astro": "^3.1.1" } } diff --git a/examples/component/package.json b/examples/component/package.json index 460763afe..fc0aa1e19 100644 --- a/examples/component/package.json +++ b/examples/component/package.json @@ -15,7 +15,7 @@ ], "scripts": {}, "devDependencies": { - "astro": "^3.1.0" + "astro": "^3.1.1" }, "peerDependencies": { "astro": "^2.0.0-beta.0" diff --git a/examples/deno/package.json b/examples/deno/package.json index 7ead37e41..dbf19159e 100644 --- a/examples/deno/package.json +++ b/examples/deno/package.json @@ -10,7 +10,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^3.1.0" + "astro": "^3.1.1" }, "devDependencies": { "@astrojs/deno": "^5.0.0" diff --git a/examples/framework-alpine/package.json b/examples/framework-alpine/package.json index 31d9e057a..34dfd5bb1 100644 --- a/examples/framework-alpine/package.json +++ b/examples/framework-alpine/package.json @@ -14,6 +14,6 @@ "@astrojs/alpinejs": "^0.3.0", "@types/alpinejs": "^3.7.2", "alpinejs": "^3.12.3", - "astro": "^3.1.0" + "astro": "^3.1.1" } } diff --git a/examples/framework-lit/package.json b/examples/framework-lit/package.json index a14686cdf..dc3b50539 100644 --- a/examples/framework-lit/package.json +++ b/examples/framework-lit/package.json @@ -13,7 +13,7 @@ "dependencies": { "@astrojs/lit": "^3.0.0", "@webcomponents/template-shadowroot": "^0.2.1", - "astro": "^3.1.0", + "astro": "^3.1.1", "lit": "^2.8.0" } } diff --git a/examples/framework-multiple/package.json b/examples/framework-multiple/package.json index 78fb01e41..c00d687e5 100644 --- a/examples/framework-multiple/package.json +++ b/examples/framework-multiple/package.json @@ -16,7 +16,7 @@ "@astrojs/solid-js": "^3.0.1", "@astrojs/svelte": "^4.0.2", "@astrojs/vue": "^3.0.0", - "astro": "^3.1.0", + "astro": "^3.1.1", "preact": "^10.17.1", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/examples/framework-preact/package.json b/examples/framework-preact/package.json index 7a42ca07d..941a20c78 100644 --- a/examples/framework-preact/package.json +++ b/examples/framework-preact/package.json @@ -13,7 +13,7 @@ "dependencies": { "@astrojs/preact": "^3.0.0", "@preact/signals": "^1.2.1", - "astro": "^3.1.0", + "astro": "^3.1.1", "preact": "^10.17.1" } } diff --git a/examples/framework-react/package.json b/examples/framework-react/package.json index 1f99c9729..f258a4ee6 100644 --- a/examples/framework-react/package.json +++ b/examples/framework-react/package.json @@ -14,7 +14,7 @@ "@astrojs/react": "^3.0.2", "@types/react": "^18.2.21", "@types/react-dom": "^18.2.7", - "astro": "^3.1.0", + "astro": "^3.1.1", "react": "^18.2.0", "react-dom": "^18.2.0" } diff --git a/examples/framework-solid/package.json b/examples/framework-solid/package.json index 3d42bab15..101ce6424 100644 --- a/examples/framework-solid/package.json +++ b/examples/framework-solid/package.json @@ -12,7 +12,7 @@ }, "dependencies": { "@astrojs/solid-js": "^3.0.1", - "astro": "^3.1.0", + "astro": "^3.1.1", "solid-js": "^1.7.11" } } diff --git a/examples/framework-svelte/package.json b/examples/framework-svelte/package.json index 0fa4a9980..5b8426439 100644 --- a/examples/framework-svelte/package.json +++ b/examples/framework-svelte/package.json @@ -12,7 +12,7 @@ }, "dependencies": { "@astrojs/svelte": "^4.0.2", - "astro": "^3.1.0", + "astro": "^3.1.1", "svelte": "^4.2.0" } } diff --git a/examples/framework-vue/package.json b/examples/framework-vue/package.json index d7cce47c9..13807d5aa 100644 --- a/examples/framework-vue/package.json +++ b/examples/framework-vue/package.json @@ -12,7 +12,7 @@ }, "dependencies": { "@astrojs/vue": "^3.0.0", - "astro": "^3.1.0", + "astro": "^3.1.1", "vue": "^3.3.4" } } diff --git a/examples/hackernews/package.json b/examples/hackernews/package.json index 6c221804b..1624fca82 100644 --- a/examples/hackernews/package.json +++ b/examples/hackernews/package.json @@ -12,6 +12,6 @@ }, "dependencies": { "@astrojs/node": "^6.0.0", - "astro": "^3.1.0" + "astro": "^3.1.1" } } diff --git a/examples/integration/package.json b/examples/integration/package.json index d7ee4b2d1..918b3ee79 100644 --- a/examples/integration/package.json +++ b/examples/integration/package.json @@ -15,7 +15,7 @@ ], "scripts": {}, "devDependencies": { - "astro": "^3.1.0" + "astro": "^3.1.1" }, "peerDependencies": { "astro": "^2.0.0-beta.0" diff --git a/examples/middleware/package.json b/examples/middleware/package.json index a97b73972..aadcb936e 100644 --- a/examples/middleware/package.json +++ b/examples/middleware/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@astrojs/node": "^6.0.0", - "astro": "^3.1.0", + "astro": "^3.1.1", "html-minifier": "^4.0.0" } } diff --git a/examples/minimal/package.json b/examples/minimal/package.json index b36c4a8d3..d0afec388 100644 --- a/examples/minimal/package.json +++ b/examples/minimal/package.json @@ -11,6 +11,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^3.1.0" + "astro": "^3.1.1" } } diff --git a/examples/non-html-pages/package.json b/examples/non-html-pages/package.json index 7e4a6ddbf..866aed7d4 100644 --- a/examples/non-html-pages/package.json +++ b/examples/non-html-pages/package.json @@ -11,6 +11,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^3.1.0" + "astro": "^3.1.1" } } diff --git a/examples/portfolio/package.json b/examples/portfolio/package.json index 4b4ca5f03..c03444410 100644 --- a/examples/portfolio/package.json +++ b/examples/portfolio/package.json @@ -11,6 +11,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^3.1.0" + "astro": "^3.1.1" } } diff --git a/examples/portfolio/src/pages/index.astro b/examples/portfolio/src/pages/index.astro index f7362284d..76761523f 100644 --- a/examples/portfolio/src/pages/index.astro +++ b/examples/portfolio/src/pages/index.astro @@ -83,7 +83,7 @@ const projects = (await getCollection('work'))

Mentions

- I have been fortunate enough to recieve praise for my work in several publications. Take + I have been fortunate enough to receive praise for my work in several publications. Take a look below to learn more.

diff --git a/examples/ssr/package.json b/examples/ssr/package.json index 8db6c31e2..db4bedd88 100644 --- a/examples/ssr/package.json +++ b/examples/ssr/package.json @@ -14,7 +14,7 @@ "dependencies": { "@astrojs/node": "^6.0.0", "@astrojs/svelte": "^4.0.2", - "astro": "^3.1.0", + "astro": "^3.1.1", "svelte": "^4.2.0" } } diff --git a/examples/with-markdoc/package.json b/examples/with-markdoc/package.json index 9a1ee15db..4fec42e94 100644 --- a/examples/with-markdoc/package.json +++ b/examples/with-markdoc/package.json @@ -12,6 +12,6 @@ }, "dependencies": { "@astrojs/markdoc": "^0.5.0", - "astro": "^3.1.0" + "astro": "^3.1.1" } } diff --git a/examples/with-markdown-plugins/package.json b/examples/with-markdown-plugins/package.json index 725433585..fc8c83334 100644 --- a/examples/with-markdown-plugins/package.json +++ b/examples/with-markdown-plugins/package.json @@ -12,7 +12,7 @@ }, "dependencies": { "@astrojs/markdown-remark": "^3.2.0", - "astro": "^3.1.0", + "astro": "^3.1.1", "hast-util-select": "^5.0.5", "rehype-autolink-headings": "^6.1.1", "rehype-slug": "^5.1.0", diff --git a/examples/with-markdown-shiki/package.json b/examples/with-markdown-shiki/package.json index 9fae2b331..3d7f11cca 100644 --- a/examples/with-markdown-shiki/package.json +++ b/examples/with-markdown-shiki/package.json @@ -11,6 +11,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^3.1.0" + "astro": "^3.1.1" } } diff --git a/examples/with-mdx/package.json b/examples/with-mdx/package.json index dc26ecea1..facaf432e 100644 --- a/examples/with-mdx/package.json +++ b/examples/with-mdx/package.json @@ -13,7 +13,7 @@ "dependencies": { "@astrojs/mdx": "^1.1.0", "@astrojs/preact": "^3.0.0", - "astro": "^3.1.0", + "astro": "^3.1.1", "preact": "^10.17.1" } } diff --git a/examples/with-nanostores/package.json b/examples/with-nanostores/package.json index d00393ca5..9efbc21cf 100644 --- a/examples/with-nanostores/package.json +++ b/examples/with-nanostores/package.json @@ -13,7 +13,7 @@ "dependencies": { "@astrojs/preact": "^3.0.0", "@nanostores/preact": "^0.5.0", - "astro": "^3.1.0", + "astro": "^3.1.1", "nanostores": "^0.9.3", "preact": "^10.17.1" } diff --git a/examples/with-tailwindcss/package.json b/examples/with-tailwindcss/package.json index b3bd69f5c..76b0d02e5 100644 --- a/examples/with-tailwindcss/package.json +++ b/examples/with-tailwindcss/package.json @@ -14,7 +14,7 @@ "@astrojs/mdx": "^1.1.0", "@astrojs/tailwind": "^5.0.0", "@types/canvas-confetti": "^1.6.0", - "astro": "^3.1.0", + "astro": "^3.1.1", "autoprefixer": "^10.4.15", "canvas-confetti": "^1.6.0", "postcss": "^8.4.28", diff --git a/examples/with-vite-plugin-pwa/package.json b/examples/with-vite-plugin-pwa/package.json index b75ab17eb..d8f176dc3 100644 --- a/examples/with-vite-plugin-pwa/package.json +++ b/examples/with-vite-plugin-pwa/package.json @@ -11,7 +11,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^3.1.0", + "astro": "^3.1.1", "vite-plugin-pwa": "0.16.4", "workbox-window": "^7.0.0" } diff --git a/examples/with-vitest/package.json b/examples/with-vitest/package.json index 1ac25f3d4..d4fd8a86e 100644 --- a/examples/with-vitest/package.json +++ b/examples/with-vitest/package.json @@ -12,7 +12,7 @@ "test": "vitest" }, "dependencies": { - "astro": "^3.1.0", + "astro": "^3.1.1", "vitest": "^0.34.2" } } diff --git a/packages/astro/CHANGELOG.md b/packages/astro/CHANGELOG.md index 21670dfa8..1a9537e78 100644 --- a/packages/astro/CHANGELOG.md +++ b/packages/astro/CHANGELOG.md @@ -1,5 +1,15 @@ # astro +## 3.1.1 + +### Patch Changes + +- [#8580](https://github.com/withastro/astro/pull/8580) [`8d361169b`](https://github.com/withastro/astro/commit/8d361169b8e487933d671ce347f0ce74922c80cc) Thanks [@rishi-raj-jain](https://github.com/rishi-raj-jain)! - add hide to style & script generated for island + +- [#8568](https://github.com/withastro/astro/pull/8568) [`95b5f6280`](https://github.com/withastro/astro/commit/95b5f6280d124f8d6f866dc3286406c272ee91bf) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Fix small types issues related to `astro:assets`'s AVIF support and `getImage` + +- [#8579](https://github.com/withastro/astro/pull/8579) [`0586e20e8`](https://github.com/withastro/astro/commit/0586e20e8338e077b8eb1a3a96bdd19f5950c22f) Thanks [@rishi-raj-jain](https://github.com/rishi-raj-jain)! - show redirect symbol as of the page + ## 3.1.0 ### Minor Changes diff --git a/packages/astro/components/ViewTransitions.astro b/packages/astro/components/ViewTransitions.astro index 9c0a9dfdd..39b9996ce 100644 --- a/packages/astro/components/ViewTransitions.astro +++ b/packages/astro/components/ViewTransitions.astro @@ -129,31 +129,18 @@ const { fallback = 'animate' } = Astro.props as Props; var noopEl = document.createElement('div'); } - async function updateDOM(doc: Document, loc: URL, state?: State, fallback?: Fallback) { + async function updateDOM(newDocument: Document, loc: URL, state?: State, fallback?: Fallback) { // Check for a head element that should persist, either because it has the data // attribute or is a link el. const persistedHeadElement = (el: HTMLElement): Element | null => { const id = el.getAttribute(PERSIST_ATTR); - const newEl = id && doc.head.querySelector(`[${PERSIST_ATTR}="${id}"]`); + const newEl = id && newDocument.head.querySelector(`[${PERSIST_ATTR}="${id}"]`); if (newEl) { return newEl; } if (el.matches('link[rel=stylesheet]')) { const href = el.getAttribute('href'); - return doc.head.querySelector(`link[rel=stylesheet][href="${href}"]`); - } - if (el.tagName === 'SCRIPT') { - let s1 = el as HTMLScriptElement; - for (const s2 of doc.scripts) { - if ( - // Inline - (s1.textContent && s1.textContent === s2.textContent) || - // External - (s1.type === s2.type && s1.src === s2.src) - ) { - return s2; - } - } + return newDocument.head.querySelector(`link[rel=stylesheet][href="${href}"]`); } // Only run this in dev. This will get stripped from production builds and is not needed. if (import.meta.env.DEV) { @@ -161,7 +148,7 @@ const { fallback = 'animate' } = Astro.props as Props; const devId = el.dataset.viteDevId; // If this same style tag exists, remove it from the new page return ( - doc.querySelector(`style[data-astro-dev-id="${devId}"]`) || + newDocument.querySelector(`style[data-astro-dev-id="${devId}"]`) || // Otherwise, keep it anyways. This is client:only styles. noopEl ); @@ -173,7 +160,7 @@ const { fallback = 'animate' } = Astro.props as Props; const swap = () => { // noscript tags inside head element are not honored on swap (#7969). // Remove them before swapping. - doc.querySelectorAll('head noscript').forEach((el) => el.remove()); + newDocument.querySelectorAll('head noscript').forEach((el) => el.remove()); // swap attributes of the html element // - delete all attributes from the current document @@ -183,10 +170,26 @@ const { fallback = 'animate' } = Astro.props as Props; const astro = [...html.attributes].filter( ({ name }) => (html.removeAttribute(name), name.startsWith('data-astro-')) ); - [...doc.documentElement.attributes, ...astro].forEach(({ name, value }) => + [...newDocument.documentElement.attributes, ...astro].forEach(({ name, value }) => html.setAttribute(name, value) ); + // Replace scripts in both the head and body. + for (const s1 of document.scripts) { + for (const s2 of newDocument.scripts) { + if ( + // Inline + (s1.textContent && s1.textContent === s2.textContent) || + // External + (s1.type === s2.type && s1.src === s2.src) + ) { + s2.remove(); + } else { + s1.remove(); + } + } + } + // Swap head for (const el of Array.from(document.head.children)) { const newEl = persistedHeadElement(el as HTMLElement); @@ -199,12 +202,13 @@ const { fallback = 'animate' } = Astro.props as Props; el.remove(); } } + // Everything left in the new head is new, append it all. - document.head.append(...doc.head.children); + document.head.append(...newDocument.head.children); // Persist elements in the existing body const oldBody = document.body; - document.body.replaceWith(doc.body); + document.body.replaceWith(newDocument.body); for (const el of oldBody.querySelectorAll(`[${PERSIST_ATTR}]`)) { const id = el.getAttribute(PERSIST_ATTR); const newEl = document.querySelector(`[${PERSIST_ATTR}="${id}"]`); @@ -247,7 +251,7 @@ const { fallback = 'animate' } = Astro.props as Props; // Wait on links to finish, to prevent FOUC const links: Promise[] = []; - for (const el of doc.querySelectorAll('head link[rel=stylesheet]')) { + for (const el of newDocument.querySelectorAll('head link[rel=stylesheet]')) { // Do not preload links that are already on the page. if ( !document.querySelector( @@ -299,8 +303,8 @@ const { fallback = 'animate' } = Astro.props as Props; return; } - const doc = parser.parseFromString(html, mediaType); - if (!doc.querySelector('[name="astro-view-transitions-enabled"]')) { + const newDocument = parser.parseFromString(html, mediaType); + if (!newDocument.querySelector('[name="astro-view-transitions-enabled"]')) { location.href = href; return; } @@ -310,9 +314,9 @@ const { fallback = 'animate' } = Astro.props as Props; document.documentElement.dataset.astroTransition = dir; if (supportsViewTransitions) { - finished = document.startViewTransition(() => updateDOM(doc, loc, state)).finished; + finished = document.startViewTransition(() => updateDOM(newDocument, loc, state)).finished; } else { - finished = updateDOM(doc, loc, state, getFallback()); + finished = updateDOM(newDocument, loc, state, getFallback()); } try { await finished; diff --git a/packages/astro/e2e/fixtures/view-transitions/src/components/InlineScript.astro b/packages/astro/e2e/fixtures/view-transitions/src/components/InlineScript.astro new file mode 100644 index 000000000..5418c5a64 --- /dev/null +++ b/packages/astro/e2e/fixtures/view-transitions/src/components/InlineScript.astro @@ -0,0 +1,9 @@ +
Count
+ diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/four.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/four.astro index c6547dc20..82dda9475 100644 --- a/packages/astro/e2e/fixtures/view-transitions/src/pages/four.astro +++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/four.astro @@ -11,4 +11,5 @@ import Layout from '../components/Layout.astro'; load page / no navigation + load page / no navigation diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/inline-script-one.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/inline-script-one.astro new file mode 100644 index 000000000..e887fe6a5 --- /dev/null +++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/inline-script-one.astro @@ -0,0 +1,8 @@ +--- +import Layout from '../components/Layout.astro'; +import InlineScript from '../components/InlineScript.astro'; +--- + + + Go to 2 + diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/inline-script-two.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/inline-script-two.astro new file mode 100644 index 000000000..430ad9465 --- /dev/null +++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/inline-script-two.astro @@ -0,0 +1,8 @@ +--- +import Layout from '../components/Layout.astro'; +import InlineScript from '../components/InlineScript.astro'; +--- + + + Go to 1 + diff --git a/packages/astro/e2e/view-transitions.test.js b/packages/astro/e2e/view-transitions.test.js index 868660f9f..d777d9b2f 100644 --- a/packages/astro/e2e/view-transitions.test.js +++ b/packages/astro/e2e/view-transitions.test.js @@ -520,6 +520,22 @@ test.describe('View Transitions', () => { await downloadPromise; }); + test('data-astro-reload not required for non-html content', async ({ page, astro }) => { + const loads = []; + page.addListener('load', (p) => { + loads.push(p.title()); + }); + // Go to page 4 + await page.goto(astro.resolveUrl('/four')); + let p = page.locator('#four'); + await expect(p, 'should have content').toHaveText('Page 4'); + + await page.click('#click-svg'); + p = page.locator('svg'); + await expect(p).toBeVisible(); + expect(loads.length, 'There should be 2 page load').toEqual(2); + }); + test('Scroll position is restored on back navigation from page w/o ViewTransitions', async ({ page, astro, @@ -663,4 +679,22 @@ test.describe('View Transitions', () => { locator = page.locator('#click-one'); await expect(locator).not.toBeInViewport(); }); + + test('body inline scripts do not re-execute on navigation', async ({ page, astro }) => { + const errors = []; + page.addListener('pageerror', (err) => { + errors.push(err); + }); + + await page.goto(astro.resolveUrl('/inline-script-one')); + let article = page.locator('#counter'); + await expect(article, 'should have script content').toBeVisible('exists'); + + await page.click('#click-one'); + + article = page.locator('#counter'); + await expect(article, 'should have script content').toHaveText('Count: 3'); + + expect(errors).toHaveLength(0); + }); }); diff --git a/packages/astro/package.json b/packages/astro/package.json index 396028465..f3fa8cf52 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -1,6 +1,6 @@ { "name": "astro", - "version": "3.1.0", + "version": "3.1.1", "description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.", "type": "module", "author": "withastro", diff --git a/packages/astro/src/cli/add/index.ts b/packages/astro/src/cli/add/index.ts index 62cec7a71..afd63716b 100644 --- a/packages/astro/src/cli/add/index.ts +++ b/packages/astro/src/cli/add/index.ts @@ -9,7 +9,12 @@ import ora from 'ora'; import preferredPM from 'preferred-pm'; import prompts from 'prompts'; import type yargs from 'yargs-parser'; -import { loadTSConfig, resolveConfigPath, resolveRoot } from '../../core/config/index.js'; +import { + loadTSConfig, + resolveConfig, + resolveConfigPath, + resolveRoot, +} from '../../core/config/index.js'; import { defaultTSConfig, presets, @@ -23,7 +28,7 @@ import { appendForwardSlash } from '../../core/path.js'; import { apply as applyPolyfill } from '../../core/polyfill.js'; import { parseNpmName } from '../../core/util.js'; import { eventCliSession, telemetry } from '../../events/index.js'; -import { createLoggerFromFlags } from '../flags.js'; +import { createLoggerFromFlags, flagsToAstroInlineConfig } from '../flags.js'; import { generate, parse, t, visit } from './babel.js'; import { ensureImport } from './imports.js'; import { wrapDefaultExport } from './wrapper.js'; @@ -87,7 +92,9 @@ async function getRegistry(): Promise { } export async function add(names: string[], { flags }: AddOptions) { - telemetry.record(eventCliSession('add')); + const inlineConfig = flagsToAstroInlineConfig(flags); + const { userConfig } = await resolveConfig(inlineConfig, 'add'); + telemetry.record(eventCliSession('add', userConfig)); applyPolyfill(); if (flags.help || names.length === 0) { printHelp({ diff --git a/packages/astro/src/core/config/schema.ts b/packages/astro/src/core/config/schema.ts index b36017c22..4ac40d4c5 100644 --- a/packages/astro/src/core/config/schema.ts +++ b/packages/astro/src/core/config/schema.ts @@ -140,7 +140,6 @@ export const AstroConfigSchema = z.object({ .optional() .default(ASTRO_CONFIG_DEFAULTS.build.excludeMiddleware), }) - .optional() .default({}), server: z.preprocess( // preprocess @@ -158,7 +157,6 @@ export const AstroConfigSchema = z.object({ port: z.number().optional().default(ASTRO_CONFIG_DEFAULTS.server.port), headers: z.custom().optional(), }) - .optional() .default({}) ), redirects: z @@ -274,27 +272,11 @@ export const AstroConfigSchema = z.object({ .optional() .default(ASTRO_CONFIG_DEFAULTS.experimental.optimizeHoistedScript), }) - .passthrough() - .refine( - (d) => { - const validKeys = Object.keys(ASTRO_CONFIG_DEFAULTS.experimental); - const invalidKeys = Object.keys(d).filter((key) => !validKeys.includes(key)); - if (invalidKeys.length > 0) return false; - return true; - }, - (d) => { - const validKeys = Object.keys(ASTRO_CONFIG_DEFAULTS.experimental); - const invalidKeys = Object.keys(d).filter((key) => !validKeys.includes(key)); - return { - message: `Invalid experimental key: \`${invalidKeys.join( - ', ' - )}\`. \nMake sure the spelling is correct, and that your Astro version supports this experiment.\nSee https://docs.astro.build/en/reference/configuration-reference/#experimental-flags for more information.`, - }; - } + .strict( + `Invalid or outdated experimental feature.\nCheck for incorrect spelling or outdated Astro version.\nSee https://docs.astro.build/en/reference/configuration-reference/#experimental-flags for a list of all current experiments.` ) - .optional() .default({}), - legacy: z.object({}).optional().default({}), + legacy: z.object({}).default({}), }); export type AstroConfigType = z.infer; diff --git a/packages/astro/src/events/session.ts b/packages/astro/src/events/session.ts index b37530342..d9c492cb0 100644 --- a/packages/astro/src/events/session.ts +++ b/packages/astro/src/events/session.ts @@ -1,25 +1,8 @@ -import type { AstroUserConfig } from '../@types/astro.js'; +import type { AstroIntegration, AstroUserConfig } from '../@types/astro.js'; +import { AstroConfigSchema } from '../core/config/schema.js'; const EVENT_SESSION = 'ASTRO_CLI_SESSION_STARTED'; -interface ConfigInfo { - markdownPlugins: string[]; - adapter: string | null; - integrations: string[]; - trailingSlash: undefined | 'always' | 'never' | 'ignore'; - build: - | undefined - | { - format: undefined | 'file' | 'directory'; - }; - markdown: - | undefined - | { - drafts: undefined | boolean; - syntaxHighlight: undefined | 'shiki' | 'prism' | false; - }; -} - interface EventPayload { cliCommand: string; config?: ConfigInfo; @@ -28,87 +11,126 @@ interface EventPayload { optionalIntegrations?: number; } -const multiLevelKeys = new Set([ - 'build', - 'markdown', - 'markdown.shikiConfig', - 'server', - 'vite', - 'vite.resolve', - 'vite.css', - 'vite.json', - 'vite.server', - 'vite.server.fs', - 'vite.build', - 'vite.preview', - 'vite.optimizeDeps', - 'vite.ssr', - 'vite.worker', -]); -function configKeys(obj: Record | undefined, parentKey: string): string[] { - if (!obj) { - return []; +type ConfigInfoValue = string | boolean | string[] | undefined; +type ConfigInfoRecord = Record; +type ConfigInfoBase = { + [alias in keyof AstroUserConfig]: ConfigInfoValue | ConfigInfoRecord; +}; +export interface ConfigInfo extends ConfigInfoBase { + build: ConfigInfoRecord; + image: ConfigInfoRecord; + markdown: ConfigInfoRecord; + experimental: ConfigInfoRecord; + legacy: ConfigInfoRecord; + vite: ConfigInfoRecord | undefined; +} + +function measureIsDefined(val: unknown) { + // if val is undefined, measure undefined as a value + if (val === undefined) { + return undefined; } + // otherwise, convert the value to a boolean + return Boolean(val); +} - return Object.entries(obj) - .map(([key, value]) => { - if (typeof value === 'object' && !Array.isArray(value)) { - const localKey = parentKey ? parentKey + '.' + key : key; - if (multiLevelKeys.has(localKey)) { - let keys = configKeys(value, localKey).map((subkey) => key + '.' + subkey); - keys.unshift(key); - return keys; - } - } +type StringLiteral = T extends string ? (string extends T ? never : T) : never; - return key; - }) - .flat(1); +/** + * Measure supports string literal values. Passing a generic `string` type + * results in an error, to make sure generic user input is never measured directly. + */ +function measureStringLiteral( + val: StringLiteral | boolean | undefined +): string | boolean | undefined { + return val; +} + +function measureIntegration(val: AstroIntegration | false | null | undefined): string | undefined { + if (!val || !val.name) { + return undefined; + } + return val.name; +} + +function sanitizeConfigInfo(obj: object | undefined, validKeys: string[]): ConfigInfoRecord { + if (!obj || validKeys.length === 0) { + return {}; + } + return validKeys.reduce( + (result, key) => { + result[key] = measureIsDefined((obj as Record)[key]); + return result; + }, + {} as Record + ); +} + +/** + * This function creates an anonymous ConfigInfo object from the user's config. + * All values are sanitized to preserve anonymity. Simple "exist" boolean checks + * are used by default, with a few additional sanitized values added manually. + * Helper functions should always be used to ensure correct sanitization. + */ +function createAnonymousConfigInfo(userConfig: AstroUserConfig) { + // Sanitize and measure the generic config object + // NOTE(fks): Using _def is the correct, documented way to get the `shape` + // from a Zod object that includes a wrapping default(), optional(), etc. + // Even though `_def` appears private, it is type-checked for us so that + // any changes between versions will be detected. + const configInfo: ConfigInfo = { + ...sanitizeConfigInfo(userConfig, Object.keys(AstroConfigSchema.shape)), + build: sanitizeConfigInfo( + userConfig.build, + Object.keys(AstroConfigSchema.shape.build._def.innerType.shape) + ), + image: sanitizeConfigInfo( + userConfig.image, + Object.keys(AstroConfigSchema.shape.image._def.innerType.shape) + ), + markdown: sanitizeConfigInfo( + userConfig.markdown, + Object.keys(AstroConfigSchema.shape.markdown._def.innerType.shape) + ), + experimental: sanitizeConfigInfo( + userConfig.experimental, + Object.keys(AstroConfigSchema.shape.experimental._def.innerType.shape) + ), + legacy: sanitizeConfigInfo( + userConfig.legacy, + Object.keys(AstroConfigSchema.shape.legacy._def.innerType.shape) + ), + vite: userConfig.vite + ? sanitizeConfigInfo(userConfig.vite, Object.keys(userConfig.vite)) + : undefined, + }; + // Measure string literal/enum configuration values + configInfo.build.format = measureStringLiteral(userConfig.build?.format); + configInfo.markdown.syntaxHighlight = measureStringLiteral(userConfig.markdown?.syntaxHighlight); + configInfo.output = measureStringLiteral(userConfig.output); + configInfo.scopedStyleStrategy = measureStringLiteral(userConfig.scopedStyleStrategy); + configInfo.trailingSlash = measureStringLiteral(userConfig.trailingSlash); + // Measure integration & adapter usage + configInfo.adapter = measureIntegration(userConfig.adapter); + configInfo.integrations = userConfig.integrations + ?.flat(100) + .map(measureIntegration) + .filter(Boolean) as string[]; + // Return the sanitized ConfigInfo object + return configInfo; } export function eventCliSession( cliCommand: string, - userConfig?: AstroUserConfig, + userConfig: AstroUserConfig, flags?: Record ): { eventName: string; payload: EventPayload }[] { - // Filter out falsy integrations - const configValues = userConfig - ? { - markdownPlugins: [ - ...(userConfig?.markdown?.remarkPlugins?.map((p) => - typeof p === 'string' ? p : typeof p - ) ?? []), - ...(userConfig?.markdown?.rehypePlugins?.map((p) => - typeof p === 'string' ? p : typeof p - ) ?? []), - ] as string[], - adapter: userConfig?.adapter?.name ?? null, - integrations: (userConfig?.integrations ?? []) - .filter(Boolean) - .flat() - .map((i: any) => i?.name), - trailingSlash: userConfig?.trailingSlash, - build: userConfig?.build - ? { - format: userConfig?.build?.format, - } - : undefined, - markdown: userConfig?.markdown - ? { - drafts: userConfig.markdown?.drafts, - syntaxHighlight: userConfig.markdown?.syntaxHighlight, - } - : undefined, - } - : undefined; - // Filter out yargs default `_` flag which is the cli command const cliFlags = flags ? Object.keys(flags).filter((name) => name != '_') : undefined; const payload: EventPayload = { cliCommand, - configKeys: userConfig ? configKeys(userConfig, '') : undefined, - config: configValues, + config: createAnonymousConfigInfo(userConfig), flags: cliFlags, }; return [{ eventName: EVENT_SESSION, payload }]; diff --git a/packages/astro/src/vite-plugin-config-alias/index.ts b/packages/astro/src/vite-plugin-config-alias/index.ts index 8b8535af9..e91197a8e 100644 --- a/packages/astro/src/vite-plugin-config-alias/index.ts +++ b/packages/astro/src/vite-plugin-config-alias/index.ts @@ -70,7 +70,8 @@ export default function configAliasVitePlugin({ const plugin: VitePlugin = { name: 'astro:tsconfig-alias', - enforce: 'pre', + // use post to only resolve ids that all other plugins before it can't + enforce: 'post', configResolved(config) { patchCreateResolver(config, plugin); }, @@ -100,7 +101,7 @@ export default function configAliasVitePlugin({ * * Vite may simplify this soon: https://github.com/vitejs/vite/pull/10555 */ -function patchCreateResolver(config: ResolvedConfig, prePlugin: VitePlugin) { +function patchCreateResolver(config: ResolvedConfig, postPlugin: VitePlugin) { const _createResolver = config.createResolver; // @ts-expect-error override readonly property intentionally config.createResolver = function (...args1: any) { @@ -124,15 +125,16 @@ function patchCreateResolver(config: ResolvedConfig, prePlugin: VitePlugin) { ssr, }; + const result = await resolver.apply(_createResolver, args2); + if (result) return result; + // @ts-expect-error resolveId exists - const resolved = await prePlugin.resolveId.apply(fakePluginContext, [ + const resolved = await postPlugin.resolveId.apply(fakePluginContext, [ id, importer, fakeResolveIdOpts, ]); if (resolved) return resolved; - - return resolver.apply(_createResolver, args2); }; }; } diff --git a/packages/astro/test/events.test.js b/packages/astro/test/events.test.js index 3bc1a6590..b0732a15c 100644 --- a/packages/astro/test/events.test.js +++ b/packages/astro/test/events.test.js @@ -5,44 +5,7 @@ import * as events from '../dist/events/index.js'; describe('Events', () => { describe('eventCliSession()', () => { - it('All top-level keys added', () => { - const config = { - root: 1, - srcDir: 2, - publicDir: 3, - outDir: 4, - site: 5, - base: 6, - trailingSlash: 7, - experimental: 8, - }; - const expected = Object.keys(config); - const [{ payload }] = events.eventCliSession( - { - cliCommand: 'dev', - }, - config - ); - expect(payload.configKeys).to.deep.equal(expected); - }); - - it('configKeys includes format', () => { - const config = { - srcDir: 1, - build: { - format: 'file', - }, - }; - const [{ payload }] = events.eventCliSession( - { - cliCommand: 'dev', - }, - config - ); - expect(payload.configKeys).to.deep.equal(['srcDir', 'build', 'build.format']); - }); - - it('config.build.format', () => { + it('string literal "build.format" is included', () => { const config = { srcDir: 1, build: { @@ -58,59 +21,7 @@ describe('Events', () => { expect(payload.config.build.format).to.equal('file'); }); - it('configKeys includes server props', () => { - const config = { - srcDir: 1, - server: { - host: 'example.com', - port: 8033, - }, - }; - const [{ payload }] = events.eventCliSession( - { - cliCommand: 'dev', - }, - config - ); - expect(payload.configKeys).to.deep.equal(['srcDir', 'server', 'server.host', 'server.port']); - }); - - it('configKeys is deep', () => { - const config = { - publicDir: 1, - markdown: { - drafts: true, - shikiConfig: { - lang: 1, - theme: 2, - wrap: 3, - }, - syntaxHighlight: 'shiki', - remarkPlugins: [], - rehypePlugins: [], - }, - }; - const [{ payload }] = events.eventCliSession( - { - cliCommand: 'dev', - }, - config - ); - expect(payload.configKeys).to.deep.equal([ - 'publicDir', - 'markdown', - 'markdown.drafts', - 'markdown.shikiConfig', - 'markdown.shikiConfig.lang', - 'markdown.shikiConfig.theme', - 'markdown.shikiConfig.wrap', - 'markdown.syntaxHighlight', - 'markdown.remarkPlugins', - 'markdown.rehypePlugins', - ]); - }); - - it('syntaxHighlight', () => { + it('string literal "markdown.syntaxHighlight" is included', () => { const config = { markdown: { syntaxHighlight: 'shiki', @@ -145,233 +56,16 @@ describe('Events', () => { }, config ); - expect(payload.configKeys).is.deep.equal([ - 'root', - 'vite', - 'vite.css', - 'vite.css.modules', - 'vite.base', - 'vite.mode', - 'vite.define', - 'vite.publicDir', + expect(Object.keys(payload.config.vite)).is.deep.equal([ + 'css', + 'base', + 'mode', + 'define', + 'publicDir', ]); }); - it('vite.resolve keys are captured', async () => { - const config = { - vite: { - resolve: { - alias: { - a: 'b', - }, - dedupe: ['one', 'two'], - }, - }, - }; - - const [{ payload }] = events.eventCliSession( - { - cliCommand: 'dev', - }, - config - ); - expect(payload.configKeys).is.deep.equal([ - 'vite', - 'vite.resolve', - 'vite.resolve.alias', - 'vite.resolve.dedupe', - ]); - }); - - it('vite.css keys are captured', async () => { - const config = { - vite: { - resolve: { - dedupe: ['one', 'two'], - }, - css: { - modules: [], - postcss: {}, - }, - }, - }; - - const [{ payload }] = events.eventCliSession( - { - cliCommand: 'dev', - }, - config - ); - expect(payload.configKeys).is.deep.equal([ - 'vite', - 'vite.resolve', - 'vite.resolve.dedupe', - 'vite.css', - 'vite.css.modules', - 'vite.css.postcss', - ]); - }); - - it('vite.server keys are captured', async () => { - const config = { - vite: { - server: { - host: 'example.com', - open: true, - fs: { - strict: true, - allow: ['a', 'b'], - }, - }, - }, - }; - - const [{ payload }] = events.eventCliSession( - { - cliCommand: 'dev', - }, - config - ); - expect(payload.configKeys).is.deep.equal([ - 'vite', - 'vite.server', - 'vite.server.host', - 'vite.server.open', - 'vite.server.fs', - 'vite.server.fs.strict', - 'vite.server.fs.allow', - ]); - }); - - it('vite.build keys are captured', async () => { - const config = { - vite: { - build: { - target: 'one', - outDir: 'some/dir', - cssTarget: { - one: 'two', - }, - }, - }, - }; - - const [{ payload }] = events.eventCliSession( - { - cliCommand: 'dev', - }, - config - ); - expect(payload.configKeys).is.deep.equal([ - 'vite', - 'vite.build', - 'vite.build.target', - 'vite.build.outDir', - 'vite.build.cssTarget', - ]); - }); - - it('vite.preview keys are captured', async () => { - const config = { - vite: { - preview: { - host: 'example.com', - port: 8080, - another: { - a: 'b', - }, - }, - }, - }; - - const [{ payload }] = events.eventCliSession( - { - cliCommand: 'dev', - }, - config - ); - expect(payload.configKeys).is.deep.equal([ - 'vite', - 'vite.preview', - 'vite.preview.host', - 'vite.preview.port', - 'vite.preview.another', - ]); - }); - - it('vite.optimizeDeps keys are captured', async () => { - const config = { - vite: { - optimizeDeps: { - entries: ['one', 'two'], - exclude: ['secret', 'name'], - }, - }, - }; - - const [{ payload }] = events.eventCliSession( - { - cliCommand: 'dev', - }, - config - ); - expect(payload.configKeys).is.deep.equal([ - 'vite', - 'vite.optimizeDeps', - 'vite.optimizeDeps.entries', - 'vite.optimizeDeps.exclude', - ]); - }); - - it('vite.ssr keys are captured', async () => { - const config = { - vite: { - ssr: { - external: ['a'], - target: { one: 'two' }, - }, - }, - }; - - const [{ payload }] = events.eventCliSession( - { - cliCommand: 'dev', - }, - config - ); - expect(payload.configKeys).is.deep.equal([ - 'vite', - 'vite.ssr', - 'vite.ssr.external', - 'vite.ssr.target', - ]); - }); - - it('vite.worker keys are captured', async () => { - const config = { - vite: { - worker: { - format: { a: 'b' }, - plugins: ['a', 'b'], - }, - }, - }; - - const [{ payload }] = events.eventCliSession( - { - cliCommand: 'dev', - }, - config - ); - expect(payload.configKeys).is.deep.equal([ - 'vite', - 'vite.worker', - 'vite.worker.format', - 'vite.worker.plugins', - ]); - }); - - it('falsy integrations', () => { + it('falsy integrations are handled', () => { const config = { srcDir: 1, integrations: [null, undefined, false], @@ -385,7 +79,7 @@ describe('Events', () => { expect(payload.config.integrations.length).to.equal(0); }); - it('finds names for integration arrays', () => { + it('only integration names are included', () => { const config = { integrations: [{ name: 'foo' }, [{ name: 'bar' }, { name: 'baz' }]], }; @@ -393,6 +87,14 @@ describe('Events', () => { expect(payload.config.integrations).to.deep.equal(['foo', 'bar', 'baz']); }); + it('only adapter name is included', () => { + const config = { + adapter: { name: 'ADAPTER_NAME' }, + }; + const [{ payload }] = events.eventCliSession({ cliCommand: 'dev' }, config); + expect(payload.config.adapter).to.equal('ADAPTER_NAME'); + }); + it('includes cli flags in payload', () => { const config = {}; const flags = { diff --git a/packages/create-astro/CHANGELOG.md b/packages/create-astro/CHANGELOG.md index fabd98390..0e11c1bf4 100644 --- a/packages/create-astro/CHANGELOG.md +++ b/packages/create-astro/CHANGELOG.md @@ -1,5 +1,11 @@ # create-astro +## 4.2.0 + +### Minor Changes + +- [#8551](https://github.com/withastro/astro/pull/8551) [`1d5b3f079`](https://github.com/withastro/astro/commit/1d5b3f079d0b4aa5a5c46f97b8b724ab88497fbe) Thanks [@jacobthesheep](https://github.com/jacobthesheep)! - Adds `--yes` and `dry-run` flags to project-name and the `yes` flag to template. + ## 4.1.0 ### Minor Changes diff --git a/packages/create-astro/package.json b/packages/create-astro/package.json index 583c98164..3c8f98667 100644 --- a/packages/create-astro/package.json +++ b/packages/create-astro/package.json @@ -1,6 +1,6 @@ { "name": "create-astro", - "version": "4.1.0", + "version": "4.2.0", "type": "module", "author": "withastro", "license": "MIT", diff --git a/packages/create-astro/src/actions/project-name.ts b/packages/create-astro/src/actions/project-name.ts index 533240efd..8802387af 100644 --- a/packages/create-astro/src/actions/project-name.ts +++ b/packages/create-astro/src/actions/project-name.ts @@ -6,7 +6,9 @@ import { info, log, title } from '../messages.js'; import { isEmpty, toValidName } from './shared.js'; -export async function projectName(ctx: Pick) { +export async function projectName( + ctx: Pick +) { await checkCwd(ctx.cwd); if (!ctx.cwd || !isEmpty(ctx.cwd)) { @@ -14,6 +16,13 @@ export async function projectName(ctx: Pick) { - if (!ctx.template) { +export async function template( + ctx: Pick +) { + if (ctx.yes) { + ctx.template = 'basics'; + await info('tmpl', `Using ${color.reset(ctx.template)}${color.dim(' as project template')}`); + } else if (!ctx.template) { const { template: tmpl } = await ctx.prompt({ name: 'template', type: 'select', diff --git a/packages/create-astro/test/project-name.test.js b/packages/create-astro/test/project-name.test.js index 4b8cdce7f..1672fce66 100644 --- a/packages/create-astro/test/project-name.test.js +++ b/packages/create-astro/test/project-name.test.js @@ -92,4 +92,48 @@ describe('project name', () => { expect(context.cwd).to.eq('@astro/site'); expect(context.projectName).to.eq('@astro/site'); }); + + it('--yes', async () => { + const context = { + projectName: '', + cwd: './foo/bar/baz', + yes: true, + prompt: () => {}, + }; + await projectName(context); + expect(context.projectName).to.eq('baz'); + }); + + it('dry run with name', async () => { + const context = { + projectName: '', + cwd: './foo/bar/baz', + dryRun: true, + prompt: () => {}, + }; + await projectName(context); + expect(context.projectName).to.eq('baz'); + }); + + it('dry run with dot', async () => { + const context = { + projectName: '', + cwd: '.', + dryRun: true, + prompt: () => ({ name: 'foobar' }), + }; + await projectName(context); + expect(context.projectName).to.eq('foobar'); + }); + + it('dry run with empty', async () => { + const context = { + projectName: '', + cwd: './test/fixtures/empty', + dryRun: true, + prompt: () => ({ name: 'foobar' }), + }; + await projectName(context); + expect(context.projectName).to.eq('empty'); + }); }); diff --git a/packages/integrations/cloudflare/CHANGELOG.md b/packages/integrations/cloudflare/CHANGELOG.md index d6255ea6b..ad291c413 100644 --- a/packages/integrations/cloudflare/CHANGELOG.md +++ b/packages/integrations/cloudflare/CHANGELOG.md @@ -1,5 +1,15 @@ # @astrojs/cloudflare +## 7.1.1 + +### Patch Changes + +- [#8560](https://github.com/withastro/astro/pull/8560) [`3da5d8404`](https://github.com/withastro/astro/commit/3da5d8404e56a05da93f6b0a70841acda5ca1a8f) Thanks [@alexanderniebuhr](https://github.com/alexanderniebuhr)! - add the option to type environment variables using a generic + +- Updated dependencies [[`8d361169b`](https://github.com/withastro/astro/commit/8d361169b8e487933d671ce347f0ce74922c80cc), [`95b5f6280`](https://github.com/withastro/astro/commit/95b5f6280d124f8d6f866dc3286406c272ee91bf), [`0586e20e8`](https://github.com/withastro/astro/commit/0586e20e8338e077b8eb1a3a96bdd19f5950c22f)]: + - astro@3.1.1 + - @astrojs/underscore-redirects@0.3.0 + ## 7.1.0 ### Minor Changes diff --git a/packages/integrations/cloudflare/README.md b/packages/integrations/cloudflare/README.md index 27e621853..719a5688c 100644 --- a/packages/integrations/cloudflare/README.md +++ b/packages/integrations/cloudflare/README.md @@ -202,6 +202,33 @@ This will enable Cloudflare to serve files and process static redirects without See [Cloudflare's documentation](https://developers.cloudflare.com/pages/platform/functions/routing/#create-a-_routesjson-file) for more details. +## Node.js compatibility + +Astro's Cloudflare adapter allows you to use any Node.js runtime API supported by Cloudflare: + +- assert +- AsyncLocalStorage +- Buffer +- Diagnostics Channel +- EventEmitter +- path +- process +- Streams +- StringDecoder +- util + +To use these APIs, your page or endpoint must be server-side rendered (not pre-rendered) and must use the the `import {} from 'node:*'` import syntax. + +```js +// pages/api/endpoint.js +export const prerender = false; +import { Buffer } from 'node:buffer'; +``` + +Additionally, you'll need to enable the Compatibility Flag in Cloudflare. The configuration for this flag may vary based on where you deploy your Astro site. + +For detailed guidance, please refer to the [Cloudflare documentation](https://developers.cloudflare.com/workers/runtime-apis/nodejs). + ## Troubleshooting For help, check out the `#support` channel on [Discord](https://astro.build/chat). Our friendly Support Squad members are here to help! diff --git a/packages/integrations/cloudflare/package.json b/packages/integrations/cloudflare/package.json index 0b5f61028..57d2dc93b 100644 --- a/packages/integrations/cloudflare/package.json +++ b/packages/integrations/cloudflare/package.json @@ -1,7 +1,7 @@ { "name": "@astrojs/cloudflare", "description": "Deploy your site to Cloudflare Workers/Pages", - "version": "7.1.0", + "version": "7.1.1", "type": "module", "types": "./dist/index.d.ts", "author": "withastro", @@ -51,7 +51,7 @@ "tiny-glob": "^0.2.9" }, "peerDependencies": { - "astro": "workspace:^3.1.0" + "astro": "workspace:^3.1.1" }, "devDependencies": { "@types/iarna__toml": "^2.0.2", diff --git a/packages/integrations/cloudflare/src/index.ts b/packages/integrations/cloudflare/src/index.ts index b64d986af..24c22d8f1 100644 --- a/packages/integrations/cloudflare/src/index.ts +++ b/packages/integrations/cloudflare/src/index.ts @@ -296,6 +296,18 @@ export default function createIntegration(args?: Options): AstroIntegration { target: 'es2020', platform: 'browser', conditions: ['workerd', 'worker', 'browser'], + external: [ + 'node:assert', + 'node:async_hooks', + 'node:buffer', + 'node:diagnostics_channel', + 'node:events', + 'node:path', + 'node:process', + 'node:stream', + 'node:string_decoder', + 'node:util', + ], entryPoints: entryPaths, outdir: outputDir, allowOverwrite: true, @@ -357,6 +369,18 @@ export default function createIntegration(args?: Options): AstroIntegration { target: 'es2020', platform: 'browser', conditions: ['workerd', 'worker', 'browser'], + external: [ + 'node:assert', + 'node:async_hooks', + 'node:buffer', + 'node:diagnostics_channel', + 'node:events', + 'node:path', + 'node:process', + 'node:stream', + 'node:string_decoder', + 'node:util', + ], entryPoints: [entryPath], outfile: buildPath, allowOverwrite: true, diff --git a/packages/integrations/deno/package.json b/packages/integrations/deno/package.json index 7905956c1..496ed7427 100644 --- a/packages/integrations/deno/package.json +++ b/packages/integrations/deno/package.json @@ -36,7 +36,7 @@ "esbuild": "^0.19.2" }, "peerDependencies": { - "astro": "workspace:^3.1.0" + "astro": "workspace:^3.1.1" }, "devDependencies": { "astro": "workspace:*", diff --git a/packages/integrations/markdoc/package.json b/packages/integrations/markdoc/package.json index 0aae4a982..33d058ba3 100644 --- a/packages/integrations/markdoc/package.json +++ b/packages/integrations/markdoc/package.json @@ -75,7 +75,7 @@ "zod": "3.21.1" }, "peerDependencies": { - "astro": "workspace:^3.1.0" + "astro": "workspace:^3.1.1" }, "devDependencies": { "@astrojs/markdown-remark": "workspace:*", diff --git a/packages/integrations/mdx/package.json b/packages/integrations/mdx/package.json index c621384c1..906298fee 100644 --- a/packages/integrations/mdx/package.json +++ b/packages/integrations/mdx/package.json @@ -51,7 +51,7 @@ "vfile": "^5.3.7" }, "peerDependencies": { - "astro": "workspace:^3.1.0" + "astro": "workspace:^3.1.1" }, "devDependencies": { "@types/chai": "^4.3.5", diff --git a/packages/integrations/netlify/package.json b/packages/integrations/netlify/package.json index c477c02e5..12b7291b5 100644 --- a/packages/integrations/netlify/package.json +++ b/packages/integrations/netlify/package.json @@ -43,7 +43,7 @@ "esbuild": "^0.19.2" }, "peerDependencies": { - "astro": "workspace:^3.1.0" + "astro": "workspace:^3.1.1" }, "devDependencies": { "@netlify/edge-functions": "^2.0.0", diff --git a/packages/integrations/node/package.json b/packages/integrations/node/package.json index 4f852bdc6..4dda2e251 100644 --- a/packages/integrations/node/package.json +++ b/packages/integrations/node/package.json @@ -37,7 +37,7 @@ "server-destroy": "^1.0.1" }, "peerDependencies": { - "astro": "workspace:^3.1.0" + "astro": "workspace:^3.1.1" }, "devDependencies": { "@types/node": "^18.17.8", diff --git a/packages/integrations/node/src/nodeMiddleware.ts b/packages/integrations/node/src/nodeMiddleware.ts index 32b8020dc..ddaa95deb 100644 --- a/packages/integrations/node/src/nodeMiddleware.ts +++ b/packages/integrations/node/src/nodeMiddleware.ts @@ -51,6 +51,9 @@ export default function (app: NodeApp, mode: Options['mode']) { await writeWebResponse(app, res, response); } } catch (err: unknown) { + const logger = app.getAdapterLogger(); + logger.error(`Could not render ${req.url}`); + console.error(err); if (!res.headersSent) { res.writeHead(500, `Server error`); res.end(); diff --git a/packages/integrations/svelte/package.json b/packages/integrations/svelte/package.json index 1d36d5e17..04d135ee2 100644 --- a/packages/integrations/svelte/package.json +++ b/packages/integrations/svelte/package.json @@ -48,7 +48,7 @@ "vite": "^4.4.9" }, "peerDependencies": { - "astro": "workspace:^3.1.0", + "astro": "workspace:^3.1.1", "svelte": "^3.55.0 || ^4.0.0" }, "engines": { diff --git a/packages/integrations/tailwind/package.json b/packages/integrations/tailwind/package.json index 9c0c68a07..6717c461c 100644 --- a/packages/integrations/tailwind/package.json +++ b/packages/integrations/tailwind/package.json @@ -43,7 +43,7 @@ "vite": "^4.4.9" }, "peerDependencies": { - "astro": "workspace:^3.1.0", + "astro": "workspace:^3.1.1", "tailwindcss": "^3.0.24" } } diff --git a/packages/integrations/vercel/CHANGELOG.md b/packages/integrations/vercel/CHANGELOG.md index 2c3e74b47..ae77d38a1 100644 --- a/packages/integrations/vercel/CHANGELOG.md +++ b/packages/integrations/vercel/CHANGELOG.md @@ -1,5 +1,14 @@ # @astrojs/vercel +## 5.0.1 + +### Patch Changes + +- [#8581](https://github.com/withastro/astro/pull/8581) [`d0e513f21`](https://github.com/withastro/astro/commit/d0e513f214fe3cb30bab6d98936cda796477f2f8) Thanks [@rishi-raj-jain](https://github.com/rishi-raj-jain)! - log only once in serverless adapter + +- Updated dependencies [[`8d361169b`](https://github.com/withastro/astro/commit/8d361169b8e487933d671ce347f0ce74922c80cc), [`95b5f6280`](https://github.com/withastro/astro/commit/95b5f6280d124f8d6f866dc3286406c272ee91bf), [`0586e20e8`](https://github.com/withastro/astro/commit/0586e20e8338e077b8eb1a3a96bdd19f5950c22f)]: + - astro@3.1.1 + ## 5.0.0 ### Major Changes diff --git a/packages/integrations/vercel/package.json b/packages/integrations/vercel/package.json index 999181be2..894d8d5b6 100644 --- a/packages/integrations/vercel/package.json +++ b/packages/integrations/vercel/package.json @@ -1,7 +1,7 @@ { "name": "@astrojs/vercel", "description": "Deploy your site to Vercel", - "version": "5.0.0", + "version": "5.0.1", "type": "module", "author": "withastro", "license": "MIT", @@ -61,7 +61,7 @@ "web-vitals": "^3.4.0" }, "peerDependencies": { - "astro": "workspace:^3.1.0" + "astro": "workspace:^3.1.1" }, "devDependencies": { "@types/set-cookie-parser": "^2.4.3", diff --git a/packages/integrations/vue/package.json b/packages/integrations/vue/package.json index 26d0dbe68..d045f2ab8 100644 --- a/packages/integrations/vue/package.json +++ b/packages/integrations/vue/package.json @@ -56,7 +56,7 @@ "vue": "^3.3.4" }, "peerDependencies": { - "astro": "workspace:^3.1.0", + "astro": "workspace:^3.1.1", "vue": "^3.2.30" }, "engines": { diff --git a/packages/telemetry/README.md b/packages/telemetry/README.md index 6adc8b96f..c9dc896fc 100644 --- a/packages/telemetry/README.md +++ b/packages/telemetry/README.md @@ -1,9 +1,17 @@ # Astro Telemetry -This package is used to collect anonymous telemetry data within the Astro CLI. It is enabled by default. Telemetry data does not contain any personal identifying information and can be disabled via: +This package is used to collect anonymous telemetry data within the Astro CLI. + +It can be disabled in Astro using either method documented below: ```shell +# Option 1: Run this to disable telemetry globally across your entire machine. astro telemetry disable ``` -See the [CLI documentation](https://docs.astro.build/en/reference/cli-reference/#astro-telemetry) for more options on configuration telemetry. +```shell +# Option 2: The ASTRO_TELEMETRY_DISABLED environment variable disables telemetry when set. +ASTRO_TELEMETRY_DISABLED=1 astro dev +``` + +Visit https://astro.build/telemetry/ for more information about our approach to anonymous telemetry in Astro. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e49068992..1aebf6930 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -125,7 +125,7 @@ importers: examples/basics: dependencies: astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro examples/blog: @@ -140,19 +140,19 @@ importers: specifier: ^3.0.0 version: link:../../packages/integrations/sitemap astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro examples/component: devDependencies: astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro examples/deno: dependencies: astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro devDependencies: '@astrojs/deno': @@ -171,7 +171,7 @@ importers: specifier: ^3.12.3 version: 3.12.3 astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro examples/framework-lit: @@ -183,7 +183,7 @@ importers: specifier: ^0.2.1 version: 0.2.1 astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro lit: specifier: ^2.8.0 @@ -207,7 +207,7 @@ importers: specifier: ^3.0.0 version: link:../../packages/integrations/vue astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro preact: specifier: ^10.17.1 @@ -237,7 +237,7 @@ importers: specifier: ^1.2.1 version: 1.2.1(preact@10.17.1) astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro preact: specifier: ^10.17.1 @@ -255,7 +255,7 @@ importers: specifier: ^18.2.7 version: 18.2.7 astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro react: specifier: ^18.2.0 @@ -270,7 +270,7 @@ importers: specifier: ^3.0.1 version: link:../../packages/integrations/solid astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro solid-js: specifier: ^1.7.11 @@ -282,7 +282,7 @@ importers: specifier: ^4.0.2 version: link:../../packages/integrations/svelte astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro svelte: specifier: ^4.2.0 @@ -294,7 +294,7 @@ importers: specifier: ^3.0.0 version: link:../../packages/integrations/vue astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro vue: specifier: ^3.3.4 @@ -306,13 +306,13 @@ importers: specifier: ^6.0.0 version: link:../../packages/integrations/node astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro examples/integration: devDependencies: astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro examples/middleware: @@ -321,7 +321,7 @@ importers: specifier: ^6.0.0 version: link:../../packages/integrations/node astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro html-minifier: specifier: ^4.0.0 @@ -330,19 +330,19 @@ importers: examples/minimal: dependencies: astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro examples/non-html-pages: dependencies: astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro examples/portfolio: dependencies: astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro examples/ssr: @@ -354,7 +354,7 @@ importers: specifier: ^4.0.2 version: link:../../packages/integrations/svelte astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro svelte: specifier: ^4.2.0 @@ -366,7 +366,7 @@ importers: specifier: ^0.5.0 version: link:../../packages/integrations/markdoc astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro examples/with-markdown-plugins: @@ -375,7 +375,7 @@ importers: specifier: ^3.2.0 version: link:../../packages/markdown/remark astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro hast-util-select: specifier: ^5.0.5 @@ -396,7 +396,7 @@ importers: examples/with-markdown-shiki: dependencies: astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro examples/with-mdx: @@ -408,7 +408,7 @@ importers: specifier: ^3.0.0 version: link:../../packages/integrations/preact astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro preact: specifier: ^10.17.1 @@ -423,7 +423,7 @@ importers: specifier: ^0.5.0 version: 0.5.0(nanostores@0.9.3)(preact@10.17.1) astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro nanostores: specifier: ^0.9.3 @@ -444,7 +444,7 @@ importers: specifier: ^1.6.0 version: 1.6.0 astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro autoprefixer: specifier: ^10.4.15 @@ -462,7 +462,7 @@ importers: examples/with-vite-plugin-pwa: dependencies: astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro vite-plugin-pwa: specifier: 0.16.4 @@ -474,7 +474,7 @@ importers: examples/with-vitest: dependencies: astro: - specifier: ^3.1.0 + specifier: ^3.1.1 version: link:../../packages/astro vitest: specifier: ^0.34.2