Refactor routing in App component to enhance navigation and improve error handling by integrating dynamic routes and updating the NotFound route.

This commit is contained in:
becarta
2025-05-23 12:43:00 +02:00
parent f40db0f5c9
commit a544759a3b
11127 changed files with 1647032 additions and 0 deletions

24
node_modules/astro/dist/assets/build/generate.d.ts generated vendored Normal file
View File

@@ -0,0 +1,24 @@
import type PQueue from 'p-queue';
import type { AstroConfig } from '../../@types/astro.js';
import type { BuildPipeline } from '../../core/build/pipeline.js';
import type { Logger } from '../../core/logger/core.js';
import type { MapValue } from '../../type-utils.js';
import type { AssetsGlobalStaticImagesList } from '../types.js';
type AssetEnv = {
logger: Logger;
isSSR: boolean;
count: {
total: number;
current: number;
};
useCache: boolean;
assetsCacheDir: URL;
serverRoot: URL;
clientRoot: URL;
imageConfig: AstroConfig['image'];
assetsFolder: AstroConfig['build']['assets'];
};
export declare function prepareAssetsGenerationEnv(pipeline: BuildPipeline, totalCount: number): Promise<AssetEnv>;
export declare function generateImagesForPath(originalFilePath: string, transformsAndPath: MapValue<AssetsGlobalStaticImagesList>, env: AssetEnv, queue: PQueue): Promise<void>;
export declare function getStaticImageList(): AssetsGlobalStaticImagesList;
export {};

198
node_modules/astro/dist/assets/build/generate.js generated vendored Normal file
View File

@@ -0,0 +1,198 @@
import fs, { readFileSync } from "node:fs";
import { basename } from "node:path/posix";
import { dim, green } from "kleur/colors";
import { getOutDirWithinCwd } from "../../core/build/common.js";
import { getTimeStat } from "../../core/build/util.js";
import { AstroError } from "../../core/errors/errors.js";
import { AstroErrorData } from "../../core/errors/index.js";
import { isRemotePath, removeLeadingForwardSlash } from "../../core/path.js";
import { isServerLikeOutput } from "../../core/util.js";
import { getConfiguredImageService } from "../internal.js";
import { isESMImportedImage } from "../utils/imageKind.js";
import { loadRemoteImage } from "./remote.js";
async function prepareAssetsGenerationEnv(pipeline, totalCount) {
const { config, logger } = pipeline;
let useCache = true;
const assetsCacheDir = new URL("assets/", config.cacheDir);
const count = { total: totalCount, current: 1 };
try {
await fs.promises.mkdir(assetsCacheDir, { recursive: true });
} catch (err) {
logger.warn(
null,
`An error was encountered while creating the cache directory. Proceeding without caching. Error: ${err}`
);
useCache = false;
}
let serverRoot, clientRoot;
if (isServerLikeOutput(config)) {
serverRoot = config.build.server;
clientRoot = config.build.client;
} else {
serverRoot = getOutDirWithinCwd(config.outDir);
clientRoot = config.outDir;
}
return {
logger,
isSSR: isServerLikeOutput(config),
count,
useCache,
assetsCacheDir,
serverRoot,
clientRoot,
imageConfig: config.image,
assetsFolder: config.build.assets
};
}
function getFullImagePath(originalFilePath, env) {
return new URL(removeLeadingForwardSlash(originalFilePath), env.serverRoot);
}
async function generateImagesForPath(originalFilePath, transformsAndPath, env, queue) {
let originalImage;
for (const [_, transform] of transformsAndPath.transforms) {
await queue.add(async () => generateImage(transform.finalPath, transform.transform)).catch((e) => {
throw e;
});
}
if (!env.isSSR && transformsAndPath.originalSrcPath && !globalThis.astroAsset.referencedImages?.has(transformsAndPath.originalSrcPath)) {
try {
if (transformsAndPath.originalSrcPath) {
env.logger.debug(
"assets",
`Deleting ${originalFilePath} as it's not referenced outside of image processing.`
);
await fs.promises.unlink(getFullImagePath(originalFilePath, env));
}
} catch {
}
}
async function generateImage(filepath, options) {
const timeStart = performance.now();
const generationData = await generateImageInternal(filepath, options);
const timeEnd = performance.now();
const timeChange = getTimeStat(timeStart, timeEnd);
const timeIncrease = `(+${timeChange})`;
const statsText = generationData.cached ? `(reused cache entry)` : `(before: ${generationData.weight.before}kB, after: ${generationData.weight.after}kB)`;
const count = `(${env.count.current}/${env.count.total})`;
env.logger.info(
null,
` ${green("\u25B6")} ${filepath} ${dim(statsText)} ${dim(timeIncrease)} ${dim(count)}`
);
env.count.current++;
}
async function generateImageInternal(filepath, options) {
const isLocalImage = isESMImportedImage(options.src);
const finalFileURL = new URL("." + filepath, env.clientRoot);
const finalFolderURL = new URL("./", finalFileURL);
await fs.promises.mkdir(finalFolderURL, { recursive: true });
const cacheFile = basename(filepath) + (isLocalImage ? "" : ".json");
const cachedFileURL = new URL(cacheFile, env.assetsCacheDir);
try {
if (isLocalImage) {
await fs.promises.copyFile(cachedFileURL, finalFileURL, fs.constants.COPYFILE_FICLONE);
return {
cached: true
};
} else {
const JSONData = JSON.parse(readFileSync(cachedFileURL, "utf-8"));
if (!JSONData.data || !JSONData.expires) {
await fs.promises.unlink(cachedFileURL);
throw new Error(
`Malformed cache entry for ${filepath}, cache will be regenerated for this file.`
);
}
if (JSONData.expires > Date.now()) {
await fs.promises.writeFile(finalFileURL, Buffer.from(JSONData.data, "base64"));
return {
cached: true
};
} else {
await fs.promises.unlink(cachedFileURL);
}
}
} catch (e) {
if (e.code !== "ENOENT") {
throw new Error(`An error was encountered while reading the cache file. Error: ${e}`);
}
}
const originalImagePath = isLocalImage ? options.src.src : options.src;
if (!originalImage) {
originalImage = await loadImage(originalFilePath, env);
}
let resultData = {
data: void 0,
expires: originalImage.expires
};
const imageService = await getConfiguredImageService();
try {
resultData.data = (await imageService.transform(
originalImage.data,
{ ...options, src: originalImagePath },
env.imageConfig
)).data;
} catch (e) {
const error = new AstroError(
{
...AstroErrorData.CouldNotTransformImage,
message: AstroErrorData.CouldNotTransformImage.message(originalFilePath)
},
{ cause: e }
);
throw error;
}
try {
if (env.useCache) {
if (isLocalImage) {
await fs.promises.writeFile(cachedFileURL, resultData.data);
} else {
await fs.promises.writeFile(
cachedFileURL,
JSON.stringify({
data: Buffer.from(resultData.data).toString("base64"),
expires: resultData.expires
})
);
}
}
} catch (e) {
env.logger.warn(
null,
`An error was encountered while creating the cache directory. Proceeding without caching. Error: ${e}`
);
} finally {
await fs.promises.writeFile(finalFileURL, resultData.data);
}
return {
cached: false,
weight: {
// Divide by 1024 to get size in kilobytes
before: Math.trunc(originalImage.data.byteLength / 1024),
after: Math.trunc(Buffer.from(resultData.data).byteLength / 1024)
}
};
}
}
function getStaticImageList() {
if (!globalThis?.astroAsset?.staticImages) {
return /* @__PURE__ */ new Map();
}
return globalThis.astroAsset.staticImages;
}
async function loadImage(path, env) {
if (isRemotePath(path)) {
const remoteImage = await loadRemoteImage(path);
return {
data: remoteImage.data,
expires: remoteImage.expires
};
}
return {
data: await fs.promises.readFile(getFullImagePath(path, env)),
expires: 0
};
}
export {
generateImagesForPath,
getStaticImageList,
prepareAssetsGenerationEnv
};

8
node_modules/astro/dist/assets/build/remote.d.ts generated vendored Normal file
View File

@@ -0,0 +1,8 @@
export type RemoteCacheEntry = {
data: string;
expires: number;
};
export declare function loadRemoteImage(src: string): Promise<{
data: Buffer;
expires: number;
}>;

42
node_modules/astro/dist/assets/build/remote.js generated vendored Normal file
View File

@@ -0,0 +1,42 @@
import CachePolicy from "http-cache-semantics";
async function loadRemoteImage(src) {
const req = new Request(src);
const res = await fetch(req);
if (!res.ok) {
throw new Error(
`Failed to load remote image ${src}. The request did not return a 200 OK response. (received ${res.status}))`
);
}
const policy = new CachePolicy(webToCachePolicyRequest(req), webToCachePolicyResponse(res));
const expires = policy.storable() ? policy.timeToLive() : 0;
return {
data: Buffer.from(await res.arrayBuffer()),
expires: Date.now() + expires
};
}
function webToCachePolicyRequest({ url, method, headers: _headers }) {
let headers = {};
try {
headers = Object.fromEntries(_headers.entries());
} catch {
}
return {
method,
url,
headers
};
}
function webToCachePolicyResponse({ status, headers: _headers }) {
let headers = {};
try {
headers = Object.fromEntries(_headers.entries());
} catch {
}
return {
status,
headers
};
}
export {
loadRemoteImage
};

11
node_modules/astro/dist/assets/consts.d.ts generated vendored Normal file
View File

@@ -0,0 +1,11 @@
export declare const VIRTUAL_MODULE_ID = "astro:assets";
export declare const VIRTUAL_SERVICE_ID = "virtual:image-service";
export declare const VALID_INPUT_FORMATS: readonly ["jpeg", "jpg", "png", "tiff", "webp", "gif", "svg", "avif"];
/**
* Valid formats that our base services support.
* Certain formats can be imported (namely SVGs) but will not be processed.
*/
export declare const VALID_SUPPORTED_FORMATS: readonly ["jpeg", "jpg", "png", "tiff", "webp", "gif", "svg", "avif"];
export declare const DEFAULT_OUTPUT_FORMAT: "webp";
export declare const VALID_OUTPUT_FORMATS: readonly ["avif", "png", "webp", "jpeg", "jpg", "svg"];
export declare const DEFAULT_HASH_PROPS: string[];

34
node_modules/astro/dist/assets/consts.js generated vendored Normal file
View File

@@ -0,0 +1,34 @@
const VIRTUAL_MODULE_ID = "astro:assets";
const VIRTUAL_SERVICE_ID = "virtual:image-service";
const VALID_INPUT_FORMATS = [
"jpeg",
"jpg",
"png",
"tiff",
"webp",
"gif",
"svg",
"avif"
];
const VALID_SUPPORTED_FORMATS = [
"jpeg",
"jpg",
"png",
"tiff",
"webp",
"gif",
"svg",
"avif"
];
const DEFAULT_OUTPUT_FORMAT = "webp";
const VALID_OUTPUT_FORMATS = ["avif", "png", "webp", "jpeg", "jpg", "svg"];
const DEFAULT_HASH_PROPS = ["src", "width", "height", "format", "quality"];
export {
DEFAULT_HASH_PROPS,
DEFAULT_OUTPUT_FORMAT,
VALID_INPUT_FORMATS,
VALID_OUTPUT_FORMATS,
VALID_SUPPORTED_FORMATS,
VIRTUAL_MODULE_ID,
VIRTUAL_SERVICE_ID
};

