import fs from "node:fs"; import path from "node:path"; import { type WechatUploadAsset, detectImageFormatFromBuffer, } from "./wechat-image-processor.ts"; export type { WechatUploadAsset }; const MIME_TYPES_BY_EXT: Record = { ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".png": "image/png", ".gif": "image/gif", ".webp": "image/webp", ".bmp": "image/bmp", ".tiff": "image/tiff", ".tif": "image/tiff", ".svg": "image/svg+xml", ".ico": "image/x-icon", }; export async function loadUploadAsset( imagePath: string, baseDir?: string, ): Promise { let fileBuffer: Buffer; let filename: string; let contentType: string; let fileSize = 0; let fileExt = ""; if (imagePath.startsWith("http://") || imagePath.startsWith("https://")) { const response = await fetch(imagePath); if (!response.ok) { throw new Error(`Failed to download image: ${imagePath}`); } const buffer = await response.arrayBuffer(); if (buffer.byteLength === 0) { throw new Error(`Remote image is empty: ${imagePath}`); } fileBuffer = Buffer.from(buffer); fileSize = buffer.byteLength; const urlPath = imagePath.split("?")[0]!; filename = path.basename(urlPath) || "image.jpg"; fileExt = path.extname(filename).toLowerCase(); contentType = response.headers.get("content-type") || "image/jpeg"; } else { const resolvedPath = path.isAbsolute(imagePath) ? imagePath : path.resolve(baseDir || process.cwd(), imagePath); if (!fs.existsSync(resolvedPath)) { throw new Error(`Image not found: ${resolvedPath}`); } const stats = fs.statSync(resolvedPath); if (stats.size === 0) { throw new Error(`Local image is empty: ${resolvedPath}`); } fileSize = stats.size; fileBuffer = fs.readFileSync(resolvedPath); filename = path.basename(resolvedPath); fileExt = path.extname(filename).toLowerCase(); contentType = MIME_TYPES_BY_EXT[fileExt] || "image/jpeg"; } const detected = detectImageFormatFromBuffer(fileBuffer); if (detected && detected.contentType !== contentType) { console.error(`[wechat-api] Format mismatch: ${filename} declared as ${contentType}, actual ${detected.contentType}`); contentType = detected.contentType; fileExt = detected.fileExt; filename = `${path.basename(filename, path.extname(filename))}${detected.fileExt}`; } return { buffer: fileBuffer, filename, contentType, fileExt, fileSize, }; }