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
if: ${{ github.repository_owner == 'withastro' }}
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- uses: actions/checkout@v3

View file

@ -81,6 +81,8 @@ jobs:
id: publish
run: |
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`
env:
# Needs access to publish to npm

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,5 +1,46 @@
# 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
### Minor Changes

View file

@ -3,7 +3,6 @@
// ISOMORPHIC FILE: NO TOP-LEVEL IMPORT/REQUIRE() ALLOWED
// 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 = {
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 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 *` */
async function main() {
const version = process.versions.node;
// Fast-path for higher Node.js versions
if (!isStackblitz && (parseInt(version) || 0) <= skipSemverCheckIfAbove) {
if ((parseInt(version) || 0) <= skipSemverCheckIfAbove) {
try {
const semver = await import('semver');
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)');
});
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());
// 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);
// style[data-vite-dev-id] should exist in initial SSR'd markup
expect(html).toMatch('data-vite-dev-id');
});
});

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;
}
</style>
<link rel="stylesheet" href="/style.css">
<ViewTransitions />
<DarkMode />
<meta name="script-executions" content="0">

View file

@ -1,7 +1,7 @@
---
import Layout from '../components/Layout.astro';
---
<Layout>
<Layout link="/one.css">
<p id="one">Page 1</p>
<a id="click-one" href="#test">test</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('Moving from page 1 to page 2', async ({ page, astro }) => {
const loads = [];
@ -170,11 +184,15 @@ test.describe('View Transitions', () => {
let p = page.locator('#one');
await expect(p, 'should have content').toHaveText('Page 1');
await collectPreloads(page);
// Go to page 2
await page.click('#click-two');
p = page.locator('#two');
await expect(p, 'should have content').toHaveText('Page 2');
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 }) => {
@ -631,7 +649,7 @@ test.describe('View Transitions', () => {
});
test('client:only styles are retained on transition', async ({ page, astro }) => {
const totalExpectedStyles = 8;
const totalExpectedStyles = 7;
// Go to page 1
await page.goto(astro.resolveUrl('/client-only-one'));

View file

@ -1,6 +1,6 @@
{
"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.",
"type": "module",
"author": "withastro",
@ -56,7 +56,7 @@
"./components/*": "./components/*",
"./assets": "./dist/assets/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/squoosh": "./dist/assets/services/squoosh.js",
"./assets/services/noop": "./dist/assets/services/noop.js",
@ -168,7 +168,6 @@
"string-width": "^6.1.0",
"strip-ansi": "^7.1.0",
"tsconfig-resolver": "^3.0.1",
"undici": "^5.23.0",
"unist-util-visit": "^4.1.2",
"vfile": "^5.3.7",
"vite": "^4.4.9",
@ -226,5 +225,8 @@
"engines": {
"node": ">=18.14.1",
"npm": ">=6.14.0"
},
"publishConfig": {
"provenance": true
}
}

View file

@ -636,7 +636,7 @@ export interface AstroUserConfig {
* @see output
* @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.
*
@ -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.
*
* ```js
* import rehypeMinifyHtml from 'rehype-minify';
* import { rehypeAccessibleEmojis } from 'rehype-accessible-emojis';
* {
* markdown: {
* rehypePlugins: [rehypeMinifyHtml]
* rehypePlugins: [rehypeAccessibleEmojis]
* }
* }
* ```
@ -2213,7 +2213,7 @@ export interface SSRMetadata {
hasRenderedHead: boolean;
headInTree: boolean;
extraHead: string[];
propagators: Map<AstroComponentFactory, AstroComponentInstance>;
propagators: Set<AstroComponentInstance>;
}
/* Preview server stuff */

View file

@ -1,8 +1,8 @@
import { isRemotePath } from '@astrojs/internal-helpers/path';
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';
import type { APIRoute } from '../../@types/astro.js';
import { getConfiguredImageService, isRemoteAllowed } from '../internal.js';
import { etag } from '../utils/etag.js';
// @ts-expect-error
import { imageConfig } from 'astro:assets';
@ -40,7 +40,6 @@ export const GET: APIRoute = async ({ request }) => {
let inputBuffer: Buffer | undefined = undefined;
// TODO: handle config subpaths?
const sourceUrl = isRemotePath(transform.src)
? new URL(transform.src)
: 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';
import { matchHostname, matchPattern } from './utils/remotePattern.js';
export function injectImageEndpoint(settings: AstroSettings) {
const endpointEntrypoint = settings.config.image.endpoint ?? 'astro/assets/image-endpoint';
export function injectImageEndpoint(settings: AstroSettings, mode: 'dev' | 'build') {
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({
pattern: '/_image',
entryPoint: endpointEntrypoint,

View file

@ -10,6 +10,7 @@ import {
prependForwardSlash,
removeQueryString,
} from '../core/path.js';
import { isServerLikeOutput } from '../prerender/utils.js';
import { VALID_INPUT_FORMATS, VIRTUAL_MODULE_ID, VIRTUAL_SERVICE_ID } from './consts.js';
import { emitESMImage } from './utils/emitAsset.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 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);
`;
}

View file

@ -41,10 +41,22 @@ export async function printInfo({ flags }: InfoOptions) {
await copyToClipboard(output.trim());
}
const SUPPORTED_SYSTEM = new Set(['darwin', 'win32']);
async function copyToClipboard(text: string) {
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();
const { shouldCopy } = await prompts({
@ -54,11 +66,11 @@ async function copyToClipboard(text: string) {
initial: true,
});
if (!shouldCopy) return;
const command = system === 'darwin' ? 'pbcopy' : 'clip';
try {
execSync(`echo ${JSON.stringify(text.trim())} | ${command}`, {
execSync(command, {
input: text.trim(),
encoding: 'utf8',
stdio: 'ignore',
});
} catch (e) {
console.error(

View file

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

View file

@ -148,9 +148,15 @@ export const _internal = {
hasContentFlag(modUrl, DATA_FLAG) ||
Boolean(getContentRendererByViteId(modUrl, settings))
) {
const mod = await viteServer.moduleGraph.getModuleByUrl(modUrl);
if (mod) {
viteServer.moduleGraph.invalidateModule(mod);
try {
const mod = await viteServer.moduleGraph.getModuleByUrl(modUrl);
if (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)) {
this.settings = injectImageEndpoint(this.settings);
this.settings = injectImageEndpoint(this.settings, 'build');
}
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 { assetsInlineLimit = 4096 } = settings.config.vite?.build ?? {};
Object.entries(bundle).forEach(([_, stylesheet]) => {
Object.entries(bundle).forEach(([id, stylesheet]) => {
if (
stylesheet.type !== 'asset' ||
stylesheet.name?.endsWith('.css') !== true ||
@ -224,10 +224,15 @@ function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] {
: { type: 'external', src: stylesheet.fileName };
const pages = Array.from(eachPageData(internals));
let sheetAddedToPage = false;
pages.forEach((pageData) => {
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];
if (propagatedPaths === undefined) return;
@ -243,8 +248,21 @@ function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] {
pageData.propagatedStyles.set(pageInfoId, new Set()).get(pageInfoId)!;
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,
});
settings = injectImageEndpoint(settings);
settings = injectImageEndpoint(settings, 'dev');
const {
base,

View file

@ -39,7 +39,6 @@ export function createAPIContext({
props,
adapterName,
}: CreateAPIContext): APIContext {
initResponseWithEncoding();
const context = {
cookies: new AstroCookies(request),
request,
@ -92,44 +91,28 @@ export function createAPIContext({
type ResponseParameters = ConstructorParameters<typeof Response>;
export let ResponseWithEncoding: ReturnType<typeof initResponseWithEncoding>;
// TODO Remove this after StackBlitz supports Node 18.
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.
// We don't do the full handling as simple objects so users can control how headers are set instead.
if (typeof body === 'string') {
// In NodeJS, we can use Buffer.from which supports all BufferEncoding
if (typeof Buffer !== 'undefined' && Buffer.from) {
body = Buffer.from(body, encoding);
}
// In non-NodeJS, use the web-standard TextEncoder for utf-8 strings
else if (encoding == null || encoding === 'utf8' || encoding === 'utf-8') {
body = encoder.encode(body);
}
export class ResponseWithEncoding 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.
// We don't do the full handling as simple objects so users can control how headers are set instead.
if (typeof body === 'string') {
// In NodeJS, we can use Buffer.from which supports all BufferEncoding
if (typeof Buffer !== 'undefined' && Buffer.from) {
body = Buffer.from(body, encoding);
}
super(body, init);
if (encoding) {
this.headers.set('X-Astro-Encoding', encoding);
// In non-NodeJS, use the web-standard TextEncoder for utf-8 strings
else if (encoding == null || encoding === 'utf8' || encoding === 'utf-8') {
body = encoder.encode(body);
}
}
super(body, init);
if (encoding) {
this.headers.set('X-Astro-Encoding', encoding);
}
}
// Set the module scoped variable.
ResponseWithEncoding = LocalResponseWithEncoding;
// Turn this into a noop.
initResponseWithEncoding = (() => {}) as any;
return LocalResponseWithEncoding;
};
}
export async function callEndpoint<MiddlewareResult = Response | EndpointOutput>(
mod: EndpointHandler,

View file

@ -1158,7 +1158,7 @@ export const ContentSchemaContainsSlugError = {
/**
* @docs
* @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
* 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 path from 'node:path';
import type * as vite from 'vite';
import type { ModuleLoader, ModuleLoaderEventEmitter } from './loader.js';
export function createViteLoader(viteServer: vite.ViteDevServer): ModuleLoader {
const events = new EventEmitter() as ModuleLoaderEventEmitter;
viteServer.watcher.on('add', (...args) => events.emit('file-add', args));
viteServer.watcher.on('unlink', (...args) => events.emit('file-unlink', args));
viteServer.watcher.on('change', (...args) => events.emit('file-change', args));
let isTsconfigUpdated = false;
function isTsconfigUpdate(filePath: string) {
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') {
events.emit('hmr-error', msg);
}
});
_wsSend.apply(this, args);
};
return {
import(src) {
@ -56,11 +89,3 @@ export function createViteLoader(viteServer: vite.ViteDevServer): ModuleLoader {
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 {
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() {
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
if (!globalThis.crypto) {
Object.defineProperty(globalThis, 'crypto', {
@ -68,7 +12,7 @@ export function apply() {
// Remove when Node 18 is dropped for Node 20
if (!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(),
headInTree: false,
extraHead: [],
propagators: new Map(),
propagators: new Set(),
},
};

View file

@ -1,46 +1,7 @@
/// <reference types="vite/client" />
if (import.meta.hot) {
// Vite injects `<style data-vite-dev-id>` for ESM imports of styles
// but Astro also SSRs with `<style data-astro-dev-id>` blocks. This MutationObserver
// removes any duplicates as soon as they are hydrated client-side.
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');
// HMR temporarily not needed for now, but kept here in case we need it again.
// To re-instate this module again, update `vite-plugin-astro-server/route.ts`
// to add this module as a script similar to `/@vite/client`
}

View file

@ -56,17 +56,34 @@ declare const Astro: {
document.addEventListener('astro:after-swap', this.unmount, { once: true });
}
connectedCallback() {
if (!this.hasAttribute('await-children') || this.firstChild) {
if (
!this.hasAttribute('await-children') ||
document.readyState === 'interactive' ||
document.readyState === 'complete'
) {
this.childrenConnectedCallback();
} else {
// connectedCallback may run *before* children are rendered (ex. HTML streaming)
// If SSR children are expected, but not yet rendered,
// Wait with a mutation observer
new MutationObserver((_, mo) => {
// If SSR children are expected, but not yet rendered, wait with a mutation observer
// for a special marker inserted when rendering islands that signals the end of the island
const onConnected = () => {
document.removeEventListener('DOMContentLoaded', onConnected);
mo.disconnect();
// Wait until the next macrotask to ensure children are really rendered
setTimeout(() => this.childrenConnectedCallback(), 0);
}).observe(this, { childList: true });
this.childrenConnectedCallback();
};
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() {

View file

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

View file

@ -82,8 +82,8 @@ export function createAstroComponentInstance(
) {
validateComponentProps(props, displayName);
const instance = new AstroComponentInstance(result, props, slots, factory);
if (isAPropagatingComponent(result, factory) && !result._metadata.propagators.has(factory)) {
result._metadata.propagators.set(factory, instance);
if (isAPropagatingComponent(result, factory)) {
result._metadata.propagators.add(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) {
island.props['await-children'] = '';
// Marker to signal that Astro island children is completed while streaming
island.children += `<!--astro:end-->`;
}
return {

View file

@ -208,7 +208,7 @@ async function updateDOM(
const devId = el.dataset.viteDevId;
// If this same style tag exists, remove it from the new page
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.
noopEl
);
@ -292,7 +292,9 @@ async function updateDOM(
// Do not preload links that are already on the page.
if (
!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');

View file

@ -4,14 +4,21 @@ import { viteID } from '../core/util.js';
import { isBuildableCSSRequest } from './util.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. */
export async function getStylesForURL(
filePath: URL,
loader: ModuleLoader,
mode: RuntimeMode
): Promise<{ urls: Set<string>; stylesMap: Map<string, string> }> {
): Promise<{ urls: Set<string>; styles: ImportedStyle[] }> {
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)) {
if (isBuildableCSSRequest(importedModule.url)) {
@ -28,7 +35,11 @@ export async function getStylesForURL(
mode === 'development' && // only inline in development
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 {
// NOTE: We use the `url` property here. `id` would break Windows.
importedCssUrls.add(importedModule.url);
@ -38,6 +49,6 @@ export async function getStylesForURL(
return {
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 { createRequest } from '../core/request.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 { isServerLikeOutput } from '../prerender/utils.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' },
children: '',
});
scripts.add({
props: {
type: 'module',
src: await resolveIdToUrl(moduleLoader, 'astro/runtime/client/hmr.js'),
},
children: '',
});
scripts.add({
props: {
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.
const { urls: styleUrls, stylesMap } = await getStylesForURL(filePath, moduleLoader, mode);
const { urls: styleUrls, styles: importedStyles } = await getStylesForURL(
filePath,
moduleLoader,
mode
);
let links = new Set<SSRElement>();
[...styleUrls].forEach((href) => {
links.add({
@ -320,7 +317,7 @@ async function getScriptsAndStyles({ pipeline, filePath }: GetScriptsAndStylesPa
});
let styles = new Set<SSRElement>();
[...stylesMap].forEach(([url, content]) => {
importedStyles.forEach(({ id, url, content }) => {
// Vite handles HMR for styles injected as scripts
scripts.add({
props: {
@ -329,11 +326,11 @@ async function getScriptsAndStyles({ pipeline, filePath }: GetScriptsAndStylesPa
},
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({
props: {
// Track the ID so we can match it to Vite's injected style later
'data-astro-dev-id': viteID(new URL(`.${url}`, settings.config.root)),
'data-vite-dev-id': id,
},
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 type { PluginMetadata } from '../vite-plugin-astro/types.js';
import { escapeViteEnvReferences, getFileInfo } from '../vite-plugin-utils/index.js';
import { getMarkdownCodeForImages, type MarkdownImagePath } from './images.js';
interface AstroPluginOptions {
settings: AstroSettings;
@ -95,7 +96,7 @@ export default function markdown({ settings, logger }: AstroPluginOptions): Plug
const { headings, imagePaths: rawImagePaths, frontmatter } = renderResult.metadata;
// 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()) {
imagePaths.push({
raw: imagePath,
@ -119,34 +120,15 @@ export default function markdown({ settings, logger }: AstroPluginOptions): Plug
astroServerRuntimeModulePath
)};
import { AstroError, AstroErrorData } from ${JSON.stringify(astroErrorModulePath)};
${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 {
${imagePaths
.map((entry) => `"${entry.raw}": await getImage({src: Astro__${entry.safeName}})`)
.join(',\n')}
}
${
// Only include the code relevant to `astro:assets` if there's images in the file
imagePaths.length > 0
? getMarkdownCodeForImages(imagePaths, html)
: `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 file = ${JSON.stringify(fileId)};
export const url = ${JSON.stringify(fileUrl)};

View file

@ -180,8 +180,6 @@ describe('astro:image', () => {
let html = await res.text();
$ = cheerio.load(html);
console.log(html);
let $img = $('img');
expect($img).to.have.a.lengthOf(1);
@ -854,17 +852,14 @@ describe('astro:image', () => {
output: 'server',
adapter: testAdapter(),
image: {
endpoint: 'astro/assets/endpoint/node',
service: testImageService(),
},
});
await fixture.build();
});
// TODO
// 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 () => {
it('dynamic route images are built at response time sss', async () => {
const app = await fixture.loadTestAdapterApp();
let request = new Request('http://example.com/');
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 {
return await fetch(resolvedUrl, init);
} 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')) {
console.error(`[astro test] failed to fetch ${resolvedUrl}`);
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": {
"node": ">=18.14.1"
},
"publishConfig": {
"provenance": true
}
}

View file

@ -1,5 +1,11 @@
# @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
### Minor Changes

View file

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

View file

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

View file

@ -1,5 +1,47 @@
# @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
### 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.
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"
// astro.config.mjs
@ -192,7 +192,7 @@ default `"off"`
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
- `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
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.

View file

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

View file

@ -1,11 +1,9 @@
import type { AstroConfig, AstroIntegration, RouteData } from 'astro';
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 esbuild from 'esbuild';
import { Miniflare } from 'miniflare';
import * as fs from 'node:fs';
import * as os from 'node:os';
import { dirname, relative, sep } from 'node:path';
@ -14,7 +12,13 @@ import glob from 'tiny-glob';
import { getAdapter } from './getAdapter.js';
import { deduplicatePatterns } from './utils/deduplicatePatterns.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 { rewriteWasmImportPath } from './utils/rewriteWasmImportPath.js';
import { wasmModuleLoader } from './utils/wasm-module-loader.js';
@ -55,20 +59,10 @@ interface BuildConfig {
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 {
let _config: AstroConfig;
let _buildConfig: BuildConfig;
let _mf: Miniflare;
let _entryPoints = new Map<RouteData, URL>();
const SERVER_BUILD_FOLDER = '/$server_build/';
@ -122,7 +116,55 @@ export default function createIntegration(args?: Options): AstroIntegration {
try {
const cf = await getCFObject(runtimeMode);
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');
Reflect.set(req, clientLocalsSymbol, {
runtime: {
@ -136,18 +178,14 @@ export default function createIntegration(args?: Options): AstroIntegration {
// will be fetched from git dynamically once we support mocking of bindings
CF_PAGES_COMMIT_SHA: 'TBA',
CF_PAGES_URL: `http://${req.headers.host}`,
...bindingsEnv,
...vars,
},
cf: cf,
waitUntil: (_promise: Promise<any>) => {
return;
},
caches: new CacheStorage(
{ cache: true, cachePersist: false },
new NoOpLog(),
new StorageFactory(),
{}
),
caches: mfCache,
},
});
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 }) => {
if (target === 'server') {
vite.resolve ||= {};

View file

@ -7,11 +7,13 @@
* 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 dotenv from 'dotenv';
import { findUpSync } from 'find-up';
import * as fs from 'node:fs';
import { dirname, resolve } from 'node:path';
let _wrangler: any;
function findWranglerToml(
referencePath: string = process.cwd(),
@ -119,7 +121,9 @@ function getVarsForDev(config: any, configPath: string | undefined): any {
return config.vars;
}
}
export async function getEnvVars() {
function parseConfig() {
if (_wrangler) return _wrangler;
let rawConfig;
const configPath = findWranglerToml(process.cwd(), false); // false = args.experimentalJsonConfig
if (!configPath) {
@ -129,6 +133,59 @@ export async function getEnvVars() {
if (configPath?.endsWith('toml')) {
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);
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({
runtime: 'local',
}),
image: {
service: {
entrypoint: 'astro/assets/services/noop',
},
},
});
process.chdir('./test/fixtures/cf');
devServer = await fixture.startDevServer();
@ -68,12 +63,65 @@ describe('Astro Cloudflare Runtime', () => {
await devServer?.stop();
});
it('Populates CF, Vars & Bindings', async () => {
it('adds cf object', async () => {
let res = await fixture.fetch('/');
expect(res.status).to.equal(200);
let html = await res.text();
let $ = cheerio.load(html);
expect($('#hasRuntime').text()).to.equal('true');
expect($('#hasCache').text()).to.equal('true');
expect($('#hasCF').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>
<body>
<h1>Testing</h1>
<div id="hasRuntime">{!!runtime.cf?.colo}</div>
<div id="hasCache">{!!runtime.caches}</div>
<div id="hasCF">{!!runtime.cf?.colo}</div>
</body>
</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"
kv_namespaces = [
{ binding = "KV", id = "<YOUR_ID>", preview_id = "<YOUR_ID>" },
{ binding = "KV_PROD", id = "<YOUR_ID>", preview_id = "<YOUR_ID>" }
]
[vars]
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 🦖
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
## 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
### Major Changes

View file

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

View file

@ -1,5 +1,24 @@
# @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
### Minor Changes

View file

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

View file

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

View file

@ -1,5 +1,15 @@
# @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
### Minor Changes

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