Project Files
src / renderers / image-results.ts
/**
* Render the Fetch Images tool's per-image response records: pair each subject's scraped
* metadata with its download outcome, emitting a markdown image reference on success and a
* human-readable message on failure. Sits a layer above `downloadImages` — download, then render.
*/
import { filenameFromUrl } from "../fs"
import { escapeMarkdownText, escapeMarkdownUrl } from "../text"
import type { DownloadedImage } from "../images"
/**
* Per-image input accumulated before downloading: the source URL plus any alt/title metadata
* scraped from the containing page. Explicit URL arguments arrive with empty alt/title.
*/
export interface ImageSubject {
/** Absolute source URL of the image. */
src: string
/** Alternative text from the `<img>` `alt` attribute, or an empty string when unavailable. */
alt: string
/** Advisory text from the `<img>` `title` attribute, or an empty string when unavailable. */
title: string
}
/**
* Per-image record returned by the Fetch Images tool. Exactly one of `image` or `error` is
* present on each record: `image` for successful downloads, `error` for failures.
*/
export interface ImageResult {
/** Filename segment of the source URL, percent-decoded when possible. */
filename: string
/** Alternative text from the source page's `<img>` `alt` attribute, or an empty string. */
alt: string
/** Advisory text from the source page's `<img>` `title` attribute, or an empty string. */
title: string
/** Markdown image reference pointing at the downloaded local file, present on success. */
image?: string
/** Human-readable error message, present when the download failed. */
error?: string
}
/**
* Render per-image response records by pairing each subject with the parallel download outcome,
* building a markdown reference for successes and an error message for failures. The `batch`
* array is positionally aligned with `subjects`.
*
* @param subjects - Per-image subjects in the order they were submitted for download.
* @param batch - Parallel array of download outcomes, aligned to `subjects` by index.
* @returns One response record per subject, each carrying filename, alt, title, and either a
* markdown reference or an error message.
*/
export function renderImageResults(subjects: ImageSubject[], batch: DownloadedImage[]): ImageResult[] {
return subjects.map((subject, index) => {
const base = {
filename: filenameFromUrl(subject.src),
alt: subject.alt,
title: subject.title,
}
const result = batch[index]
if (result.ok) {
const altForMarkdown = subject.alt === "" ? `Image ${index + 1}` : subject.alt
return {
...base,
image: `})`,
}
}
return { ...base, error: `Failed to fetch image from ${result.url}` }
})
}