diff --git a/.changeset/every-birds-relax.md b/.changeset/every-birds-relax.md new file mode 100644 index 000000000000..2dec90e4db22 --- /dev/null +++ b/.changeset/every-birds-relax.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes images outside the project directory not working when using astro:assets in development mode diff --git a/packages/astro/src/assets/endpoint/dev.ts b/packages/astro/src/assets/endpoint/dev.ts index d9d818433a5a..075215bf7bf9 100644 --- a/packages/astro/src/assets/endpoint/dev.ts +++ b/packages/astro/src/assets/endpoint/dev.ts @@ -1,24 +1,27 @@ // @ts-expect-error import { root } from 'astro:config/server'; import { readFile } from 'node:fs/promises'; -import os from 'node:os'; import { fileURLToPath } from 'node:url'; import { isParentDirectory } from '@astrojs/internal-helpers/path'; import type { APIRoute } from '../../types/public/common.js'; import { handleImageRequest, loadRemoteImage } from './shared.js'; -function replaceFileSystemReferences(src: string) { - return os.platform().includes('win32') ? src.replace(/^\/@fs\//, '') : src.replace(/^\/@fs/, ''); -} - async function loadLocalImage(src: string, url: URL) { - // Vite uses /@fs/ to denote filesystem access + // Vite uses /@fs/ to denote filesystem access, we can fetch those files directly if (src.startsWith('/@fs/')) { - src = replaceFileSystemReferences(src); - if (!isParentDirectory(fileURLToPath(root), src)) { + try { + const res = await fetch(new URL(src, url)); + + if (!res.ok) { + return undefined; + } + + return Buffer.from(await res.arrayBuffer()); + } catch { return undefined; } } + // Vite allows loading files directly from the filesystem // as long as they are inside the project root. if (isParentDirectory(fileURLToPath(root), src)) { diff --git a/packages/astro/test/core-image.test.js b/packages/astro/test/core-image.test.js index ddb0f2c3cbcd..2791e3c75341 100644 --- a/packages/astro/test/core-image.test.js +++ b/packages/astro/test/core-image.test.js @@ -164,6 +164,12 @@ describe('astro:image', () => { }), true, ); + + // Verify that the images can be fetched successfully + for (const img of $img.toArray()) { + const imgRes = await fixture.fetch(img.attribs['src']); + assert.equal(imgRes.status, 200); + } }); it('supports inlined imports', async () => {