diff --git a/.changeset/odd-plants-tie.md b/.changeset/odd-plants-tie.md new file mode 100644 index 000000000..b57376dee --- /dev/null +++ b/.changeset/odd-plants-tie.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Add support for non-awaited imports to the Image component and `getImage` diff --git a/packages/astro/client-base.d.ts b/packages/astro/client-base.d.ts index c0203e0ef..3b0ee4901 100644 --- a/packages/astro/client-base.d.ts +++ b/packages/astro/client-base.d.ts @@ -48,7 +48,9 @@ declare module 'astro:assets' { * This is functionally equivalent to using the `` component, as the component calls this function internally. */ getImage: ( - options: import('./dist/assets/types.js').ImageTransform + options: + | import('./dist/assets/types.js').ImageTransform + | import('./dist/assets/types.js').UnresolvedImageTransform ) => Promise; getConfiguredImageService: typeof import('./dist/assets/index.js').getConfiguredImageService; Image: typeof import('./components/Image.astro').default; diff --git a/packages/astro/src/assets/internal.ts b/packages/astro/src/assets/internal.ts index c56b5369c..06e4f8cc0 100644 --- a/packages/astro/src/assets/internal.ts +++ b/packages/astro/src/assets/internal.ts @@ -1,7 +1,12 @@ import type { AstroSettings } from '../@types/astro.js'; import { AstroError, AstroErrorData } from '../core/errors/index.js'; import { isLocalService, type ImageService } from './services/service.js'; -import type { GetImageResult, ImageMetadata, ImageTransform } from './types.js'; +import type { + GetImageResult, + ImageMetadata, + ImageTransform, + UnresolvedImageTransform, +} from './types.js'; export function injectImageEndpoint(settings: AstroSettings) { settings.injectedRoutes.push({ @@ -37,7 +42,7 @@ export async function getConfiguredImageService(): Promise { } export async function getImage( - options: ImageTransform, + options: ImageTransform | UnresolvedImageTransform, serviceConfig: Record ): Promise { if (!options || typeof options !== 'object') { @@ -48,9 +53,19 @@ export async function getImage( } const service = await getConfiguredImageService(); + + // If the user inlined an import, something fairly common especially in MDX, await it for them + const resolvedOptions: ImageTransform = { + ...options, + src: + typeof options.src === 'object' && 'then' in options.src + ? (await options.src).default + : options.src, + }; + const validatedOptions = service.validateOptions - ? await service.validateOptions(options, serviceConfig) - : options; + ? await service.validateOptions(resolvedOptions, serviceConfig) + : resolvedOptions; let imageURL = await service.getURL(validatedOptions, serviceConfig); @@ -60,7 +75,7 @@ export async function getImage( } return { - rawOptions: options, + rawOptions: resolvedOptions, options: validatedOptions, src: imageURL, attributes: diff --git a/packages/astro/src/assets/types.ts b/packages/astro/src/assets/types.ts index 5632d7691..9c5990cb7 100644 --- a/packages/astro/src/assets/types.ts +++ b/packages/astro/src/assets/types.ts @@ -27,6 +27,10 @@ export interface ImageMetadata { orientation?: number; } +export type UnresolvedImageTransform = Omit & { + src: Promise<{ default: ImageMetadata }>; +}; + /** * Options accepted by the image transformation service. */ @@ -93,7 +97,7 @@ export type LocalImageProps = ImageSharedProps & { * ... * ``` */ - src: ImageMetadata; + src: ImageMetadata | Promise<{ default: ImageMetadata }>; /** * Desired output format for the image. Defaults to `webp`. * diff --git a/packages/astro/test/core-image.test.js b/packages/astro/test/core-image.test.js index 4d5f467bf..8c09de245 100644 --- a/packages/astro/test/core-image.test.js +++ b/packages/astro/test/core-image.test.js @@ -147,6 +147,19 @@ describe('astro:image', () => { }) ).to.be.true; }); + + it('supports inlined imports', async () => { + let res = await fixture.fetch('/inlineImport'); + let html = await res.text(); + $ = cheerio.load(html); + + let $img = $('img'); + expect($img).to.have.a.lengthOf(1); + + let src = $img.attr('src'); + res = await fixture.fetch(src); + expect(res.status).to.equal(200); + }); }); describe('vite-isms', () => { diff --git a/packages/astro/test/fixtures/core-image/src/pages/inlineImport.astro b/packages/astro/test/fixtures/core-image/src/pages/inlineImport.astro new file mode 100644 index 000000000..323587993 --- /dev/null +++ b/packages/astro/test/fixtures/core-image/src/pages/inlineImport.astro @@ -0,0 +1,7 @@ +--- +import { getImage } from "astro:assets"; + +const optimizedImage = await getImage({src: import('../assets/penguin1.jpg')}) +--- + +