import { AstroError, AstroErrorData } from "../../core/errors/index.js"; import { joinPaths } from "../../core/path.js"; import { VALID_SUPPORTED_FORMATS } from "../consts.js"; import { isESMImportedImage } from "../internal.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 = { 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)) }); } if (!isESMImportedImage(options.src)) { if (options.src.startsWith("/@fs/")) { 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.src.format === "svg") { options.format = "svg"; } } if (!options.format) { options.format = "webp"; } return options; }, getHTMLAttributes(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; } } const { src, width, height, format, quality, ...attributes } = options; return { ...attributes, width: targetWidth, height: targetHeight, loading: attributes.loading ?? "lazy", decoding: attributes.decoding ?? "async" }; }, getURL(options) { if (!isESMImportedImage(options.src)) { return options.src; } const searchParams = new URLSearchParams(); searchParams.append("href", options.src.src); options.width && searchParams.append("w", options.width.toString()); options.height && searchParams.append("h", options.height.toString()); options.quality && searchParams.append("q", options.quality.toString()); options.format && searchParams.append("f", options.format); return joinPaths(import.meta.env.BASE_URL, "/_image?") + 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; } }; export { baseService, isLocalService, parseQuality };