import { readFile, mkdir, stat, writeFile } from 'node:fs/promises' import { basename, dirname, join } from 'node:path' import type { Payload } from 'payload' const CACHE_PATH = '.import-cache/media.json' type Cache = Record async function loadCache(): Promise { try { const raw = await readFile(CACHE_PATH, 'utf8') return JSON.parse(raw) } catch { return {} } } async function saveCache(cache: Cache) { await mkdir(dirname(CACHE_PATH), { recursive: true }) await writeFile(CACHE_PATH, JSON.stringify(cache, null, 2)) } export async function uploadImage( payload: Payload, publicImagePath: string, // e.g. /images/foo.png sourceRoot: string, alt: string, cache: Cache, ): Promise { if (cache[publicImagePath]) return cache[publicImagePath] const filePath = join(sourceRoot, 'public', publicImagePath) try { await stat(filePath) } catch { console.warn(`[image] missing ${filePath}`) return undefined } const data = await readFile(filePath) const filename = basename(filePath) const created = await payload.create({ collection: 'media', data: { alt }, file: { data, mimetype: mimeFor(filename), name: filename, size: data.byteLength }, }) cache[publicImagePath] = created.id return created.id } export async function loadImageCache() { return loadCache() } export async function persistImageCache(cache: Cache) { await saveCache(cache) } function mimeFor(name: string) { const ext = name.toLowerCase().split('.').pop() || '' return ( { png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg', webp: 'image/webp', gif: 'image/gif', svg: 'image/svg+xml', } as Record )[ext] ?? 'application/octet-stream' }