import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); /** * 아바타 이미지 저장 디렉터리 * @returns {string} */ export function getAvatarsDir() { const dir = process.env.AVATARS_PATH || path.join(__dirname, '..', '..', 'data', 'avatars'); if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } return dir; } /** * @param {number|string} userId * @returns {string} */ export function getAvatarFilePath(userId) { const filePath = path.join(getAvatarsDir(), `${userId}.png`); return fs.existsSync(filePath) ? filePath : null; } /** * @param {number|string} userId * @returns {string|null} */ export function getAvatarUrl(userId) { return getAvatarFilePath(userId) ? `/api/v1/auth/avatar/${userId}` : null; } /** * base64 data URL을 PNG로 저장 * @param {number|string} userId * @param {string} dataUrl * @returns {string|null} */ export function saveAvatarImage(userId, dataUrl) { if (!dataUrl || !dataUrl.startsWith('data:image')) { return null; } const base64 = dataUrl.replace(/^data:image\/\w+;base64,/, ''); if (!base64) { return null; } const fileName = `${userId}.png`; const filePath = path.join(getAvatarsDir(), fileName); fs.writeFileSync(filePath, Buffer.from(base64, 'base64')); return fs.existsSync(filePath) ? fileName : null; } /** * 아바타 이미지 삭제 * @param {number|string} userId * @returns {boolean} */ export function deleteAvatarImage(userId) { const filePath = path.join(getAvatarsDir(), `${userId}.png`); if (!fs.existsSync(filePath)) return false; try { fs.unlinkSync(filePath); return true; } catch (err) { console.warn(`[avatar] 삭제 실패: ${filePath}`, err); return false; } }