Skip to content

Commit

Permalink
Fix issue #515: Image optimization crash
Browse files Browse the repository at this point in the history
  • Loading branch information
prototypa committed Oct 13, 2024
1 parent c8bc46d commit eebebeb
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 20 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@onwidget/astrowind",
"version": "1.0.0-beta.47",
"version": "1.0.0-beta.48",
"description": "AstroWind: A free template using Astro 4.0 and Tailwind CSS. Astro starter theme.",
"type": "module",
"private": true,
Expand Down
31 changes: 23 additions & 8 deletions src/utils/images-optimization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@ export interface ImageProps extends Omit<HTMLAttributes<'img'>, 'src'> {
widths?: number[] | null;
aspectRatio?: string | number | null;
objectPosition?: string;

format?: string;
}

export type ImagesOptimizer = (
image: ImageMetadata | string,
breakpoints: number[],
width?: number,
height?: number
height?: number,
format?: string
) => Promise<Array<{ src: string; width: number }>>;

/* ******* */
Expand Down Expand Up @@ -209,17 +212,25 @@ const getBreakpoints = ({
};

/* ** */
export const astroAsseetsOptimizer: ImagesOptimizer = async (image, breakpoints, _width, _height) => {
export const astroAsseetsOptimizer: ImagesOptimizer = async (
image,
breakpoints,
_width,
_height,
format = undefined
) => {
if (!image) {
return [];
}

return Promise.all(
breakpoints.map(async (w: number) => {
const url = (await getImage({ src: image, width: w, inferSize: true })).src;
const result = (await getImage({ src: image, width: w, inferSize: true, ...(format ? { format: format } : {}) }));

return {
src: url,
width: w,
src: result?.src,
width: result?.attributes?.width ?? w,
height: result?.attributes?.height
};
})
);
Expand All @@ -230,7 +241,7 @@ export const isUnpicCompatible = (image: string) => {
};

/* ** */
export const unpicOptimizer: ImagesOptimizer = async (image, breakpoints, width, height) => {
export const unpicOptimizer: ImagesOptimizer = async (image, breakpoints, width, height, format = undefined) => {
if (!image || typeof image !== 'string') {
return [];
}
Expand All @@ -242,16 +253,19 @@ export const unpicOptimizer: ImagesOptimizer = async (image, breakpoints, width,

return Promise.all(
breakpoints.map(async (w: number) => {
const _height = width && height ? computeHeight(w, width / height) : height;
const url =
transformUrl({
url: image,
width: w,
height: width && height ? computeHeight(w, width / height) : height,
height: _height,
cdn: urlParsed.cdn,
...(format ? { format: format } : {}),
}) || image;
return {
src: String(url),
width: w,
height: _height,
};
})
);
Expand All @@ -270,6 +284,7 @@ export async function getImagesOptimized(
widths,
layout = 'constrained',
style = '',
format,
...rest
}: ImageProps,
transform: ImagesOptimizer = () => Promise.resolve([])
Expand Down Expand Up @@ -312,7 +327,7 @@ export async function getImagesOptimized(
let breakpoints = getBreakpoints({ width: width, breakpoints: widths, layout: layout });
breakpoints = [...new Set(breakpoints)].sort((a, b) => a - b);

const srcset = (await transform(image, breakpoints, Number(width) || undefined, Number(height) || undefined))
const srcset = (await transform(image, breakpoints, Number(width) || undefined, Number(height) || undefined, format))
.map(({ src, width }) => `${src} ${width}w`)
.join(', ');

Expand Down
27 changes: 18 additions & 9 deletions src/utils/images.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getImage } from 'astro:assets';
import { isUnpicCompatible, unpicOptimizer, astroAsseetsOptimizer } from './images-optimization';
import type { ImageMetadata } from 'astro';
import type { OpenGraph } from '@astrolib/seo';

Expand Down Expand Up @@ -64,23 +64,32 @@ export const adaptOpenGraphImages = async (
const adaptedImages = await Promise.all(
images.map(async (image) => {
if (image?.url) {
const resolvedImage = (await findImage(image.url)) as ImageMetadata | undefined;
const resolvedImage = (await findImage(image.url)) as ImageMetadata | string | undefined;
if (!resolvedImage) {
return {
url: '',
};
}

const _image = await getImage({
src: resolvedImage,
alt: 'Placeholder alt',
width: image?.width || defaultWidth,
height: image?.height || defaultHeight,
});
let _image;

if (
typeof resolvedImage === 'string' &&
(resolvedImage.startsWith('http://') || resolvedImage.startsWith('https://')) &&
isUnpicCompatible(resolvedImage)
) {
_image = (await unpicOptimizer(resolvedImage, [defaultWidth], defaultWidth, defaultHeight, 'jpg'))[0];
} else if (resolvedImage) {
const dimensions =
typeof resolvedImage !== 'string' && resolvedImage?.width <= defaultWidth
? [resolvedImage?.width, resolvedImage?.height]
: [defaultWidth, defaultHeight];
_image = (await astroAsseetsOptimizer(resolvedImage, [dimensions[0]], dimensions[0], dimensions[1], 'jpg'))[0];
}

if (typeof _image === 'object') {
return {
url: 'src' in _image && typeof _image.src === 'string' ? String(new URL(_image.src, astroSite)) : 'pepe',
url: 'src' in _image && typeof _image.src === 'string' ? String(new URL(_image.src, astroSite)) : '',
width: 'width' in _image && typeof _image.width === 'number' ? _image.width : undefined,
height: 'height' in _image && typeof _image.height === 'number' ? _image.height : undefined,
};
Expand Down

0 comments on commit eebebeb

Please sign in to comment.