'use strict'; const IMPORTED_FIELDS = ['title', 'altTitles', 'authors', 'status', 'year', 'tags', 'description']; const same = (a, b) => JSON.stringify(a) === JSON.stringify(b); const { normalizeWorkIdentity, sameWorkIdentity } = require('./work-identity'); // The effective fields remain at the top of manga.json. A snapshot of the last // imported values lets later imports refresh unchanged fields without replacing // values somebody edited in the library. Legacy files have no snapshot, so their // existing values are conservatively treated as intentional. function mergeImportedMetadata(prior, imported, fallbackTitle) { const previous = prior['x-metadata']?.imported || {}; const result = { ...prior }; for (const field of IMPORTED_FIELDS) { if (!Object.hasOwn(imported, field)) continue; if (result[field] === undefined || result[field] === null || result[field] === '' || (Object.hasOwn(previous, field) && same(result[field], previous[field]))) { result[field] = imported[field]; } } if (!result.title) result.title = fallbackTitle; const oldId = prior['x-anilist']?.id; const newId = imported['x-anilist']?.id; if (oldId != null && newId != null && String(oldId) !== String(newId)) { throw new Error(`AniList identity conflict: existing ${oldId}, imported ${newId}; review the manga match`); } if (imported['x-anilist']) result['x-anilist'] = { ...(prior['x-anilist'] || {}), ...imported['x-anilist'] }; const oldWorkIdentity = normalizeWorkIdentity(prior['x-work-identity']); const newWorkIdentity = normalizeWorkIdentity(imported['x-work-identity']); if (oldWorkIdentity && newWorkIdentity && !sameWorkIdentity(oldWorkIdentity, newWorkIdentity)) { throw new Error(`MangaCircus work identity conflict: existing ${oldWorkIdentity.kind} identity differs from imported ${newWorkIdentity.kind} identity`); } if (newWorkIdentity) result['x-work-identity'] = newWorkIdentity; const snapshot = { ...previous }; for (const field of IMPORTED_FIELDS) if (Object.hasOwn(imported, field)) snapshot[field] = imported[field]; if (Object.keys(snapshot).length) result['x-metadata'] = { ...(prior['x-metadata'] || {}), imported: snapshot }; return result; } module.exports = { mergeImportedMetadata, IMPORTED_FIELDS };