const fs = require('fs'); const path = require('path'); const IMAGE_EXTENSIONS = new Set(['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.tif', '.webp', '.heic', '.heif']); function listImages(folderPath) { return fs.readdirSync(folderPath) .filter(fileName => IMAGE_EXTENSIONS.has(path.extname(fileName).toLowerCase())) .map(fileName => { const fullPath = path.join(folderPath, fileName); const stat = fs.statSync(fullPath); return { name: fileName, path: fullPath, mtime: stat.mtimeMs }; }) .sort((a, b) => a.name.localeCompare(b.name, 'ko')); } function readImageAsDataUrl(filePath) { const data = fs.readFileSync(filePath); const mime = getImageMime(path.extname(filePath)); return `data:image/${mime};base64,${data.toString('base64')}`; } function getImageMime(extName) { const ext = extName.toLowerCase().replace('.', ''); if (ext === 'jpg' || ext === 'jpeg') return 'jpeg'; if (ext === 'png') return 'png'; if (ext === 'gif') return 'gif'; if (ext === 'webp') return 'webp'; if (ext === 'tiff' || ext === 'tif') return 'tiff'; if (ext === 'bmp') return 'bmp'; if (ext === 'heic' || ext === 'heif') return 'heic'; return 'jpeg'; } function fileExists(filePath) { try { fs.accessSync(filePath); return true; } catch { return false; } } function moveFileWithCopyFallback(src, dest) { try { fs.renameSync(src, dest); } catch (e) { if (e.code !== 'EXDEV') throw e; fs.copyFileSync(src, dest); fs.unlinkSync(src); } } module.exports = { fileExists, listImages, moveFileWithCopyFallback, readImageAsDataUrl, };