import { pathToFileURL } from 'url'; import path from 'path'; /** * @typedef {object} CardIndex * @property {Map} byNumber * @property {Map} byImgSrc */ /** @type {Map} */ const cache = new Map(); /** * 시리즈 카드 인덱스 로드 * @param {string} seriesKey * @returns {Promise} */ export async function getCardMap(seriesKey) { if (cache.has(seriesKey)) { return cache.get(seriesKey); } const datasPath = process.env.DATAS_PATH || path.join(process.cwd(), '..', 'datas'); const filePath = path.join(datasPath, `${seriesKey}.js`); let mod; try { mod = await import(pathToFileURL(filePath).href); } catch { throw new Error(`시리즈 데이터를 찾을 수 없습니다: ${seriesKey}`); } const byNumber = new Map(); const byImgSrc = new Map(); for (const card of mod.cardList) { if (!byNumber.has(card.Number)) { byNumber.set(card.Number, card); } if (card.imgSrc && !byImgSrc.has(card.imgSrc)) { byImgSrc.set(card.imgSrc, card); } } const index = { byNumber, byImgSrc }; cache.set(seriesKey, index); return index; } /** * 저장된 덱 카드를 풀 카드 객체로 합성 * @param {string} seriesKey * @param {Array<{number?: string, imgSrc?: string, count: number, key: boolean}>} cards * @returns {Promise<{cards: object[], totalCards: number}>} */ export async function resolveDeckCards(seriesKey, cards) { const index = await getCardMap(seriesKey); const resolved = []; let totalCards = 0; for (const item of cards) { const base = (item.imgSrc && index.byImgSrc.get(item.imgSrc)) || index.byNumber.get(item.number); if (!base) continue; totalCards += item.count; resolved.push({ number: base.Number, count: item.count, key: item.key, imgSrc: base.imgSrc, color: base.color, rarity: base.rarity, trigger: base.trigger ?? null, parallel: Boolean(base.parallel), }); } return { cards: resolved, totalCards }; }