Merge branch 'main' into feat/dev-overlay

This commit is contained in:
Erika 2023-10-05 20:53:14 +02:00 committed by GitHub
commit 5bb1398b2a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
138 changed files with 1290 additions and 566 deletions

View file

@ -1,5 +0,0 @@
---
'@astrojs/cloudflare': minor
---
Change build target from `es2020` to `es2022`, for better support

View file

@ -22,6 +22,9 @@ jobs:
name: Changelog PR or Release name: Changelog PR or Release
if: ${{ github.repository_owner == 'withastro' }} if: ${{ github.repository_owner == 'withastro' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3

View file

@ -81,6 +81,8 @@ jobs:
id: publish id: publish
run: | run: |
pnpm run release --tag next--${{ steps.getSnapshotName.outputs.result }} > publish.output.txt 2>&1 pnpm run release --tag next--${{ steps.getSnapshotName.outputs.result }} > publish.output.txt 2>&1
echo "Release complete"
cat publish.output.txt
echo ::set-output name=result::`cat publish.output.txt` echo ::set-output name=result::`cat publish.output.txt`
env: env:
# Needs access to publish to npm # Needs access to publish to npm

View file

@ -11,6 +11,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^3.2.0" "astro": "^3.2.3"
} }
} }

View file

@ -11,9 +11,9 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/mdx": "^1.1.0", "@astrojs/mdx": "^1.1.1",
"@astrojs/rss": "^3.0.0", "@astrojs/rss": "^3.0.0",
"@astrojs/sitemap": "^3.0.0", "@astrojs/sitemap": "^3.0.1",
"astro": "^3.2.0" "astro": "^3.2.3"
} }
} }

View file

@ -15,7 +15,7 @@
], ],
"scripts": {}, "scripts": {},
"devDependencies": { "devDependencies": {
"astro": "^3.2.0" "astro": "^3.2.3"
}, },
"peerDependencies": { "peerDependencies": {
"astro": "^2.0.0-beta.0" "astro": "^2.0.0-beta.0"

View file

@ -11,9 +11,9 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/alpinejs": "^0.3.0", "@astrojs/alpinejs": "^0.3.1",
"@types/alpinejs": "^3.7.2", "@types/alpinejs": "^3.7.2",
"alpinejs": "^3.12.3", "alpinejs": "^3.12.3",
"astro": "^3.2.0" "astro": "^3.2.3"
} }
} }

View file

@ -11,9 +11,9 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/lit": "^3.0.0", "@astrojs/lit": "^3.0.1",
"@webcomponents/template-shadowroot": "^0.2.1", "@webcomponents/template-shadowroot": "^0.2.1",
"astro": "^3.2.0", "astro": "^3.2.3",
"lit": "^2.8.0" "lit": "^2.8.0"
} }
} }

View file

@ -11,12 +11,12 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/preact": "^3.0.0", "@astrojs/preact": "^3.0.1",
"@astrojs/react": "^3.0.2", "@astrojs/react": "^3.0.3",
"@astrojs/solid-js": "^3.0.1", "@astrojs/solid-js": "^3.0.2",
"@astrojs/svelte": "^4.0.2", "@astrojs/svelte": "^4.0.3",
"@astrojs/vue": "^3.0.0", "@astrojs/vue": "^3.0.1",
"astro": "^3.2.0", "astro": "^3.2.3",
"preact": "^10.17.1", "preact": "^10.17.1",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",

View file

@ -11,9 +11,9 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/preact": "^3.0.0", "@astrojs/preact": "^3.0.1",
"@preact/signals": "^1.2.1", "@preact/signals": "^1.2.1",
"astro": "^3.2.0", "astro": "^3.2.3",
"preact": "^10.17.1" "preact": "^10.17.1"
} }
} }

View file

@ -11,10 +11,10 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/react": "^3.0.2", "@astrojs/react": "^3.0.3",
"@types/react": "^18.2.21", "@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7", "@types/react-dom": "^18.2.7",
"astro": "^3.2.0", "astro": "^3.2.3",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0" "react-dom": "^18.2.0"
} }

View file

@ -11,8 +11,8 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/solid-js": "^3.0.1", "@astrojs/solid-js": "^3.0.2",
"astro": "^3.2.0", "astro": "^3.2.3",
"solid-js": "^1.7.11" "solid-js": "^1.7.11"
} }
} }

View file

@ -11,8 +11,8 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/svelte": "^4.0.2", "@astrojs/svelte": "^4.0.3",
"astro": "^3.2.0", "astro": "^3.2.3",
"svelte": "^4.2.0" "svelte": "^4.2.0"
} }
} }

View file

@ -11,8 +11,8 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/vue": "^3.0.0", "@astrojs/vue": "^3.0.1",
"astro": "^3.2.0", "astro": "^3.2.3",
"vue": "^3.3.4" "vue": "^3.3.4"
} }
} }

View file

@ -11,7 +11,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/node": "^6.0.1", "@astrojs/node": "^6.0.3",
"astro": "^3.2.0" "astro": "^3.2.3"
} }
} }

View file

@ -15,7 +15,7 @@
], ],
"scripts": {}, "scripts": {},
"devDependencies": { "devDependencies": {
"astro": "^3.2.0" "astro": "^3.2.3"
}, },
"peerDependencies": { "peerDependencies": {
"astro": "^2.0.0-beta.0" "astro": "^2.0.0-beta.0"

View file

@ -12,8 +12,8 @@
"server": "node dist/server/entry.mjs" "server": "node dist/server/entry.mjs"
}, },
"dependencies": { "dependencies": {
"@astrojs/node": "^6.0.1", "@astrojs/node": "^6.0.3",
"astro": "^3.2.0", "astro": "^3.2.3",
"html-minifier": "^4.0.0" "html-minifier": "^4.0.0"
} }
} }

View file

@ -11,6 +11,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^3.2.0" "astro": "^3.2.3"
} }
} }

View file

@ -11,6 +11,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^3.2.0" "astro": "^3.2.3"
} }
} }

View file

@ -11,6 +11,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^3.2.0" "astro": "^3.2.3"
} }
} }

View file

@ -12,9 +12,9 @@
"server": "node dist/server/entry.mjs" "server": "node dist/server/entry.mjs"
}, },
"dependencies": { "dependencies": {
"@astrojs/node": "^6.0.1", "@astrojs/node": "^6.0.3",
"@astrojs/svelte": "^4.0.2", "@astrojs/svelte": "^4.0.3",
"astro": "^3.2.0", "astro": "^3.2.3",
"svelte": "^4.2.0" "svelte": "^4.2.0"
} }
} }

View file

@ -10,8 +10,8 @@
"astro": "astro" "astro": "astro"
}, },
"devDependencies": { "devDependencies": {
"@astrojs/tailwind": "^5.0.0", "@astrojs/tailwind": "^5.0.1",
"@astrojs/node": "^6.0.1", "@astrojs/node": "^6.0.3",
"astro": "^3.2.0" "astro": "^3.2.3"
} }
} }

View file

@ -11,7 +11,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/markdoc": "^0.5.0", "@astrojs/markdoc": "^0.5.2",
"astro": "^3.2.0" "astro": "^3.2.3"
} }
} }

View file

@ -11,8 +11,8 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/markdown-remark": "^3.2.0", "@astrojs/markdown-remark": "^3.2.1",
"astro": "^3.2.0", "astro": "^3.2.3",
"hast-util-select": "^5.0.5", "hast-util-select": "^5.0.5",
"rehype-autolink-headings": "^6.1.1", "rehype-autolink-headings": "^6.1.1",
"rehype-slug": "^5.1.0", "rehype-slug": "^5.1.0",

View file

@ -11,6 +11,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^3.2.0" "astro": "^3.2.3"
} }
} }

View file

@ -11,9 +11,9 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/mdx": "^1.1.0", "@astrojs/mdx": "^1.1.1",
"@astrojs/preact": "^3.0.0", "@astrojs/preact": "^3.0.1",
"astro": "^3.2.0", "astro": "^3.2.3",
"preact": "^10.17.1" "preact": "^10.17.1"
} }
} }

View file

@ -11,9 +11,9 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/preact": "^3.0.0", "@astrojs/preact": "^3.0.1",
"@nanostores/preact": "^0.5.0", "@nanostores/preact": "^0.5.0",
"astro": "^3.2.0", "astro": "^3.2.3",
"nanostores": "^0.9.3", "nanostores": "^0.9.3",
"preact": "^10.17.1" "preact": "^10.17.1"
} }

View file

@ -11,10 +11,10 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/mdx": "^1.1.0", "@astrojs/mdx": "^1.1.1",
"@astrojs/tailwind": "^5.0.0", "@astrojs/tailwind": "^5.0.1",
"@types/canvas-confetti": "^1.6.0", "@types/canvas-confetti": "^1.6.0",
"astro": "^3.2.0", "astro": "^3.2.3",
"autoprefixer": "^10.4.15", "autoprefixer": "^10.4.15",
"canvas-confetti": "^1.6.0", "canvas-confetti": "^1.6.0",
"postcss": "^8.4.28", "postcss": "^8.4.28",

View file

@ -11,7 +11,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^3.2.0", "astro": "^3.2.3",
"vite-plugin-pwa": "0.16.4", "vite-plugin-pwa": "0.16.4",
"workbox-window": "^7.0.0" "workbox-window": "^7.0.0"
} }

View file

@ -12,7 +12,7 @@
"test": "vitest" "test": "vitest"
}, },
"dependencies": { "dependencies": {
"astro": "^3.2.0", "astro": "^3.2.3",
"vitest": "^0.34.2" "vitest": "^0.34.2"
} }
} }

View file

