152 lines
3.9 KiB
JavaScript
152 lines
3.9 KiB
JavaScript
// @ts-check
|
|
import path from "node:path";
|
|
import objectHash from "object-hash";
|
|
|
|
import { store } from "../index.js";
|
|
import { getCachedBuffer } from "../utils/cache.js";
|
|
import { getSrcPath } from "../../api/utils/getSrcPath.js";
|
|
import { getAssetPath, getConfigOptions } from "../utils/shared.js";
|
|
import { sharp, supportedImageTypes } from "../../utils/runtimeChecks.js";
|
|
|
|
const { getLoadedImage, getTransformedImage } = await import("../utils/imagetools.js")
|
|
|
|
export default async function load(id) {
|
|
try {
|
|
var fileURL = new URL(`file://${id}`);
|
|
} catch (error) {
|
|
return null;
|
|
}
|
|
|
|
|
|
const { search, searchParams } = fileURL;
|
|
|
|
id = id.replace(search, "");
|
|
|
|
const ext = path.extname(id).slice(1);
|
|
|
|
if (!supportedImageTypes.includes(ext)) return null;
|
|
|
|
const { default: astroViteConfigs } = await import(
|
|
// @ts-ignore
|
|
"../../astroViteConfigs.js"
|
|
);
|
|
|
|
const { environment, projectBase, assetFileNames } = astroViteConfigs;
|
|
|
|
const src = await getSrcPath(id);
|
|
|
|
const rootRelativePosixSrc = path.posix.normalize(
|
|
path.relative("", src).split(path.sep).join(path.posix.sep)
|
|
);
|
|
|
|
const getHash = (width) =>
|
|
objectHash(
|
|
{ width, options, rootRelativePosixSrc },
|
|
// @ts-ignore
|
|
{ algorithm: "sha256" }
|
|
);
|
|
|
|
const base =
|
|
typeof arguments[1] === "string"
|
|
? arguments[1]
|
|
: path.basename(src, path.extname(src));
|
|
|
|
const config = Object.fromEntries(searchParams);
|
|
|
|
const { image: loadedImage, width: imageWidth } =
|
|
store.get(src) || store.set(src, await getLoadedImage(src, ext)).get(src);
|
|
|
|
const { type, widths, options, extension, raw, inline } = getConfigOptions(
|
|
config,
|
|
ext,
|
|
imageWidth
|
|
);
|
|
|
|
if (raw) {
|
|
const testConfig = { ...config }
|
|
delete testConfig.raw
|
|
delete testConfig.inline
|
|
delete testConfig.base64
|
|
|
|
if (Object.keys(testConfig).length > 0) {
|
|
throw new Error(
|
|
"If raw is set, no other options can be set except inline and base64"
|
|
);
|
|
}
|
|
}
|
|
|
|
if (inline) {
|
|
if (widths.length > 1) {
|
|
throw new Error(
|
|
`The base64 or inline parameter can't be used with multiple widths`
|
|
);
|
|
}
|
|
const [width] = widths
|
|
const hash = getHash(width)
|
|
if (store.has(hash)) {
|
|
return `export default "${store.get(hash)}"`;
|
|
} else {
|
|
const config = { width, ...options };
|
|
|
|
const { image, buffer } = raw
|
|
? {
|
|
image: sharp ? loadedImage : null,
|
|
buffer: !sharp ? loadedImage.data : null,
|
|
}
|
|
: await getTransformedImage({
|
|
src,
|
|
image: loadedImage,
|
|
config,
|
|
type,
|
|
});
|
|
const dataUri = `data:${type};base64,${(
|
|
buffer || (await getCachedBuffer(hash, image))
|
|
).toString("base64")}`
|
|
|
|
store.set(hash, dataUri)
|
|
return `export default "${dataUri}"`;
|
|
}
|
|
} else {
|
|
const sources = await Promise.all(
|
|
widths.map(async (width) => {
|
|
const hash = getHash(width)
|
|
const assetPath = getAssetPath(
|
|
base,
|
|
assetFileNames,
|
|
extension,
|
|
width,
|
|
hash
|
|
)
|
|
if (!store.has(assetPath)) {
|
|
const config = { width, ...options }
|
|
const { image, buffer } = raw
|
|
? {
|
|
image: sharp && loadedImage,
|
|
buffer: !sharp && loadedImage.data,
|
|
}
|
|
: await getTransformedImage({
|
|
src,
|
|
image: loadedImage,
|
|
config,
|
|
type,
|
|
});
|
|
|
|
const imageObject = { hash, type, image, buffer }
|
|
store.set(assetPath, imageObject)
|
|
}
|
|
const modulePath =
|
|
environment === "dev" ? assetPath : projectBase + assetPath
|
|
return { width, modulePath }
|
|
})
|
|
)
|
|
const srcset =
|
|
sources.length > 1
|
|
? sources
|
|
.map(({ width, modulePath }) => `${modulePath} ${width}w`)
|
|
.join(", ")
|
|
: sources[0].modulePath
|
|
|
|
return `export default "${srcset}"`
|
|
}
|
|
}
|