import fs from 'node:fs'; import path from 'node:path'; import crypto from 'node:crypto'; import { fileURLToPath } from 'node:url'; const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); const [oldRoot, nextRoot, output] = process.argv.slice(2); if (!oldRoot || !nextRoot || !output) throw new Error('사용법: node tools/translation-files.mjs 이전원본앱폴더 새원본앱폴더 새보고서JSON'); for (const dir of [oldRoot, nextRoot]) if (!fs.statSync(dir).isDirectory()) throw new Error(`앱 폴더가 아닙니다: ${dir}`); const digest = file => fs.existsSync(file) && fs.statSync(file).isFile() ? crypto.createHash('sha256').update(fs.readFileSync(file)).digest('hex') : null; const manifest = JSON.parse(fs.readFileSync(path.join(root, 'release/manifest.json'), 'utf8')); // 배포판의 수정 대상만 검사한다. 새로 추가된 전체 파일은 원본 소스의 Git 비교로 별도 확인해야 한다. const files = Object.keys(manifest.files).map(file => { const before = digest(path.join(oldRoot, file)), after = digest(path.join(nextRoot, file)); const status = !before ? (after ? 'new-upstream-path' : 'local-only') : !after ? 'removed-or-moved' : before === after ? 'upstream-unchanged' : 'upstream-changed'; return { file, status, previousSha256: before, nextSha256: after, koreanSha256: manifest.files[file].sha256 }; }); fs.writeFileSync(output, JSON.stringify({ baselineVersion: manifest.appVersion, warning: '같은 경로의 변경 여부만 확인합니다. 번역 패치 적용 가능 여부와 실행 호환성을 보장하지 않습니다.', files }, null, 2) + '\n', { flag: 'wx' }); console.log(`수정 대상 ${files.length}개 비교 완료`);