feat(assets): Add support for passing non-awaited imports to the Image component and getImage
(#8066)
* feat(assets): Add support for passing non-awaited imports to the Image component and `getImage` * test: add test
This commit is contained in:
parent
c5b60fadb8
commit
afc45af202
6 changed files with 53 additions and 7 deletions
5
.changeset/odd-plants-tie.md
Normal file
5
.changeset/odd-plants-tie.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Add support for non-awaited imports to the Image component and `getImage`
|
4
packages/astro/client-base.d.ts
vendored
4
packages/astro/client-base.d.ts
vendored
|
@ -48,7 +48,9 @@ declare module 'astro:assets' {
|
||||||
* This is functionally equivalent to using the `<Image />` component, as the component calls this function internally.
|
* This is functionally equivalent to using the `<Image />` component, as the component calls this function internally.
|
||||||
*/
|
*/
|
||||||
getImage: (
|
getImage: (
|
||||||
options: import('./dist/assets/types.js').ImageTransform
|
options:
|
||||||
|
| import('./dist/assets/types.js').ImageTransform
|
||||||
|
| import('./dist/assets/types.js').UnresolvedImageTransform
|
||||||
) => Promise<import('./dist/assets/types.js').GetImageResult>;
|
) => Promise<import('./dist/assets/types.js').GetImageResult>;
|
||||||
getConfiguredImageService: typeof import('./dist/assets/index.js').getConfiguredImageService;
|
getConfiguredImageService: typeof import('./dist/assets/index.js').getConfiguredImageService;
|
||||||
Image: typeof import('./components/Image.astro').default;
|
Image: typeof import('./components/Image.astro').default;
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
import type { AstroSettings } from '../@types/astro.js';
|
import type { AstroSettings } from '../@types/astro.js';
|
||||||
import { AstroError, AstroErrorData } from '../core/errors/index.js';
|
import { AstroError, AstroErrorData } from '../core/errors/index.js';
|
||||||
import { isLocalService, type ImageService } from './services/service.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) {
|
export function injectImageEndpoint(settings: AstroSettings) {
|
||||||
settings.injectedRoutes.push({
|
settings.injectedRoutes.push({
|
||||||
|
@ -37,7 +42,7 @@ export async function getConfiguredImageService(): Promise<ImageService> {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getImage(
|
export async function getImage(
|
||||||
options: ImageTransform,
|
options: ImageTransform | UnresolvedImageTransform,
|
||||||
serviceConfig: Record<string, any>
|
serviceConfig: Record<string, any>
|
||||||
): Promise<GetImageResult> {
|
): Promise<GetImageResult> {
|
||||||
if (!options || typeof options !== 'object') {
|
if (!options || typeof options !== 'object') {
|
||||||
|
@ -48,9 +53,19 @@ export async function getImage(
|
||||||
}
|
}
|
||||||
|
|
||||||
const service = await getConfiguredImageService();
|
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
|
const validatedOptions = service.validateOptions
|
||||||
? await service.validateOptions(options, serviceConfig)
|
? await service.validateOptions(resolvedOptions, serviceConfig)
|
||||||
: options;
|
: resolvedOptions;
|
||||||
|
|
||||||
let imageURL = await service.getURL(validatedOptions, serviceConfig);
|
let imageURL = await service.getURL(validatedOptions, serviceConfig);
|
||||||
|
|
||||||
|
@ -60,7 +75,7 @@ export async function getImage(
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
rawOptions: options,
|
rawOptions: resolvedOptions,
|
||||||
options: validatedOptions,
|
options: validatedOptions,
|
||||||
src: imageURL,
|
src: imageURL,
|
||||||
attributes:
|
attributes:
|
||||||
|
|
|
@ -27,6 +27,10 @@ export interface ImageMetadata {
|
||||||
orientation?: number;
|
orientation?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type UnresolvedImageTransform = Omit<ImageTransform, 'src'> & {
|
||||||
|
src: Promise<{ default: ImageMetadata }>;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Options accepted by the image transformation service.
|
* Options accepted by the image transformation service.
|
||||||
*/
|
*/
|
||||||
|
@ -93,7 +97,7 @@ export type LocalImageProps<T> = ImageSharedProps<T> & {
|
||||||
* <Image src={myImage} alt="..."></Image>
|
* <Image src={myImage} alt="..."></Image>
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
src: ImageMetadata;
|
src: ImageMetadata | Promise<{ default: ImageMetadata }>;
|
||||||
/**
|
/**
|
||||||
* Desired output format for the image. Defaults to `webp`.
|
* Desired output format for the image. Defaults to `webp`.
|
||||||
*
|
*
|
||||||
|
|
|
@ -147,6 +147,19 @@ describe('astro:image', () => {
|
||||||
})
|
})
|
||||||
).to.be.true;
|
).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', () => {
|
describe('vite-isms', () => {
|
||||||
|
|
7
packages/astro/test/fixtures/core-image/src/pages/inlineImport.astro
vendored
Normal file
7
packages/astro/test/fixtures/core-image/src/pages/inlineImport.astro
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
import { getImage } from "astro:assets";
|
||||||
|
|
||||||
|
const optimizedImage = await getImage({src: import('../assets/penguin1.jpg')})
|
||||||
|
---
|
||||||
|
|
||||||
|
<img src={optimizedImage.src} {...optimizedImage.attributes} />
|
Loading…
Add table
Reference in a new issue