blank project
This commit is contained in:
3
node_modules/astro/dist/assets/services/noop.d.ts
generated
vendored
Normal file
3
node_modules/astro/dist/assets/services/noop.d.ts
generated
vendored
Normal 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
15
node_modules/astro/dist/assets/services/noop.js
generated
vendored
Normal 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
|
||||
};
|
||||
103
node_modules/astro/dist/assets/services/service.d.ts
generated
vendored
Normal file
103
node_modules/astro/dist/assets/services/service.d.ts
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
import type { AstroConfig } from '../../types/public/config.js';
|
||||
import type { ImageFit, 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 which by default, is located 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>;
|
||||
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;
|
||||
fit?: ImageFit;
|
||||
position?: string;
|
||||
};
|
||||
/**
|
||||
* 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 {};
|
||||
231
node_modules/astro/dist/assets/services/service.js
generated
vendored
Normal file
231
node_modules/astro/dist/assets/services/service.js
generated
vendored
Normal file
@@ -0,0 +1,231 @@
|
||||
import { isRemoteAllowed } from "@astrojs/internal-helpers/remote";
|
||||
import { AstroError, AstroErrorData } from "../../core/errors/index.js";
|
||||
import { isRemotePath, joinPaths } from "../../core/path.js";
|
||||
import { DEFAULT_HASH_PROPS, DEFAULT_OUTPUT_FORMAT, VALID_SUPPORTED_FORMATS } from "../consts.js";
|
||||
import { isESMImportedImage, isRemoteImage } from "../utils/imageKind.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 sortNumeric = (a, b) => a - b;
|
||||
const baseService = {
|
||||
propertiesToHash: DEFAULT_HASH_PROPS,
|
||||
validateOptions(options) {
|
||||
if (!options.src || !isRemoteImage(options.src) && !isESMImportedImage(options.src)) {
|
||||
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);
|
||||
if (options.layout && options.width && options.height) {
|
||||
options.fit ??= "cover";
|
||||
delete options.layout;
|
||||
}
|
||||
if (options.fit === "none") {
|
||||
delete options.fit;
|
||||
}
|
||||
return options;
|
||||
},
|
||||
getHTMLAttributes(options) {
|
||||
const { targetWidth, targetHeight } = getTargetDimensions(options);
|
||||
const {
|
||||
src,
|
||||
width,
|
||||
height,
|
||||
format,
|
||||
quality,
|
||||
densities,
|
||||
widths,
|
||||
formats,
|
||||
layout,
|
||||
priority,
|
||||
fit,
|
||||
position,
|
||||
...attributes
|
||||
} = options;
|
||||
return {
|
||||
...attributes,
|
||||
width: targetWidth,
|
||||
height: targetHeight,
|
||||
loading: attributes.loading ?? "lazy",
|
||||
decoding: attributes.decoding ?? "async"
|
||||
};
|
||||
},
|
||||
getSrcSet(options) {
|
||||
const { targetWidth, targetHeight } = getTargetDimensions(options);
|
||||
const aspectRatio = targetWidth / targetHeight;
|
||||
const { widths, densities } = options;
|
||||
const targetFormat = options.format ?? DEFAULT_OUTPUT_FORMAT;
|
||||
let transformedWidths = (widths ?? []).sort(sortNumeric);
|
||||
let imageWidth = options.width;
|
||||
let maxWidth = Infinity;
|
||||
if (isESMImportedImage(options.src)) {
|
||||
imageWidth = options.src.width;
|
||||
maxWidth = imageWidth;
|
||||
if (transformedWidths.length > 0 && transformedWidths.at(-1) > maxWidth) {
|
||||
transformedWidths = transformedWidths.filter((width) => width <= maxWidth);
|
||||
transformedWidths.push(maxWidth);
|
||||
}
|
||||
}
|
||||
transformedWidths = Array.from(new Set(transformedWidths));
|
||||
const {
|
||||
width: transformWidth,
|
||||
height: transformHeight,
|
||||
...transformWithoutDimensions
|
||||
} = options;
|
||||
let allWidths = [];
|
||||
if (densities) {
|
||||
const densityValues = densities.map((density) => {
|
||||
if (typeof density === "number") {
|
||||
return density;
|
||||
} else {
|
||||
return parseFloat(density);
|
||||
}
|
||||
});
|
||||
const densityWidths = densityValues.sort(sortNumeric).map((density) => Math.round(targetWidth * density));
|
||||
allWidths = densityWidths.map((width, index) => ({
|
||||
width,
|
||||
descriptor: `${densityValues[index]}x`
|
||||
}));
|
||||
} else if (transformedWidths.length > 0) {
|
||||
allWidths = transformedWidths.map((width) => ({
|
||||
width,
|
||||
descriptor: `${width}w`
|
||||
}));
|
||||
}
|
||||
return allWidths.map(({ width, descriptor }) => {
|
||||
const height = Math.round(width / aspectRatio);
|
||||
const transform = { ...transformWithoutDimensions, width, height };
|
||||
return {
|
||||
transform,
|
||||
descriptor,
|
||||
attributes: {
|
||||
type: `image/${targetFormat}`
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
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",
|
||||
fit: "fit",
|
||||
position: "position"
|
||||
};
|
||||
Object.entries(params).forEach(([param, key]) => {
|
||||
options[key] && searchParams.append(param, options[key].toString());
|
||||
});
|
||||
const imageEndpoint = joinPaths(import.meta.env.BASE_URL, imageConfig.endpoint.route);
|
||||
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"),
|
||||
fit: params.get("fit"),
|
||||
position: params.get("position") ?? void 0
|
||||
};
|
||||
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
10
node_modules/astro/dist/assets/services/sharp.d.ts
generated
vendored
Normal 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;
|
||||
102
node_modules/astro/dist/assets/services/sharp.js
generated
vendored
Normal file
102
node_modules/astro/dist/assets/services/sharp.js
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
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 fitMap = {
|
||||
fill: "fill",
|
||||
contain: "inside",
|
||||
cover: "cover",
|
||||
none: "outside",
|
||||
"scale-down": "inside",
|
||||
outside: "outside",
|
||||
inside: "inside"
|
||||
};
|
||||
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();
|
||||
const withoutEnlargement = Boolean(transform.fit);
|
||||
if (transform.width && transform.height && transform.fit) {
|
||||
const fit = fitMap[transform.fit] ?? "inside";
|
||||
result.resize({
|
||||
width: Math.round(transform.width),
|
||||
height: Math.round(transform.height),
|
||||
fit,
|
||||
position: transform.position,
|
||||
withoutEnlargement
|
||||
});
|
||||
} else if (transform.height && !transform.width) {
|
||||
result.resize({
|
||||
height: Math.round(transform.height),
|
||||
withoutEnlargement
|
||||
});
|
||||
} else if (transform.width) {
|
||||
result.resize({
|
||||
width: Math.round(transform.width),
|
||||
withoutEnlargement
|
||||
});
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
const isGifInput = inputBuffer[0] === 71 && // 'G'
|
||||
inputBuffer[1] === 73 && // 'I'
|
||||
inputBuffer[2] === 70 && // 'F'
|
||||
inputBuffer[3] === 56 && // '8'
|
||||
(inputBuffer[4] === 57 || inputBuffer[4] === 55) && // '9' or '7'
|
||||
inputBuffer[5] === 97;
|
||||
if (transform.format === "webp" && isGifInput) {
|
||||
result.webp({ quality: typeof quality === "number" ? quality : void 0, loop: 0 });
|
||||
} else {
|
||||
result.toFormat(transform.format, { quality });
|
||||
}
|
||||
}
|
||||
const { data, info } = await result.toBuffer({ resolveWithObject: true });
|
||||
const needsCopy = "buffer" in data && data.buffer instanceof SharedArrayBuffer;
|
||||
return {
|
||||
data: needsCopy ? new Uint8Array(data) : data,
|
||||
format: info.format
|
||||
};
|
||||
}
|
||||
};
|
||||
var sharp_default = sharpService;
|
||||
export {
|
||||
sharp_default as default
|
||||
};
|
||||
Reference in New Issue
Block a user