2
node_modules/astro/dist/assets/endpoint/config.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
import type { AstroSettings } from '../../@types/astro.js';
export declare function injectImageEndpoint(settings: AstroSettings, mode: 'dev' | 'build'): AstroSettings;

12
node_modules/astro/dist/assets/endpoint/config.js generated vendored Normal file
View File

@@ -0,0 +1,12 @@
function injectImageEndpoint(settings, mode) {
const endpointEntrypoint = settings.config.image.endpoint ?? (mode === "dev" ? "astro/assets/endpoint/node" : "astro/assets/endpoint/generic");
settings.injectedRoutes.push({
pattern: "/_image",
entrypoint: endpointEntrypoint,
prerender: false
});
return settings;
}
export {
injectImageEndpoint
};

5
node_modules/astro/dist/assets/endpoint/generic.d.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import type { APIRoute } from '../../@types/astro.js';
/**
* Endpoint used in dev and SSR to serve optimized images by the base image services
*/
export declare const GET: APIRoute;

63
node_modules/astro/dist/assets/endpoint/generic.js generated vendored Normal file
View File

@@ -0,0 +1,63 @@
import { imageConfig } from "astro:assets";
import { isRemotePath } from "@astrojs/internal-helpers/path";
import * as mime from "mrmime";
import { getConfiguredImageService } from "../internal.js";
import { etag } from "../utils/etag.js";
import { isRemoteAllowed } from "../utils/remotePattern.js";
async function loadRemoteImage(src, headers) {
try {
const res = await fetch(src, {
// Forward all headers from the original request
headers
});
if (!res.ok) {
return void 0;
}
return await res.arrayBuffer();
} catch {
return void 0;
}
}
const GET = async ({ request }) => {
try {
const imageService = await getConfiguredImageService();
if (!("transform" in imageService)) {
throw new Error("Configured image service is not a local service");
}
const url = new URL(request.url);
const transform = await imageService.parseURL(url, imageConfig);
if (!transform?.src) {
throw new Error("Incorrect transform returned by `parseURL`");
}
let inputBuffer = void 0;
const isRemoteImage = isRemotePath(transform.src);
const sourceUrl = isRemoteImage ? new URL(transform.src) : new URL(transform.src, url.origin);
if (isRemoteImage && isRemoteAllowed(transform.src, imageConfig) === false) {
return new Response("Forbidden", { status: 403 });
}
inputBuffer = await loadRemoteImage(sourceUrl, isRemoteImage ? new Headers() : request.headers);
if (!inputBuffer) {
return new Response("Not Found", { status: 404 });
}
const { data, format } = await imageService.transform(
new Uint8Array(inputBuffer),
transform,
imageConfig
);
return new Response(data, {
status: 200,
headers: {
"Content-Type": mime.lookup(format) ?? `image/${format}`,
"Cache-Control": "public, max-age=31536000",
ETag: etag(data.toString()),
Date: (/* @__PURE__ */ new Date()).toUTCString()
}
});
} catch (err) {
console.error("Could not process image request:", err);
return new Response(`Server Error: ${err}`, { status: 500 });
}
};
export {
GET
};

5
node_modules/astro/dist/assets/endpoint/node.d.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import type { APIRoute } from '../../@types/astro.js';
/**
* Endpoint used in dev and SSR to serve optimized images by the base image services
*/
export declare const GET: APIRoute;

108
node_modules/astro/dist/assets/endpoint/node.js generated vendored Normal file
View File

