The product to resolve images for.
The resolved images in display order (thumbnail source, full-size source, and optional alt text), or an empty array when the product has no photos and no identifier to derive a structure from.
resolveProductImages({
images: [{ href: "full.jpg", type: "image" }, { href: "t.jpg", type: "thumbnail" }],
} as Product);
// => [{ thumbSrc: "t.jpg", fullSrc: "full.jpg" }]
resolveProductImages({ cas: "69-57-8" } as Product);
// => [{ thumbSrc: ".../structure/69-57-8/image", fullSrc: ".../structure/69-57-8/image?width=500&height=500" }]
resolveProductImages({ title: "x" } as Product);
// => []
export function resolveProductImages(product: Product): ResolvedProductImage[] {
const entries = (product.images ?? []).filter((image) => isPresent(image.href));
const { image: fulls = [], thumbnail: thumbs = [] } = Object.groupBy(
entries,
(image) => image.type,
);
// Cycle through the full-size images (or thumbnails when that's all there is),
// opening the full source on click. Pair each with a thumbnail by position,
// falling back to the default thumbnail, then to the source itself.
const sources = fulls.length > 0 ? fulls : thumbs;
if (sources.length > 0) {
return sources.map((image, index) => ({
thumbSrc: (thumbs[index] ?? thumbs[0] ?? image).href,
fullSrc: image.href,
altText: image.altText,
}));
}
// No photo: derive a 2D structure depiction from a chemical identifier.
const identifier = [product.cas, product.smiles, product.iupacName].find((id) => isPresent(id));
if (identifier === undefined) return [];
const encoded = encodeURIComponent(String(identifier));
const structureUrl = `${CACTUS_STRUCTURE_BASE}/${encoded}/image`;
return [{ thumbSrc: structureUrl, fullSrc: `${structureUrl}?width=500&height=500` }];
}
Resolves the images to display for a product, falling back from real photos to a single NCI CACTUS structure depiction built from the first available chemical identifier (CAS → SMILES → IUPAC name).