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,12 +1 @@
/**
* FNV-1a Hash implementation
* @author Travis Webb (tjwebb) <me@traviswebb.com>
*
* Ported from https://github.com/tjwebb/fnv-plus/blob/master/index.js
* License https://github.com/tjwebb/fnv-plus#license
*
* Simplified, optimized and add modified for 52 bit, which provides a larger hash space
* and still making use of Javascript's 53-bit integer space.
*/
export declare const fnv1a52: (str: string) => number;
export declare const etag: (payload: string, weak?: boolean) => string;

View File

@@ -23,6 +23,5 @@ const etag = (payload, weak = false) => {
return prefix + fnv1a52(payload).toString(36) + payload.length.toString(36) + '"';
};
export {
etag,
fnv1a52
etag
};

View File

@@ -0,0 +1,2 @@
export declare const cssFitValues: string[];
export declare function addCSSVarsToStyle(vars: Record<string, string | false | undefined>, styles?: string | Record<string, any>): string;

View File

@@ -0,0 +1,14 @@
import { toStyleString } from "../../runtime/server/render/util.js";
const cssFitValues = ["fill", "contain", "cover", "scale-down"];
function addCSSVarsToStyle(vars, styles) {
const cssVars = Object.entries(vars).filter(([_, value]) => value !== void 0 && value !== false).map(([key, value]) => `--${key}: ${value};`).join(" ");
if (!styles) {
return cssVars;
}
const style = typeof styles === "string" ? styles : toStyleString(styles);
return `${cssVars} ${style}`;
}
export {
addCSSVarsToStyle,
cssFitValues
};

View File

@@ -1,4 +1,22 @@
import type { ImageMetadata, UnresolvedImageTransform } from '../types.js';
/**
* Determines if the given source is an ECMAScript Module (ESM) imported image.
*
* @param {ImageMetadata | string} src - The source to check. It can be an `ImageMetadata` object or a string.
* @return {boolean} Returns `true` if the source is an `ImageMetadata` object, otherwise `false`.
*/
export declare function isESMImportedImage(src: ImageMetadata | string): src is ImageMetadata;
/**
* Determines if the provided source is a remote image URL in the form of a string.
*
* @param {ImageMetadata | string} src - The source to check, which can either be an `ImageMetadata` object or a string.
* @return {boolean} Returns `true` if the source is a string, otherwise `false`.
*/
export declare function isRemoteImage(src: ImageMetadata | string): src is string;
/**
* Resolves the source of an image transformation by handling asynchronous or synchronous inputs.
*
* @param {UnresolvedImageTransform['src']} src - The source of the image transformation.
* @return {Promise<string | ImageMetadata>} A promise that resolves to the image source. It returns either the default export of the resolved source or the resolved source itself if the default export doesn't exist.
*/
export declare function resolveSrc(src: UnresolvedImageTransform['src']): Promise<string | ImageMetadata>;

View File