@@ -0,0 +1,108 @@
import { readFile } from "node:fs/promises";
import os from "node:os";
import { isAbsolute } from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import { assetsDir, imageConfig, outDir } from "astro:assets";
import { isRemotePath, removeQueryString } from "@astrojs/internal-helpers/path";
import * as mime from "mrmime";
import { getConfiguredImageService } from "../internal.js";
import { etag } from "../utils/etag.js";
import { isRemoteAllowed } from "../utils/remotePattern.js";
function replaceFileSystemReferences(src) {
return os.platform().includes("win32") ? src.replace(/^\/@fs\//, "") : src.replace(/^\/@fs/, "");
}
async function loadLocalImage(src, url) {
const assetsDirPath = fileURLToPath(assetsDir);
let fileUrl;
if (import.meta.env.DEV) {
fileUrl = pathToFileURL(removeQueryString(replaceFileSystemReferences(src)));
} else {
try {
const idx = url.pathname.indexOf("/_image");
if (idx > 0) {
src = src.slice(idx);
}
fileUrl = new URL("." + src, outDir);
const filePath = fileURLToPath(fileUrl);
if (!isAbsolute(filePath) || !filePath.startsWith(assetsDirPath)) {
return void 0;
}
} catch {
return void 0;
}
}
let buffer = void 0;
try {
buffer = await readFile(fileUrl);
} catch {
try {
const sourceUrl = new URL(src, url.origin);
buffer = await loadRemoteImage(sourceUrl);
} catch (err) {
console.error("Could not process image request:", err);
return void 0;
}
}
return buffer;
}
async function loadRemoteImage(src) {
try {
const res = await fetch(src);
if (!res.ok) {
return void 0;
}
return Buffer.from(await res.arrayBuffer());
} catch {
return void 0;
}
}
const GET = async ({ request }) => {
try {
const imageService = await getConfiguredImageService();
if (!("transform" in imageService)) {
throw new Error("Configured image service is not a local service");
}
const url = new URL(request.url);
const transform = await imageService.parseURL(url, imageConfig);
if (!transform?.src) {
const err = new Error(
"Incorrect transform returned by `parseURL`. Expected a transform with a `src` property."
);
console.error("Could not parse image transform from URL:", err);
return new Response("Internal Server Error", { status: 500 });
}
let inputBuffer = void 0;
if (isRemotePath(transform.src)) {
if (isRemoteAllowed(transform.src, imageConfig) === false) {
return new Response("Forbidden", { status: 403 });
}
inputBuffer = await loadRemoteImage(new URL(transform.src));
} else {
inputBuffer = await loadLocalImage(transform.src, url);
}
if (!inputBuffer) {
return new Response("Internal Server Error", { status: 500 });
}
const { data, format } = await imageService.transform(inputBuffer, transform, imageConfig);
return new Response(data, {
status: 200,
headers: {
"Content-Type": mime.lookup(format) ?? `image/${format}`,
"Cache-Control": "public, max-age=31536000",
ETag: etag(data.toString()),
Date: (/* @__PURE__ */ new Date()).toUTCString()
}
});
} catch (err) {
console.error("Could not process image request:", err);
return new Response(
import.meta.env.DEV ? `Could not process image request: ${err}` : `Internal Server Error`,
{
status: 500
}
);
}
};
export {
GET
};

3
node_modules/astro/dist/assets/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
export { getConfiguredImageService, getImage } from './internal.js';
export { baseService, isLocalService } from './services/service.js';
export { type LocalImageProps, type RemoteImageProps } from './types.js';

9
node_modules/astro/dist/assets/index.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
import { getConfiguredImageService, getImage } from "./internal.js";
import { baseService, isLocalService } from "./services/service.js";
import {} from "./types.js";
export {
baseService,
getConfiguredImageService,
getImage,
isLocalService
};

5
node_modules/astro/dist/assets/internal.d.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import type { AstroConfig } from '../@types/astro.js';
import { type ImageService } from './services/service.js';
import { type GetImageResult, type UnresolvedImageTransform } from './types.js';
export declare function getConfiguredImageService(): Promise<ImageService>;
export declare function getImage(options: UnresolvedImageTransform, imageConfig: AstroConfig['image']): Promise<GetImageResult>;

102
node_modules/astro/dist/assets/internal.js generated vendored Normal file
View File

@@ -0,0 +1,102 @@
import { isRemotePath } from "@astrojs/internal-helpers/path";
import { AstroError, AstroErrorData } from "../core/errors/index.js";
import { DEFAULT_HASH_PROPS } from "./consts.js";
import { isLocalService } from "./services/service.js";
import {
isImageMetadata
} from "./types.js";
import { isESMImportedImage, isRemoteImage, resolveSrc } from "./utils/imageKind.js";
import { inferRemoteSize } from "./utils/remoteProbe.js";
async function getConfiguredImageService() {
if (!globalThis?.astroAsset?.imageService) {
const { default: service } = await import(
// @ts-expect-error
"virtual:image-service"
).catch((e) => {
const error = new AstroError(AstroErrorData.InvalidImageService);
error.cause = e;
throw error;
});
if (!globalThis.astroAsset) globalThis.astroAsset = {};
globalThis.astroAsset.imageService = service;
return service;
}
return globalThis.astroAsset.imageService;
}
async function getImage(options, imageConfig) {
if (!options || typeof options !== "object") {
throw new AstroError({
...AstroErrorData.ExpectedImageOptions,
message: AstroErrorData.ExpectedImageOptions.message(JSON.stringify(options))
});
}
if (typeof options.src === "undefined") {
throw new AstroError({
...AstroErrorData.ExpectedImage,
message: AstroErrorData.ExpectedImage.message(
options.src,
"undefined",
JSON.stringify(options)
)
});
}
if (isImageMetadata(options)) {
throw new AstroError(AstroErrorData.ExpectedNotESMImage);
}
const service = await getConfiguredImageService();
const resolvedOptions = {
...options,
src: await resolveSrc(options.src)
};
if (options.inferSize && isRemoteImage(resolvedOptions.src) && isRemotePath(resolvedOptions.src)) {
const result = await inferRemoteSize(resolvedOptions.src);
resolvedOptions.width ??= result.width;
resolvedOptions.height ??= result.height;
delete resolvedOptions.inferSize;
}
const originalFilePath = isESMImportedImage(resolvedOptions.src) ? resolvedOptions.src.fsPath : void 0;
const clonedSrc = isESMImportedImage(resolvedOptions.src) ? (
// @ts-expect-error - clone is a private, hidden prop
resolvedOptions.src.clone ?? resolvedOptions.src
) : resolvedOptions.src;
resolvedOptions.src = clonedSrc;
const validatedOptions = service.validateOptions ? await service.validateOptions(resolvedOptions, imageConfig) : resolvedOptions;
const srcSetTransforms = service.getSrcSet ? await service.getSrcSet(validatedOptions, imageConfig) : [];
let imageURL = await service.getURL(validatedOptions, imageConfig);
let srcSets = await Promise.all(
srcSetTransforms.map(async (srcSet) => ({
transform: srcSet.transform,
url: await service.getURL(srcSet.transform, imageConfig),
descriptor: srcSet.descriptor,
attributes: srcSet.attributes
}))
);
if (isLocalService(service) && globalThis.astroAsset.addStaticImage && !(isRemoteImage(validatedOptions.src) && imageURL === validatedOptions.src)) {
const propsToHash = service.propertiesToHash ?? DEFAULT_HASH_PROPS;
imageURL = globalThis.astroAsset.addStaticImage(
validatedOptions,
propsToHash,
originalFilePath
);
srcSets = srcSetTransforms.map((srcSet) => ({
transform: srcSet.transform,
url: globalThis.astroAsset.addStaticImage(srcSet.transform, propsToHash, originalFilePath),
descriptor: srcSet.descriptor,
attributes: srcSet.attributes
}));
}
return {
rawOptions: resolvedOptions,
options: validatedOptions,
src: imageURL,
srcSet: {
values: srcSets,
attribute: srcSets.map((srcSet) => `${srcSet.url} ${srcSet.descriptor}`).join(", ")
},
attributes: service.getHTMLAttributes !== void 0 ? await service.getHTMLAttributes(validatedOptions, imageConfig) : {}
};
}
export {
getConfiguredImageService,
getImage
};

3
node_modules/astro/dist/assets/services/noop.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import { type LocalImageService } from './service.js';
declare const noopService: LocalImageService;
export default noopService;

15
node_modules/astro/dist/assets/services/noop.js generated vendored Normal file
View File

@@ -0,0 +1,15 @@
import { baseService } from "./service.js";
const noopService = {
...baseService,
propertiesToHash: ["src"],
async transform(inputBuffer, transformOptions) {
return {
data: inputBuffer,
format: transformOptions.format
};
}
};
var noop_default = noopService;
export {
noop_default as default
};

101
node_modules/astro/dist/assets/services/service.d.ts generated vendored Normal file
View File

@@ -0,0 +1,101 @@
import type { AstroConfig } from '../../@types/astro.js';
import type { ImageOutputFormat, ImageTransform, UnresolvedSrcSetValue } from '../types.js';
export type ImageService = LocalImageService | ExternalImageService;
export declare function isLocalService(service: ImageService | undefined): service is LocalImageService;
export declare function parseQuality(quality: string): string | number;
type ImageConfig<T> = Omit<AstroConfig['image'], 'service'> & {
service: {
entrypoint: string;
config: T;
};
};
interface SharedServiceProps<T extends Record<string, any> = Record<string, any>> {
/**
* Return the URL to the endpoint or URL your images are generated from.
*
* For a local service, your service should expose an endpoint handling the image requests, or use Astro's at `/_image`.
*
* For external services, this should point to the URL your images are coming from, for instance, `/_vercel/image`
*
*/
getURL: (options: ImageTransform, imageConfig: ImageConfig<T>) => string | Promise<string>;
/**
* Generate additional `srcset` values for the image.
*
* While in most cases this is exclusively used for `srcset`, it can also be used in a more generic way to generate
* multiple variants of the same image. For instance, you can use this to generate multiple aspect ratios or multiple formats.
*/
getSrcSet?: (options: ImageTransform, imageConfig: ImageConfig<T>) => UnresolvedSrcSetValue[] | Promise<UnresolvedSrcSetValue[]>;
/**
* Return any additional HTML attributes separate from `src` that your service requires to show the image properly.
*
* For example, you might want to return the `width` and `height` to avoid CLS, or a particular `class` or `style`.
* In most cases, you'll want to return directly what your user supplied you, minus the attributes that were used to generate the image.
*/
getHTMLAttributes?: (options: ImageTransform, imageConfig: ImageConfig<T>) => Record<string, any> | Promise<Record<string, any>>;
/**
* Validate and return the options passed by the user.
*
* This method is useful to present errors to users who have entered invalid options.
* For instance, if they are missing a required property or have entered an invalid image format.
*
* This method should returns options, and can be used to set defaults (ex: a default output format to be used if the user didn't specify one.)
*/
validateOptions?: (options: ImageTransform, imageConfig: ImageConfig<T>) => ImageTransform | Promise<ImageTransform>;
}
export type ExternalImageService<T extends Record<string, any> = Record<string, any>> = SharedServiceProps<T>;
export type LocalImageTransform = {
src: string;
[key: string]: any;
};
export interface LocalImageService<T extends Record<string, any> = Record<string, any>> extends SharedServiceProps<T> {
/**
* Parse the requested parameters passed in the URL from `getURL` back into an object to be used later by `transform`.
*
* In most cases, this will get query parameters using, for example, `params.get('width')` and return those.
*/
parseURL: (url: URL, imageConfig: ImageConfig<T>) => LocalImageTransform | undefined | Promise<LocalImageTransform> | Promise<undefined>;
/**
* Performs the image transformations on the input image and returns both the binary data and
* final image format of the optimized image.
*/
transform: (inputBuffer: Uint8Array, transform: LocalImageTransform, imageConfig: ImageConfig<T>) => Promise<{
data: Uint8Array;
format: ImageOutputFormat;
}>;
/**
* A list of properties that should be used to generate the hash for the image.
*
* Generally, this should be all the properties that can change the result of the image. By default, this is `src`, `width`, `height`, `quality`, and `format`.
*/
propertiesToHash?: string[];
}
export type BaseServiceTransform = {
src: string;
width?: number;
height?: number;
format: string;
quality?: string | null;
};
/**
* Basic local service using the included `_image` endpoint.
* This service intentionally does not implement `transform`.
*
* Example usage:
* ```ts
* const service = {
* getURL: baseService.getURL,
* parseURL: baseService.parseURL,
* getHTMLAttributes: baseService.getHTMLAttributes,
* async transform(inputBuffer, transformOptions) {...}
* }
* ```
*
* This service adhere to the included services limitations:
* - Remote images are passed as is.
* - Only a limited amount of formats are supported.
* - For remote images, `width` and `height` are always required.
*
*/
export declare const baseService: Omit<LocalImageService, 'transform'>;
export {};

211
node_modules/astro/dist/assets/services/service.js generated vendored Normal file
View File

@@ -0,0 +1,211 @@
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";
function isLocalService(service) {
if (!service) {
return false;
}
return "transform" in service;
}
function parseQuality(quality) {
let result = parseInt(quality);
if (Number.isNaN(result)) {
return quality;
}
return result;
}
const baseService = {
propertiesToHash: DEFAULT_HASH_PROPS,
validateOptions(options) {
if (!options.src || typeof options.src !== "string" && typeof options.src !== "object") {
throw new AstroError({
...AstroErrorData.ExpectedImage,
message: AstroErrorData.ExpectedImage.message(
JSON.stringify(options.src),
typeof options.src,
JSON.stringify(options, (_, v) => v === void 0 ? null : v)
)
});
}
if (!isESMImportedImage(options.src)) {
if (options.src.startsWith("/@fs/") || !isRemotePath(options.src) && !options.src.startsWith("/")) {
throw new AstroError({
...AstroErrorData.LocalImageUsedWrongly,
message: AstroErrorData.LocalImageUsedWrongly.message(options.src)
});
}
let missingDimension;
if (!options.width && !options.height) {
missingDimension = "both";
} else if (!options.width && options.height) {
missingDimension = "width";
} else if (options.width && !options.height) {
missingDimension = "height";
}
if (missingDimension) {
throw new AstroError({
...AstroErrorData.MissingImageDimension,
message: AstroErrorData.MissingImageDimension.message(missingDimension, options.src)
});
}
} else {
if (!VALID_SUPPORTED_FORMATS.includes(options.src.format)) {
throw new AstroError({
...AstroErrorData.UnsupportedImageFormat,
message: AstroErrorData.UnsupportedImageFormat.message(
options.src.format,
options.src.src,
VALID_SUPPORTED_FORMATS
)
});
}
if (options.widths && options.densities) {
throw new AstroError(AstroErrorData.IncompatibleDescriptorOptions);
}
if (options.src.format === "svg") {
options.format = "svg";
}
if (options.src.format === "svg" && options.format !== "svg" || options.src.format !== "svg" && options.format === "svg") {
throw new AstroError(AstroErrorData.UnsupportedImageConversion);
}
}
if (!options.format) {
options.format = DEFAULT_OUTPUT_FORMAT;
}
if (options.width) options.width = Math.round(options.width);
if (options.height) options.height = Math.round(options.height);
return options;
},
getHTMLAttributes(options) {
const { targetWidth, targetHeight } = getTargetDimensions(options);
const { src, width, height, format, quality, densities, widths, formats, ...attributes } = options;
return {
...attributes,
width: targetWidth,
height: targetHeight,
loading: attributes.loading ?? "lazy",
decoding: attributes.decoding ?? "async"
};
},
getSrcSet(options) {
const srcSet = [];
const { targetWidth } = getTargetDimensions(options);
const { widths, densities } = options;
const targetFormat = options.format ?? DEFAULT_OUTPUT_FORMAT;
let imageWidth = options.width;
let maxWidth = Infinity;
if (isESMImportedImage(options.src)) {
imageWidth = options.src.width;
maxWidth = imageWidth;
}
const {
width: transformWidth,
height: transformHeight,
...transformWithoutDimensions
} = options;
const allWidths = [];
if (densities) {
const densityValues = densities.map((density) => {
if (typeof density === "number") {
return density;
} else {
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`
}))
);
}
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,
descriptor,
attributes: {
type: `image/${targetFormat}`
}
});
}
return srcSet;
},
getURL(options, imageConfig) {
const searchParams = new URLSearchParams();
if (isESMImportedImage(options.src)) {
searchParams.append("href", options.src.src);
} else if (isRemoteAllowed(options.src, imageConfig)) {
searchParams.append("href", options.src);
} else {
return options.src;
}
const params = {
w: "width",
h: "height",
q: "quality",
f: "format"
};
Object.entries(params).forEach(([param, key]) => {
options[key] && searchParams.append(param, options[key].toString());
});
const imageEndpoint = joinPaths(import.meta.env.BASE_URL, "/_image");
return `${imageEndpoint}?${searchParams}`;
},
parseURL(url) {
const params = url.searchParams;
if (!params.has("href")) {
return void 0;
}
const transform = {
src: params.get("href"),
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")
};
return transform;
}
};
function getTargetDimensions(options) {
let targetWidth = options.width;
let targetHeight = options.height;
if (isESMImportedImage(options.src)) {
const aspectRatio = options.src.width / options.src.height;
if (targetHeight && !targetWidth) {
targetWidth = Math.round(targetHeight * aspectRatio);
} else if (targetWidth && !targetHeight) {
targetHeight = Math.round(targetWidth / aspectRatio);
} else if (!targetWidth && !targetHeight) {
targetWidth = options.src.width;
targetHeight = options.src.height;
}
}
return {
targetWidth,
targetHeight
};
}
export {
baseService,
isLocalService,
parseQuality
};

10
node_modules/astro/dist/assets/services/sharp.d.ts generated vendored Normal file
View File

@@ -0,0 +1,10 @@
import type { SharpOptions } from 'sharp';
import { type LocalImageService } from './service.js';
export interface SharpImageServiceConfig {
/**
* The `limitInputPixels` option passed to Sharp. See https://sharp.pixelplumbing.com/api-constructor for more information
*/
limitInputPixels?: SharpOptions['limitInputPixels'];
}
declare const sharpService: LocalImageService<SharpImageServiceConfig>;
export default sharpService;

66
node_modules/astro/dist/assets/services/sharp.js generated vendored Normal file
View File

@@ -0,0 +1,66 @@
import { AstroError, AstroErrorData } from "../../core/errors/index.js";
import {
baseService,
parseQuality
} from "./service.js";
let sharp;
const qualityTable = {
low: 25,
mid: 50,
high: 80,
max: 100
};
async function loadSharp() {
let sharpImport;
try {
sharpImport = (await import("sharp")).default;
} catch {
throw new AstroError(AstroErrorData.MissingSharp);
}
sharpImport.cache(false);
return sharpImport;
}
const sharpService = {
validateOptions: baseService.validateOptions,
getURL: baseService.getURL,
parseURL: baseService.parseURL,
getHTMLAttributes: baseService.getHTMLAttributes,
getSrcSet: baseService.getSrcSet,
async transform(inputBuffer, transformOptions, config) {
if (!sharp) sharp = await loadSharp();
const transform = transformOptions;
if (transform.format === "svg") return { data: inputBuffer, format: "svg" };
const result = sharp(inputBuffer, {
failOnError: false,
pages: -1,
limitInputPixels: config.service.config.limitInputPixels
});
result.rotate();
if (transform.height && !transform.width) {
result.resize({ height: Math.round(transform.height) });
} else if (transform.width) {
result.resize({ width: Math.round(transform.width) });
}
if (transform.format) {
let quality = void 0;
if (transform.quality) {
const parsedQuality = parseQuality(transform.quality);
if (typeof parsedQuality === "number") {
quality = parsedQuality;
} else {
quality = transform.quality in qualityTable ? qualityTable[transform.quality] : void 0;
}
}
result.toFormat(transform.format, { quality });
}
const { data, info } = await result.toBuffer({ resolveWithObject: true });
return {
data,
format: info.format
};
}
};
var sharp_default = sharpService;
export {
sharp_default as default
};

3
node_modules/astro/dist/assets/services/squoosh.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import { type LocalImageService } from './service.js';
declare const service: LocalImageService;
export default service;

90
node_modules/astro/dist/assets/services/squoosh.js generated vendored Normal file
View File

@@ -0,0 +1,90 @@
import { yellow } from "kleur/colors";
import { imageMetadata } from "../utils/metadata.js";
import {
baseService,
parseQuality
} from "./service.js";
import { processBuffer } from "./vendor/squoosh/image-pool.js";
console.warn(
yellow(
"The Squoosh image service is deprecated and will be removed in Astro 5.x. We suggest migrating to the default Sharp image service instead, as it is faster, more powerful and better maintained."
)
);
const baseQuality = { low: 25, mid: 50, high: 80, max: 100 };
const qualityTable = {
avif: {
// Squoosh's AVIF encoder has a bit of a weird behavior where `62` is technically the maximum, and anything over is overkill
max: 62,
high: 45,
mid: 35,
low: 20
},
jpeg: baseQuality,
jpg: baseQuality,
webp: baseQuality
// Squoosh's PNG encoder does not support a quality setting, so we can skip that here
};
async function getRotationForEXIF(inputBuffer, src) {
const meta = await imageMetadata(inputBuffer, src);
if (!meta) return void 0;
switch (meta.orientation) {
case 3:
case 4:
return { type: "rotate", numRotations: 2 };
case 5:
case 6:
return { type: "rotate", numRotations: 1 };
case 7:
case 8:
return { type: "rotate", numRotations: 3 };
case void 0:
default:
return void 0;
}
}
const service = {
validateOptions: baseService.validateOptions,
getURL: baseService.getURL,
parseURL: baseService.parseURL,
getHTMLAttributes: baseService.getHTMLAttributes,
getSrcSet: baseService.getSrcSet,
async transform(inputBuffer, transformOptions) {
const transform = transformOptions;
let format = transform.format;
if (format === "svg") return { data: inputBuffer, format: "svg" };
const operations = [];
const rotation = await getRotationForEXIF(inputBuffer, transform.src);
if (rotation) {
operations.push(rotation);
}
if (transform.height && !transform.width) {
operations.push({
type: "resize",
height: Math.round(transform.height)
});
} else if (transform.width) {
operations.push({
type: "resize",
width: Math.round(transform.width)
});
}
let quality = void 0;
if (transform.quality) {
const parsedQuality = parseQuality(transform.quality);
if (typeof parsedQuality === "number") {
quality = parsedQuality;
} else {
quality = transform.quality in qualityTable[format] ? qualityTable[format][transform.quality] : void 0;
}
}
const data = await processBuffer(inputBuffer, operations, format, quality);
return {
data: Buffer.from(data),
format
};
}
};
var squoosh_default = service;
export {
squoosh_default as default
};

View File

@@ -0,0 +1,11 @@
var AVIFTune = /* @__PURE__ */ ((AVIFTune2) => {
AVIFTune2[AVIFTune2["auto"] = 0] = "auto";
AVIFTune2[AVIFTune2["psnr"] = 1] = "psnr";
AVIFTune2[AVIFTune2["ssim"] = 2] = "ssim";
return AVIFTune2;
})(AVIFTune || {});
var avif_enc_d_default = moduleFactory;
export {
AVIFTune,
avif_enc_d_default as default
};

View File

@@ -0,0 +1,2 @@
declare var Module: (Module: any) => any;
export default Module;

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,2 @@
declare const _default: Buffer;
export default _default;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,2 @@
declare var Module: (Module: any) => any;
export default Module;

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,2 @@
declare const _default: Buffer;
export default _default;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,157 @@
interface DecodeModule extends EmscriptenWasm.Module {
decode: (data: Uint8Array) => ImageData;
}
export interface ResizeOptions {
width?: number;
height?: number;
method: 'triangle' | 'catrom' | 'mitchell' | 'lanczos3';
premultiply: boolean;
linearRGB: boolean;
}
export interface RotateOptions {
numRotations: number;
}
import type { MozJPEGModule as MozJPEGEncodeModule } from './mozjpeg/mozjpeg_enc.js';
import type { WebPModule as WebPEncodeModule } from './webp/webp_enc.js';
import type { AVIFModule as AVIFEncodeModule } from './avif/avif_enc.js';
import ImageData from './image_data.js';
export declare const preprocessors: {
readonly resize: {
readonly name: "Resize";
readonly description: "Resize the image before compressing";
readonly instantiate: () => Promise<(buffer: Uint8Array, input_width: number, input_height: number, { width, height, method, premultiply, linearRGB }: ResizeOptions) => ImageData>;
readonly defaultOptions: {
readonly method: "lanczos3";
readonly fitMethod: "stretch";
readonly premultiply: true;
readonly linearRGB: true;
};
};
readonly rotate: {
readonly name: "Rotate";
readonly description: "Rotate image";
readonly instantiate: () => Promise<(buffer: Uint8Array, width: number, height: number, { numRotations }: RotateOptions) => Promise<ImageData>>;
readonly defaultOptions: {
readonly numRotations: 0;
};
};
};
export declare const codecs: {
readonly mozjpeg: {
readonly name: "MozJPEG";
readonly extension: "jpg";
readonly detectors: readonly [RegExp];
readonly dec: () => Promise<DecodeModule>;
readonly enc: () => Promise<MozJPEGEncodeModule>;
readonly defaultEncoderOptions: {
readonly quality: 75;
readonly baseline: false;
readonly arithmetic: false;
readonly progressive: true;
readonly optimize_coding: true;
readonly smoothing: 0;
readonly color_space: 3;
readonly quant_table: 3;
readonly trellis_multipass: false;
readonly trellis_opt_zero: false;
readonly trellis_opt_table: false;
readonly trellis_loops: 1;
readonly auto_subsample: true;
readonly chroma_subsample: 2;
readonly separate_chroma_quality: false;
readonly chroma_quality: 75;
};
readonly autoOptimize: {
readonly option: "quality";
readonly min: 0;
readonly max: 100;
};
};
readonly webp: {
readonly name: "WebP";
readonly extension: "webp";
readonly detectors: readonly [RegExp];
readonly dec: () => Promise<DecodeModule>;
readonly enc: () => Promise<WebPEncodeModule>;
readonly defaultEncoderOptions: {
readonly quality: 75;
readonly target_size: 0;
readonly target_PSNR: 0;
readonly method: 4;
readonly sns_strength: 50;
readonly filter_strength: 60;
readonly filter_sharpness: 0;
readonly filter_type: 1;
readonly partitions: 0;
readonly segments: 4;
readonly pass: 1;
readonly show_compressed: 0;
readonly preprocessing: 0;
readonly autofilter: 0;
readonly partition_limit: 0;
readonly alpha_compression: 1;
readonly alpha_filtering: 1;
readonly alpha_quality: 100;
readonly lossless: 0;
readonly exact: 0;
readonly image_hint: 0;
readonly emulate_jpeg_size: 0;
readonly thread_level: 0;
readonly low_memory: 0;
readonly near_lossless: 100;
readonly use_delta_palette: 0;
readonly use_sharp_yuv: 0;
};
readonly autoOptimize: {
readonly option: "quality";
readonly min: 0;
readonly max: 100;
};
};
readonly avif: {
readonly name: "AVIF";
readonly extension: "avif";
readonly detectors: readonly [RegExp];
readonly dec: () => Promise<DecodeModule>;
readonly enc: () => Promise<AVIFEncodeModule>;
readonly defaultEncoderOptions: {
readonly cqLevel: 33;
readonly cqAlphaLevel: -1;
readonly denoiseLevel: 0;
readonly tileColsLog2: 0;
readonly tileRowsLog2: 0;
readonly speed: 6;
readonly subsample: 1;
readonly chromaDeltaQ: false;
readonly sharpness: 0;
readonly tune: 0;
};
readonly autoOptimize: {
readonly option: "cqLevel";
readonly min: 62;
readonly max: 0;
};
};
readonly oxipng: {
readonly name: "OxiPNG";
readonly extension: "png";
readonly detectors: readonly [RegExp];
readonly dec: () => Promise<{
decode: (buffer: Buffer | Uint8Array) => any;
}>;
readonly enc: () => Promise<{
encode: (buffer: Uint8ClampedArray | ArrayBuffer, width: number, height: number, opts: {
level: number;
}) => any;
}>;
readonly defaultEncoderOptions: {
readonly level: 2;
};
readonly autoOptimize: {
readonly option: "level";
readonly min: 6;
readonly max: 1;
};
};
};
export {};

View File

@@ -0,0 +1,287 @@
import { instantiateEmscriptenWasm } from "./emscripten-utils.js";
import mozDec from "./mozjpeg/mozjpeg_node_dec.js";
import mozDecWasm from "./mozjpeg/mozjpeg_node_dec.wasm.js";
import mozEnc from "./mozjpeg/mozjpeg_node_enc.js";
import mozEncWasm from "./mozjpeg/mozjpeg_node_enc.wasm.js";
import webpDec from "./webp/webp_node_dec.js";
import webpDecWasm from "./webp/webp_node_dec.wasm.js";
import webpEnc from "./webp/webp_node_enc.js";
import webpEncWasm from "./webp/webp_node_enc.wasm.js";
import avifDec from "./avif/avif_node_dec.js";
import avifDecWasm from "./avif/avif_node_dec.wasm.js";
import avifEnc from "./avif/avif_node_enc.js";
import avifEncWasm from "./avif/avif_node_enc.wasm.js";
import * as pngEncDec from "./png/squoosh_png.js";
import pngEncDecWasm from "./png/squoosh_png_bg.wasm.js";
const pngEncDecInit = () => pngEncDec.default(pngEncDecWasm);
import * as oxipng from "./png/squoosh_oxipng.js";
import oxipngWasm from "./png/squoosh_oxipng_bg.wasm.js";
const oxipngInit = () => oxipng.default(oxipngWasm);
import * as resize from "./resize/squoosh_resize.js";
import resizeWasm from "./resize/squoosh_resize_bg.wasm.js";
const resizeInit = () => resize.default(resizeWasm);
import rotateWasm from "./rotate/rotate.wasm.js";
import ImageData from "./image_data.js";
global.ImageData = ImageData;
function resizeNameToIndex(name) {
switch (name) {
case "triangle":
return 0;
case "catrom":
return 1;
case "mitchell":
return 2;
case "lanczos3":
return 3;
default:
throw Error(`Unknown resize algorithm "${name}"`);
}
}
function resizeWithAspect({
input_width,
input_height,
target_width,
target_height
}) {
if (!target_width && !target_height) {
throw Error("Need to specify at least width or height when resizing");
}
if (target_width && target_height) {
return { width: target_width, height: target_height };
}
if (!target_width) {
return {
width: Math.round(input_width / input_height * target_height),
height: target_height
};
}
return {
width: target_width,
height: Math.round(input_height / input_width * target_width)
};
}
const preprocessors = {
resize: {
name: "Resize",
description: "Resize the image before compressing",
instantiate: async () => {
await resizeInit();
return (buffer, input_width, input_height, { width, height, method, premultiply, linearRGB }) => {
;
({ width, height } = resizeWithAspect({
input_width,
input_height,
target_width: width,
target_height: height
}));
const imageData = new ImageData(
resize.resize(
buffer,
input_width,
input_height,
width,
height,
resizeNameToIndex(method),
premultiply,
linearRGB
),
width,
height
);
resize.cleanup();
return imageData;
};
},
defaultOptions: {
method: "lanczos3",
fitMethod: "stretch",
premultiply: true,
linearRGB: true
}
},
rotate: {
name: "Rotate",
description: "Rotate image",
instantiate: async () => {
return async (buffer, width, height, { numRotations }) => {
const degrees = numRotations * 90 % 360;
const sameDimensions = degrees === 0 || degrees === 180;
const size = width * height * 4;
const instance = (await WebAssembly.instantiate(rotateWasm)).instance;
const { memory } = instance.exports;
const additionalPagesNeeded = Math.ceil(
(size * 2 - memory.buffer.byteLength + 8) / (64 * 1024)
);
if (additionalPagesNeeded > 0) {
memory.grow(additionalPagesNeeded);
}
const view = new Uint8ClampedArray(memory.buffer);
view.set(buffer, 8);
instance.exports.rotate(width, height, degrees);
return new ImageData(
view.slice(size + 8, size * 2 + 8),
sameDimensions ? width : height,
sameDimensions ? height : width
);
};
},
defaultOptions: {
numRotations: 0
}
}
};
const codecs = {
mozjpeg: {
name: "MozJPEG",
extension: "jpg",
detectors: [/^\xFF\xD8\xFF/],
dec: () => instantiateEmscriptenWasm(mozDec, mozDecWasm),
enc: () => instantiateEmscriptenWasm(
mozEnc,
mozEncWasm
),
defaultEncoderOptions: {
quality: 75,
baseline: false,
arithmetic: false,
progressive: true,
optimize_coding: true,
smoothing: 0,
color_space: 3,
quant_table: 3,
trellis_multipass: false,
trellis_opt_zero: false,
trellis_opt_table: false,
trellis_loops: 1,
auto_subsample: true,
chroma_subsample: 2,
separate_chroma_quality: false,
chroma_quality: 75
},
autoOptimize: {
option: "quality",
min: 0,
max: 100
}
},
webp: {
name: "WebP",
extension: "webp",
detectors: [/^RIFF....WEBPVP8[LX ]/s],
dec: () => instantiateEmscriptenWasm(webpDec, webpDecWasm),
enc: () => instantiateEmscriptenWasm(
webpEnc,
webpEncWasm
),
defaultEncoderOptions: {
quality: 75,
target_size: 0,
target_PSNR: 0,
method: 4,
sns_strength: 50,
filter_strength: 60,
filter_sharpness: 0,
filter_type: 1,
partitions: 0,
segments: 4,
pass: 1,
show_compressed: 0,
preprocessing: 0,
autofilter: 0,
partition_limit: 0,
alpha_compression: 1,
alpha_filtering: 1,
alpha_quality: 100,
lossless: 0,
exact: 0,
image_hint: 0,
emulate_jpeg_size: 0,
thread_level: 0,
low_memory: 0,
near_lossless: 100,
use_delta_palette: 0,
use_sharp_yuv: 0
},
autoOptimize: {
option: "quality",
min: 0,
max: 100
}
},
avif: {
name: "AVIF",
extension: "avif",
// Disable eslint rule to not touch the original code
// eslint-disable-next-line no-control-regex, regexp/control-character-escape
detectors: [/^\x00\x00\x00 ftypavif\x00\x00\x00\x00/],
dec: () => instantiateEmscriptenWasm(avifDec, avifDecWasm),
enc: async () => {
return instantiateEmscriptenWasm(
avifEnc,
avifEncWasm
);
},
defaultEncoderOptions: {
cqLevel: 33,
cqAlphaLevel: -1,
denoiseLevel: 0,
tileColsLog2: 0,
tileRowsLog2: 0,
speed: 6,
subsample: 1,
chromaDeltaQ: false,
sharpness: 0,
tune: 0
},
autoOptimize: {
option: "cqLevel",
min: 62,
max: 0
}
},
oxipng: {
name: "OxiPNG",
extension: "png",
// Disable eslint rule to not touch the original code
// eslint-disable-next-line no-control-regex, regexp/control-character-escape
detectors: [/^\x89PNG\x0D\x0A\x1A\x0A/],
dec: async () => {
await pngEncDecInit();
return {
decode: (buffer) => {
const imageData = pngEncDec.decode(buffer);
pngEncDec.cleanup();
return imageData;
}
};
},
enc: async () => {
await pngEncDecInit();
await oxipngInit();
return {
encode: (buffer, width, height, opts) => {
const simplePng = pngEncDec.encode(
new Uint8Array(buffer),
width,
height
);
const imageData = oxipng.optimise(simplePng, opts.level, false);
oxipng.cleanup();
return imageData;
}
};
},
defaultEncoderOptions: {
level: 2
},
autoOptimize: {
option: "level",
min: 6,
max: 1
}
}
};
export {
codecs,
preprocessors
};

View File

@@ -0,0 +1,9 @@
export declare function pathify(path: string): string;
export declare function instantiateEmscriptenWasm<T extends EmscriptenWasm.Module>(factory: EmscriptenWasm.ModuleFactory<T>, bytes: Uint8Array): Promise<T>;
export declare function dirname(url: string): string;
/**
* On certain serverless hosts, our ESM bundle is transpiled to CJS before being run, which means
* import.meta.url is undefined, so we'll fall back to __filename in those cases
* We should be able to remove this once https://github.com/netlify/zip-it-and-ship-it/issues/750 is fixed
*/
export declare function getModuleURL(url: string | undefined): string;

View File

@@ -0,0 +1,31 @@
import { fileURLToPath, pathToFileURL } from "node:url";
function pathify(path) {
if (path.startsWith("file://")) {
path = fileURLToPath(path);
}
return path;
}
function instantiateEmscriptenWasm(factory, bytes) {
return factory({
// @ts-expect-error This is a valid Emscripten option, but the type definitions don't know about it
wasmBinary: bytes,
locateFile(file) {
return file;
}
});
}
function dirname(url) {
return url.substring(0, url.lastIndexOf("/"));
}
function getModuleURL(url) {
if (!url) {
return pathToFileURL(__filename).toString();
}
return url;
}
export {
dirname,
getModuleURL,
instantiateEmscriptenWasm,
pathify
};

View File

@@ -0,0 +1,3 @@
import type { ImageOutputFormat } from '../../../types.js';
import type { Operation } from './image.js';
export declare function processBuffer(buffer: Uint8Array, operations: Operation[], encoding: ImageOutputFormat, quality?: number): Promise<Uint8Array>;

View File

@@ -0,0 +1,97 @@
import { cpus } from "node:os";
import { fileURLToPath } from "node:url";
import { isMainThread } from "node:worker_threads";
import { getModuleURL } from "./emscripten-utils.js";
import * as impl from "./impl.js";
import execOnce from "./utils/execOnce.js";
import WorkerPool from "./utils/workerPool.js";
const getWorker = execOnce(() => {
return new WorkerPool(
// There will be at most 7 workers needed since each worker will take
// at least 1 operation type.
Math.max(1, Math.min(cpus().length - 1, 7)),
fileURLToPath(getModuleURL(import.meta.url))
);
});
function handleJob(params) {
switch (params.operation) {
case "decode":
return impl.decodeBuffer(params.buffer);
case "resize":
return impl.resize({
image: params.imageData,
width: params.width,
height: params.height
});
case "rotate":
return impl.rotate(params.imageData, params.numRotations);
case "encodeavif":
return impl.encodeAvif(params.imageData, { quality: params.quality });
case "encodejpeg":
return impl.encodeJpeg(params.imageData, { quality: params.quality });
case "encodepng":
return impl.encodePng(params.imageData);
case "encodewebp":
return impl.encodeWebp(params.imageData, { quality: params.quality });
default:
throw Error(`Invalid job "${params.operation}"`);
}
}
async function processBuffer(buffer, operations, encoding, quality) {
const worker = await getWorker();
let imageData = await worker.dispatchJob({
operation: "decode",
buffer
});
for (const operation of operations) {
if (operation.type === "rotate") {
imageData = await worker.dispatchJob({
operation: "rotate",
imageData,
numRotations: operation.numRotations
});
} else if (operation.type === "resize") {
imageData = await worker.dispatchJob({
operation: "resize",
imageData,
height: operation.height,
width: operation.width
});
}
}
switch (encoding) {
case "avif":
return await worker.dispatchJob({
operation: "encodeavif",
imageData,
quality
});
case "jpeg":
case "jpg":
return await worker.dispatchJob({
operation: "encodejpeg",
imageData,
quality
});
case "png":
return await worker.dispatchJob({
operation: "encodepng",
imageData
});
case "webp":
return await worker.dispatchJob({
operation: "encodewebp",
imageData,
quality
});
case "svg":
default:
throw Error(`Unsupported encoding format`);
}
}
if (!isMainThread) {
WorkerPool.useThisThreadAsWorker(handleJob);
}
export {
processBuffer
};

View File

@@ -0,0 +1,13 @@
import type { ImageOutputFormat } from '../../../types.js';
type RotateOperation = {
type: 'rotate';
numRotations: number;
};
type ResizeOperation = {
type: 'resize';
width?: number;
height?: number;
};
export type Operation = RotateOperation | ResizeOperation;
export declare function processBuffer(buffer: Buffer, operations: Operation[], encoding: ImageOutputFormat, quality?: number): Promise<Uint8Array>;
export {};

View File

@@ -0,0 +1,28 @@
import * as impl from "./impl.js";
async function processBuffer(buffer, operations, encoding, quality) {
let imageData = await impl.decodeBuffer(buffer);
for (const operation of operations) {
if (operation.type === "rotate") {
imageData = await impl.rotate(imageData, operation.numRotations);
} else if (operation.type === "resize") {
imageData = await impl.resize({ image: imageData, width: operation.width, height: operation.height });
}
}
switch (encoding) {
case "avif":
return await impl.encodeAvif(imageData, { quality });
case "jpeg":
case "jpg":
return await impl.encodeJpeg(imageData, { quality });
case "png":
return await impl.encodePng(imageData);
case "webp":
return await impl.encodeWebp(imageData, { quality });
case "svg":
default:
throw Error(`Unsupported encoding format`);
}
}
export {
processBuffer
};

View File

@@ -0,0 +1,8 @@
export default class ImageData {
static from(input: ImageData): ImageData;
private _data;
width: number;
height: number;
get data(): Buffer;
constructor(data: Buffer | Uint8Array | Uint8ClampedArray, width: number, height: number);
}

View File

@@ -0,0 +1,25 @@
class ImageData {
static from(input) {
return new ImageData(input.data || input._data, input.width, input.height);
}
_data;
width;
height;
get data() {
if (Object.prototype.toString.call(this._data) === "[object Object]") {
return Buffer.from(Object.values(this._data));
}
if (this._data instanceof Buffer || this._data instanceof Uint8Array || this._data instanceof Uint8ClampedArray) {
return Buffer.from(this._data);
}
throw new Error("invariant");
}
constructor(data, width, height) {
this._data = data;
this.width = width;
this.height = height;
}
}
export {
ImageData as default
};

View File

@@ -0,0 +1,21 @@
import ImageData from './image_data.js';
export declare function decodeBuffer(_buffer: Buffer | Uint8Array): Promise<ImageData>;
export declare function rotate(image: ImageData, numRotations: number): Promise<ImageData>;
type ResizeOpts = {
image: ImageData;
} & {
width?: number;
height?: number;
};
export declare function resize({ image, width, height }: ResizeOpts): Promise<ImageData>;
export declare function encodeJpeg(image: ImageData, opts: {
quality?: number;
}): Promise<Uint8Array>;
export declare function encodeWebp(image: ImageData, opts: {
quality?: number;
}): Promise<Uint8Array>;
export declare function encodeAvif(image: ImageData, opts: {
quality?: number;
}): Promise<Uint8Array>;
export declare function encodePng(image: ImageData): Promise<Uint8Array>;
export {};

View File

@@ -0,0 +1,111 @@
import { preprocessors, codecs as supportedFormats } from "./codecs.js";
import ImageData from "./image_data.js";
const DELAY_MS = 1e3;
let _promise;
function delayOnce(ms) {
if (!_promise) {
_promise = new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
return _promise;
}
function maybeDelay() {
const isAppleM1 = process.arch === "arm64" && process.platform === "darwin";
if (isAppleM1) {
return delayOnce(DELAY_MS);
}
return Promise.resolve();
}
async function decodeBuffer(_buffer) {
const buffer = Buffer.from(_buffer);
const firstChunk = buffer.slice(0, 16);
const firstChunkString = Array.from(firstChunk).map((v) => String.fromCodePoint(v)).join("");
if (firstChunkString.includes("GIF")) {
throw Error(`GIF images are not supported, please use the Sharp image service`);
}
const key = Object.entries(supportedFormats).find(
([, { detectors }]) => detectors.some((detector) => detector.exec(firstChunkString))
)?.[0];
if (!key) {
throw Error(`Buffer has an unsupported format`);
}
const encoder = supportedFormats[key];
const mod = await encoder.dec();
const rgba = mod.decode(new Uint8Array(buffer));
return rgba;
}
async function rotate(image, numRotations) {
image = ImageData.from(image);
const m = await preprocessors["rotate"].instantiate();
return await m(image.data, image.width, image.height, { numRotations });
}
async function resize({ image, width, height }) {
image = ImageData.from(image);
const p = preprocessors["resize"];
const m = await p.instantiate();
await maybeDelay();
return await m(image.data, image.width, image.height, {
...p.defaultOptions,
width,
height
});
}
async function encodeJpeg(image, opts) {
image = ImageData.from(image);
const e = supportedFormats["mozjpeg"];
const m = await e.enc();
await maybeDelay();
const quality = opts.quality || e.defaultEncoderOptions.quality;
const r = await m.encode(image.data, image.width, image.height, {
...e.defaultEncoderOptions,
quality
});
return r;
}
async function encodeWebp(image, opts) {
image = ImageData.from(image);
const e = supportedFormats["webp"];
const m = await e.enc();
await maybeDelay();
const quality = opts.quality || e.defaultEncoderOptions.quality;
const r = await m.encode(image.data, image.width, image.height, {
...e.defaultEncoderOptions,
quality
});
return r;
}
async function encodeAvif(image, opts) {
image = ImageData.from(image);
const e = supportedFormats["avif"];
const m = await e.enc();
await maybeDelay();
const val = e.autoOptimize.min;
const quality = opts.quality || 75;
const r = await m.encode(image.data, image.width, image.height, {
...e.defaultEncoderOptions,
// Think of cqLevel as the "amount" of quantization (0 to 62),
// so a lower value yields higher quality (0 to 100).
cqLevel: quality === 0 ? val : Math.round(val - quality / 100 * val)
});
return r;
}
async function encodePng(image) {
image = ImageData.from(image);
const e = supportedFormats["oxipng"];
const m = await e.enc();
await maybeDelay();
const r = await m.encode(image.data, image.width, image.height, {
...e.defaultEncoderOptions
});
return r;
}
export {
decodeBuffer,
encodeAvif,
encodeJpeg,
encodePng,
encodeWebp,
resize,
rotate
};

View File

@@ -0,0 +1,11 @@
var MozJpegColorSpace = /* @__PURE__ */ ((MozJpegColorSpace2) => {
MozJpegColorSpace2[MozJpegColorSpace2["GRAYSCALE"] = 1] = "GRAYSCALE";
MozJpegColorSpace2[MozJpegColorSpace2["RGB"] = 2] = "RGB";
MozJpegColorSpace2[MozJpegColorSpace2["YCbCr"] = 3] = "YCbCr";
return MozJpegColorSpace2;
})(MozJpegColorSpace || {});
var mozjpeg_enc_d_default = moduleFactory;
export {
MozJpegColorSpace,
mozjpeg_enc_d_default as default
};

View File

@@ -0,0 +1,2 @@
declare var Module: (Module: any) => any;
export default Module;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
declare const _default: Buffer;
export default _default;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,2 @@
declare var Module: (Module: any) => any;
export default Module;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
declare const _default: Buffer;
export default _default;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,10 @@
/**
* @param {Uint8Array} data
* @param {number} level
* @param {boolean} interlace
* @returns {Uint8Array}
*/
export declare function optimise(data: any, level: any, interlace: any): any;
declare function init(input: any): Promise<WebAssembly.Exports>;
export default init;
export declare function cleanup(): void;

View File

@@ -0,0 +1,89 @@
let wasm;
let cachedTextDecoder = new TextDecoder("utf-8", {
ignoreBOM: true,
fatal: true
});
cachedTextDecoder.decode();
let cachegetUint8Memory0 = null;
function getUint8Memory0() {
if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {
cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
}
return cachegetUint8Memory0;
}
function getStringFromWasm0(ptr, len) {
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
}
let WASM_VECTOR_LEN = 0;
function passArray8ToWasm0(arg, malloc) {
const ptr = malloc(arg.length * 1);
getUint8Memory0().set(arg, ptr / 1);
WASM_VECTOR_LEN = arg.length;
return ptr;
}
let cachegetInt32Memory0 = null;
function getInt32Memory0() {
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
}
return cachegetInt32Memory0;
}
function getArrayU8FromWasm0(ptr, len) {
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
}
function optimise(data, level, interlace) {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
const len0 = WASM_VECTOR_LEN;
wasm.optimise(retptr, ptr0, len0, level, interlace);
const r0 = getInt32Memory0()[retptr / 4 + 0];
const r1 = getInt32Memory0()[retptr / 4 + 1];
const v1 = getArrayU8FromWasm0(r0, r1).slice();
wasm.__wbindgen_free(r0, r1 * 1);
return v1;
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
}
}
async function load(module, imports) {
if (typeof Response === "function" && module instanceof Response) {
if (typeof WebAssembly.instantiateStreaming === "function") {
return await WebAssembly.instantiateStreaming(module, imports);
}
const bytes = await module.arrayBuffer();
return await WebAssembly.instantiate(bytes, imports);
} else {
const instance = await WebAssembly.instantiate(module, imports);
if (instance instanceof WebAssembly.Instance) {
return { instance, module };
} else {
return instance;
}
}
}
async function init(input) {
const imports = {};
imports.wbg = {};
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
throw new Error(getStringFromWasm0(arg0, arg1));
};
if (typeof input === "string" || typeof Request === "function" && input instanceof Request || typeof URL === "function" && input instanceof URL) {
input = fetch(input);
}
const { instance, module } = await load(await input, imports);
wasm = instance.exports;
init.__wbindgen_wasm_module = module;
return wasm;
}
var squoosh_oxipng_default = init;
function cleanup() {
wasm = null;
cachegetUint8Memory0 = null;
cachegetInt32Memory0 = null;
}
export {
cleanup,
squoosh_oxipng_default as default,
optimise
};

Binary file not shown.

View File

@@ -0,0 +1,2 @@
declare const _default: Buffer;
export default _default;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,15 @@
/**
* @param {Uint8Array} data
* @param {number} width
* @param {number} height
* @returns {Uint8Array}
*/
export declare function encode(data: any, width: any, height: any): any;
/**
* @param {Uint8Array} data
* @returns {ImageData}
*/
export declare function decode(data: any): any;
declare function init(input: any): Promise<WebAssembly.Exports>;
export default init;
export declare function cleanup(): void;

View File

@@ -0,0 +1,136 @@
let wasm;
let cachedTextDecoder = new TextDecoder("utf-8", {
ignoreBOM: true,
fatal: true
});
cachedTextDecoder.decode();
let cachegetUint8Memory0 = null;
function getUint8Memory0() {
if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {
cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
}
return cachegetUint8Memory0;
}
function getStringFromWasm0(ptr, len) {
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
}
let cachegetUint8ClampedMemory0 = null;
function getUint8ClampedMemory0() {
if (cachegetUint8ClampedMemory0 === null || cachegetUint8ClampedMemory0.buffer !== wasm.memory.buffer) {
cachegetUint8ClampedMemory0 = new Uint8ClampedArray(wasm.memory.buffer);
}
return cachegetUint8ClampedMemory0;
}
function getClampedArrayU8FromWasm0(ptr, len) {
return getUint8ClampedMemory0().subarray(ptr / 1, ptr / 1 + len);
}
const heap = new Array(32).fill(void 0);
heap.push(void 0, null, true, false);
let heap_next = heap.length;
function addHeapObject(obj) {
if (heap_next === heap.length) heap.push(heap.length + 1);
const idx = heap_next;
heap_next = heap[idx];
heap[idx] = obj;
return idx;
}
let WASM_VECTOR_LEN = 0;
function passArray8ToWasm0(arg, malloc) {
const ptr = malloc(arg.length * 1);
getUint8Memory0().set(arg, ptr / 1);
WASM_VECTOR_LEN = arg.length;
return ptr;
}
let cachegetInt32Memory0 = null;
function getInt32Memory0() {
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
}
return cachegetInt32Memory0;
}
function getArrayU8FromWasm0(ptr, len) {
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
}
function encode(data, width, height) {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
const len0 = WASM_VECTOR_LEN;
wasm.encode(retptr, ptr0, len0, width, height);
const r0 = getInt32Memory0()[retptr / 4 + 0];
const r1 = getInt32Memory0()[retptr / 4 + 1];
const v1 = getArrayU8FromWasm0(r0, r1).slice();
wasm.__wbindgen_free(r0, r1 * 1);
return v1;
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
}
}
function getObject(idx) {
return heap[idx];
}
function dropObject(idx) {
if (idx < 36) return;
heap[idx] = heap_next;
heap_next = idx;
}
function takeObject(idx) {
const ret = getObject(idx);
dropObject(idx);
return ret;
}
function decode(data) {
const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.decode(ptr0, len0);
return takeObject(ret);
}
async function load(module, imports) {
if (typeof Response === "function" && module instanceof Response) {
if (typeof WebAssembly.instantiateStreaming === "function") {
return await WebAssembly.instantiateStreaming(module, imports);
}
const bytes = await module.arrayBuffer();
return await WebAssembly.instantiate(bytes, imports);
} else {
const instance = await WebAssembly.instantiate(module, imports);
if (instance instanceof WebAssembly.Instance) {
return { instance, module };
} else {
return instance;
}
}
}
async function init(input) {
const imports = {};
imports.wbg = {};
imports.wbg.__wbg_newwithownedu8clampedarrayandsh_787b2db8ea6bfd62 = function(arg0, arg1, arg2, arg3) {
const v0 = getClampedArrayU8FromWasm0(arg0, arg1).slice();
wasm.__wbindgen_free(arg0, arg1 * 1);
const ret = new ImageData(v0, arg2 >>> 0, arg3 >>> 0);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
throw new Error(getStringFromWasm0(arg0, arg1));
};
if (typeof input === "string" || typeof Request === "function" && input instanceof Request || typeof URL === "function" && input instanceof URL) {
input = fetch(input);
}
const { instance, module } = await load(await input, imports);
wasm = instance.exports;
init.__wbindgen_wasm_module = module;
return wasm;
}
var squoosh_png_default = init;
function cleanup() {
wasm = null;
cachegetUint8ClampedMemory0 = null;
cachegetUint8Memory0 = null;
cachegetInt32Memory0 = null;
}
export {
cleanup,
decode,
squoosh_png_default as default,
encode
};

Binary file not shown.

View File

@@ -0,0 +1,2 @@
declare const _default: Buffer;
export default _default;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,15 @@
/**
* @param {Uint8Array} input_image
* @param {number} input_width
* @param {number} input_height
* @param {number} output_width
* @param {number} output_height
* @param {number} typ_idx
* @param {boolean} premultiply
* @param {boolean} color_space_conversion
* @returns {Uint8ClampedArray}
*/
export declare function resize(input_image: any, input_width: any, input_height: any, output_width: any, output_height: any, typ_idx: any, premultiply: any, color_space_conversion: any): any;
declare function init(input: any): Promise<WebAssembly.Exports>;
export default init;
export declare function cleanup(): void;

View File

@@ -0,0 +1,95 @@
let wasm;
let cachegetUint8Memory0 = null;
function getUint8Memory0() {
if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {
cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
}
return cachegetUint8Memory0;
}
let WASM_VECTOR_LEN = 0;
function passArray8ToWasm0(arg, malloc) {
const ptr = malloc(arg.length * 1);
getUint8Memory0().set(arg, ptr / 1);
WASM_VECTOR_LEN = arg.length;
return ptr;
}
let cachegetInt32Memory0 = null;
function getInt32Memory0() {
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
}
return cachegetInt32Memory0;
}
let cachegetUint8ClampedMemory0 = null;
function getUint8ClampedMemory0() {
if (cachegetUint8ClampedMemory0 === null || cachegetUint8ClampedMemory0.buffer !== wasm.memory.buffer) {
cachegetUint8ClampedMemory0 = new Uint8ClampedArray(wasm.memory.buffer);
}
return cachegetUint8ClampedMemory0;
}
function getClampedArrayU8FromWasm0(ptr, len) {
return getUint8ClampedMemory0().subarray(ptr / 1, ptr / 1 + len);
}
function resize(input_image, input_width, input_height, output_width, output_height, typ_idx, premultiply, color_space_conversion) {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passArray8ToWasm0(input_image, wasm.__wbindgen_malloc);
const len0 = WASM_VECTOR_LEN;
wasm.resize(
retptr,
ptr0,
len0,
input_width,
input_height,
output_width,
output_height,
typ_idx,
premultiply,
color_space_conversion
);
const r0 = getInt32Memory0()[retptr / 4 + 0];
const r1 = getInt32Memory0()[retptr / 4 + 1];
const v1 = getClampedArrayU8FromWasm0(r0, r1).slice();
wasm.__wbindgen_free(r0, r1 * 1);
return v1;
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
}
}
async function load(module, imports) {
if (typeof Response === "function" && module instanceof Response) {
if (typeof WebAssembly.instantiateStreaming === "function") {
return await WebAssembly.instantiateStreaming(module, imports);
}
const bytes = await module.arrayBuffer();
return await WebAssembly.instantiate(bytes, imports);
} else {
const instance = await WebAssembly.instantiate(module, imports);
if (instance instanceof WebAssembly.Instance) {
return { instance, module };
} else {
return instance;
}
}
}
async function init(input) {
const imports = {};
if (typeof input === "string" || typeof Request === "function" && input instanceof Request || typeof URL === "function" && input instanceof URL) {
input = fetch(input);
}
const { instance, module } = await load(await input, imports);
wasm = instance.exports;
init.__wbindgen_wasm_module = module;
return wasm;
}
var squoosh_resize_default = init;
function cleanup() {
wasm = null;
cachegetUint8Memory0 = null;
cachegetInt32Memory0 = null;
}
export {
cleanup,
squoosh_resize_default as default,
resize
};

View File

@@ -0,0 +1,2 @@
declare const _default: Buffer;
export default _default;

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -0,0 +1,2 @@
declare const _default: Buffer;
export default _default;

View File

@@ -0,0 +1,4 @@
var rotate_wasm_default = Buffer.from("AGFzbQEAAAABDAJgAn9/AGADf39/AAMGBQAAAAABBQMBABAGEQJ/AEGAgMAAC38AQYCAwAALBy4EBm1lbW9yeQIABnJvdGF0ZQAECl9fZGF0YV9lbmQDAAtfX2hlYXBfYmFzZQMBCpsJBUkBAX8gACABbCIAQf////8DcSICBEBBCCEBIABBAnRBCGohAANAIAAgASgCADYCACABQQRqIQEgAEEEaiEAIAJBf2oiAg0ACwsLzQMBFH8gAUECdCERIAAgAWwiDEECdEEEaiESA0ACQAJAAkACQCAEQQFxRQRAIAMgAU8NAiADQQFqIQgMAQsgA0EPaiICIANJIggNASACIAFJIgVFDQEgASADQRBqIAgbIAEgBRshCCACIQMLIAEgA0EQaiICIAIgAUsbIQ0gA0F/cyETIBIgA0ECdGshFEEAIQVBACEOA0ACQAJAIA5FBEAgBSAASQ0BQQEhBAwGCyAAIAVBEGogBUEPaiICIAVJIgcbIAAgAiAASRshBUEBIQQgByACIABPcg0FDAELIAUiAkEBaiEFC0EBIQ4gAyANTw0AIAAgAkEQaiIPIAAgD0kbQQJ0IAJBAnRrIRUgEyABIAJsaiEHIBQgASACQQFqbEECdGohCSADIQoDQCAAIApsIgYgAmoiBEEQaiAAIAZqIA8gAEkbIgYgBEkgDCAGSXINAyAEIAZHBEAgBEECdEEIaiELIBUhBiAHIRAgCSEEA0AgDCABIBBqIhBNDQUgBCALKAIANgIAIAQgEWohBCALQQRqIQsgBkF8aiIGDQALCyAHQX9qIQcgCUF8aiEJIA0gCkEBaiIKRw0ACwwACwALDwsACyAIIQMMAAsAC1MBAX8CQCAAIAFsQQJ0IgJBCGoiAEEIRg0AIAAgAmpBfGohAEEAIQEDQCABIAJGDQEgACABQQhqKAIANgIAIABBfGohACACIAFBBGoiAUcNAAsLC9oDARN/IABBf2ohEEEAIAFBAnRrIREgACABbCIMQQJ0QQhqIRIDQAJAAkACQAJAIARBAXFFBEAgAyABTw0CIANBAWohCQwBCyADQQ9qIgIgA0kiCQ0BIAIgAUkiBUUNASABIANBEGogCRsgASAFGyEJIAIhAwsgASADQRBqIgIgAiABSxshDSASIANBAnRqIRNBACEFQQAhBgNAAkACQCAGQQFxRQRAIAUgAEkNAUEBIQQMBgsgACAFQRBqIAVBD2oiAiAFSSIIGyAAIAIgAEkbIQVBASEEIAggAiAAT3INBQwBCyAFIgJBAWohBQtBASEGIAMgDU8NACAAIAJBEGoiDiAAIA5JG0ECdCACQQJ0ayEUIAMgASAAIAJrbGohCCATIAEgECACa2xBAnRqIQogAyELA0AgACALbCIHIAJqIgRBEGogACAHaiAOIABJGyIHIARJIAwgB0lyDQMgBCAHRwRAIARBAnRBCGohBiAUIQcgCCEPIAohBANAIAwgDyABayIPTQ0FIAQgBigCADYCACAEIBFqIQQgBkEEaiEGIAdBfGoiBw0ACwtBASEGIAhBAWohCCAKQQRqIQogDSALQQFqIgtHDQALDAALAAsPCwALIAkhAwwACwALUAACQAJAAkACQCACQbMBTARAIAJFDQIgAkHaAEcNASAAIAEQAQ8LIAJBtAFGDQIgAkGOAkYNAwsACyAAIAEQAA8LIAAgARACDwsgACABEAMLAE0JcHJvZHVjZXJzAghsYW5ndWFnZQEEUnVzdAAMcHJvY2Vzc2VkLWJ5AQVydXN0Yx0xLjQ3LjAgKDE4YmY2YjRmMCAyMDIwLTEwLTA3KQ==", "base64");
export {
rotate_wasm_default as default
};

View File

@@ -0,0 +1 @@
export default function execOnce<T extends (...args: any[]) => ReturnType<T>>(fn: T): T;

View File

@@ -0,0 +1,14 @@
function execOnce(fn) {
let used = false;
let result;
return (...args) => {
if (!used) {
used = true;
result = fn(...args);
}
return result;
};
}
export {
execOnce as default
};

View File

@@ -0,0 +1,21 @@
import { Worker } from 'worker_threads';
interface Job<I> {
msg: I;
resolve: (result: any) => void;
reject: (reason: any) => void;
}
export default class WorkerPool<I, O> {
numWorkers: number;
jobQueue: TransformStream<Job<I>, Job<I>>;
workerQueue: TransformStream<Worker, Worker>;
done: Promise<void>;
constructor(numWorkers: number, workerFile: string);
_readLoop(): Promise<void>;
_nextWorker(): Promise<Worker>;
_terminateAll(): Promise<void>;
join(): Promise<void>;
dispatchJob(msg: I): Promise<O>;
private jobPromise;
static useThisThreadAsWorker<I, O>(cb: (msg: I) => O): void;
}
export {};

View File

@@ -0,0 +1,99 @@
import { parentPort, Worker } from "worker_threads";
function uuid() {
return Array.from({ length: 16 }, () => Math.floor(Math.random() * 256).toString(16)).join("");
}
class WorkerPool {
numWorkers;
jobQueue;
workerQueue;
done;
constructor(numWorkers, workerFile) {
this.numWorkers = numWorkers;
this.jobQueue = new TransformStream();
this.workerQueue = new TransformStream();
const writer = this.workerQueue.writable.getWriter();
for (let i = 0; i < numWorkers; i++) {
writer.write(new Worker(workerFile));
}
writer.releaseLock();
this.done = this._readLoop();
}
async _readLoop() {
const reader = this.jobQueue.readable.getReader();
while (true) {
const { value, done } = await reader.read();
if (done) {
await this._terminateAll();
return;
}
if (!value) {
throw new Error("Reader did not return any value");
}
const { msg, resolve, reject } = value;
const worker = await this._nextWorker();
this.jobPromise(worker, msg).then((result) => resolve(result)).catch((reason) => reject(reason)).finally(() => {
const writer = this.workerQueue.writable.getWriter();
writer.write(worker);
writer.releaseLock();
});
}
}
async _nextWorker() {
const reader = this.workerQueue.readable.getReader();
const { value } = await reader.read();
reader.releaseLock();
if (!value) {
throw new Error("No worker left");
}
return value;
}
async _terminateAll() {
for (let n = 0; n < this.numWorkers; n++) {
const worker = await this._nextWorker();
worker.terminate();
}
this.workerQueue.writable.close();
}
async join() {
this.jobQueue.writable.getWriter().close();
await this.done;
}
dispatchJob(msg) {
return new Promise((resolve, reject) => {
const writer = this.jobQueue.writable.getWriter();
writer.write({ msg, resolve, reject });
writer.releaseLock();
});
}
jobPromise(worker, msg) {
return new Promise((resolve, reject) => {
const id = uuid();
worker.postMessage({ msg, id });
worker.on("message", function f({ error, result, id: rid }) {
if (rid !== id) {
return;
}
if (error) {
reject(error);
return;
}
worker.off("message", f);
resolve(result);
});
});
}
static useThisThreadAsWorker(cb) {
parentPort.on("message", async (data) => {
const { msg, id } = data;
try {
const result = await cb(msg);
parentPort.postMessage({ result, id });
} catch (e) {
parentPort.postMessage({ error: e.message, id });
}
});
}
}
export {
WorkerPool as default
};

View File

@@ -0,0 +1,4 @@
var webp_enc_d_default = moduleFactory;
export {
webp_enc_d_default as default
};

View File

@@ -0,0 +1,2 @@
declare var Module: (Module: any) => any;
export default Module;

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,2 @@
declare const _default: Buffer;
export default _default;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,2 @@
declare var Module: (Module: any) => any;
export default Module;

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,2 @@
declare const _default: Buffer;
export default _default;

File diff suppressed because one or more lines are too long

202
node_modules/astro/dist/assets/types.d.ts generated vendored Normal file
View File

@@ -0,0 +1,202 @@
import type { OmitPreservingIndexSignature, Simplify, WithRequired } from '../type-utils.js';
import type { VALID_INPUT_FORMATS, VALID_OUTPUT_FORMATS } from './consts.js';
import type { ImageService } from './services/service.js';
export type ImageQualityPreset = 'low' | 'mid' | 'high' | 'max' | (string & {});
export type ImageQuality = ImageQualityPreset | number;
export type ImageInputFormat = (typeof VALID_INPUT_FORMATS)[number];
export type ImageOutputFormat = (typeof VALID_OUTPUT_FORMATS)[number] | (string & {});
export type AssetsGlobalStaticImagesList = Map<string, {
originalSrcPath: string | undefined;
transforms: Map<string, {
finalPath: string;
transform: ImageTransform;
}>;
}>;
declare global {
var astroAsset: {
imageService?: ImageService;
addStaticImage?: ((options: ImageTransform, hashProperties: string[], fsPath: string | undefined) => string) | undefined;
staticImages?: AssetsGlobalStaticImagesList;
referencedImages?: Set<string>;
};
}
declare const isESMImport: unique symbol;
export type OmitBrand<T> = Omit<T, typeof isESMImport>;
/**
* Type returned by ESM imports of images
*/
export type ImageMetadata = {
src: string;
width: number;
height: number;
format: ImageInputFormat;
orientation?: number;
[isESMImport]?: true;
};
export declare function isImageMetadata(src: any): src is ImageMetadata;
/**
* A yet to be completed with an url `SrcSetValue`. Other hooks will only see a resolved value, where the URL of the image has been added.
*/
export type UnresolvedSrcSetValue = {
transform: ImageTransform;
descriptor?: string;
attributes?: Record<string, any>;
};
export type SrcSetValue = UnresolvedSrcSetValue & {
url: string;
};
/**
* A yet to be resolved image transform. Used by `getImage`
*/
export type UnresolvedImageTransform = Simplify<OmitPreservingIndexSignature<ImageTransform, 'src'> & {
src: ImageMetadata | string | Promise<{
default: ImageMetadata;
}>;
inferSize?: boolean;
}> & {
[isESMImport]?: never;
};
/**
* Options accepted by the image transformation service.
*/
export type ImageTransform = {
src: ImageMetadata | string;
width?: number | undefined;
widths?: number[] | undefined;
densities?: (number | `${number}x`)[] | undefined;
height?: number | undefined;
quality?: ImageQuality | undefined;
format?: ImageOutputFormat | undefined;
[key: string]: any;
};
export interface GetImageResult {
rawOptions: ImageTransform;
options: ImageTransform;
src: string;
srcSet: {
values: SrcSetValue[];
attribute: string;
};
attributes: Record<string, any>;
}
type ImageSharedProps<T> = T & {
/**
* Width of the image, the value of this property will be used to assign the `width` property on the final `img` element.
*
* This value will additionally be used to resize the image to the desired width, taking into account the original aspect ratio of the image.
*
* **Example**:
* ```astro
* <Image src={...} width={300} alt="..." />
* ```
* **Result**:
* ```html
* <img src="..." width="300" height="..." alt="..." />
* ```
*/
width?: number | `${number}`;
/**
* Height of the image, the value of this property will be used to assign the `height` property on the final `img` element.
*
* For local images, if `width` is not present, this value will additionally be used to resize the image to the desired height, taking into account the original aspect ratio of the image.
*
* **Example**:
* ```astro
* <Image src={...} height={300} alt="..." />
* ```
* **Result**:
* ```html
* <img src="..." height="300" width="..." alt="..." />
* ```
*/
height?: number | `${number}`;
/**
* Desired output format for the image. Defaults to `webp`.
*
* **Example**:
* ```astro
* <Image src={...} format="avif" alt="..." />
* ```
*/
format?: ImageOutputFormat;
/**
* Desired quality for the image. Value can either be a preset such as `low` or `high`, or a numeric value from 0 to 100.
*
* The perceptual quality of the output image is service-specific.
* For instance, a certain service might decide that `high` results in a very beautiful image, but another could choose for it to be at best passable.
*
* **Example**:
* ```astro
* <Image src={...} quality='high' alt="..." />
* <Image src={...} quality={300} alt="..." />
* ```
*/
quality?: ImageQuality;
} & ({
/**
* A list of widths to generate images for. The value of this property will be used to assign the `srcset` property on the final `img` element.
*
* This attribute is incompatible with `densities`.
*/
widths?: number[];
densities?: never;
} | {
/**
* A list of pixel densities to generate images for. The value of this property will be used to assign the `srcset` property on the final `img` element.
*
* This attribute is incompatible with `widths`.
*/
densities?: (number | `${number}x`)[];
widths?: never;
});
export type LocalImageProps<T> = ImageSharedProps<T> & {
/**
* A reference to a local image imported through an ESM import.
*
* **Example**:
* ```js
* import myImage from "../assets/my_image.png";
* ```
* And then refer to the image, like so:
* ```astro
* <Image src={myImage} alt="..."></Image>
* ```
*/
src: ImageMetadata | Promise<{
default: ImageMetadata;
}>;
};
export type RemoteImageProps<T> = (ImageSharedProps<T> & {
/**
* URL of a remote image. Can start with a protocol (ex: `https://`) or alternatively `/`, or `Astro.url`, for images in the `public` folder
*
* Remote images are not optimized, and require both `width` and `height` to be set.
*
* **Example**:
* ```
* <Image src="https://example.com/image.png" width={450} height={300} alt="..." />
* ```
*/
src: string;
/**
* When inferSize is true width and height are not required
*/
inferSize: true;
}) | (WithRequired<ImageSharedProps<T>, 'width' | 'height'> & {
/**
* URL of a remote image. Can start with a protocol (ex: `https://`) or alternatively `/`, or `Astro.url`, for images in the `public` folder
*
* Remote images are not optimized, and require both `width` and `height` to be set.
*
* **Example**:
* ```
* <Image src="https://example.com/image.png" width={450} height={300} alt="..." />
* ```
*/
src: string;
/**
* When inferSize is false or undefined width and height are required
*/
inferSize?: false | undefined;
});
export {};

7
node_modules/astro/dist/assets/types.js generated vendored Normal file
View File

@@ -0,0 +1,7 @@
const isESMImport = Symbol("#isESM");
function isImageMetadata(src) {
return src.fsPath && !("fsPath" in src);
}
export {
isImageMetadata
};

12
node_modules/astro/dist/assets/utils/etag.d.ts generated vendored Normal file
View File

@@ -0,0 +1,12 @@
/**
* 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;

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

@@ -0,0 +1,28 @@
const fnv1a52 = (str) => {
const len = str.length;
let i = 0, t0 = 0, v0 = 8997, t1 = 0, v1 = 33826, t2 = 0, v2 = 40164, t3 = 0, v3 = 52210;
while (i < len) {
v0 ^= str.charCodeAt(i++);
t0 = v0 * 435;
t1 = v1 * 435;
t2 = v2 * 435;
t3 = v3 * 435;
t2 += v0 << 8;
t3 += v1 << 8;
t1 += t0 >>> 16;
v0 = t0 & 65535;
t2 += t1 >>> 16;
v1 = t1 & 65535;
v3 = t3 + (t2 >>> 16) & 65535;
v2 = t2 & 65535;
}
return (v3 & 15) * 281474976710656 + v2 * 4294967296 + v1 * 65536 + (v0 ^ v3 >> 4);
};
const etag = (payload, weak = false) => {
const prefix = weak ? 'W/"' : '"';
return prefix + fnv1a52(payload).toString(36) + payload.length.toString(36) + '"';
};
export {
etag,
fnv1a52
};

View File

@@ -0,0 +1,2 @@
import type { AssetsPrefix } from '../../core/app/types.js';
export declare function getAssetsPrefix(fileExtension: string, assetsPrefix?: AssetsPrefix): string;

View File

@@ -0,0 +1,12 @@
function getAssetsPrefix(fileExtension, assetsPrefix) {
if (!assetsPrefix) return "";
if (typeof assetsPrefix === "string") return assetsPrefix;
const dotLessFileExtension = fileExtension.slice(1);
if (assetsPrefix[dotLessFileExtension]) {
return assetsPrefix[dotLessFileExtension];
}
return assetsPrefix.fallback;
}
export {
getAssetsPrefix
};

4
node_modules/astro/dist/assets/utils/imageKind.d.ts generated vendored Normal file
View File

@@ -0,0 +1,4 @@
import type { ImageMetadata, UnresolvedImageTransform } from '../types.js';
export declare function isESMImportedImage(src: ImageMetadata | string): src is ImageMetadata;
export declare function isRemoteImage(src: ImageMetadata | string): src is string;
export declare function resolveSrc(src: UnresolvedImageTransform['src']): Promise<string | ImageMetadata>;

14
node_modules/astro/dist/assets/utils/imageKind.js generated vendored Normal file
View File

@@ -0,0 +1,14 @@
function isESMImportedImage(src) {
return typeof src === "object";
}
function isRemoteImage(src) {
return typeof src === "string";
}
async function resolveSrc(src) {
return typeof src === "object" && "then" in src ? (await src).default ?? await src : src;
}
export {
isESMImportedImage,
isRemoteImage,
resolveSrc
};

Some files were not shown because too many files have changed in this diff Show More