import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); /** * 미리보기 이미지 저장 디렉터리 * @returns {string} */ export function getPreviewsDir() { const dir = process.env.PREVIEWS_PATH || path.join(__dirname, '..', '..', 'data', 'previews'); if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } return dir; } /** * base64 data URL을 PNG 파일로 저장 * @param {string} shareCode * @param {string} dataUrl * @returns {string} 파일명 */ export function savePreviewImage(shareCode, dataUrl) { if (!dataUrl || !dataUrl.startsWith('data:image')) { return null; } const base64 = dataUrl.replace(/^data:image\/\w+;base64,/, ''); const fileName = `${shareCode}.png`; fs.writeFileSync(path.join(getPreviewsDir(), fileName), Buffer.from(base64, 'base64')); return fileName; } /** * @param {string} shareCode * @returns {string|null} */ export function getPreviewFilePath(shareCode) { const filePath = path.join(getPreviewsDir(), `${shareCode}.png`); return fs.existsSync(filePath) ? filePath : null; } /** * @param {string} shareCode * @param {string|null} [previewImageRecord] DB preview_image 컬럼 * @returns {string|null} */ export function getPreviewUrl(shareCode, previewImageRecord = null) { const hasFile = Boolean(getPreviewFilePath(shareCode)); if (hasFile || previewImageRecord) { return `/api/v1/decks/${shareCode}/preview`; } return null; }