Files
triliumnext-korean-patch/updates/2026-09-05/work/trilium/build-phase4.mjs
T

50 lines
5.7 KiB
JavaScript

import fs from 'node:fs';import crypto from 'node:crypto';
const b='work/trilium',out=b+'/phase4';fs.mkdirSync(out,{recursive:true});
const data=JSON.parse(fs.readFileSync(b+'/phase4-inspect/data.json','utf8'));
const hash=s=>crypto.createHash('sha256').update(s).digest('hex');
const names={text:'텍스트',code:'코드',file:'파일',image:'이미지',search:'저장된 검색',book:'책',relationMap:'관계도',noteMap:'노트 지도',render:'렌더링 노트',mermaid:'Mermaid 도표',canvas:'캔버스',webView:'웹 보기',mindMap:'마인드맵',geoMap:'지리 지도',doc:'도움말',launcher:'실행 도구'};
const changes=data.notes.filter(n=>n.content).map(n=>{
let content=n.content;
if(n.noteId==='EW0u2LoAZTYv')content=content.replace('addRow(count.type,','addRow(('+JSON.stringify(names)+')[count.type] || count.type,');
if(n.noteId==='WJaFVVj6QO1J')content=content.replace('name: nc.type,','name: ('+JSON.stringify(names)+')[nc.type] || nc.type,');
if(n.noteId==='ga590IKu7zmy')content=content.replace("'DONE'","'완료'").replace("'TODO'","'할 일'");
if(content===n.content)throw Error('Unchanged '+n.noteId);
return {noteId:n.noteId,oldTitle:n.title,title:n.title,oldContentSha256:hash(n.content),content};
});
const aliases={weight:'체중',geolocation:'위치 좌표',readingEnd:'독서 종료일',readingStart:'독서 시작일',author:'저자',link:'링크',location:'장소',tag:'태그',todoDate:'예정일',doneDate:'완료일'};
const attributes=data.attributes.map(a=>({...a,oldValue:a.value,value:a.value.replace(/,alias=[^,]*/,'')+',alias='+aliases[a.name.slice(6)]}));
const prefixes={TODO:'할 일',DONE:'완료','28. 11. 2017':'2017년 11월 28일'};
const branches=data.branches.map(r=>({...r,oldPrefix:r.prefix,prefix:prefixes[r.prefix]}));
fs.writeFileSync(out+'/korean-phase4-pending.json',JSON.stringify({version:4,changes,attributes,branches},null,2));
const known={'런치바 템플릿':'실행 도구 템플릿','기본 추상 런처':'실행 도구 기본 템플릿','명령 런처':'명령 실행 도구','노트 런처':'노트 실행 도구','스크립트 런처':'스크립트 실행 도구','런치바':'실행 도구 모음','사용 가능한 런처':'사용 가능한 실행 도구','표시된 런처':'표시할 실행 도구','캘린더':'달력','최근 변경 내역':'최근 변경 사항','노트와 채팅':'노트와 대화','옵션':'설정','외관':'모양','MFA':'다중 인증','사용자 가이드':'사용자 안내서','사용자 숨김':'사용자 숨김 영역','Mobile Launch Bar':'모바일 실행 도구 모음'};
const server=JSON.parse(fs.readFileSync(b+'/server.ko.json','utf8'));
for(const [key,value]of Object.entries(server['hidden-subtree']))if(known[value])server['hidden-subtree'][key]=known[value];
fs.writeFileSync(out+'/server.json',JSON.stringify(server,null,2)+'\n');
let main=fs.readFileSync(b+'/phase3/main.cjs','utf8');const oldmain=main;
const replace=(from,to)=>{if(main.split(from).length!==2)throw Error('Patch point mismatch '+from);main=main.replace(from,to);};
replace('jg=`assets/v${CR.version}-ko-20260913-r3`','jg=`assets/v${CR.version}-ko-20260913-r4`');
replace('title:"Mobile Launch Bar"','title:"모바일 실행 도구 모음"');
replace('(r.restoreNames||n.noteId.startsWith("_help_"))&&n.title!==t.title','(r.restoreNames||n.noteId.startsWith("_help_")||('+JSON.stringify(known)+')[n.title]===t.title)&&n.title!==t.title');
replace('triliumApplyKoreanNotes()})','triliumApplyKoreanNotes();triliumApplyKoreanPhase4()})');
const hook=`
function triliumApplyKoreanPhase4(){
const fs=require('fs'),crypto=require('crypto'),file='/home/node/trilium-data/korean-phase4-pending.json';
if(!fs.existsSync(file))return;
const plan=JSON.parse(fs.readFileSync(file,'utf8'));
if(plan.version!==4)throw Error('Invalid Korean phase 4 migration');
const hash=s=>crypto.createHash('sha256').update(s).digest('hex');
de.transactional(()=>{
for(const c of plan.changes){const n=J.getNoteOrThrow(c.noteId);if(n.isDeleted||n.isProtected||n.title!==c.oldTitle||(n.getContent()!==c.content&&hash(n.getContent())!==c.oldContentSha256))throw Error('Note conflict '+c.noteId);}
for(const c of plan.attributes){const a=J.getAttributeOrThrow(c.attributeId);if(a.isDeleted||a.noteId!==c.noteId||a.name!==c.name||(a.value!==c.oldValue&&a.value!==c.value))throw Error('Attribute conflict '+c.attributeId);}
for(const c of plan.branches){const a=J.getBranchOrThrow(c.branchId);if(a.isDeleted||a.noteId!==c.noteId||(a.prefix!==c.oldPrefix&&a.prefix!==c.prefix))throw Error('Branch conflict '+c.branchId);}
for(const c of plan.changes){const n=J.getNoteOrThrow(c.noteId);if(n.getContent()===c.content)continue;const rev=new Mk({noteId:n.noteId,title:n.title,type:n.type,mime:n.mime,isProtected:n.isProtected,utcDateLastEdited:n.utcDateModified,utcDateCreated:kr.utcNowDateTime(),utcDateModified:kr.utcNowDateTime(),dateLastEdited:n.dateModified,dateCreated:kr.localNowDateTime()},true);rev.save();rev.setContent(n.getContent());n.setContent(c.content);}
for(const c of plan.attributes){const a=J.getAttributeOrThrow(c.attributeId);if(a.value!==c.value){a.value=c.value;a.save();}}
for(const c of plan.branches){const a=J.getBranchOrThrow(c.branchId);if(a.prefix!==c.prefix){a.prefix=c.prefix;a.save();}}
});
fs.renameSync(file,file+'.applied-'+Date.now());console.log('KOREAN_PHASE4 '+JSON.stringify({notes:plan.changes.length,attributes:plan.attributes.length,branches:plan.branches.length}));
}
`;
fs.writeFileSync(out+'/main.cjs',hook+main);
fs.writeFileSync(out+'/manifest.json',JSON.stringify({previousMainSha256:hash(oldmain),files:Object.fromEntries(['main.cjs','server.json','korean-phase4-pending.json'].map(n=>[n,hash(fs.readFileSync(out+'/'+n))]))},null,2));
console.log({notes:changes.length,attributes:attributes.length,branches:branches.length});