full site update

This commit is contained in:
2025-07-24 18:46:24 +02:00
parent bfe2b90d8d
commit 37a6e0ab31
6912 changed files with 540482 additions and 361712 deletions

View File

@@ -1,8 +1,8 @@
import { isRemoteAllowed } from "@astrojs/internal-helpers/remote";
import { AstroError, AstroErrorData } from "../../core/errors/index.js";
import { isRemotePath, joinPaths } from "../../core/path.js";
import { DEFAULT_HASH_PROPS, DEFAULT_OUTPUT_FORMAT, VALID_SUPPORTED_FORMATS } from "../consts.js";
import { isESMImportedImage } from "../utils/imageKind.js";
import { isRemoteAllowed } from "../utils/remotePattern.js";
import { isESMImportedImage, isRemoteImage } from "../utils/imageKind.js";
function isLocalService(service) {
if (!service) {
return false;
@@ -16,10 +16,11 @@ function parseQuality(quality) {
}
return result;
}
const sortNumeric = (a, b) => a - b;
const baseService = {
propertiesToHash: DEFAULT_HASH_PROPS,
validateOptions(options) {
if (!options.src || typeof options.src !== "string" && typeof options.src !== "object") {
if (!options.src || !isRemoteImage(options.src) && !isESMImportedImage(options.src)) {
throw new AstroError({
...AstroErrorData.ExpectedImage,
message: AstroErrorData.ExpectedImage.message(
@@ -76,11 +77,32 @@ const baseService = {
}
if (options.width) options.width = Math.round(options.width);
if (options.height) options.height = Math.round(options.height);
if (options.layout && options.width && options.height) {
options.fit ??= "cover";
delete options.layout;
}
if (options.fit === "none") {
delete options.fit;
}
return options;
},
getHTMLAttributes(options) {
const { targetWidth, targetHeight } = getTargetDimensions(options);
const { src, width, height, format, quality, densities, widths, formats, ...attributes } = options;
const {
src,
width,
height,
format,
quality,
densities,
widths,
formats,
layout,
priority,
fit,
position,
...attributes
} = options;
return {
...attributes,
width: targetWidth,
@@ -90,22 +112,28 @@ const baseService = {
};
},
getSrcSet(options) {
const srcSet = [];
const { targetWidth } = getTargetDimensions(options);
const { targetWidth, targetHeight } = getTargetDimensions(options);
const aspectRatio = targetWidth / targetHeight;
const { widths, densities } = options;
const targetFormat = options.format ?? DEFAULT_OUTPUT_FORMAT;
let transformedWidths = (widths ?? []).sort(sortNumeric);
let imageWidth = options.width;
let maxWidth = Infinity;
if (isESMImportedImage(options.src)) {
imageWidth = options.src.width;
maxWidth = imageWidth;
if (transformedWidths.length > 0 && transformedWidths.at(-1) > maxWidth) {
transformedWidths = transformedWidths.filter((width) => width <= maxWidth);
transformedWidths.push(maxWidth);
}
}
transformedWidths = Array.from(new Set(transformedWidths));
const {
width: transformWidth,
height: transformHeight,
...transformWithoutDimensions
} = options;
const allWidths = [];
let allWidths = [];
if (densities) {
const densityValues = densities.map((density) => {
if (typeof density === "number") {
@@ -114,40 +142,28 @@ const baseService = {
return parseFloat(density);
}
});
const densityWidths = densityValues.sort().map((density) => Math.round(targetWidth * density));
allWidths.push(
...densityWidths.map((width, index) => ({
maxTargetWidth: Math.min(width, maxWidth),
descriptor: `${densityValues[index]}x`
}))
);
} else if (widths) {
allWidths.push(
...widths.map((width) => ({
maxTargetWidth: Math.min(width, maxWidth),
descriptor: `${width}w`
}))
);
const densityWidths = densityValues.sort(sortNumeric).map((density) => Math.round(targetWidth * density));
allWidths = densityWidths.map((width, index) => ({
width,
descriptor: `${densityValues[index]}x`
}));
} else if (transformedWidths.length > 0) {
allWidths = transformedWidths.map((width) => ({
width,
descriptor: `${width}w`
}));
}
for (const { maxTargetWidth, descriptor } of allWidths) {
const srcSetTransform = { ...transformWithoutDimensions };
if (maxTargetWidth !== imageWidth) {
srcSetTransform.width = maxTargetWidth;
} else {
if (options.width && options.height) {
srcSetTransform.width = options.width;
srcSetTransform.height = options.height;
}
}
srcSet.push({
transform: srcSetTransform,
return allWidths.map(({ width, descriptor }) => {
const height = Math.round(width / aspectRatio);
const transform = { ...transformWithoutDimensions, width, height };
return {
transform,
descriptor,
attributes: {
type: `image/${targetFormat}`
}
});
}
return srcSet;
};
});
},
getURL(options, imageConfig) {
const searchParams = new URLSearchParams();
@@ -162,12 +178,14 @@ const baseService = {
w: "width",
h: "height",
q: "quality",
f: "format"
f: "format",
fit: "fit",
position: "position"
};
Object.entries(params).forEach(([param, key]) => {
options[key] && searchParams.append(param, options[key].toString());
});
const imageEndpoint = joinPaths(import.meta.env.BASE_URL, "/_image");
const imageEndpoint = joinPaths(import.meta.env.BASE_URL, imageConfig.endpoint.route);
return `${imageEndpoint}?${searchParams}`;
},
parseURL(url) {
@@ -180,7 +198,9 @@ const baseService = {
width: params.has("w") ? parseInt(params.get("w")) : void 0,
height: params.has("h") ? parseInt(params.get("h")) : void 0,
format: params.get("f"),
quality: params.get("q")
quality: params.get("q"),
fit: params.get("fit"),
position: params.get("position") ?? void 0
};
return transform;
}