@ -1,5 +1,46 @@
# astro # astro
## 3.2.3
### Patch Changes
- [#8737](https://github.com/withastro/astro/pull/8737) [`6f60da805`](https://github.com/withastro/astro/commit/6f60da805e0014bc50dd07bef972e91c73560c3c) Thanks [@ematipico](https://github.com/ematipico)! - Add provenance statement when publishing the library from CI
- [#8747](https://github.com/withastro/astro/pull/8747) [`d78806dfe`](https://github.com/withastro/astro/commit/d78806dfe0301ea7ffe6c7c1f783bd415ac7cda9) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Improve error message when user attempts to render a dynamic component reference
- [#8736](https://github.com/withastro/astro/pull/8736) [`d1c75fe15`](https://github.com/withastro/astro/commit/d1c75fe158839699c59728cf3a83888e8c72a459) Thanks [@bluwy](https://github.com/bluwy)! - Fix `tsconfig.json` update causing the server to crash
- [#8743](https://github.com/withastro/astro/pull/8743) [`aa265d730`](https://github.com/withastro/astro/commit/aa265d73024422967c1b1c68ad268c419c6c798f) Thanks [@bluwy](https://github.com/bluwy)! - Remove unused CSS output files when inlined
- [#8700](https://github.com/withastro/astro/pull/8700) [`78adbc443`](https://github.com/withastro/astro/commit/78adbc4433208458291e36713909762e148e1e5d) Thanks [@jacobthesheep](https://github.com/jacobthesheep)! - Update link for Netlify SSR
- [#8729](https://github.com/withastro/astro/pull/8729) [`21e0757ea`](https://github.com/withastro/astro/commit/21e0757ea22a57d344c934045ca19db93b684436) Thanks [@lilnasy](https://github.com/lilnasy)! - Node-based adapters now create less server-side javascript
- [#8730](https://github.com/withastro/astro/pull/8730) [`357270f2a`](https://github.com/withastro/astro/commit/357270f2a3d0bf2aa634ba7e52e9d17618eff4a7) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Improve `astro info` copy to clipboard compatability
- Updated dependencies [[`21f482657`](https://github.com/withastro/astro/commit/21f4826576c2c812a1604e18717799da3470decd), [`6f60da805`](https://github.com/withastro/astro/commit/6f60da805e0014bc50dd07bef972e91c73560c3c), [`21e0757ea`](https://github.com/withastro/astro/commit/21e0757ea22a57d344c934045ca19db93b684436)]:
- @astrojs/markdown-remark@3.2.1
- @astrojs/internal-helpers@0.2.1
- @astrojs/telemetry@3.0.3
## 3.2.2
### Patch Changes
- [#8724](https://github.com/withastro/astro/pull/8724) [`455af3235`](https://github.com/withastro/astro/commit/455af3235b3268852e6988accecc796f03f6d16e) Thanks [@bluwy](https://github.com/bluwy)! - Fix CSS styles on Windows
- [#8710](https://github.com/withastro/astro/pull/8710) [`4c2bec681`](https://github.com/withastro/astro/commit/4c2bec681b0752e7215b8a32bd2d44bf477adac1) Thanks [@matthewp](https://github.com/matthewp)! - Fixes View transition styles being missing when component used multiple times
## 3.2.1
### Patch Changes
- [#8680](https://github.com/withastro/astro/pull/8680) [`31c59ad8b`](https://github.com/withastro/astro/commit/31c59ad8b6a72f95c98a306ecf92d198c03110b4) Thanks [@bluwy](https://github.com/bluwy)! - Fix hydration on slow connection
- [#8698](https://github.com/withastro/astro/pull/8698) [`47ea310f0`](https://github.com/withastro/astro/commit/47ea310f01d06ed1562c790bec348718a2fa8277) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Use a Node-specific image endpoint to resolve images in dev and Node SSR. This should fix many issues related to getting 404 from the \_image endpoint under certain configurations
- [#8706](https://github.com/withastro/astro/pull/8706) [`345808170`](https://github.com/withastro/astro/commit/345808170fce783ddd3c9a4035a91fa64dcc5f46) Thanks [@bluwy](https://github.com/bluwy)! - Fix duplicated Astro and Vite injected styles
## 3.2.0 ## 3.2.0
### Minor Changes ### Minor Changes

View file

@ -3,7 +3,6 @@
// ISOMORPHIC FILE: NO TOP-LEVEL IMPORT/REQUIRE() ALLOWED // ISOMORPHIC FILE: NO TOP-LEVEL IMPORT/REQUIRE() ALLOWED
// This file has to run as both ESM and CJS on older Node.js versions // This file has to run as both ESM and CJS on older Node.js versions
// Needed for Stackblitz: https://github.com/stackblitz/webcontainer-core/issues/281
const CI_INSTRUCTIONS = { const CI_INSTRUCTIONS = {
NETLIFY: 'https://docs.netlify.com/configure-builds/manage-dependencies/#node-js-and-javascript', NETLIFY: 'https://docs.netlify.com/configure-builds/manage-dependencies/#node-js-and-javascript',
@ -16,15 +15,11 @@ const CI_INSTRUCTIONS = {
const engines = '>=18.14.1'; const engines = '>=18.14.1';
const skipSemverCheckIfAbove = 19; const skipSemverCheckIfAbove = 19;
// HACK (2023-08-18) Stackblitz does not support Node 18 yet, so we'll fake Node 16 support for some time until it's supported
// TODO: Remove when Node 18 is supported on Stackblitz
const isStackblitz = process.env.SHELL === '/bin/jsh' && process.versions.webcontainer != null;
/** `astro *` */ /** `astro *` */
async function main() { async function main() {
const version = process.versions.node; const version = process.versions.node;
// Fast-path for higher Node.js versions // Fast-path for higher Node.js versions
if (!isStackblitz && (parseInt(version) || 0) <= skipSemverCheckIfAbove) { if ((parseInt(version) || 0) <= skipSemverCheckIfAbove) {
try { try {
const semver = await import('semver'); const semver = await import('semver');
if (!semver.satisfies(version, engines)) { if (!semver.satisfies(version, engines)) {

View file

@ -1,36 +0,0 @@
import { expect } from '@playwright/test';
import { testFactory } from './test-utils.js';
const test = testFactory({
root: './fixtures/css/',
});
let devServer;
test.beforeAll(async ({ astro }) => {
devServer = await astro.startDevServer();
});
test.afterAll(async () => {
await devServer.stop();
});
test.describe('CSS Sourcemap HMR', () => {
test('removes Astro-injected CSS once Vite-injected CSS loads', async ({ page, astro }) => {
const html = await astro.fetch('/').then((res) => res.text());
// style[data-astro-dev-id] should exist in initial SSR'd markup
expect(html).toMatch('data-astro-dev-id');
await page.goto(astro.resolveUrl('/'));
// Ensure JS has initialized
await page.waitForTimeout(500);
// style[data-astro-dev-id] should NOT exist once JS runs
expect(await page.locator('style[data-astro-dev-id]').count()).toEqual(0);
// style[data-vite-dev-id] should exist now
expect(await page.locator('style[data-vite-dev-id]').count()).toBeGreaterThan(0);
});
});

View file

@ -29,21 +29,9 @@ test.describe('CSS HMR', () => {
await expect(h).toHaveCSS('color', 'rgb(0, 128, 0)'); await expect(h).toHaveCSS('color', 'rgb(0, 128, 0)');
}); });
test('removes Astro-injected CSS once Vite-injected CSS loads', async ({ page, astro }) => { test('removes Astro-injected CSS once Vite-injected CSS loads', async ({ astro }) => {
const html = await astro.fetch('/').then((res) => res.text()); const html = await astro.fetch('/').then((res) => res.text());
// style[data-vite-dev-id] should exist in initial SSR'd markup
// style[data-astro-dev-id] should exist in initial SSR'd markup expect(html).toMatch('data-vite-dev-id');
expect(html).toMatch('data-astro-dev-id');
await page.goto(astro.resolveUrl('/'));
// Ensure JS has initialized
await page.waitForTimeout(500);
// style[data-astro-dev-id] should NOT exist once JS runs
expect(await page.locator('style[data-astro-dev-id]').count()).toEqual(0);
// style[data-vite-dev-id] should exist now
expect(await page.locator('style[data-vite-dev-id]').count()).toBeGreaterThan(0);
}); });
}); });

View file

@ -1,7 +0,0 @@
export default {
vite: {
css: {
devSourcemap: true,
}
}
};

View file

@ -1,8 +0,0 @@
{
"name": "@e2e/css-sourcemaps",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}

View file

@ -1 +0,0 @@
/// <reference types="astro/client" />

View file

@ -1,9 +0,0 @@
<h1>hello world</h1>
<style>
@import "../styles/main.css";
h1 {
color: var(--h1-color);
}
</style>

View file

@ -1,3 +0,0 @@
:root {
--h1-color: red;
}

View file

@ -0,0 +1,3 @@
#one {
background-color: whitesmoke;
}

View file

@ -0,0 +1,3 @@
h1 {
color: blue
}

View file

@ -18,6 +18,7 @@ const { link } = Astro.props as Props;
margin: auto; margin: auto;
} }
</style> </style>
<link rel="stylesheet" href="/style.css">
<ViewTransitions /> <ViewTransitions />
<DarkMode /> <DarkMode />
<meta name="script-executions" content="0"> <meta name="script-executions" content="0">

View file

@ -1,7 +1,7 @@
--- ---
import Layout from '../components/Layout.astro'; import Layout from '../components/Layout.astro';
--- ---
<Layout> <Layout link="/one.css">
<p id="one">Page 1</p> <p id="one">Page 1</p>
<a id="click-one" href="#test">test</a> <a id="click-one" href="#test">test</a>
<a id="click-two" href="/two">go to 2</a> <a id="click-two" href="/two">go to 2</a>

View file

@ -20,6 +20,20 @@ function scrollToBottom(page) {
}); });
} }
function collectPreloads(page) {
return page.evaluate(() => {
window.preloads = [];
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) =>
mutation.addedNodes.forEach((node) => {
if (node.nodeName === 'LINK' && node.rel === 'preload') preloads.push(node.href);
})
);
});
observer.observe(document.head, { childList: true });
});
}
test.describe('View Transitions', () => { test.describe('View Transitions', () => {
test('Moving from page 1 to page 2', async ({ page, astro }) => { test('Moving from page 1 to page 2', async ({ page, astro }) => {
const loads = []; const loads = [];
@ -170,11 +184,15 @@ test.describe('View Transitions', () => {
let p = page.locator('#one'); let p = page.locator('#one');
await expect(p, 'should have content').toHaveText('Page 1'); await expect(p, 'should have content').toHaveText('Page 1');
await collectPreloads(page);
// Go to page 2 // Go to page 2
await page.click('#click-two'); await page.click('#click-two');
p = page.locator('#two'); p = page.locator('#two');
await expect(p, 'should have content').toHaveText('Page 2'); await expect(p, 'should have content').toHaveText('Page 2');
await expect(p, 'imported CSS updated').toHaveCSS('font-size', '24px'); await expect(p, 'imported CSS updated').toHaveCSS('font-size', '24px');
const preloads = await page.evaluate(() => window.preloads);
expect(preloads.length === 1 && preloads[0].endsWith('/two.css')).toBeTruthy();
}); });
test('astro:page-load event fires when navigating to new page', async ({ page, astro }) => { test('astro:page-load event fires when navigating to new page', async ({ page, astro }) => {
@ -631,7 +649,7 @@ test.describe('View Transitions', () => {
}); });
test('client:only styles are retained on transition', async ({ page, astro }) => { test('client:only styles are retained on transition', async ({ page, astro }) => {
const totalExpectedStyles = 8; const totalExpectedStyles = 7;
// Go to page 1 // Go to page 1
await page.goto(astro.resolveUrl('/client-only-one')); await page.goto(astro.resolveUrl('/client-only-one'));

View file

@ -1,6 +1,6 @@
{ {
"name": "astro", "name": "astro",
"version": "3.2.0", "version": "3.2.3",
"description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.", "description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
"type": "module", "type": "module",
"author": "withastro", "author": "withastro",
@ -56,7 +56,7 @@
"./components/*": "./components/*", "./components/*": "./components/*",
"./assets": "./dist/assets/index.js", "./assets": "./dist/assets/index.js",
"./assets/utils": "./dist/assets/utils/index.js", "./assets/utils": "./dist/assets/utils/index.js",
"./assets/image-endpoint": "./dist/assets/image-endpoint.js", "./assets/endpoint/*": "./dist/assets/endpoint/*.js",
"./assets/services/sharp": "./dist/assets/services/sharp.js", "./assets/services/sharp": "./dist/assets/services/sharp.js",
"./assets/services/squoosh": "./dist/assets/services/squoosh.js", "./assets/services/squoosh": "./dist/assets/services/squoosh.js",
"./assets/services/noop": "./dist/assets/services/noop.js", "./assets/services/noop": "./dist/assets/services/noop.js",
@ -168,7 +168,6 @@
"string-width": "^6.1.0", "string-width": "^6.1.0",
"strip-ansi": "^7.1.0", "strip-ansi": "^7.1.0",
"tsconfig-resolver": "^3.0.1", "tsconfig-resolver": "^3.0.1",
"undici": "^5.23.0",
"unist-util-visit": "^4.1.2", "unist-util-visit": "^4.1.2",
"vfile": "^5.3.7", "vfile": "^5.3.7",
"vite": "^4.4.9", "vite": "^4.4.9",
@ -226,5 +225,8 @@
"engines": { "engines": {
"node": ">=18.14.1", "node": ">=18.14.1",
"npm": ">=6.14.0" "npm": ">=6.14.0"
},
"publishConfig": {
"provenance": true
} }
} }

View file

@ -636,7 +636,7 @@ export interface AstroUserConfig {
* @see output * @see output
* @description * @description
* *
* Deploy to your favorite server, serverless, or edge host with build adapters. Import one of our first-party adapters for [Netlify](https://docs.astro.build/en/guides/deploy/netlify/#adapter-for-ssredge), [Vercel](https://docs.astro.build/en/guides/deploy/vercel/#adapter-for-ssr), and more to engage Astro SSR. * Deploy to your favorite server, serverless, or edge host with build adapters. Import one of our first-party adapters for [Netlify](https://docs.astro.build/en/guides/deploy/netlify/#adapter-for-ssr), [Vercel](https://docs.astro.build/en/guides/deploy/vercel/#adapter-for-ssr), and more to engage Astro SSR.
* *
* [See our Server-side Rendering guide](https://docs.astro.build/en/guides/server-side-rendering/) for more on SSR, and [our deployment guides](https://docs.astro.build/en/guides/deploy/) for a complete list of hosts. * [See our Server-side Rendering guide](https://docs.astro.build/en/guides/server-side-rendering/) for more on SSR, and [our deployment guides](https://docs.astro.build/en/guides/deploy/) for a complete list of hosts.
* *
@ -1172,10 +1172,10 @@ export interface AstroUserConfig {
* Pass [rehype plugins](https://github.com/remarkjs/remark-rehype) to customize how your Markdown's output HTML is processed. You can import and apply the plugin function (recommended), or pass the plugin name as a string. * Pass [rehype plugins](https://github.com/remarkjs/remark-rehype) to customize how your Markdown's output HTML is processed. You can import and apply the plugin function (recommended), or pass the plugin name as a string.
* *
* ```js * ```js
* import rehypeMinifyHtml from 'rehype-minify'; * import { rehypeAccessibleEmojis } from 'rehype-accessible-emojis';
* { * {
* markdown: { * markdown: {
* rehypePlugins: [rehypeMinifyHtml] * rehypePlugins: [rehypeAccessibleEmojis]
* } * }
* } * }
* ``` * ```
@ -2213,7 +2213,7 @@ export interface SSRMetadata {
hasRenderedHead: boolean; hasRenderedHead: boolean;
headInTree: boolean; headInTree: boolean;
extraHead: string[]; extraHead: string[];
propagators: Map<AstroComponentFactory, AstroComponentInstance>; propagators: Set<AstroComponentInstance>;
} }
/* Preview server stuff */ /* Preview server stuff */

View file

@ -1,8 +1,8 @@
import { isRemotePath } from '@astrojs/internal-helpers/path'; import { isRemotePath } from '@astrojs/internal-helpers/path';
import mime from 'mime/lite.js'; import mime from 'mime/lite.js';
import type { APIRoute } from '../@types/astro.js'; import type { APIRoute } from '../../@types/astro.js';
import { getConfiguredImageService, isRemoteAllowed } from './internal.js'; import { getConfiguredImageService, isRemoteAllowed } from '../internal.js';
import { etag } from './utils/etag.js'; import { etag } from '../utils/etag.js';
// @ts-expect-error // @ts-expect-error
import { imageConfig } from 'astro:assets'; import { imageConfig } from 'astro:assets';
@ -40,7 +40,6 @@ export const GET: APIRoute = async ({ request }) => {
let inputBuffer: Buffer | undefined = undefined; let inputBuffer: Buffer | undefined = undefined;
// TODO: handle config subpaths?
const sourceUrl = isRemotePath(transform.src) const sourceUrl = isRemotePath(transform.src)
? new URL(transform.src) ? new URL(transform.src)
: new URL(transform.src, url.origin); : new URL(transform.src, url.origin);

View file

@ -0,0 +1,88 @@
import { isRemotePath, removeQueryString } from '@astrojs/internal-helpers/path';
import { readFile } from 'fs/promises';
import mime from 'mime/lite.js';
import type { APIRoute } from '../../@types/astro.js';
import { getConfiguredImageService, isRemoteAllowed } from '../internal.js';
import { etag } from '../utils/etag.js';
// @ts-expect-error
import { assetsDir, imageConfig } from 'astro:assets';
async function loadLocalImage(src: string, url: URL) {
const filePath = import.meta.env.DEV
? removeQueryString(src.slice('/@fs'.length))
: new URL('.' + src, assetsDir);
let buffer: Buffer | undefined = undefined;
try {
buffer = await readFile(filePath);
} catch (e) {
const sourceUrl = new URL(src, url.origin);
buffer = await loadRemoteImage(sourceUrl);
}
return buffer;
}
async function loadRemoteImage(src: URL) {
try {
const res = await fetch(src);
if (!res.ok) {
return undefined;
}
return Buffer.from(await res.arrayBuffer());
} catch (err: unknown) {
return undefined;
}
}
/**
* Endpoint used in dev and SSR to serve optimized images by the base image services
*/
export const GET: APIRoute = async ({ request }) => {
try {
const imageService = await getConfiguredImageService();
if (!('transform' in imageService)) {
throw new Error('Configured image service is not a local service');
}
const url = new URL(request.url);
const transform = await imageService.parseURL(url, imageConfig);
if (!transform?.src) {
throw new Error('Incorrect transform returned by `parseURL`');
}
let inputBuffer: Buffer | undefined = undefined;
if (isRemotePath(transform.src)) {
if (isRemoteAllowed(transform.src, imageConfig) === false) {
return new Response('Forbidden', { status: 403 });
}
inputBuffer = await loadRemoteImage(new URL(transform.src));
} else {
inputBuffer = await loadLocalImage(transform.src, url);
}
if (!inputBuffer) {
return new Response('Not Found', { status: 404 });
}
const { data, format } = await imageService.transform(inputBuffer, transform, imageConfig);
return new Response(data, {
status: 200,
headers: {
'Content-Type': mime.getType(format) ?? `image/${format}`,
'Cache-Control': 'public, max-age=31536000',
ETag: etag(data.toString()),
Date: new Date().toUTCString(),
},
});
} catch (err: unknown) {
return new Response(`Server Error: ${err}`, { status: 500 });
}
};

View file

@ -10,10 +10,11 @@ import type {
} from './types.js'; } from './types.js';
import { matchHostname, matchPattern } from './utils/remotePattern.js'; import { matchHostname, matchPattern } from './utils/remotePattern.js';
export function injectImageEndpoint(settings: AstroSettings) { export function injectImageEndpoint(settings: AstroSettings, mode: 'dev' | 'build') {
const endpointEntrypoint = settings.config.image.endpoint ?? 'astro/assets/image-endpoint'; const endpointEntrypoint =
settings.config.image.endpoint ??
(mode === 'dev' ? 'astro/assets/endpoint/node' : 'astro/assets/endpoint/generic');
// TODO: Add a setting to disable the image endpoint
settings.injectedRoutes.push({ settings.injectedRoutes.push({
pattern: '/_image', pattern: '/_image',
entryPoint: endpointEntrypoint, entryPoint: endpointEntrypoint,

View file

@ -10,6 +10,7 @@ import {
prependForwardSlash, prependForwardSlash,
removeQueryString, removeQueryString,
} from '../core/path.js'; } from '../core/path.js';
import { isServerLikeOutput } from '../prerender/utils.js';
import { VALID_INPUT_FORMATS, VIRTUAL_MODULE_ID, VIRTUAL_SERVICE_ID } from './consts.js'; import { VALID_INPUT_FORMATS, VIRTUAL_MODULE_ID, VIRTUAL_SERVICE_ID } from './consts.js';
import { emitESMImage } from './utils/emitAsset.js'; import { emitESMImage } from './utils/emitAsset.js';
import { hashTransform, propsToFilename } from './utils/transformToPath.js'; import { hashTransform, propsToFilename } from './utils/transformToPath.js';
@ -58,6 +59,13 @@ export default function assets({
export { default as Image } from "astro/components/Image.astro"; export { default as Image } from "astro/components/Image.astro";
export const imageConfig = ${JSON.stringify(settings.config.image)}; export const imageConfig = ${JSON.stringify(settings.config.image)};
export const assetsDir = new URL(${JSON.stringify(
new URL(
isServerLikeOutput(settings.config)
? settings.config.build.client
: settings.config.outDir
)
)});
export const getImage = async (options) => await getImageInternal(options, imageConfig); export const getImage = async (options) => await getImageInternal(options, imageConfig);
`; `;
} }

View file

@ -41,10 +41,22 @@ export async function printInfo({ flags }: InfoOptions) {
await copyToClipboard(output.trim()); await copyToClipboard(output.trim());
} }
const SUPPORTED_SYSTEM = new Set(['darwin', 'win32']);
async function copyToClipboard(text: string) { async function copyToClipboard(text: string) {
const system = platform(); const system = platform();
if (!SUPPORTED_SYSTEM.has(system)) return; let command = '';
if (system === 'darwin') {
command = 'pbcopy';
} else if (system === 'win32') {
command = 'clip';
} else {
// Unix: check if `xclip` is installed
const output = execSync('which xclip', { encoding: 'utf8' });
if (output[0] !== '/') {
// Did not find a path for xclip, bail out!
return;
}
command = 'xclip -sel clipboard -l 1';
}
console.log(); console.log();
const { shouldCopy } = await prompts({ const { shouldCopy } = await prompts({
@ -54,11 +66,11 @@ async function copyToClipboard(text: string) {
initial: true, initial: true,
}); });
if (!shouldCopy) return; if (!shouldCopy) return;
const command = system === 'darwin' ? 'pbcopy' : 'clip';
try { try {
execSync(`echo ${JSON.stringify(text.trim())} | ${command}`, { execSync(command, {
input: text.trim(),
encoding: 'utf8', encoding: 'utf8',
stdio: 'ignore',
}); });
} catch (e) { } catch (e) {
console.error( console.error(

View file

@ -64,7 +64,7 @@ export function astroContentAssetPropagationPlugin({
if (!devModuleLoader.getModuleById(basePath)?.ssrModule) { if (!devModuleLoader.getModuleById(basePath)?.ssrModule) {
await devModuleLoader.import(basePath); await devModuleLoader.import(basePath);
} }
const { stylesMap, urls } = await getStylesForURL( const { styles, urls } = await getStylesForURL(
pathToFileURL(basePath), pathToFileURL(basePath),
devModuleLoader, devModuleLoader,
'development' 'development'
@ -77,7 +77,7 @@ export function astroContentAssetPropagationPlugin({
); );
stringifiedLinks = JSON.stringify([...urls]); stringifiedLinks = JSON.stringify([...urls]);
stringifiedStyles = JSON.stringify([...stylesMap.values()]); stringifiedStyles = JSON.stringify(styles.map((s) => s.content));
stringifiedScripts = JSON.stringify([...hoistedScripts]); stringifiedScripts = JSON.stringify([...hoistedScripts]);
} else { } else {
// Otherwise, use placeholders to inject styles and scripts // Otherwise, use placeholders to inject styles and scripts

View file

@ -148,10 +148,16 @@ export const _internal = {
hasContentFlag(modUrl, DATA_FLAG) || hasContentFlag(modUrl, DATA_FLAG) ||
Boolean(getContentRendererByViteId(modUrl, settings)) Boolean(getContentRendererByViteId(modUrl, settings))
) { ) {
try {
const mod = await viteServer.moduleGraph.getModuleByUrl(modUrl); const mod = await viteServer.moduleGraph.getModuleByUrl(modUrl);
if (mod) { if (mod) {
viteServer.moduleGraph.invalidateModule(mod); viteServer.moduleGraph.invalidateModule(mod);
} }
} catch (e: any) {
// The server may be closed due to a restart caused by this file change
if (e.code === 'ERR_CLOSED_SERVER') break;
throw e;
}
} }
} }
} }

View file

@ -111,7 +111,7 @@ class AstroBuilder {
}); });
if (isServerLikeOutput(this.settings.config)) { if (isServerLikeOutput(this.settings.config)) {
this.settings = injectImageEndpoint(this.settings); this.settings = injectImageEndpoint(this.settings, 'build');
} }
this.manifest = createRouteManifest({ settings: this.settings }, this.logger); this.manifest = createRouteManifest({ settings: this.settings }, this.logger);

View file

@ -200,7 +200,7 @@ function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] {
const inlineConfig = settings.config.build.inlineStylesheets; const inlineConfig = settings.config.build.inlineStylesheets;
const { assetsInlineLimit = 4096 } = settings.config.vite?.build ?? {}; const { assetsInlineLimit = 4096 } = settings.config.vite?.build ?? {};
Object.entries(bundle).forEach(([_, stylesheet]) => { Object.entries(bundle).forEach(([id, stylesheet]) => {
if ( if (
stylesheet.type !== 'asset' || stylesheet.type !== 'asset' ||
stylesheet.name?.endsWith('.css') !== true || stylesheet.name?.endsWith('.css') !== true ||
@ -224,10 +224,15 @@ function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] {
: { type: 'external', src: stylesheet.fileName }; : { type: 'external', src: stylesheet.fileName };
const pages = Array.from(eachPageData(internals)); const pages = Array.from(eachPageData(internals));
let sheetAddedToPage = false;
pages.forEach((pageData) => { pages.forEach((pageData) => {
const orderingInfo = pagesToCss[pageData.moduleSpecifier]?.[stylesheet.fileName]; const orderingInfo = pagesToCss[pageData.moduleSpecifier]?.[stylesheet.fileName];
if (orderingInfo !== undefined) return pageData.styles.push({ ...orderingInfo, sheet }); if (orderingInfo !== undefined) {
pageData.styles.push({ ...orderingInfo, sheet });
sheetAddedToPage = true;
return;
}
const propagatedPaths = pagesToPropagatedCss[pageData.moduleSpecifier]; const propagatedPaths = pagesToPropagatedCss[pageData.moduleSpecifier];
if (propagatedPaths === undefined) return; if (propagatedPaths === undefined) return;
@ -243,8 +248,21 @@ function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] {
pageData.propagatedStyles.set(pageInfoId, new Set()).get(pageInfoId)!; pageData.propagatedStyles.set(pageInfoId, new Set()).get(pageInfoId)!;
propagatedStyles.add(sheet); propagatedStyles.add(sheet);
sheetAddedToPage = true;
}); });
}); });
if (toBeInlined && sheetAddedToPage) {
// CSS is already added to all used pages, we can delete it from the bundle
// and make sure no chunks reference it via `importedCss` (for Vite preloading)
// to avoid duplicate CSS.
delete bundle[id];
for (const chunk of Object.values(bundle)) {
if (chunk.type === 'chunk') {
chunk.viteMetadata?.importedCss?.delete(id);
}
}
}
}); });
}, },
}; };

View file

@ -50,7 +50,7 @@ export async function createContainer({
isRestart, isRestart,
}); });
settings = injectImageEndpoint(settings); settings = injectImageEndpoint(settings, 'dev');
const { const {
base, base,

View file

@ -39,7 +39,6 @@ export function createAPIContext({
props, props,
adapterName, adapterName,
}: CreateAPIContext): APIContext { }: CreateAPIContext): APIContext {
initResponseWithEncoding();
const context = { const context = {
cookies: new AstroCookies(request), cookies: new AstroCookies(request),
request, request,
@ -92,15 +91,8 @@ export function createAPIContext({
type ResponseParameters = ConstructorParameters<typeof Response>; type ResponseParameters = ConstructorParameters<typeof Response>;
export let ResponseWithEncoding: ReturnType<typeof initResponseWithEncoding>; export class ResponseWithEncoding extends Response {
// TODO Remove this after StackBlitz supports Node 18. constructor(body: ResponseParameters[0], init: ResponseParameters[1], encoding?: BufferEncoding) {
let initResponseWithEncoding = () => {
class LocalResponseWithEncoding extends Response {
constructor(
body: ResponseParameters[0],
init: ResponseParameters[1],
encoding?: BufferEncoding
) {
// If a body string is given, try to encode it to preserve the behaviour as simple objects. // If a body string is given, try to encode it to preserve the behaviour as simple objects.
// We don't do the full handling as simple objects so users can control how headers are set instead. // We don't do the full handling as simple objects so users can control how headers are set instead.
if (typeof body === 'string') { if (typeof body === 'string') {
@ -122,15 +114,6 @@ let initResponseWithEncoding = () => {
} }
} }
// Set the module scoped variable.
ResponseWithEncoding = LocalResponseWithEncoding;
// Turn this into a noop.
initResponseWithEncoding = (() => {}) as any;
return LocalResponseWithEncoding;
};
export async function callEndpoint<MiddlewareResult = Response | EndpointOutput>( export async function callEndpoint<MiddlewareResult = Response | EndpointOutput>(
mod: EndpointHandler, mod: EndpointHandler,
env: Environment, env: Environment,

View file

@ -1158,7 +1158,7 @@ export const ContentSchemaContainsSlugError = {
/** /**
* @docs * @docs
* @message A collection queried via `getCollection()` does not exist. * @message A collection queried via `getCollection()` does not exist.
* @deprecated Collections that do not exist no longer result in an error. A warning is omitted instead. * @deprecated Collections that do not exist no longer result in an error. A warning is given instead.
* @description * @description
* When querying a collection, ensure a collection directory with the requested name exists under `src/content/`. * When querying a collection, ensure a collection directory with the requested name exists under `src/content/`.
*/ */

View file

@ -1,19 +1,52 @@
import { EventEmitter } from 'node:events'; import { EventEmitter } from 'node:events';
import path from 'node:path';
import type * as vite from 'vite'; import type * as vite from 'vite';
import type { ModuleLoader, ModuleLoaderEventEmitter } from './loader.js'; import type { ModuleLoader, ModuleLoaderEventEmitter } from './loader.js';
export function createViteLoader(viteServer: vite.ViteDevServer): ModuleLoader { export function createViteLoader(viteServer: vite.ViteDevServer): ModuleLoader {
const events = new EventEmitter() as ModuleLoaderEventEmitter; const events = new EventEmitter() as ModuleLoaderEventEmitter;
viteServer.watcher.on('add', (...args) => events.emit('file-add', args)); let isTsconfigUpdated = false;
viteServer.watcher.on('unlink', (...args) => events.emit('file-unlink', args)); function isTsconfigUpdate(filePath: string) {
viteServer.watcher.on('change', (...args) => events.emit('file-change', args)); const result = path.basename(filePath) === 'tsconfig.json';
if (result) isTsconfigUpdated = true;
return result;
}
wrapMethod(viteServer.ws, 'send', (msg) => { // Skip event emit on tsconfig change as Vite restarts the server, and we don't
// want to trigger unnecessary work that will be invalidated shortly.
viteServer.watcher.on('add', (...args) => {
if (!isTsconfigUpdate(args[0])) {
events.emit('file-add', args);
}
});
viteServer.watcher.on('unlink', (...args) => {
if (!isTsconfigUpdate(args[0])) {
events.emit('file-unlink', args);
}
});
viteServer.watcher.on('change', (...args) => {
if (!isTsconfigUpdate(args[0])) {
events.emit('file-change', args);
}
});
const _wsSend = viteServer.ws.send;
viteServer.ws.send = function (...args: any) {
// If the tsconfig changed, Vite will trigger a reload as it invalidates the module.
// However in Astro, the whole server is restarted when the tsconfig changes. If we
// do a restart and reload at the same time, the browser will refetch and the server
// is not ready yet, causing a blank page. Here we block that reload from happening.
if (isTsconfigUpdated) {
isTsconfigUpdated = false;
return;
}
const msg = args[0] as vite.HMRPayload;
if (msg?.type === 'error') { if (msg?.type === 'error') {
events.emit('hmr-error', msg); events.emit('hmr-error', msg);
} }
}); _wsSend.apply(this, args);
};
return { return {
import(src) { import(src) {
@ -56,11 +89,3 @@ export function createViteLoader(viteServer: vite.ViteDevServer): ModuleLoader {
events, events,
}; };
} }
function wrapMethod(object: any, method: string, newFn: (...args: any[]) => void) {
const orig = object[method];
object[method] = function (...args: any[]) {
newFn.apply(this, args);
return orig.apply(this, args);
};
}

View file

@ -1,63 +1,7 @@
import buffer from 'node:buffer';
import crypto from 'node:crypto'; import crypto from 'node:crypto';
import {
ByteLengthQueuingStrategy,
CountQueuingStrategy,
ReadableByteStreamController,
ReadableStream,
ReadableStreamBYOBReader,
ReadableStreamBYOBRequest,
ReadableStreamDefaultController,
ReadableStreamDefaultReader,
TransformStream,
WritableStream,
WritableStreamDefaultController,
WritableStreamDefaultWriter,
} from 'node:stream/web';
import { File, FormData, Headers, Request, Response, fetch } from 'undici';
// NOTE: This file does not intend to polyfill everything that exists, its main goal is to make life easier
// for users deploying to runtime that do support these features. In the future, we hope for this file to disappear.
// HACK (2023-08-18) Stackblitz does not support Node 18 yet, so we'll fake Node 16 support for some time until it's supported
// TODO: Remove when Node 18 is supported on Stackblitz. File should get imported from `node:buffer` instead of `undici` once this is removed
const isStackblitz = process.env.SHELL === '/bin/jsh' && process.versions.webcontainer != null;
export function apply() { export function apply() {
if (isStackblitz) {
const neededPolyfills = {
ByteLengthQueuingStrategy,
CountQueuingStrategy,
ReadableByteStreamController,
ReadableStream,
ReadableStreamBYOBReader,
ReadableStreamBYOBRequest,
ReadableStreamDefaultController,
ReadableStreamDefaultReader,
TransformStream,
WritableStream,
WritableStreamDefaultController,
WritableStreamDefaultWriter,
File,
FormData,
Headers,
Request,
Response,
fetch,
};
for (let polyfillName of Object.keys(neededPolyfills)) {
if (Object.hasOwnProperty.call(globalThis, polyfillName)) continue;
// Add polyfill to globalThis
Object.defineProperty(globalThis, polyfillName, {
configurable: true,
enumerable: true,
writable: true,
value: neededPolyfills[polyfillName as keyof typeof neededPolyfills],
});
}
}
// Remove when Node 18 is dropped for Node 20 // Remove when Node 18 is dropped for Node 20
if (!globalThis.crypto) { if (!globalThis.crypto) {
Object.defineProperty(globalThis, 'crypto', { Object.defineProperty(globalThis, 'crypto', {
@ -68,7 +12,7 @@ export function apply() {
// Remove when Node 18 is dropped for Node 20 // Remove when Node 18 is dropped for Node 20
if (!globalThis.File) { if (!globalThis.File) {
Object.defineProperty(globalThis, 'File', { Object.defineProperty(globalThis, 'File', {
value: File, value: buffer.File,
}); });
} }
} }

View file

@ -224,7 +224,7 @@ export function createResult(args: CreateResultArgs): SSRResult {
hasDirectives: new Set(), hasDirectives: new Set(),
headInTree: false, headInTree: false,
extraHead: [], extraHead: [],
propagators: new Map(), propagators: new Set(),
}, },
}; };

View file

@ -1,46 +1,7 @@
/// <reference types="vite/client" /> /// <reference types="vite/client" />
if (import.meta.hot) { if (import.meta.hot) {
// Vite injects `<style data-vite-dev-id>` for ESM imports of styles // HMR temporarily not needed for now, but kept here in case we need it again.
// but Astro also SSRs with `<style data-astro-dev-id>` blocks. This MutationObserver // To re-instate this module again, update `vite-plugin-astro-server/route.ts`
// removes any duplicates as soon as they are hydrated client-side. // to add this module as a script similar to `/@vite/client`
const injectedStyles = getInjectedStyles();
const mo = new MutationObserver((records) => {
for (const record of records) {
for (const node of record.addedNodes) {
if (isViteInjectedStyle(node)) {
injectedStyles.get(node.getAttribute('data-vite-dev-id')!)?.remove();
}
}
}
});
mo.observe(document.documentElement, { subtree: true, childList: true });
// Vue `link` styles need to be manually refreshed in Firefox
import.meta.hot.on('vite:beforeUpdate', async (payload) => {
for (const file of payload.updates) {
if (file.acceptedPath.includes('vue&type=style')) {
const link = document.querySelector(`link[href="${file.acceptedPath}"]`);
if (link) {
link.replaceWith(link.cloneNode(true));
}
}
}
});
}
function getInjectedStyles() {
const injectedStyles = new Map<string, Element>();
document.querySelectorAll<HTMLStyleElement>('style[data-astro-dev-id]').forEach((el) => {
injectedStyles.set(el.getAttribute('data-astro-dev-id')!, el);
});
return injectedStyles;
}
function isStyle(node: Node): node is HTMLStyleElement {
return node.nodeType === node.ELEMENT_NODE && (node as Element).tagName.toLowerCase() === 'style';
}
function isViteInjectedStyle(node: Node): node is HTMLStyleElement {
return isStyle(node) && !!node.getAttribute('data-vite-dev-id');
} }

View file

@ -56,17 +56,34 @@ declare const Astro: {
document.addEventListener('astro:after-swap', this.unmount, { once: true }); document.addEventListener('astro:after-swap', this.unmount, { once: true });
} }
connectedCallback() { connectedCallback() {
if (!this.hasAttribute('await-children') || this.firstChild) { if (
!this.hasAttribute('await-children') ||
document.readyState === 'interactive' ||
document.readyState === 'complete'
) {
this.childrenConnectedCallback(); this.childrenConnectedCallback();
} else { } else {
// connectedCallback may run *before* children are rendered (ex. HTML streaming) // connectedCallback may run *before* children are rendered (ex. HTML streaming)
// If SSR children are expected, but not yet rendered, // If SSR children are expected, but not yet rendered, wait with a mutation observer
// Wait with a mutation observer // for a special marker inserted when rendering islands that signals the end of the island
new MutationObserver((_, mo) => { const onConnected = () => {
document.removeEventListener('DOMContentLoaded', onConnected);
mo.disconnect(); mo.disconnect();
// Wait until the next macrotask to ensure children are really rendered this.childrenConnectedCallback();
setTimeout(() => this.childrenConnectedCallback(), 0); };
}).observe(this, { childList: true }); const mo = new MutationObserver(() => {
if (
this.lastChild?.nodeType === Node.COMMENT_NODE &&
this.lastChild.nodeValue === 'astro:end'
) {
this.lastChild.remove();
onConnected();
}
});
mo.observe(this, { childList: true });
// in case the marker comment got stripped and the mutation observer waited indefinitely,
// also wait for DOMContentLoaded as a last resort
document.addEventListener('DOMContentLoaded', onConnected);
} }
} }
async childrenConnectedCallback() { async childrenConnectedCallback() {

View file

@ -122,9 +122,10 @@ export async function generateHydrateScript(
const { hydrate, componentUrl, componentExport } = metadata; const { hydrate, componentUrl, componentExport } = metadata;
if (!componentExport.value) { if (!componentExport.value) {
throw new Error( throw new AstroError({
`Unable to resolve a valid export for "${metadata.displayName}"! Please open an issue at https://astro.build/issues!` ...AstroErrorData.NoMatchingImport,
); message: AstroErrorData.NoMatchingImport.message(metadata.displayName),
});
} }
const island: SSRElement = { const island: SSRElement = {

View file

@ -82,8 +82,8 @@ export function createAstroComponentInstance(
) { ) {
validateComponentProps(props, displayName); validateComponentProps(props, displayName);
const instance = new AstroComponentInstance(result, props, slots, factory); const instance = new AstroComponentInstance(result, props, slots, factory);
if (isAPropagatingComponent(result, factory) && !result._metadata.propagators.has(factory)) { if (isAPropagatingComponent(result, factory)) {
result._metadata.propagators.set(factory, instance); result._metadata.propagators.add(instance);
} }
return instance; return instance;
} }

View file

@ -360,6 +360,8 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr
if (island.children) { if (island.children) {
island.props['await-children'] = ''; island.props['await-children'] = '';
// Marker to signal that Astro island children is completed while streaming
island.children += `<!--astro:end-->`;
} }
return { return {

View file

@ -208,7 +208,7 @@ async function updateDOM(
const devId = el.dataset.viteDevId; const devId = el.dataset.viteDevId;
// If this same style tag exists, remove it from the new page // If this same style tag exists, remove it from the new page
return ( return (
newDocument.querySelector(`style[data-astro-dev-id="${devId}"]`) || newDocument.querySelector(`style[data-vite-dev-id="${devId}"]`) ||
// Otherwise, keep it anyways. This is client:only styles. // Otherwise, keep it anyways. This is client:only styles.
noopEl noopEl
); );
@ -292,7 +292,9 @@ async function updateDOM(
// Do not preload links that are already on the page. // Do not preload links that are already on the page.
if ( if (
!document.querySelector( !document.querySelector(
`[${PERSIST_ATTR}="${el.getAttribute(PERSIST_ATTR)}"], link[rel=stylesheet]` `[${PERSIST_ATTR}="${el.getAttribute(
PERSIST_ATTR
)}"], link[rel=stylesheet][href="${el.getAttribute('href')}"]`
) )
) { ) {
const c = document.createElement('link'); const c = document.createElement('link');

View file

@ -4,14 +4,21 @@ import { viteID } from '../core/util.js';
import { isBuildableCSSRequest } from './util.js'; import { isBuildableCSSRequest } from './util.js';
import { crawlGraph } from './vite.js'; import { crawlGraph } from './vite.js';
interface ImportedStyle {
id: string;
url: string;
content: string;
}
/** Given a filePath URL, crawl Vites module graph to find all style imports. */ /** Given a filePath URL, crawl Vites module graph to find all style imports. */
export async function getStylesForURL( export async function getStylesForURL(
filePath: URL, filePath: URL,
loader: ModuleLoader, loader: ModuleLoader,
mode: RuntimeMode mode: RuntimeMode
): Promise<{ urls: Set<string>; stylesMap: Map<string, string> }> { ): Promise<{ urls: Set<string>; styles: ImportedStyle[] }> {
const importedCssUrls = new Set<string>(); const importedCssUrls = new Set<string>();
const importedStylesMap = new Map<string, string>(); // Map of url to injected style object. Use a `url` key to deduplicate styles
const importedStylesMap = new Map<string, ImportedStyle>();
for await (const importedModule of crawlGraph(loader, viteID(filePath), true)) { for await (const importedModule of crawlGraph(loader, viteID(filePath), true)) {
if (isBuildableCSSRequest(importedModule.url)) { if (isBuildableCSSRequest(importedModule.url)) {
@ -28,7 +35,11 @@ export async function getStylesForURL(
mode === 'development' && // only inline in development mode === 'development' && // only inline in development
typeof ssrModule?.default === 'string' // ignore JS module styles typeof ssrModule?.default === 'string' // ignore JS module styles
) { ) {
importedStylesMap.set(importedModule.url, ssrModule.default); importedStylesMap.set(importedModule.url, {
id: importedModule.id ?? importedModule.url,
url: importedModule.url,
content: ssrModule.default,
});
} else { } else {
// NOTE: We use the `url` property here. `id` would break Windows. // NOTE: We use the `url` property here. `id` would break Windows.
importedCssUrls.add(importedModule.url); importedCssUrls.add(importedModule.url);
@ -38,6 +49,6 @@ export async function getStylesForURL(
return { return {
urls: importedCssUrls, urls: importedCssUrls,
stylesMap: importedStylesMap, styles: [...importedStylesMap.values()],
}; };
} }

View file

@ -12,7 +12,7 @@ import { loadMiddleware } from '../core/middleware/loadMiddleware.js';
import { createRenderContext, getParamsAndProps, type SSROptions } from '../core/render/index.js'; import { createRenderContext, getParamsAndProps, type SSROptions } from '../core/render/index.js';
import { createRequest } from '../core/request.js'; import { createRequest } from '../core/request.js';
import { matchAllRoutes } from '../core/routing/index.js'; import { matchAllRoutes } from '../core/routing/index.js';
import { isPage, resolveIdToUrl, viteID } from '../core/util.js'; import { isPage } from '../core/util.js';
import { getSortedPreloadedMatches } from '../prerender/routing.js'; import { getSortedPreloadedMatches } from '../prerender/routing.js';
import { isServerLikeOutput } from '../prerender/utils.js'; import { isServerLikeOutput } from '../prerender/utils.js';
import { PAGE_SCRIPT_ID } from '../vite-plugin-scripts/index.js'; import { PAGE_SCRIPT_ID } from '../vite-plugin-scripts/index.js';
@ -275,13 +275,6 @@ async function getScriptsAndStyles({ pipeline, filePath }: GetScriptsAndStylesPa
props: { type: 'module', src: '/@vite/client' }, props: { type: 'module', src: '/@vite/client' },
children: '', children: '',
}); });
scripts.add({
props: {
type: 'module',
src: await resolveIdToUrl(moduleLoader, 'astro/runtime/client/hmr.js'),
},
children: '',
});
scripts.add({ scripts.add({
props: { props: {
type: 'module', type: 'module',
@ -307,7 +300,11 @@ async function getScriptsAndStyles({ pipeline, filePath }: GetScriptsAndStylesPa
} }
// Pass framework CSS in as style tags to be appended to the page. // Pass framework CSS in as style tags to be appended to the page.
const { urls: styleUrls, stylesMap } = await getStylesForURL(filePath, moduleLoader, mode); const { urls: styleUrls, styles: importedStyles } = await getStylesForURL(
filePath,
moduleLoader,
mode
);
let links = new Set<SSRElement>(); let links = new Set<SSRElement>();
[...styleUrls].forEach((href) => { [...styleUrls].forEach((href) => {
links.add({ links.add({
@ -320,7 +317,7 @@ async function getScriptsAndStyles({ pipeline, filePath }: GetScriptsAndStylesPa
}); });
let styles = new Set<SSRElement>(); let styles = new Set<SSRElement>();
[...stylesMap].forEach(([url, content]) => { importedStyles.forEach(({ id, url, content }) => {
// Vite handles HMR for styles injected as scripts // Vite handles HMR for styles injected as scripts
scripts.add({ scripts.add({
props: { props: {
@ -329,11 +326,11 @@ async function getScriptsAndStyles({ pipeline, filePath }: GetScriptsAndStylesPa
}, },
children: '', children: '',
}); });
// But we still want to inject the styles to avoid FOUC // But we still want to inject the styles to avoid FOUC. The style tags
// should emulate what Vite injects so further HMR works as expected.
styles.add({ styles.add({
props: { props: {
// Track the ID so we can match it to Vite's injected style later 'data-vite-dev-id': id,
'data-astro-dev-id': viteID(new URL(`.${url}`, settings.config.root)),
}, },
children: content, children: content,
}); });

View file

@ -0,0 +1,34 @@
export type MarkdownImagePath = { raw: string; resolved: string; safeName: string };
export function getMarkdownCodeForImages(imagePaths: MarkdownImagePath[], html: string) {
return `
import { getImage } from "astro:assets";
${imagePaths
.map((entry) => `import Astro__${entry.safeName} from ${JSON.stringify(entry.raw)};`)
.join('\n')}
const images = async function() {
return {
${imagePaths
.map((entry) => `"${entry.raw}": await getImage({src: Astro__${entry.safeName}})`)
.join(',\n')}
}
}
async function updateImageReferences(html) {
return images().then((images) => {
return html.replaceAll(/__ASTRO_IMAGE_="([^"]+)"/gm, (full, imagePath) =>
spreadAttributes({
src: images[imagePath].src,
...images[imagePath].attributes,
})
);
});
}
// NOTE: This causes a top-level await to appear in the user's code, which can break very easily due to a Rollup
// bug and certain adapters not supporting it correctly. See: https://github.com/rollup/rollup/issues/4708
// Tread carefully!
const html = await updateImageReferences(${JSON.stringify(html)});
`;
}

View file

@ -16,6 +16,7 @@ import { isMarkdownFile } from '../core/util.js';
import { shorthash } from '../runtime/server/shorthash.js'; import { shorthash } from '../runtime/server/shorthash.js';
import type { PluginMetadata } from '../vite-plugin-astro/types.js'; import type { PluginMetadata } from '../vite-plugin-astro/types.js';
import { escapeViteEnvReferences, getFileInfo } from '../vite-plugin-utils/index.js'; import { escapeViteEnvReferences, getFileInfo } from '../vite-plugin-utils/index.js';
import { getMarkdownCodeForImages, type MarkdownImagePath } from './images.js';
interface AstroPluginOptions { interface AstroPluginOptions {
settings: AstroSettings; settings: AstroSettings;
@ -95,7 +96,7 @@ export default function markdown({ settings, logger }: AstroPluginOptions): Plug
const { headings, imagePaths: rawImagePaths, frontmatter } = renderResult.metadata; const { headings, imagePaths: rawImagePaths, frontmatter } = renderResult.metadata;
// Resolve all the extracted images from the content // Resolve all the extracted images from the content
const imagePaths: { raw: string; resolved: string; safeName: string }[] = []; const imagePaths: MarkdownImagePath[] = [];
for (const imagePath of rawImagePaths.values()) { for (const imagePath of rawImagePaths.values()) {
imagePaths.push({ imagePaths.push({
raw: imagePath, raw: imagePath,
@ -119,33 +120,14 @@ export default function markdown({ settings, logger }: AstroPluginOptions): Plug
astroServerRuntimeModulePath astroServerRuntimeModulePath
)}; )};
import { AstroError, AstroErrorData } from ${JSON.stringify(astroErrorModulePath)}; import { AstroError, AstroErrorData } from ${JSON.stringify(astroErrorModulePath)};
${layout ? `import Layout from ${JSON.stringify(layout)};` : ''} ${layout ? `import Layout from ${JSON.stringify(layout)};` : ''}
import { getImage } from "astro:assets";
${imagePaths
.map((entry) => `import Astro__${entry.safeName} from ${JSON.stringify(entry.raw)};`)
.join('\n')}
const images = async function() { ${
return { // Only include the code relevant to `astro:assets` if there's images in the file
${imagePaths imagePaths.length > 0
.map((entry) => `"${entry.raw}": await getImage({src: Astro__${entry.safeName}})`) ? getMarkdownCodeForImages(imagePaths, html)
.join(',\n')} : `const html = ${JSON.stringify(html)};`
} }
}
async function updateImageReferences(html) {
return images().then((images) => {
return html.replaceAll(/__ASTRO_IMAGE_="([^"]+)"/gm, (full, imagePath) =>
spreadAttributes({
src: images[imagePath].src,
...images[imagePath].attributes,
})
);
});
}
const html = await updateImageReferences(${JSON.stringify(html)});
export const frontmatter = ${JSON.stringify(frontmatter)}; export const frontmatter = ${JSON.stringify(frontmatter)};
export const file = ${JSON.stringify(fileId)}; export const file = ${JSON.stringify(fileId)};

View file

@ -180,8 +180,6 @@ describe('astro:image', () => {
let html = await res.text(); let html = await res.text();
$ = cheerio.load(html); $ = cheerio.load(html);
console.log(html);
let $img = $('img'); let $img = $('img');
expect($img).to.have.a.lengthOf(1); expect($img).to.have.a.lengthOf(1);
@ -854,17 +852,14 @@ describe('astro:image', () => {
output: 'server', output: 'server',
adapter: testAdapter(), adapter: testAdapter(),
image: { image: {
endpoint: 'astro/assets/endpoint/node',
service: testImageService(), service: testImageService(),
}, },
}); });
await fixture.build(); await fixture.build();
}); });
// TODO it('dynamic route images are built at response time sss', async () => {
// This is not working because the image service does a fetch() on the underlying
// image and we do not have an HTTP server in these tests. We either need
// to start one, or find another way to tell the image service how to load these files.
it.skip('dynamic route images are built at response time', async () => {
const app = await fixture.loadTestAdapterApp(); const app = await fixture.loadTestAdapterApp();
let request = new Request('http://example.com/'); let request = new Request('http://example.com/');
let response = await app.render(request); let response = await app.render(request);

View file

@ -0,0 +1,4 @@
---
await new Promise(resolve => setTimeout(resolve, 10));
---
<pre transition:name="animate">{Astro.props.num}</pre>

View file

@ -0,0 +1,13 @@
---
import Wait from '../components/Wait.astro';
---
<html>
<head>
<title>Testing</title>
</head>
<body>
{[1,2].map(num => (
<Wait num={num} />
))}
</body>
</html>

View file

@ -170,7 +170,7 @@ export async function loadFixture(inlineConfig) {
try { try {
return await fetch(resolvedUrl, init); return await fetch(resolvedUrl, init);
} catch (err) { } catch (err) {
// undici throws a vague error when it fails, so we log the url here to easily debug it // node fetch throws a vague error when it fails, so we log the url here to easily debug it
if (err.message?.includes('fetch failed')) { if (err.message?.includes('fetch failed')) {
console.error(`[astro test] failed to fetch ${resolvedUrl}`); console.error(`[astro test] failed to fetch ${resolvedUrl}`);
console.error(err); console.error(err);

View file

@ -0,0 +1,25 @@
import { expect } from 'chai';
import * as cheerio from 'cheerio';
import { loadFixture } from './test-utils.js';
describe('View Transitions styles', () => {
let fixture;
let devServer;
before(async () => {
fixture = await loadFixture({ root: './fixtures/view-transitions/' });
devServer = await fixture.startDevServer();
});
after(async () => {
await devServer.stop();
});
it('style tag added for each instance of the component', async () => {
let res = await fixture.fetch('/multiple');
let html = await res.text();
let $ = cheerio.load(html);
expect($('head style')).to.have.a.lengthOf(3);
});
});

View file

@ -44,5 +44,8 @@
}, },
"engines": { "engines": {
"node": ">=18.14.1" "node": ">=18.14.1"
},
"publishConfig": {
"provenance": true
} }
} }

View file

@ -1,5 +1,11 @@
# @astrojs/alpinejs # @astrojs/alpinejs
## 0.3.1
### Patch Changes
- [#8737](https://github.com/withastro/astro/pull/8737) [`6f60da805`](https://github.com/withastro/astro/commit/6f60da805e0014bc50dd07bef972e91c73560c3c) Thanks [@ematipico](https://github.com/ematipico)! - Add provenance statement when publishing the library from CI
## 0.3.0 ## 0.3.0
### Minor Changes ### Minor Changes

View file

@ -1,7 +1,7 @@
{ {
"name": "@astrojs/alpinejs", "name": "@astrojs/alpinejs",
"description": "Use Alpine within Astro", "description": "Use Alpine within Astro",
"version": "0.3.0", "version": "0.3.1",
"type": "module", "type": "module",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
"author": "withastro", "author": "withastro",
@ -39,5 +39,8 @@
"devDependencies": { "devDependencies": {
"astro": "workspace:*", "astro": "workspace:*",
"astro-scripts": "workspace:*" "astro-scripts": "workspace:*"
},
"publishConfig": {
"provenance": true
} }
} }

View file

@ -1,2 +1,3 @@
# Astro cloudflare directory mode creates a function directory # Astro cloudflare directory mode creates a function directory
functions functions
.mf

View file

@ -1,5 +1,47 @@
# @astrojs/cloudflare # @astrojs/cloudflare
## 7.5.1
### Patch Changes
- [#8737](https://github.com/withastro/astro/pull/8737) [`6f60da805`](https://github.com/withastro/astro/commit/6f60da805e0014bc50dd07bef972e91c73560c3c) Thanks [@ematipico](https://github.com/ematipico)! - Add provenance statement when publishing the library from CI
- Updated dependencies [[`6f60da805`](https://github.com/withastro/astro/commit/6f60da805e0014bc50dd07bef972e91c73560c3c), [`d78806dfe`](https://github.com/withastro/astro/commit/d78806dfe0301ea7ffe6c7c1f783bd415ac7cda9), [`d1c75fe15`](https://github.com/withastro/astro/commit/d1c75fe158839699c59728cf3a83888e8c72a459), [`aa265d730`](https://github.com/withastro/astro/commit/aa265d73024422967c1b1c68ad268c419c6c798f), [`78adbc443`](https://github.com/withastro/astro/commit/78adbc4433208458291e36713909762e148e1e5d), [`21e0757ea`](https://github.com/withastro/astro/commit/21e0757ea22a57d344c934045ca19db93b684436), [`357270f2a`](https://github.com/withastro/astro/commit/357270f2a3d0bf2aa634ba7e52e9d17618eff4a7)]:
- @astrojs/underscore-redirects@0.3.1
- astro@3.2.3
## 7.5.0
### Minor Changes
- [#8655](https://github.com/withastro/astro/pull/8655) [`3dd65bf88`](https://github.com/withastro/astro/commit/3dd65bf8895faedfa4c92599961acca07457c62f) Thanks [@alexanderniebuhr](https://github.com/alexanderniebuhr)! - Introduces support for local KV bindings. Enhances development experience by allowing direct integration with `astro dev`.
- [#8655](https://github.com/withastro/astro/pull/8655) [`3dd65bf88`](https://github.com/withastro/astro/commit/3dd65bf8895faedfa4c92599961acca07457c62f) Thanks [@alexanderniebuhr](https://github.com/alexanderniebuhr)! - Introduces support for local Durable Objects bindings. Enhances development experience by allowing direct integration with `astro dev`.
- [#8655](https://github.com/withastro/astro/pull/8655) [`3dd65bf88`](https://github.com/withastro/astro/commit/3dd65bf8895faedfa4c92599961acca07457c62f) Thanks [@alexanderniebuhr](https://github.com/alexanderniebuhr)! - Introduces support for local D1 bindings. Enhances development experience by allowing direct integration with `astro dev`.
- [#8655](https://github.com/withastro/astro/pull/8655) [`3dd65bf88`](https://github.com/withastro/astro/commit/3dd65bf8895faedfa4c92599961acca07457c62f) Thanks [@alexanderniebuhr](https://github.com/alexanderniebuhr)! - Introduces support for local R2 bindings. Enhances development experience by allowing direct integration with `astro dev`.
- [#8655](https://github.com/withastro/astro/pull/8655) [`3dd65bf88`](https://github.com/withastro/astro/commit/3dd65bf8895faedfa4c92599961acca07457c62f) Thanks [@alexanderniebuhr](https://github.com/alexanderniebuhr)! - Introduces support for local Caches bindings. Enhances development experience by allowing direct integration with `astro dev`.
### Patch Changes
- Updated dependencies [[`455af3235`](https://github.com/withastro/astro/commit/455af3235b3268852e6988accecc796f03f6d16e), [`4c2bec681`](https://github.com/withastro/astro/commit/4c2bec681b0752e7215b8a32bd2d44bf477adac1)]:
- astro@3.2.2
- @astrojs/underscore-redirects@0.3.0
## 7.4.0
### Minor Changes
- [#8682](https://github.com/withastro/astro/pull/8682) [`c3572fd5e`](https://github.com/withastro/astro/commit/c3572fd5e0e3864cd728f83502a52e9274793ee2) Thanks [@dario-piotrowicz](https://github.com/dario-piotrowicz)! - Change build target from `es2020` to `es2022`, for better support
### Patch Changes
- Updated dependencies [[`31c59ad8b`](https://github.com/withastro/astro/commit/31c59ad8b6a72f95c98a306ecf92d198c03110b4), [`47ea310f0`](https://github.com/withastro/astro/commit/47ea310f01d06ed1562c790bec348718a2fa8277), [`345808170`](https://github.com/withastro/astro/commit/345808170fce783ddd3c9a4035a91fa64dcc5f46)]:
- astro@3.2.1
- @astrojs/underscore-redirects@0.3.0
## 7.3.1 ## 7.3.1
### Patch Changes ### Patch Changes

View file

@ -169,7 +169,7 @@ default: `false`
Whether or not to import `.wasm` files [directly as ES modules](https://github.com/WebAssembly/esm-integration/tree/main/proposals/esm-integration) using the `.wasm?module` import syntax. Whether or not to import `.wasm` files [directly as ES modules](https://github.com/WebAssembly/esm-integration/tree/main/proposals/esm-integration) using the `.wasm?module` import syntax.
Add `wasmModuleImports: true` to `astro.config.mjs` to enable this functionality in both the Cloudflare build and the Astro dev server. [Read more](#use-wasm-modules) Add `wasmModuleImports: true` to `astro.config.mjs` to enable this functionality in both the Cloudflare build and the Astro dev server. Read more about [using Wasm modules](#use-wasm-modules)
```diff lang="js" ```diff lang="js"
// astro.config.mjs // astro.config.mjs
@ -192,7 +192,7 @@ default `"off"`
Determines whether and how the Cloudflare Runtime is added to `astro dev`. Determines whether and how the Cloudflare Runtime is added to `astro dev`.
The Cloudflare Runtime includes [Cloudflare bindings](https://developers.cloudflare.com/pages/platform/functions/bindings), [environment variables](https://developers.cloudflare.com/pages/platform/functions/bindings/#environment-variables), and the [cf object](https://developers.cloudflare.com/workers/runtime-apis/request/#incomingrequestcfproperties). Read more about [accessing the Cloudflare Runtime](#access-to-the-cloudflare-runtime). The Cloudflare Runtime includes [Cloudflare bindings](https://developers.cloudflare.com/pages/platform/functions/bindings), [environment variables](https://developers.cloudflare.com/pages/platform/functions/bindings/#environment-variables), and the [cf object](https://developers.cloudflare.com/workers/runtime-apis/request/#incomingrequestcfproperties). Read more about [accessing the Cloudflare Runtime](#cloudflare-runtime).
- `local`: uses bindings mocking and locally static placeholders - `local`: uses bindings mocking and locally static placeholders
- `off`: no access to the Cloudflare runtime using `astro dev`. You can alternatively use [Preview with Wrangler](#preview-with-wrangler) - `off`: no access to the Cloudflare runtime using `astro dev`. You can alternatively use [Preview with Wrangler](#preview-with-wrangler)
@ -212,7 +212,14 @@ export default defineConfig({
## Cloudflare runtime ## Cloudflare runtime
Gives you access to [environment variables](https://developers.cloudflare.com/pages/platform/functions/bindings/#environment-variables). Gives you access to [environment variables](https://developers.cloudflare.com/pages/platform/functions/bindings/#environment-variables), and [Cloudflare bindings](https://developers.cloudflare.com/pages/platform/functions/bindings).
Currently supported bindings:
- [Cloudflare D1](https://developers.cloudflare.com/d1/)
- [Cloudflare R2](https://developers.cloudflare.com/r2/)
- [Cloudflare Workers KV](https://developers.cloudflare.com/kv/)
- [Cloudflare Durable Objects](https://developers.cloudflare.com/durable-objects/)
You can access the runtime from Astro components through `Astro.locals` inside any .astro` file. You can access the runtime from Astro components through `Astro.locals` inside any .astro` file.

View file

@ -1,7 +1,7 @@
{ {
"name": "@astrojs/cloudflare", "name": "@astrojs/cloudflare",
"description": "Deploy your site to Cloudflare Workers/Pages", "description": "Deploy your site to Cloudflare Workers/Pages",
"version": "7.3.1", "version": "7.5.1",
"type": "module", "type": "module",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
"author": "withastro", "author": "withastro",
@ -36,6 +36,7 @@
"dependencies": { "dependencies": {
"@astrojs/underscore-redirects": "workspace:*", "@astrojs/underscore-redirects": "workspace:*",
"@cloudflare/workers-types": "^4.20230821.0", "@cloudflare/workers-types": "^4.20230821.0",
"miniflare": "^3.20230918.0",
"@iarna/toml": "^2.2.5", "@iarna/toml": "^2.2.5",
"@miniflare/cache": "^2.14.1", "@miniflare/cache": "^2.14.1",
"@miniflare/shared": "^2.14.1", "@miniflare/shared": "^2.14.1",
@ -47,7 +48,7 @@
"vite": "^4.4.9" "vite": "^4.4.9"
}, },
"peerDependencies": { "peerDependencies": {
"astro": "workspace:^3.2.0" "astro": "workspace:^3.2.3"
}, },
"devDependencies": { "devDependencies": {
"@types/iarna__toml": "^2.0.2", "@types/iarna__toml": "^2.0.2",
@ -57,5 +58,8 @@
"cheerio": "1.0.0-rc.12", "cheerio": "1.0.0-rc.12",
"mocha": "^10.2.0", "mocha": "^10.2.0",
"wrangler": "^3.5.1" "wrangler": "^3.5.1"
},
"publishConfig": {
"provenance": true
} }
} }

View file

@ -1,11 +1,9 @@
import type { AstroConfig, AstroIntegration, RouteData } from 'astro'; import type { AstroConfig, AstroIntegration, RouteData } from 'astro';
import { createRedirectsFromAstroRoutes } from '@astrojs/underscore-redirects'; import { createRedirectsFromAstroRoutes } from '@astrojs/underscore-redirects';
import { CacheStorage } from '@miniflare/cache';
import { NoOpLog } from '@miniflare/shared';
import { MemoryStorage } from '@miniflare/storage-memory';
import { AstroError } from 'astro/errors'; import { AstroError } from 'astro/errors';
import esbuild from 'esbuild'; import esbuild from 'esbuild';
import { Miniflare } from 'miniflare';
import * as fs from 'node:fs'; import * as fs from 'node:fs';
import * as os from 'node:os'; import * as os from 'node:os';
import { dirname, relative, sep } from 'node:path'; import { dirname, relative, sep } from 'node:path';
@ -14,7 +12,13 @@ import glob from 'tiny-glob';
import { getAdapter } from './getAdapter.js'; import { getAdapter } from './getAdapter.js';
import { deduplicatePatterns } from './utils/deduplicatePatterns.js'; import { deduplicatePatterns } from './utils/deduplicatePatterns.js';
import { getCFObject } from './utils/getCFObject.js'; import { getCFObject } from './utils/getCFObject.js';
import { getEnvVars } from './utils/parser.js'; import {
getD1Bindings,
getDOBindings,
getEnvVars,
getKVBindings,
getR2Bindings,
} from './utils/parser.js';
import { prependForwardSlash } from './utils/prependForwardSlash.js'; import { prependForwardSlash } from './utils/prependForwardSlash.js';
import { rewriteWasmImportPath } from './utils/rewriteWasmImportPath.js'; import { rewriteWasmImportPath } from './utils/rewriteWasmImportPath.js';
import { wasmModuleLoader } from './utils/wasm-module-loader.js'; import { wasmModuleLoader } from './utils/wasm-module-loader.js';
@ -55,20 +59,10 @@ interface BuildConfig {
split?: boolean; split?: boolean;
} }
class StorageFactory {
storages = new Map();
storage(namespace: string) {
let storage = this.storages.get(namespace);
if (storage) return storage;
this.storages.set(namespace, (storage = new MemoryStorage()));
return storage;
}
}
export default function createIntegration(args?: Options): AstroIntegration { export default function createIntegration(args?: Options): AstroIntegration {
let _config: AstroConfig; let _config: AstroConfig;
let _buildConfig: BuildConfig; let _buildConfig: BuildConfig;
let _mf: Miniflare;
let _entryPoints = new Map<RouteData, URL>(); let _entryPoints = new Map<RouteData, URL>();
const SERVER_BUILD_FOLDER = '/$server_build/'; const SERVER_BUILD_FOLDER = '/$server_build/';
@ -122,7 +116,55 @@ export default function createIntegration(args?: Options): AstroIntegration {
try { try {
const cf = await getCFObject(runtimeMode); const cf = await getCFObject(runtimeMode);
const vars = await getEnvVars(); const vars = await getEnvVars();
const D1Bindings = await getD1Bindings();
const R2Bindings = await getR2Bindings();
const KVBindings = await getKVBindings();
const DOBindings = await getDOBindings();
let bindingsEnv = new Object({});
// fix for the error "kj/filesystem-disk-unix.c++:1709: warning: PWD environment variable doesn't match current directory."
// note: This mismatch might be primarily due to the test runner.
const originalPWD = process.env.PWD;
process.env.PWD = process.cwd();
_mf = new Miniflare({
modules: true,
script: '',
cache: true,
cachePersist: true,
cacheWarnUsage: true,
d1Databases: D1Bindings,
d1Persist: true,
r2Buckets: R2Bindings,
r2Persist: true,
kvNamespaces: KVBindings,
kvPersist: true,
durableObjects: DOBindings,
durableObjectsPersist: true,
});
await _mf.ready;
for (const D1Binding of D1Bindings) {
const db = await _mf.getD1Database(D1Binding);
Reflect.set(bindingsEnv, D1Binding, db);
}
for (const R2Binding of R2Bindings) {
const bucket = await _mf.getR2Bucket(R2Binding);
Reflect.set(bindingsEnv, R2Binding, bucket);
}
for (const KVBinding of KVBindings) {
const namespace = await _mf.getKVNamespace(KVBinding);
Reflect.set(bindingsEnv, KVBinding, namespace);
}
for (const key in DOBindings) {
if (Object.prototype.hasOwnProperty.call(DOBindings, key)) {
const DO = await _mf.getDurableObjectNamespace(key);
Reflect.set(bindingsEnv, key, DO);
}
}
const mfCache = await _mf.getCaches();
process.env.PWD = originalPWD;
const clientLocalsSymbol = Symbol.for('astro.locals'); const clientLocalsSymbol = Symbol.for('astro.locals');
Reflect.set(req, clientLocalsSymbol, { Reflect.set(req, clientLocalsSymbol, {
runtime: { runtime: {
@ -136,18 +178,14 @@ export default function createIntegration(args?: Options): AstroIntegration {
// will be fetched from git dynamically once we support mocking of bindings // will be fetched from git dynamically once we support mocking of bindings
CF_PAGES_COMMIT_SHA: 'TBA', CF_PAGES_COMMIT_SHA: 'TBA',
CF_PAGES_URL: `http://${req.headers.host}`, CF_PAGES_URL: `http://${req.headers.host}`,
...bindingsEnv,
...vars, ...vars,
}, },
cf: cf, cf: cf,
waitUntil: (_promise: Promise<any>) => { waitUntil: (_promise: Promise<any>) => {
return; return;
}, },
caches: new CacheStorage( caches: mfCache,
{ cache: true, cachePersist: false },
new NoOpLog(),
new StorageFactory(),
{}
),
}, },
}); });
next(); next();
@ -157,6 +195,12 @@ export default function createIntegration(args?: Options): AstroIntegration {
}); });
} }
}, },
'astro:server:done': async ({ logger }) => {
if (_mf) {
logger.info('Cleaning up the Miniflare instance, and shutting down the workerd server.');
await _mf.dispose();
}
},
'astro:build:setup': ({ vite, target }) => { 'astro:build:setup': ({ vite, target }) => {
if (target === 'server') { if (target === 'server') {
vite.resolve ||= {}; vite.resolve ||= {};

View file

@ -7,11 +7,13 @@
* TODO: Tackle this file, once their is an decision on the upstream request * TODO: Tackle this file, once their is an decision on the upstream request
*/ */
import type {} from '@cloudflare/workers-types/experimental';
import TOML from '@iarna/toml'; import TOML from '@iarna/toml';
import dotenv from 'dotenv'; import dotenv from 'dotenv';
import { findUpSync } from 'find-up'; import { findUpSync } from 'find-up';
import * as fs from 'node:fs'; import * as fs from 'node:fs';
import { dirname, resolve } from 'node:path'; import { dirname, resolve } from 'node:path';
let _wrangler: any;
function findWranglerToml( function findWranglerToml(
referencePath: string = process.cwd(), referencePath: string = process.cwd(),
@ -119,7 +121,9 @@ function getVarsForDev(config: any, configPath: string | undefined): any {
return config.vars; return config.vars;
} }
} }
export async function getEnvVars() {
function parseConfig() {
if (_wrangler) return _wrangler;
let rawConfig; let rawConfig;
const configPath = findWranglerToml(process.cwd(), false); // false = args.experimentalJsonConfig const configPath = findWranglerToml(process.cwd(), false); // false = args.experimentalJsonConfig
if (!configPath) { if (!configPath) {
@ -129,6 +133,59 @@ export async function getEnvVars() {
if (configPath?.endsWith('toml')) { if (configPath?.endsWith('toml')) {
rawConfig = parseTOML(fs.readFileSync(configPath).toString(), configPath); rawConfig = parseTOML(fs.readFileSync(configPath).toString(), configPath);
} }
_wrangler = { rawConfig, configPath };
return { rawConfig, configPath };
}
export async function getEnvVars() {
const { rawConfig, configPath } = parseConfig();
const vars = getVarsForDev(rawConfig, configPath); const vars = getVarsForDev(rawConfig, configPath);
return vars; return vars;
} }
export async function getD1Bindings() {
const { rawConfig } = parseConfig();
if (!rawConfig) return [];
if (!rawConfig?.d1_databases) return [];
const bindings = (rawConfig?.d1_databases as []).map(
(binding: { binding: string }) => binding.binding
);
return bindings;
}
export async function getR2Bindings() {
const { rawConfig } = parseConfig();
if (!rawConfig) return [];
if (!rawConfig?.r2_buckets) return [];
const bindings = (rawConfig?.r2_buckets as []).map(
(binding: { binding: string }) => binding.binding
);
return bindings;
}
export async function getKVBindings() {
const { rawConfig } = parseConfig();
if (!rawConfig) return [];
if (!rawConfig?.kv_namespaces) return [];
const bindings = (rawConfig?.kv_namespaces as []).map(
(binding: { binding: string }) => binding.binding
);
return bindings;
}
export function getDOBindings(): Record<
string,
{ scriptName?: string | undefined; unsafeUniqueKey?: string | undefined; className: string }
> {
const { rawConfig } = parseConfig();
if (!rawConfig) return {};
if (!rawConfig?.durable_objects) return {};
const output = new Object({}) as Record<
string,
{ scriptName?: string | undefined; unsafeUniqueKey?: string | undefined; className: string }
>;
for (const binding of rawConfig?.durable_objects.bindings) {
Reflect.set(output, binding.name, { className: binding.class_name });
}
return output;
}

View file

@ -54,11 +54,6 @@ describe('Astro Cloudflare Runtime', () => {
adapter: cloudflare({ adapter: cloudflare({
runtime: 'local', runtime: 'local',
}), }),
image: {
service: {
entrypoint: 'astro/assets/services/noop',
},
},
}); });
process.chdir('./test/fixtures/cf'); process.chdir('./test/fixtures/cf');
devServer = await fixture.startDevServer(); devServer = await fixture.startDevServer();
@ -68,12 +63,65 @@ describe('Astro Cloudflare Runtime', () => {
await devServer?.stop(); await devServer?.stop();
}); });
it('Populates CF, Vars & Bindings', async () => { it('adds cf object', async () => {
let res = await fixture.fetch('/'); let res = await fixture.fetch('/');
expect(res.status).to.equal(200); expect(res.status).to.equal(200);
let html = await res.text(); let html = await res.text();
let $ = cheerio.load(html); let $ = cheerio.load(html);
expect($('#hasRuntime').text()).to.equal('true'); expect($('#hasCF').text()).to.equal('true');
expect($('#hasCache').text()).to.equal('true'); });
it('adds cache mocking', async () => {
let res = await fixture.fetch('/caches');
expect(res.status).to.equal(200);
let html = await res.text();
let $ = cheerio.load(html);
expect($('#hasCACHE').text()).to.equal('true');
});
it('adds D1 mocking', async () => {
expect(await fixture.pathExists('../.mf/d1')).to.be.true;
let res = await fixture.fetch('/d1');
expect(res.status).to.equal(200);
let html = await res.text();
let $ = cheerio.load(html);
expect($('#hasDB').text()).to.equal('true');
expect($('#hasPRODDB').text()).to.equal('true');
expect($('#hasACCESS').text()).to.equal('true');
});
it('adds R2 mocking', async () => {
expect(await fixture.pathExists('../.mf/r2')).to.be.true;
let res = await fixture.fetch('/r2');
expect(res.status).to.equal(200);
let html = await res.text();
let $ = cheerio.load(html);
expect($('#hasBUCKET').text()).to.equal('true');
expect($('#hasPRODBUCKET').text()).to.equal('true');
expect($('#hasACCESS').text()).to.equal('true');
});
it('adds KV mocking', async () => {
expect(await fixture.pathExists('../.mf/kv')).to.be.true;
let res = await fixture.fetch('/kv');
expect(res.status).to.equal(200);
let html = await res.text();
let $ = cheerio.load(html);
expect($('#hasKV').text()).to.equal('true');
expect($('#hasPRODKV').text()).to.equal('true');
expect($('#hasACCESS').text()).to.equal('true');
});
it('adds DO mocking', async () => {
expect(await fixture.pathExists('../.mf/do')).to.be.true;
let res = await fixture.fetch('/do');
expect(res.status).to.equal(200);
let html = await res.text();
let $ = cheerio.load(html);
expect($('#hasDO').text()).to.equal('true');
}); });
}); });

View file

@ -0,0 +1,15 @@
---
const runtime = Astro.locals.runtime;
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CACHES</title>
</head>
<body>
<pre id="hasCACHE">{!!runtime.caches}</pre>
</body>
</html>

View file

@ -0,0 +1,21 @@
---
const runtime = Astro.locals.runtime;
const db = runtime.env?.D1;
await db.exec("CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)");
await db.exec("INSERT INTO test (name) VALUES ('true')");
const result = await db.prepare("SELECT * FROM test").all();
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>D1</title>
</head>
<body>
<pre id="hasDB">{!!runtime.env?.D1}</pre>
<pre id="hasPRODDB">{!!runtime.env?.D1_PROD}</pre>
<pre id="hasACCESS">{!!result.results[0].name}</pre>
</body>
</html>

View file

@ -0,0 +1,15 @@
---
const runtime = Astro.locals.runtime;
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>DO</title>
</head>
<body>
<pre id="hasDO">{!!runtime.env.DO}</pre>
</body>
</html>

View file

@ -7,7 +7,6 @@ const runtime = Astro.locals.runtime;
</head> </head>
<body> <body>
<h1>Testing</h1> <h1>Testing</h1>
<div id="hasRuntime">{!!runtime.cf?.colo}</div> <div id="hasCF">{!!runtime.cf?.colo}</div>
<div id="hasCache">{!!runtime.caches}</div>
</body> </body>
</html> </html>

View file

@ -0,0 +1,20 @@
---
const runtime = Astro.locals.runtime;
const kv = runtime.env?.KV;
await kv.put("test", "true");
const result = await kv.get("test")
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>KV</title>
</head>
<body>
<pre id="hasKV">{!!runtime.env?.KV}</pre>
<pre id="hasPRODKV">{!!runtime.env?.KV_PROD}</pre>
<pre id="hasACCESS">{!!result}</pre>
</body>
</html>

View file

@ -0,0 +1,20 @@
---
const runtime = Astro.locals.runtime;
const bucket = runtime.env?.R2;
await bucket.put("test", "true");
const result = await (await bucket.get("test")).text()
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>R2</title>
</head>
<body>
<pre id="hasBUCKET">{!!runtime.env?.R2}</pre>
<pre id="hasPRODBUCKET">{!!runtime.env?.R2_PROD}</pre>
<pre id="hasACCESS">{!!result}</pre>
</body>
</html>

View file

@ -1,4 +1,37 @@
name = "test" name = "test"
kv_namespaces = [
{ binding = "KV", id = "<YOUR_ID>", preview_id = "<YOUR_ID>" },
{ binding = "KV_PROD", id = "<YOUR_ID>", preview_id = "<YOUR_ID>" }
]
[vars] [vars]
COOL = "ME" COOL = "ME"
[[d1_databases]]
binding = "D1" # Should match preview_database_id, i.e. available in your Worker on env.DB
database_name = "<DATABASE_NAME>"
database_id = "<unique-ID-for-your-database>"
preview_database_id = "D1" # Required for Pages local development
[[d1_databases]]
binding = "D1_PROD" # Should match preview_database_id
database_name = "<DATABASE_NAME>"
database_id = "<unique-ID-for-your-database>"
preview_database_id = "D1_PROD" # Required for Pages local development
[[r2_buckets]]
binding = 'R2' # <~ valid JavaScript variable name
bucket_name = '<YOUR_BUCKET_NAME>'
[[r2_buckets]]
binding = 'R2_PROD' # <~ valid JavaScript variable name
bucket_name = '<YOUR_BUCKET_NAME>'
[[durable_objects.bindings]]
name = "DO"
class_name = "DurableObjectExample"
[[durable_objects.bindings]]
name = "DO_PROD"
class_name = "DurableObjectProductionExample"

View file

@ -1,3 +1,3 @@
# @astrojs/deno 🦖 # @astrojs/deno 🦖
This adapter is no longer maintained by Astro. Please see [the new repository for the Deno adapter](https://github.com/withastro/netlify-adapter) which is now maintained by the Deno organization. This adapter is no longer maintained by Astro. Please see [the new repository for the Deno adapter](https://github.com/denoland/deno-astro-adapter) which is now maintained by the Deno organization.

View file

@ -1,5 +1,11 @@
# @astrojs/lit # @astrojs/lit
## 3.0.1
### Patch Changes
- [#8737](https://github.com/withastro/astro/pull/8737) [`6f60da805`](https://github.com/withastro/astro/commit/6f60da805e0014bc50dd07bef972e91c73560c3c) Thanks [@ematipico](https://github.com/ematipico)! - Add provenance statement when publishing the library from CI
## 3.0.0 ## 3.0.0
### Major Changes ### Major Changes

View file

@ -1,6 +1,6 @@
{ {
"name": "@astrojs/lit", "name": "@astrojs/lit",
"version": "3.0.0", "version": "3.0.1",
"description": "Use Lit components within Astro", "description": "Use Lit components within Astro",
"type": "module", "type": "module",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
@ -59,5 +59,8 @@
"peerDependencies": { "peerDependencies": {
"@webcomponents/template-shadowroot": "^0.2.1", "@webcomponents/template-shadowroot": "^0.2.1",
"lit": "^2.7.0" "lit": "^2.7.0"
},
"publishConfig": {
"provenance": true
} }
} }

View file

@ -1,5 +1,24 @@
# @astrojs/markdoc # @astrojs/markdoc
## 0.5.2
### Patch Changes
- [#8737](https://github.com/withastro/astro/pull/8737) [`6f60da805`](https://github.com/withastro/astro/commit/6f60da805e0014bc50dd07bef972e91c73560c3c) Thanks [@ematipico](https://github.com/ematipico)! - Add provenance statement when publishing the library from CI
- Updated dependencies [[`6f60da805`](https://github.com/withastro/astro/commit/6f60da805e0014bc50dd07bef972e91c73560c3c), [`d78806dfe`](https://github.com/withastro/astro/commit/d78806dfe0301ea7ffe6c7c1f783bd415ac7cda9), [`d1c75fe15`](https://github.com/withastro/astro/commit/d1c75fe158839699c59728cf3a83888e8c72a459), [`aa265d730`](https://github.com/withastro/astro/commit/aa265d73024422967c1b1c68ad268c419c6c798f), [`78adbc443`](https://github.com/withastro/astro/commit/78adbc4433208458291e36713909762e148e1e5d), [`21e0757ea`](https://github.com/withastro/astro/commit/21e0757ea22a57d344c934045ca19db93b684436), [`357270f2a`](https://github.com/withastro/astro/commit/357270f2a3d0bf2aa634ba7e52e9d17618eff4a7)]:
- @astrojs/internal-helpers@0.2.1
- astro@3.2.3
## 0.5.1
### Patch Changes
- [#8710](https://github.com/withastro/astro/pull/8710) [`4c2bec681`](https://github.com/withastro/astro/commit/4c2bec681b0752e7215b8a32bd2d44bf477adac1) Thanks [@matthewp](https://github.com/matthewp)! - Fixes View transition styles being missing when component used multiple times
- Updated dependencies [[`455af3235`](https://github.com/withastro/astro/commit/455af3235b3268852e6988accecc796f03f6d16e), [`4c2bec681`](https://github.com/withastro/astro/commit/4c2bec681b0752e7215b8a32bd2d44bf477adac1)]:
- astro@3.2.2
## 0.5.0 ## 0.5.0
### Minor Changes ### Minor Changes

View file

@ -92,14 +92,11 @@ export const ComponentNode = createComponent({
// `result.propagators` has been moved to `result._metadata.propagators` // `result.propagators` has been moved to `result._metadata.propagators`
// TODO: remove this fallback in the next markdoc integration major // TODO: remove this fallback in the next markdoc integration major
const propagators = result._metadata.propagators || result.propagators; const propagators = result._metadata.propagators || result.propagators;
propagators.set( propagators.add({
{},
{
init() { init() {
return headAndContent; return headAndContent;
}, },
} });
);
return headAndContent; return headAndContent;
} }

View file

@ -1,7 +1,7 @@
{ {
"name": "@astrojs/markdoc", "name": "@astrojs/markdoc",
"description": "Add support for Markdoc in your Astro site", "description": "Add support for Markdoc in your Astro site",
"version": "0.5.0", "version": "0.5.2",
"type": "module", "type": "module",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
"author": "withastro", "author": "withastro",
@ -75,7 +75,7 @@
"zod": "3.21.1" "zod": "3.21.1"
}, },
"peerDependencies": { "peerDependencies": {
"astro": "workspace:^3.2.0" "astro": "workspace:^3.2.3"
}, },
"devDependencies": { "devDependencies": {
"@astrojs/markdown-remark": "workspace:*", "@astrojs/markdown-remark": "workspace:*",
@ -94,5 +94,8 @@
}, },
"engines": { "engines": {
"node": ">=18.14.1" "node": ">=18.14.1"
},
"publishConfig": {
"provenance": true
} }
} }

View file

@ -1,5 +1,15 @@
# @astrojs/mdx # @astrojs/mdx
## 1.1.1
### Patch Changes
- [#8737](https://github.com/withastro/astro/pull/8737) [`6f60da805`](https://github.com/withastro/astro/commit/6f60da805e0014bc50dd07bef972e91c73560c3c) Thanks [@ematipico](https://github.com/ematipico)! - Add provenance statement when publishing the library from CI
- Updated dependencies [[`21f482657`](https://github.com/withastro/astro/commit/21f4826576c2c812a1604e18717799da3470decd), [`6f60da805`](https://github.com/withastro/astro/commit/6f60da805e0014bc50dd07bef972e91c73560c3c), [`d78806dfe`](https://github.com/withastro/astro/commit/d78806dfe0301ea7ffe6c7c1f783bd415ac7cda9), [`d1c75fe15`](https://github.com/withastro/astro/commit/d1c75fe158839699c59728cf3a83888e8c72a459), [`aa265d730`](https://github.com/withastro/astro/commit/aa265d73024422967c1b1c68ad268c419c6c798f), [`78adbc443`](https://github.com/withastro/astro/commit/78adbc4433208458291e36713909762e148e1e5d), [`21e0757ea`](https://github.com/withastro/astro/commit/21e0757ea22a57d344c934045ca19db93b684436), [`357270f2a`](https://github.com/withastro/astro/commit/357270f2a3d0bf2aa634ba7e52e9d17618eff4a7)]:
- @astrojs/markdown-remark@3.2.1
- astro@3.2.3
## 1.1.0 ## 1.1.0
### Minor Changes ### Minor Changes

Some files were not shown because too many files have changed in this diff Show more