import { existsSync, readFileSync } from 'node:fs' import postgres from 'postgres' import { createPageCoverThumbnailForImageUrl, getExistingPageCoverThumbnailUrl, getPageCoverThumbnailUrl } from '../server/utils/post-thumbnail-image.js' /** * 로컬 실행용 환경 파일을 process.env에 반영한다. * @returns {void} */ const loadEnvironmentFile = () => { const candidates = [ process.env.ENV_FILE, '.env.development', '.env' ].filter(Boolean) const envFile = candidates.find((filePath) => existsSync(filePath)) if (!envFile) { return } const lines = readFileSync(envFile, 'utf8').split(/\r?\n/) for (const line of lines) { const trimmedLine = line.trim() if (!trimmedLine || trimmedLine.startsWith('#')) { continue } const separatorIndex = trimmedLine.indexOf('=') if (separatorIndex === -1) { continue } const key = trimmedLine.slice(0, separatorIndex).trim() const rawValue = trimmedLine.slice(separatorIndex + 1).trim() if (!key || process.env[key] !== undefined) { continue } process.env[key] = rawValue.replace(/^['"]|['"]$/g, '') } } /** * 홈 Pages 진열장 커버 이미지 목록을 조회한다. * @returns {Promise>} 페이지 커버 이미지 목록 */ const listPageCoverImages = async () => { loadEnvironmentFile() if (!process.env.DATABASE_URL) { throw new Error('DATABASE_URL 환경 변수가 필요합니다.') } const sql = postgres(process.env.DATABASE_URL, { max: 1, idle_timeout: 5, connect_timeout: 10 }) try { const rows = await sql` SELECT featured_image FROM pages WHERE featured_image IS NOT NULL AND is_listed = true ORDER BY listing_sort_order ASC, updated_at DESC ` return rows.map((row) => ({ featuredImage: row.featured_image })) } finally { await sql.end({ timeout: 5 }) } } const pages = await listPageCoverImages() const coverImageUrls = [...new Set(pages .map((page) => page.featuredImage) .filter((url) => getPageCoverThumbnailUrl(url)))] let createdCount = 0 let skippedCount = 0 for (const imageUrl of coverImageUrls) { if (getExistingPageCoverThumbnailUrl(imageUrl)) { skippedCount += 1 continue } const thumbnailUrl = await createPageCoverThumbnailForImageUrl(imageUrl) if (thumbnailUrl) { createdCount += 1 } else { skippedCount += 1 } } process.stdout.write(`페이지 커버 썸네일 생성 완료: 생성 ${createdCount}개, 건너뜀 ${skippedCount}개\n`)