@@ -1,11 +1,15 @@
function isESMImportedImage(src) {
return typeof src === "object";
return typeof src === "object" || typeof src === "function" && "src" in src;
}
function isRemoteImage(src) {
return typeof src === "string";
}
async function resolveSrc(src) {
return typeof src === "object" && "then" in src ? (await src).default ?? await src : src;
if (typeof src === "object" && "then" in src) {
const resource = await src;
return resource.default ?? resource;
}
return src;
}
export {
isESMImportedImage,

View File

@@ -1,7 +1,17 @@
export { emitESMImage } from './node/emitAsset.js';
/**
* NOTE: this is a public module exposed to the user, so all functions exposed
* here must be documented via JsDoc and in the docs website.
*
* If some functions don't need to be exposed, just import the file that contains the functions.
*/
export { isESMImportedImage, isRemoteImage } from './imageKind.js';
export { imageMetadata } from './metadata.js';
export {
/**
* @deprecated
*/
emitESMImage, emitImageMetadata, } from './node/emitAsset.js';
export { getOrigQueryParams } from './queryParams.js';
export { isRemoteAllowed, matchHostname, matchPathname, matchPattern, matchPort, matchProtocol, type RemotePattern, } from './remotePattern.js';
export { hashTransform, propsToFilename } from './transformToPath.js';
export { inferRemoteSize } from './remoteProbe.js';
export { hashTransform, propsToFilename } from './transformToPath.js';

View File

@@ -1,6 +1,9 @@
import { emitESMImage } from "./node/emitAsset.js";
import { isESMImportedImage, isRemoteImage } from "./imageKind.js";
import { imageMetadata } from "./metadata.js";
import {
emitESMImage,
emitImageMetadata
} from "./node/emitAsset.js";
import { getOrigQueryParams } from "./queryParams.js";
import {
isRemoteAllowed,
@@ -10,10 +13,11 @@ import {
matchPort,
matchProtocol
} from "./remotePattern.js";
import { hashTransform, propsToFilename } from "./transformToPath.js";
import { inferRemoteSize } from "./remoteProbe.js";
import { hashTransform, propsToFilename } from "./transformToPath.js";
export {
emitESMImage,
emitImageMetadata,
getOrigQueryParams,
hashTransform,
imageMetadata,

View File

@@ -1,2 +1,10 @@
import type { ImageMetadata } from '../types.js';
/**
* Extracts image metadata such as dimensions, format, and orientation from the provided image data.
*
* @param {Uint8Array} data - The binary data of the image.
* @param {string} [src] - The source path or URL of the image, used for error messages. Optional.
* @return {Promise<Omit<ImageMetadata, 'src' | 'fsPath'>>} A promise that resolves with the extracted metadata, excluding `src` and `fsPath`.
* @throws {AstroError} Throws an error if the image metadata cannot be extracted.
*/
export declare function imageMetadata(data: Uint8Array, src?: string): Promise<Omit<ImageMetadata, 'src' | 'fsPath'>>;

View File

@@ -1,28 +1,29 @@
import { AstroError, AstroErrorData } from "../../core/errors/index.js";
import { lookup as probe } from "../utils/vendor/image-size/lookup.js";
async function imageMetadata(data, src) {
let result;
try {
const result = probe(data);
if (!result.height || !result.width || !result.type) {
throw new AstroError({
...AstroErrorData.NoImageMetadata,
message: AstroErrorData.NoImageMetadata.message(src)
});
}
const { width, height, type, orientation } = result;
const isPortrait = (orientation || 0) >= 5;
return {
width: isPortrait ? height : width,
height: isPortrait ? width : height,
format: type,
orientation
};
result = probe(data);
} catch {
throw new AstroError({
...AstroErrorData.NoImageMetadata,
message: AstroErrorData.NoImageMetadata.message(src)
});
}
if (!result.height || !result.width || !result.type) {
throw new AstroError({
...AstroErrorData.NoImageMetadata,
message: AstroErrorData.NoImageMetadata.message(src)
});
}
const { width, height, type, orientation } = result;
const isPortrait = (orientation || 0) >= 5;
return {
width: isPortrait ? height : width,
height: isPortrait ? width : height,
format: type,
orientation
};
}
export {
imageMetadata

View File

@@ -1,7 +1,29 @@
import type * as vite from 'vite';
import type { ImageMetadata } from '../../types.js';
type FileEmitter = vite.Rollup.EmitFile;
type ImageMetadataWithContents = ImageMetadata & {
contents?: Buffer;
};
/**
* Processes an image file and emits its metadata and optionally its contents. This function supports both build and development modes.
*
* @param {string | undefined} id - The identifier or path of the image file to process. If undefined, the function returns immediately.
* @param {boolean} _watchMode - **Deprecated**: Indicates if the method is operating in watch mode. This parameter will be removed or updated in the future.
* @param {boolean} _experimentalSvgEnabled - **Deprecated**: A flag to enable experimental handling of SVG files. Embeds SVG file data if set to true.
* @param {FileEmitter | undefined} [fileEmitter] - Function for emitting files during the build process. May throw in certain scenarios.
* @return {Promise<ImageMetadataWithContents | undefined>} Resolves to metadata with optional image contents or `undefined` if processing fails.
*/
export declare function emitESMImage(id: string | undefined,
/** @deprecated */
_watchMode: boolean, fileEmitter?: FileEmitter): Promise<ImageMetadata | undefined>;
_watchMode: boolean,
/** @deprecated */
_experimentalSvgEnabled: boolean, fileEmitter?: FileEmitter): Promise<ImageMetadataWithContents | undefined>;
/**
* Processes an image file and emits its metadata and optionally its contents. This function supports both build and development modes.
*
* @param {string | undefined} id - The identifier or path of the image file to process. If undefined, the function returns immediately.
* @param {FileEmitter | undefined} [fileEmitter] - Function for emitting files during the build process. May throw in certain scenarios.
* @return {Promise<ImageMetadataWithContents | undefined>} Resolves to metadata with optional image contents or `undefined` if processing fails.
*/
export declare function emitImageMetadata(id: string | undefined, fileEmitter?: FileEmitter): Promise<ImageMetadataWithContents | undefined>;
export {};

View File

@@ -3,7 +3,51 @@ import path from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import { prependForwardSlash, slash } from "../../../core/path.js";
import { imageMetadata } from "../metadata.js";
async function emitESMImage(id, _watchMode, fileEmitter) {
async function emitESMImage(id, _watchMode, _experimentalSvgEnabled, fileEmitter) {
if (!id) {
return void 0;
}
const url = pathToFileURL(id);
let fileData;
try {
fileData = await fs.readFile(url);
} catch {
return void 0;
}
const fileMetadata = await imageMetadata(fileData, id);
const emittedImage = {
src: "",
...fileMetadata
};
Object.defineProperty(emittedImage, "fsPath", {
enumerable: false,
writable: false,
value: id
});
let isBuild = typeof fileEmitter === "function";
if (isBuild) {
const pathname = decodeURI(url.pathname);
const filename = path.basename(pathname, path.extname(pathname) + `.${fileMetadata.format}`);
try {
const handle = fileEmitter({
name: filename,
source: await fs.readFile(url),
type: "asset"
});
emittedImage.src = `__ASTRO_ASSET_IMAGE__${handle}__`;
} catch {
isBuild = false;
}
}
if (!isBuild) {
url.searchParams.append("origWidth", fileMetadata.width.toString());
url.searchParams.append("origHeight", fileMetadata.height.toString());
url.searchParams.append("origFormat", fileMetadata.format);
emittedImage.src = `/@fs` + prependForwardSlash(fileURLToNormalizedPath(url));
}
return emittedImage;
}
async function emitImageMetadata(id, fileEmitter) {
if (!id) {
return void 0;
}
@@ -51,5 +95,6 @@ function fileURLToNormalizedPath(filePath) {
return slash(fileURLToPath(filePath) + filePath.search).replace(/\\/g, "/");
}
export {
emitESMImage
emitESMImage,
emitImageMetadata
};

View File

@@ -1,2 +1,11 @@
import type { ImageMetadata } from '../types.js';
/**
* Extracts the original image query parameters (width, height, format) from the given `URLSearchParams` object
* and returns them as an object. If any of the required parameters are missing or invalid, the function returns undefined.
*
* The `width` and `height` are parsed to integer values.
*
* @param {URLSearchParams} params - The `URLSearchParams` object containing the query parameters.
* @return {Pick<ImageMetadata, 'width' | 'height' | 'format'> | undefined} An object with the original image parameters (width, height, format) or undefined if any parameter is missing.
*/
export declare function getOrigQueryParams(params: URLSearchParams): Pick<ImageMetadata, 'width' | 'height' | 'format'> | undefined;

View File

@@ -1,13 +1,3 @@
import type { AstroConfig } from '../../@types/astro.js';
export type RemotePattern = {
hostname?: string;
pathname?: string;
protocol?: string;
port?: string;
};
export declare function matchPattern(url: URL, remotePattern: RemotePattern): boolean;
export declare function matchPort(url: URL, port?: string): boolean;
export declare function matchProtocol(url: URL, protocol?: string): boolean;
export declare function matchHostname(url: URL, hostname?: string, allowWildcard?: boolean): boolean;
export declare function matchPathname(url: URL, pathname?: string, allowWildcard?: boolean): boolean;
export declare function isRemoteAllowed(src: string, { domains, remotePatterns, }: Partial<Pick<AstroConfig['image'], 'domains' | 'remotePatterns'>>): boolean;
import { isRemoteAllowed, matchHostname, matchPathname, matchPattern, matchPort, matchProtocol, type RemotePattern } from '@astrojs/internal-helpers/remote';
export { isRemoteAllowed, matchHostname, matchPort, matchPathname, matchProtocol, matchPattern };
export type { RemotePattern };

View File

@@ -1,51 +1,11 @@
import { isRemotePath } from "@astrojs/internal-helpers/path";
function matchPattern(url, remotePattern) {
return matchProtocol(url, remotePattern.protocol) && matchHostname(url, remotePattern.hostname, true) && matchPort(url, remotePattern.port) && matchPathname(url, remotePattern.pathname, true);
}
function matchPort(url, port) {
return !port || port === url.port;
}
function matchProtocol(url, protocol) {
return !protocol || protocol === url.protocol.slice(0, -1);
}
function matchHostname(url, hostname, allowWildcard) {
if (!hostname) {
return true;
} else if (!allowWildcard || !hostname.startsWith("*")) {
return hostname === url.hostname;
} else if (hostname.startsWith("**.")) {
const slicedHostname = hostname.slice(2);
return slicedHostname !== url.hostname && url.hostname.endsWith(slicedHostname);
} else if (hostname.startsWith("*.")) {
const slicedHostname = hostname.slice(1);
const additionalSubdomains = url.hostname.replace(slicedHostname, "").split(".").filter(Boolean);
return additionalSubdomains.length === 1;
}
return false;
}
function matchPathname(url, pathname, allowWildcard) {
if (!pathname) {
return true;
} else if (!allowWildcard || !pathname.endsWith("*")) {
return pathname === url.pathname;
} else if (pathname.endsWith("/**")) {
const slicedPathname = pathname.slice(0, -2);
return slicedPathname !== url.pathname && url.pathname.startsWith(slicedPathname);
} else if (pathname.endsWith("/*")) {
const slicedPathname = pathname.slice(0, -1);
const additionalPathChunks = url.pathname.replace(slicedPathname, "").split("/").filter(Boolean);
return additionalPathChunks.length === 1;
}
return false;
}
function isRemoteAllowed(src, {
domains = [],
remotePatterns = []
}) {
if (!isRemotePath(src)) return false;
const url = new URL(src);
return domains.some((domain) => matchHostname(url, domain)) || remotePatterns.some((remotePattern) => matchPattern(url, remotePattern));
}
import {
isRemoteAllowed,
matchHostname,
matchPathname,
matchPattern,
matchPort,
matchProtocol
} from "@astrojs/internal-helpers/remote";
export {
isRemoteAllowed,
matchHostname,

View File

@@ -1,2 +1,9 @@
import type { ImageMetadata } from '../types.js';
/**
* Infers the dimensions of a remote image by streaming its data and analyzing it progressively until sufficient metadata is available.
*
* @param {string} url - The URL of the remote image from which to infer size metadata.
* @return {Promise<Omit<ImageMetadata, 'src' | 'fsPath'>>} Returns a promise that resolves to an object containing the image dimensions metadata excluding `src` and `fsPath`.
* @throws {AstroError} Thrown when the fetching fails or metadata cannot be extracted.
*/
export declare function inferRemoteSize(url: string): Promise<Omit<ImageMetadata, 'src' | 'fsPath'>>;

View File

@@ -7,7 +7,7 @@ function imageSrcToImportId(imageSrc, filePath) {
if (isRemotePath(imageSrc)) {
return;
}
const ext = imageSrc.split(".").at(-1);
const ext = imageSrc.split(".").at(-1)?.toLowerCase();
if (!ext || !VALID_INPUT_FORMATS.includes(ext)) {
return;
}

2
node_modules/astro/dist/assets/utils/svg.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
import type { ImageMetadata } from '../types.js';
export declare function makeSvgComponent(meta: ImageMetadata, contents: Buffer | string): string;

28
node_modules/astro/dist/assets/utils/svg.js generated vendored Normal file
View File

@@ -0,0 +1,28 @@
import { parse, renderSync } from "ultrahtml";
import { dropAttributes } from "../runtime.js";
function parseSvg(contents) {
const root = parse(contents);
const svgNode = root.children.find(
({ name, type }) => type === 1 && name === "svg"
);
if (!svgNode) {
throw new Error("SVG file does not contain an <svg> element");
}
const { attributes, children } = svgNode;
const body = renderSync({ ...root, children });
return { attributes, body };
}
function makeSvgComponent(meta, contents) {
const file = typeof contents === "string" ? contents : contents.toString("utf-8");
const { attributes, body: children } = parseSvg(file);
const props = {
meta,
attributes: dropAttributes(attributes),
children
};
return `import { createSvgComponent } from 'astro/assets/runtime';
export default createSvgComponent(${JSON.stringify(props)})`;
}
export {
makeSvgComponent
};

View File

@@ -1,3 +1,33 @@
import type { ImageTransform } from '../types.js';
/**
* Converts a file path and transformation properties of the transformation image service, into a formatted filename.
*
* The formatted filename follows this structure:
*
* `<prefixDirname>/<baseFilename>_<hash><outputExtension>`
*
* - `prefixDirname`: If the image is an ESM imported image, this is the directory name of the original file path; otherwise, it will be an empty string.
* - `baseFilename`: The base name of the file or a hashed short name if the file is a `data:` URI.
* - `hash`: A unique hash string generated to distinguish the transformed file.
* - `outputExtension`: The desired output file extension derived from the `transform.format` or the original file extension.
*
* ## Example
* - Input: `filePath = '/images/photo.jpg'`, `transform = { format: 'png', src: '/images/photo.jpg' }`, `hash = 'abcd1234'`.
* - Output: `/images/photo_abcd1234.png`
*
* @param {string} filePath - The original file path or data URI of the source image.
* @param {ImageTransform} transform - An object representing the transformation properties, including format and source.
* @param {string} hash - A unique hash used to differentiate the transformed file.
* @return {string} The generated filename based on the provided input, transformations, and hash.
*/
export declare function propsToFilename(filePath: string, transform: ImageTransform, hash: string): string;
/**
* Transforms the provided `transform` object into a hash string based on selected properties
* and the specified `imageService`.
*
* @param {ImageTransform} transform - The transform object containing various image transformation properties.
* @param {string} imageService - The name of the image service related to the transform.
* @param {string[]} propertiesToHash - An array of property names from the `transform` object that should be used to generate the hash.
* @return {string} A hashed string created from the specified properties of the `transform` object and the image service.
*/
export declare function hashTransform(transform: ImageTransform, imageService: string, propertiesToHash: string[]): string;

View File

@@ -1,4 +1,3 @@
import type { imageType } from './types/index.js';
import type { ISizeCalculationResult } from './types/interface.ts';
/**
* Return size information based on an Uint8Array
@@ -7,4 +6,3 @@ import type { ISizeCalculationResult } from './types/interface.ts';
* @returns {ISizeCalculationResult}
*/
export declare function lookup(input: Uint8Array): ISizeCalculationResult;
export declare const disableTypes: (types: imageType[]) => void;

View File

@@ -1,14 +1,8 @@
import { typeHandlers } from "./types/index.js";
import { detector } from "./detector.js";
const globalOptions = {
disabledTypes: []
};
function lookup(input) {
const type = detector(input);
if (typeof type !== "undefined") {
if (globalOptions.disabledTypes.includes(type)) {
throw new TypeError("disabled file type: " + type);
}
const size = typeHandlers.get(type).calculate(input);
if (size !== void 0) {
size.type = size.type ?? type;
@@ -17,10 +11,6 @@ function lookup(input) {
}
throw new TypeError("unsupported file type: " + type);
}
const disableTypes = (types) => {
globalOptions.disabledTypes = types;
};
export {
disableTypes,
lookup
};

View File

@@ -1,9 +1,11 @@
import { findBox, readUInt32BE, toUTF8String } from "./utils.js";
const brandMap = {
avif: "avif",
avis: "avif",
// avif-sequence
mif1: "heif",
msf1: "heif",
// hief-sequence
// heif-sequence
heic: "heic",
heix: "heic",
hevc: "heic",
@@ -19,7 +21,7 @@ function detectBrands(buffer, start, end) {
brandsDetected[brand] = 1;
}
}
if ("avif" in brandsDetected) {
if ("avif" in brandsDetected || "avis" in brandsDetected) {
return "avif";
} else if ("heic" in brandsDetected || "heix" in brandsDetected || "hevc" in brandsDetected || "hevx" in brandsDetected) {
return "heic";