Fix issue #515: Image optimization crash
This commit is contained in:
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@onwidget/astrowind",
|
"name": "@onwidget/astrowind",
|
||||||
"version": "1.0.0-beta.47",
|
"version": "1.0.0-beta.48",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@onwidget/astrowind",
|
"name": "@onwidget/astrowind",
|
||||||
"version": "1.0.0-beta.47",
|
"version": "1.0.0-beta.48",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/rss": "^4.0.8",
|
"@astrojs/rss": "^4.0.8",
|
||||||
"@astrojs/sitemap": "^3.2.0",
|
"@astrojs/sitemap": "^3.2.0",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@onwidget/astrowind",
|
"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.",
|
"description": "AstroWind: A free template using Astro 4.0 and Tailwind CSS. Astro starter theme.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
@@ -22,13 +22,16 @@ export interface ImageProps extends Omit<HTMLAttributes<'img'>, 'src'> {
|
|||||||
widths?: number[] | null;
|
widths?: number[] | null;
|
||||||
aspectRatio?: string | number | null;
|
aspectRatio?: string | number | null;
|
||||||
objectPosition?: string;
|
objectPosition?: string;
|
||||||
|
|
||||||
|
format?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ImagesOptimizer = (
|
export type ImagesOptimizer = (
|
||||||
image: ImageMetadata | string,
|
image: ImageMetadata | string,
|
||||||
breakpoints: number[],
|
breakpoints: number[],
|
||||||
width?: number,
|
width?: number,
|
||||||
height?: number
|
height?: number,
|
||||||
|
format?: string
|
||||||
) => Promise<Array<{ src: string; width: number }>>;
|
) => Promise<Array<{ src: string; width: number }>>;
|
||||||
|
|
||||||
/* ******* */
|
/* ******* */
|
||||||
@@ -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) {
|
if (!image) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.all(
|
return Promise.all(
|
||||||
breakpoints.map(async (w: number) => {
|
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 {
|
return {
|
||||||
src: url,
|
src: result?.src,
|
||||||
width: w,
|
width: result?.attributes?.width ?? w,
|
||||||
|
height: result?.attributes?.height
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -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') {
|
if (!image || typeof image !== 'string') {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -242,16 +253,19 @@ export const unpicOptimizer: ImagesOptimizer = async (image, breakpoints, width,
|
|||||||
|
|
||||||
return Promise.all(
|
return Promise.all(
|
||||||
breakpoints.map(async (w: number) => {
|
breakpoints.map(async (w: number) => {
|
||||||
|
const _height = width && height ? computeHeight(w, width / height) : height;
|
||||||
const url =
|
const url =
|
||||||
transformUrl({
|
transformUrl({
|
||||||
url: image,
|
url: image,
|
||||||
width: w,
|
width: w,
|
||||||
height: width && height ? computeHeight(w, width / height) : height,
|
height: _height,
|
||||||
cdn: urlParsed.cdn,
|
cdn: urlParsed.cdn,
|
||||||
|
...(format ? { format: format } : {}),
|
||||||
}) || image;
|
}) || image;
|
||||||
return {
|
return {
|
||||||
src: String(url),
|
src: String(url),
|
||||||
width: w,
|
width: w,
|
||||||
|
height: _height,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -270,6 +284,7 @@ export async function getImagesOptimized(
|
|||||||
widths,
|
widths,
|
||||||
layout = 'constrained',
|
layout = 'constrained',
|
||||||
style = '',
|
style = '',
|
||||||
|
format,
|
||||||
...rest
|
...rest
|
||||||
}: ImageProps,
|
}: ImageProps,
|
||||||
transform: ImagesOptimizer = () => Promise.resolve([])
|
transform: ImagesOptimizer = () => Promise.resolve([])
|
||||||
@@ -312,7 +327,7 @@ export async function getImagesOptimized(
|
|||||||
let breakpoints = getBreakpoints({ width: width, breakpoints: widths, layout: layout });
|
let breakpoints = getBreakpoints({ width: width, breakpoints: widths, layout: layout });
|
||||||
breakpoints = [...new Set(breakpoints)].sort((a, b) => a - b);
|
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`)
|
.map(({ src, width }) => `${src} ${width}w`)
|
||||||
.join(', ');
|
.join(', ');
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { getImage } from 'astro:assets';
|
import { isUnpicCompatible, unpicOptimizer, astroAsseetsOptimizer } from './images-optimization';
|
||||||
import type { ImageMetadata } from 'astro';
|
import type { ImageMetadata } from 'astro';
|
||||||
import type { OpenGraph } from '@astrolib/seo';
|
import type { OpenGraph } from '@astrolib/seo';
|
||||||
|
|
||||||
@@ -64,23 +64,32 @@ export const adaptOpenGraphImages = async (
|
|||||||
const adaptedImages = await Promise.all(
|
const adaptedImages = await Promise.all(
|
||||||
images.map(async (image) => {
|
images.map(async (image) => {
|
||||||
if (image?.url) {
|
if (image?.url) {
|
||||||
const resolvedImage = (await findImage(image.url)) as ImageMetadata | undefined;
|
const resolvedImage = (await findImage(image.url)) as ImageMetadata | string | undefined;
|
||||||
if (!resolvedImage) {
|
if (!resolvedImage) {
|
||||||
return {
|
return {
|
||||||
url: '',
|
url: '',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const _image = await getImage({
|
let _image;
|
||||||
src: resolvedImage,
|
|
||||||
alt: 'Placeholder alt',
|
if (
|
||||||
width: image?.width || defaultWidth,
|
typeof resolvedImage === 'string' &&
|
||||||
height: image?.height || defaultHeight,
|
(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') {
|
if (typeof _image === 'object') {
|
||||||
return {
|
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,
|
width: 'width' in _image && typeof _image.width === 'number' ? _image.width : undefined,
|
||||||
height: 'height' in _image && typeof _image.height === 'number' ? _image.height : undefined,
|
height: 'height' in _image && typeof _image.height === 'number' ? _image.height : undefined,
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user