From a7b051eff453b9d04e99ef8bb2c75b02424b7b08 Mon Sep 17 00:00:00 2001 From: creamhead Date: Sat, 13 Jun 2026 18:25:18 +0900 Subject: [PATCH] Fix TypeScript strict null errors from noUncheckedIndexedAccess Array index access returns T|undefined under noUncheckedIndexedAccess; use type assertions where RTM API guarantees non-empty arrays. Fix regex match group access (match[1..3]) the same way. Co-Authored-By: Claude Sonnet 4.6 --- main.js | 24 ++++++++++++------------ src/main.ts | 19 ++++++++++--------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/main.js b/main.js index bdca83c..2c24949 100644 --- a/main.js +++ b/main.js @@ -3,24 +3,24 @@ THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ -var Y=Object.defineProperty;var it=Object.getOwnPropertyDescriptor;var rt=Object.getOwnPropertyNames;var at=Object.prototype.hasOwnProperty;var ot=(E,h)=>{for(var n in h)Y(E,n,{get:h[n],enumerable:!0})},ct=(E,h,n,d)=>{if(h&&typeof h=="object"||typeof h=="function")for(let s of rt(h))!at.call(E,s)&&s!==n&&Y(E,s,{get:()=>h[s],enumerable:!(d=it(h,s))||d.enumerable});return E};var lt=E=>ct(Y({},"__esModule",{value:!0}),E);var ut={};ot(ut,{default:()=>X});module.exports=lt(ut);var m=require("obsidian");function M(E){function h(w,k){return w<>>32-k}function n(w,k){let A=w&1073741824,T=k&1073741824,F=w&2147483648,C=k&2147483648,b=(w&1073741823)+(k&1073741823);return A&T?b^2147483648^F^C:A|T?b&1073741824?b^3221225472^F^C:b^1073741824^F^C:b^F^C}function d(w,k,A){return w&k|~w&A}function s(w,k,A){return w&A|k&~A}function l(w,k,A){return w^k^A}function c(w,k,A){return k^(w|~A)}function u(w,k,A,T,F,C,b){return w=n(w,n(n(d(k,A,T),F),b)),n(h(w,C),k)}function p(w,k,A,T,F,C,b){return w=n(w,n(n(s(k,A,T),F),b)),n(h(w,C),k)}function f(w,k,A,T,F,C,b){return w=n(w,n(n(l(k,A,T),F),b)),n(h(w,C),k)}function g(w,k,A,T,F,C,b){return w=n(w,n(n(c(k,A,T),F),b)),n(h(w,C),k)}function y(w){let k,A=w.length,T=A+8,C=((T-T%64)/64+1)*16,b=Array(C-1),J=0,N=0;for(;N>>29,b}function x(w){let k="",A="",T,F;for(F=0;F<=3;F++)T=w>>>F*8&255,A="0"+T.toString(16),k=k+A.substr(A.length-2,2);return k}function S(w){w=w.replace(/\r\n/g,` -`);let k="";for(let A=0;A127&&T<2048?(k+=String.fromCharCode(T>>6|192),k+=String.fromCharCode(T&63|128)):(k+=String.fromCharCode(T>>12|224),k+=String.fromCharCode(T>>6&63|128),k+=String.fromCharCode(T&63|128))}return k}let o=Array(),i,B,D,R,P,e,t,a,r,L=7,_=12,$=17,I=22,v=5,O=9,W=14,j=20,V=4,K=11,U=16,H=23,G=6,q=10,Q=15,z=21;for(E=S(E),o=y(E),e=1732584193,t=4023233417,a=2562383102,r=271733878,i=0;i{this.checkAuth()&&await this.fetchAndProcessTasks("status:incomplete",!1,s=>{this.insertTasksToEditor(n,s)})}}),this.addCommand({id:"select-rtm-tasks",name:"Select and import tasks",editorCallback:async(n,d)=>{this.checkAuth()&&await this.fetchAndProcessTasks("status:incomplete",!0,s=>{this.insertTasksToEditor(n,s)})}}),this.addCommand({id:"import-rtm-tasks-custom",name:"Download tasks (Custom Filter)",editorCallback:async(n,d)=>{this.checkAuth()&&new tt(this.app,s=>{this.fetchAndProcessTasks(s,!0,l=>{this.insertTasksToEditor(n,l)})}).open()}}),this.addCommand({id:"create-note-from-rtm-task",name:"Create note from RTM task",callback:async()=>{this.checkAuth()&&await this.fetchAndProcessTasks("status:incomplete",!0,n=>{this.createNotesFromTasks(n)})}}),this.addCommand({id:"add-rtm-task",name:"Add cursor line to RTM",editorCallback:async(n,d)=>{this.checkAuth()&&await this.addTaskFromEditor(n,d)}}),this.addCommand({id:"complete-rtm-task",name:"Complete task at cursor",editorCallback:async(n,d)=>{this.checkAuth()&&await this.completeTaskInEditor(n)}})}checkAuth(){return!this.settings.apiKey||!this.settings.sharedSecret?(new m.Notice("Please set your API Key and Secret in settings."),!1):this.settings.authToken?!0:(new m.Notice("Please authenticate with RTM from settings."),!1)}async fetchListsMap(){var d;let n={};try{let s=await this.callRtmApi("rtm.lists.getList");if((d=s.rsp.lists)!=null&&d.list){let l=Array.isArray(s.rsp.lists.list)?s.rsp.lists.list:[s.rsp.lists.list];for(let c of l)c!=null&&c.id&&(c!=null&&c.name)&&(n[c.id]=c.name)}}catch(s){console.error("List fetch error:",s)}return n}async fetchAndProcessTasks(n,d,s){var l,c,u,p;new m.Notice("Fetching tasks...");try{let f=await this.fetchListsMap(),g=await this.callRtmApi("rtm.tasks.getList",{filter:n,notes:"1"});if(!((l=g.rsp.tasks)!=null&&l.list)){new m.Notice("No tasks found.");return}let y=[],x=Array.isArray(g.rsp.tasks.list)?g.rsp.tasks.list:[g.rsp.tasks.list];for(let S of x){if(!S.taskseries)continue;let o=Array.isArray(S.taskseries)?S.taskseries:[S.taskseries];for(let i of o){let B=i.name,D=Array.isArray(i.task)?i.task[0]:i.task,R=S.id;!R&&i.list_id&&(R=i.list_id),R||(R="MISSING");let P="";D.due&&D.due!==""&&(P=`\u{1F4C5} ${D.due.split("T")[0]}`);let e="";D.start&&D.start!==""&&(e=`\u{1F6EB} ${D.start.split("T")[0]}`);let t="";switch(D.priority){case"1":t="\u{1F53A}";break;case"2":t="\u{1F53C}";break;case"3":t="\u{1F53D}";break}let a=(c=f[R])!=null?c:"",r=[];(u=i.tags)!=null&&u.tag&&(Array.isArray(i.tags.tag)?i.tags.tag:[i.tags.tag]).forEach($=>r.push($));let L=[];(p=i.notes)!=null&&p.note&&(Array.isArray(i.notes.note)?i.notes.note:[i.notes.note]).forEach($=>{var v;let I=(v=$.$t)!=null?v:String($);I&&L.push(I)}),y.push({name:B,due:P,start:e,priority:t,listName:a,tags:r,notes:L,rtmId:{list:R,series:i.id,task:D.id},rawPriority:D.priority,rawDue:D.due})}}d?new Z(this.app,y,S=>{s(S)}).open():s(y)}catch(f){console.error(f),new m.Notice("Fetch error.")}}insertTasksToEditor(n,d){if(d.length===0){new m.Notice("No tasks selected.");return}let s="";for(let l of d){let c="";l.listName&&(c=` #${l.listName.replace(/[\s,.]+/g,"_")}`);let u=l.tags.map(y=>` #${y}`).join(""),p=`[\u{1F42E}](rtm:${l.rtmId.list}:${l.rtmId.series}:${l.rtmId.task})`,f=l.priority?` ${l.priority}`:"",g=l.due?` ${l.due}`:"";if(s+=`- [ ] ${p} ${l.name}${f}${g}${c}${u} -`,this.settings.importWithNotesAndLink){let y=`https://www.rememberthemilk.com/app/#all/${l.rtmId.task}`;s+=` - RTM Link: ${y} +var Y=Object.defineProperty;var it=Object.getOwnPropertyDescriptor;var rt=Object.getOwnPropertyNames;var at=Object.prototype.hasOwnProperty;var ot=(E,h)=>{for(var r in h)Y(E,r,{get:h[r],enumerable:!0})},ct=(E,h,r,d)=>{if(h&&typeof h=="object"||typeof h=="function")for(let e of rt(h))!at.call(E,e)&&e!==r&&Y(E,e,{get:()=>h[e],enumerable:!(d=it(h,e))||d.enumerable});return E};var lt=E=>ct(Y({},"__esModule",{value:!0}),E);var ut={};ot(ut,{default:()=>X});module.exports=lt(ut);var m=require("obsidian");function M(E){function h(w,k){return w<>>32-k}function r(w,k){let T=w&1073741824,A=k&1073741824,F=w&2147483648,C=k&2147483648,b=(w&1073741823)+(k&1073741823);return T&A?b^2147483648^F^C:T|A?b&1073741824?b^3221225472^F^C:b^1073741824^F^C:b^F^C}function d(w,k,T){return w&k|~w&T}function e(w,k,T){return w&T|k&~T}function l(w,k,T){return w^k^T}function c(w,k,T){return k^(w|~T)}function u(w,k,T,A,F,C,b){return w=r(w,r(r(d(k,T,A),F),b)),r(h(w,C),k)}function p(w,k,T,A,F,C,b){return w=r(w,r(r(e(k,T,A),F),b)),r(h(w,C),k)}function f(w,k,T,A,F,C,b){return w=r(w,r(r(l(k,T,A),F),b)),r(h(w,C),k)}function g(w,k,T,A,F,C,b){return w=r(w,r(r(c(k,T,A),F),b)),r(h(w,C),k)}function y(w){let k,T=w.length,A=T+8,C=((A-A%64)/64+1)*16,b=Array(C-1),J=0,N=0;for(;N>>29,b}function x(w){let k="",T="",A,F;for(F=0;F<=3;F++)A=w>>>F*8&255,T="0"+A.toString(16),k=k+T.substr(T.length-2,2);return k}function S(w){w=w.replace(/\r\n/g,` +`);let k="";for(let T=0;T127&&A<2048?(k+=String.fromCharCode(A>>6|192),k+=String.fromCharCode(A&63|128)):(k+=String.fromCharCode(A>>12|224),k+=String.fromCharCode(A>>6&63|128),k+=String.fromCharCode(A&63|128))}return k}let o=Array(),n,L,R,D,P,s,t,a,i,B=7,_=12,$=17,I=22,v=5,O=9,W=14,j=20,V=4,K=11,U=16,H=23,G=6,q=10,Q=15,z=21;for(E=S(E),o=y(E),s=1732584193,t=4023233417,a=2562383102,i=271733878,n=0;n{this.checkAuth()&&await this.fetchAndProcessTasks("status:incomplete",!1,e=>{this.insertTasksToEditor(r,e)})}}),this.addCommand({id:"select-rtm-tasks",name:"Select and import tasks",editorCallback:async(r,d)=>{this.checkAuth()&&await this.fetchAndProcessTasks("status:incomplete",!0,e=>{this.insertTasksToEditor(r,e)})}}),this.addCommand({id:"import-rtm-tasks-custom",name:"Download tasks (Custom Filter)",editorCallback:async(r,d)=>{this.checkAuth()&&new tt(this.app,e=>{this.fetchAndProcessTasks(e,!0,l=>{this.insertTasksToEditor(r,l)})}).open()}}),this.addCommand({id:"create-note-from-rtm-task",name:"Create note from RTM task",callback:async()=>{this.checkAuth()&&await this.fetchAndProcessTasks("status:incomplete",!0,r=>{this.createNotesFromTasks(r)})}}),this.addCommand({id:"add-rtm-task",name:"Add cursor line to RTM",editorCallback:async(r,d)=>{this.checkAuth()&&await this.addTaskFromEditor(r,d)}}),this.addCommand({id:"complete-rtm-task",name:"Complete task at cursor",editorCallback:async(r,d)=>{this.checkAuth()&&await this.completeTaskInEditor(r)}})}checkAuth(){return!this.settings.apiKey||!this.settings.sharedSecret?(new m.Notice("Please set your API Key and Secret in settings."),!1):this.settings.authToken?!0:(new m.Notice("Please authenticate with RTM from settings."),!1)}async fetchListsMap(){var d;let r={};try{let e=await this.callRtmApi("rtm.lists.getList");if((d=e.rsp.lists)!=null&&d.list){let l=Array.isArray(e.rsp.lists.list)?e.rsp.lists.list:[e.rsp.lists.list];for(let c of l)c!=null&&c.id&&(c!=null&&c.name)&&(r[c.id]=c.name)}}catch(e){console.error("List fetch error:",e)}return r}async fetchAndProcessTasks(r,d,e){var l,c,u,p;new m.Notice("Fetching tasks...");try{let f=await this.fetchListsMap(),g=await this.callRtmApi("rtm.tasks.getList",{filter:r,notes:"1"});if(!((l=g.rsp.tasks)!=null&&l.list)){new m.Notice("No tasks found.");return}let y=[],x=Array.isArray(g.rsp.tasks.list)?g.rsp.tasks.list:[g.rsp.tasks.list];for(let S of x){if(!S.taskseries)continue;let o=Array.isArray(S.taskseries)?S.taskseries:[S.taskseries];for(let n of o){let L=n.name,R=Array.isArray(n.task)?n.task[0]:n.task,D=S.id;!D&&n.list_id&&(D=n.list_id),D||(D="MISSING");let P="";R.due&&R.due!==""&&(P=`\u{1F4C5} ${R.due.split("T")[0]}`);let s="";R.start&&R.start!==""&&(s=`\u{1F6EB} ${R.start.split("T")[0]}`);let t="";switch(R.priority){case"1":t="\u{1F53A}";break;case"2":t="\u{1F53C}";break;case"3":t="\u{1F53D}";break}let a=(c=f[D])!=null?c:"",i=[];(u=n.tags)!=null&&u.tag&&(Array.isArray(n.tags.tag)?n.tags.tag:[n.tags.tag]).forEach($=>i.push($));let B=[];(p=n.notes)!=null&&p.note&&(Array.isArray(n.notes.note)?n.notes.note:[n.notes.note]).forEach($=>{var v;let I=(v=$.$t)!=null?v:String($);I&&B.push(I)}),y.push({name:L,due:P,start:s,priority:t,listName:a,tags:i,notes:B,rtmId:{list:D,series:n.id,task:R.id},rawPriority:R.priority,rawDue:R.due})}}d?new Z(this.app,y,S=>{e(S)}).open():e(y)}catch(f){console.error(f),new m.Notice("Fetch error.")}}insertTasksToEditor(r,d){if(d.length===0){new m.Notice("No tasks selected.");return}let e="";for(let l of d){let c="";l.listName&&(c=` #${l.listName.replace(/[\s,.]+/g,"_")}`);let u=l.tags.map(y=>` #${y}`).join(""),p=`[\u{1F42E}](rtm:${l.rtmId.list}:${l.rtmId.series}:${l.rtmId.task})`,f=l.priority?` ${l.priority}`:"",g=l.due?` ${l.due}`:"";if(e+=`- [ ] ${p} ${l.name}${f}${g}${c}${u} +`,this.settings.importWithNotesAndLink){let y=`https://www.rememberthemilk.com/app/#all/${l.rtmId.task}`;e+=` - RTM Link: ${y} `,l.notes&&l.notes.length>0&&l.notes.forEach(x=>{x.split(` -`).forEach(o=>{o.trim()!==""&&(s+=` - Note: ${o} -`)})})}}n.replaceSelection(s),new m.Notice(`${d.length} tasks inserted.`)}async createNotesFromTasks(n){if(n.length===0){new m.Notice("No tasks selected.");return}let d=0;for(let s of n){let l=s.name.replace(/[\\/:*?"<>|]/g,"-"),c=this.settings.noteCreationFolder.trim();c.endsWith("/")&&(c=c.slice(0,-1)),c.startsWith("/")&&(c=c.slice(1)),c&&await this.ensureFolderExists(c);let u=c?`${c}/${l}.md`:`${l}.md`;this.app.vault.getAbstractFileByPath(u)&&(u=c?`${c}/${l}-${Date.now()}.md`:`${l}-${Date.now()}.md`);let p=s.tags.map(y=>`#${y}`).join(" "),f=s.listName?`#${s.listName.replace(/[\s,.]+/g,"_")}`:"",g=`# ${s.name} +`).forEach(o=>{o.trim()!==""&&(e+=` - Note: ${o} +`)})})}}r.replaceSelection(e),new m.Notice(`${d.length} tasks inserted.`)}async createNotesFromTasks(r){if(r.length===0){new m.Notice("No tasks selected.");return}let d=0;for(let e of r){let l=e.name.replace(/[\\/:*?"<>|]/g,"-"),c=this.settings.noteCreationFolder.trim();c.endsWith("/")&&(c=c.slice(0,-1)),c.startsWith("/")&&(c=c.slice(1)),c&&await this.ensureFolderExists(c);let u=c?`${c}/${l}.md`:`${l}.md`;this.app.vault.getAbstractFileByPath(u)&&(u=c?`${c}/${l}-${Date.now()}.md`:`${l}-${Date.now()}.md`);let p=e.tags.map(y=>`#${y}`).join(" "),f=e.listName?`#${e.listName.replace(/[\s,.]+/g,"_")}`:"",g=`# ${e.name} -`;g+=`- **RTM Link**: [\u{1F42E} Open Task](rtm:${s.rtmId.list}:${s.rtmId.series}:${s.rtmId.task}) -`,s.due&&(g+=`- **Due**: ${s.due} -`),s.start&&(g+=`- **Start**: ${s.start} -`),s.priority&&(g+=`- **Priority**: ${s.priority} +`;g+=`- **RTM Link**: [\u{1F42E} Open Task](rtm:${e.rtmId.list}:${e.rtmId.series}:${e.rtmId.task}) +`,e.due&&(g+=`- **Due**: ${e.due} +`),e.start&&(g+=`- **Start**: ${e.start} +`),e.priority&&(g+=`- **Priority**: ${e.priority} `),(f||p)&&(g+=`- **Tags**: ${f} ${p} `),g+=` --- -`,s.notes.length>0?(g+=`## Notes +`,e.notes.length>0?(g+=`## Notes -`,s.notes.forEach(y=>{g+=`${y} +`,e.notes.forEach(y=>{g+=`${y} `})):g+=`(No notes in RTM) -`;try{await this.app.vault.create(u,g),d++}catch(y){console.error(`Failed to create file: ${u}`,y),new m.Notice(`Failed to create note for "${s.name}"`)}}new m.Notice(`${d} notes created.`)}async addTaskFromEditor(n,d){var p;let s=n.getCursor(),c=n.getLine(s.line).replace(/^[-*] \[[ x]\] /,"").replace(/^[-*] /,"").trim();if(!c){new m.Notice("Task name is empty.");return}new m.Notice(`Adding: ${c}`);let u=d.file?d.file.basename:"";try{let f=await this.getTimeline(),y=(p=(await this.callRtmApi("rtm.tasks.add",{timeline:f,name:c,parse:"1"})).rsp.tasks)==null?void 0:p.list,x=Array.isArray(y)?y[0]:y!=null?y:{id:"",taskseries:void 0},S=x.id,o=x.taskseries,i=Array.isArray(o)?o[0]:o!=null?o:{id:"",name:"",task:{id:"",due:"",start:"",priority:"",completed:""}},B=i.id,R=(Array.isArray(i.task)?i.task[0]:i.task).id;if(this.settings.defaultDueForNewTask==="today")try{await this.callRtmApi("rtm.tasks.setDueDate",{timeline:f,list_id:S,taskseries_id:B,task_id:R,due:"today",parse:"1"})}catch(t){console.error("Failed to set due date",t)}if(u)try{await this.callRtmApi("rtm.tasks.notes.add",{timeline:f,list_id:S,taskseries_id:B,task_id:R,note_title:"Obsidian Link",note_text:`From Obsidian Note: [[${u}]]`})}catch(t){console.error("Failed to add note to RTM task",t)}let e=`- [ ] ${`[\u{1F42E}](rtm:${S}:${B}:${R})`} ${c}`;n.setLine(s.line,e),new m.Notice("Added to RTM!")}catch(f){console.error("Add Task Error:",f),new m.Notice("Add error.")}}async completeTaskInEditor(n){let d=n.getCursor(),s=n.getLine(d.line),l=/\(rtm:([\w\d]+):([\w\d]+):([\w\d]+)\)/,c=s.match(l);if(!c){new m.Notice("Error: No RTM Link found.");return}let u=c[1],p=c[2],f=c[3];if(!u||u==="MISSING"){new m.Notice("Error: List ID invalid.");return}new m.Notice("Completing task...");try{let g=await this.getTimeline();await this.callRtmApi("rtm.tasks.complete",{timeline:g,list_id:u,taskseries_id:p,task_id:f});let y=s.replace("- [ ]","- [x]");n.setLine(d.line,y),new m.Notice("Task completed!")}catch(g){console.error("Completion Error:",g),new m.Notice("Completion error.")}}async getTimeline(){var d;if(this.timeline)return this.timeline;let n=await this.callRtmApi("rtm.timelines.create");return this.timeline=(d=n.rsp.timeline)!=null?d:"",this.timeline}async callRtmApi(n,d={}){var x;let s=this.settings.apiKey,l=this.settings.sharedSecret;if(!s||!l)throw new Error("API Key/Secret missing");let c={...d,method:n,api_key:s,format:"json",auth_token:this.settings.authToken},u=Object.keys(c).sort(),p=l;for(let S of u)p+=S+c[S];c.api_sig=M(p);let f=`${nt}?${new URLSearchParams(c).toString()}`,y=(await(0,m.requestUrl)({url:f})).json;if(y.rsp.stat!=="ok")throw console.error("API Error:",y),new Error(`API Error: ${(x=y.rsp.err)==null?void 0:x.msg}`);return y}async ensureFolderExists(n){if(!n)return;let d=n.split("/"),s="";for(let l of d)if(l&&(s=s===""?l:`${s}/${l}`,!this.app.vault.getAbstractFileByPath(s)))try{await this.app.vault.createFolder(s)}catch(c){console.error(`Failed to create folder: ${s}`,c)}}async loadSettings(){this.settings=Object.assign({},mt,await this.loadData())}async saveSettings(){await this.saveData(this.settings)}},Z=class extends m.Modal{constructor(h,n,d){super(h),this.tasks=n,this.selected=new Array(n.length).fill(!1),this.onSubmit=d}onOpen(){let{contentEl:h}=this;new m.Setting(h).setName(`Select Tasks (${this.tasks.length})`).setHeading();let n=h.createDiv({cls:"rtm-task-list"});this.tasks.forEach((c,u)=>{var y;let p=n.createDiv({cls:"rtm-task-item"}),f=p.createEl("input",{type:"checkbox"});f.checked=(y=this.selected[u])!=null?y:!1,f.onchange=x=>{this.selected[u]=x.target.checked};let g=p.createSpan({cls:"rtm-task-label"});g.createEl("b",{text:c.name}),c.listName&&g.createEl("small",{text:` [${c.listName}]`,cls:"rtm-task-list-name"}),c.due&&g.createEl("small",{text:` ${c.due}`,cls:"rtm-task-due"}),c.notes&&c.notes.length>0&&g.createEl("small",{text:" \u{1F4DD}"})});let d=h.createDiv({cls:"rtm-btn-row"}),s=d.createEl("button",{text:"Select All"});s.onclick=()=>{let c=this.selected.every(Boolean);this.selected.fill(!c),n.querySelectorAll('input[type="checkbox"]').forEach(p=>p.checked=!c),s.textContent=c?"Select All":"Deselect All"};let l=d.createEl("button",{text:"Process Selected"});l.className="mod-cta",l.onclick=()=>{let c=this.tasks.filter((u,p)=>this.selected[p]);this.onSubmit(c),this.close()}}onClose(){this.contentEl.empty()}},tt=class extends m.Modal{constructor(h,n){super(h),this.onSubmit=n}onOpen(){let{contentEl:h}=this;h.createEl("h3",{text:"Filter RTM Tasks"}),new m.Setting(h).setName("Search Query").setDesc("e.g. list:Inbox, due:today").addText(n=>n.setValue("status:incomplete").onChange(d=>{}).inputEl.addEventListener("keydown",d=>{d.key==="Enter"&&(this.onSubmit(n.getValue()),this.close())})),new m.Setting(h).addButton(n=>n.setButtonText("Search").setCta().onClick(()=>{let d=h.querySelector("input");d&&(this.onSubmit(d.value),this.close())}))}onClose(){this.contentEl.empty()}},et=class extends m.PluginSettingTab{constructor(h,n){super(h,n),this.plugin=n}display(){let{containerEl:h}=this;h.empty(),new m.Setting(h).setName("RTM Sync").setHeading(),h.createEl("p",{text:`Version: ${this.plugin.manifest.version} (Build: 6/13/2026, 6:23:04 PM)`,cls:"setting-item-description rtm-version-info"}),new m.Setting(h).setName("API Key").addText(s=>s.setValue(this.plugin.settings.apiKey).onChange(async l=>{this.plugin.settings.apiKey=l,await this.plugin.saveSettings()})),new m.Setting(h).setName("Shared Secret").addText(s=>s.setValue(this.plugin.settings.sharedSecret).onChange(async l=>{this.plugin.settings.sharedSecret=l,await this.plugin.saveSettings()}));let d=new m.Setting(h).setName("Auth");this.plugin.settings.authToken&&d.setDesc("\u2705 Authorized"),d.addButton(s=>s.setButtonText("Start Auth").onClick(async()=>await this.startAuthProcess())),new m.Setting(h).setName("Default Due Date").setDesc("Setting for new tasks created from editor").addDropdown(s=>s.addOption("none","No Due Date").addOption("today","Today").setValue(this.plugin.settings.defaultDueForNewTask).onChange(async l=>{this.plugin.settings.defaultDueForNewTask=l,await this.plugin.saveSettings()})),new m.Setting(h).setName("Note Creation Folder").setDesc("Folder to create notes from RTM tasks.").addDropdown(s=>{s.addOption("","/ (Vault Root)"),this.app.vault.getAllLoadedFiles().filter(c=>c instanceof m.TFolder).forEach(c=>{c.path!=="/"&&s.addOption(c.path,c.path)}),s.setValue(this.plugin.settings.noteCreationFolder),s.onChange(async c=>{this.plugin.settings.noteCreationFolder=c,await this.plugin.saveSettings()})}),new m.Setting(h).setName("Import with Notes and RTM Link").setDesc("When inserting tasks to the editor, also include RTM task notes and links as sub-items.").addToggle(s=>s.setValue(this.plugin.settings.importWithNotesAndLink).onChange(async l=>{this.plugin.settings.importWithNotesAndLink=l,await this.plugin.saveSettings()}))}async startAuthProcess(){var y;let h=this.plugin,n=h.settings.apiKey,d=h.settings.sharedSecret;if(!n||!d){new m.Notice("Enter keys first");return}let s={method:"rtm.auth.getFrob",api_key:n,format:"json"},l=d;Object.keys(s).sort().forEach(x=>l+=x+s[x]),s.api_sig=M(l);let u=(y=(await(0,m.requestUrl)({url:`${nt}?${new URLSearchParams(s).toString()}`})).json.rsp.frob)!=null?y:"",p={api_key:n,perms:"delete",frob:u},f=d;Object.keys(p).sort().forEach(x=>f+=x+p[x]);let g=M(f);window.open(`${dt}?api_key=${n}&perms=delete&frob=${u}&api_sig=${g}`),new st(this.app,u,h,()=>{this.display()}).open()}},st=class extends m.Modal{constructor(h,n,d,s){super(h),this.frob=n,this.plugin=d,this.onSuccess=s}onOpen(){let{contentEl:h}=this;new m.Setting(h).addButton(n=>n.setButtonText("Finish Auth").setCta().onClick(async()=>{let d=this.plugin.settings.apiKey,s=this.plugin.settings.sharedSecret,l={method:"rtm.auth.getToken",api_key:d,format:"json",frob:this.frob},c=s;Object.keys(l).sort().forEach(u=>c+=u+l[u]),l.api_sig=M(c);try{let p=(await(0,m.requestUrl)({url:`${nt}?${new URLSearchParams(l).toString()}`})).json;p.rsp.auth?(this.plugin.settings.authToken=p.rsp.auth.token,await this.plugin.saveSettings(),new m.Notice("Success!"),this.onSuccess(),this.close()):new m.Notice("Failed.")}catch(u){new m.Notice("Error.")}}))}onClose(){this.contentEl.empty()}}; +`;try{await this.app.vault.create(u,g),d++}catch(y){console.error(`Failed to create file: ${u}`,y),new m.Notice(`Failed to create note for "${e.name}"`)}}new m.Notice(`${d} notes created.`)}async addTaskFromEditor(r,d){var p;let e=r.getCursor(),c=r.getLine(e.line).replace(/^[-*] \[[ x]\] /,"").replace(/^[-*] /,"").trim();if(!c){new m.Notice("Task name is empty.");return}new m.Notice(`Adding: ${c}`);let u=d.file?d.file.basename:"";try{let f=await this.getTimeline(),y=(p=(await this.callRtmApi("rtm.tasks.add",{timeline:f,name:c,parse:"1"})).rsp.tasks)==null?void 0:p.list,x=Array.isArray(y)?y[0]:y,S=x.id,o=x.taskseries,n=Array.isArray(o)?o[0]:o,L=n.id,D=(Array.isArray(n.task)?n.task[0]:n.task).id;if(this.settings.defaultDueForNewTask==="today")try{await this.callRtmApi("rtm.tasks.setDueDate",{timeline:f,list_id:S,taskseries_id:L,task_id:D,due:"today",parse:"1"})}catch(t){console.error("Failed to set due date",t)}if(u)try{await this.callRtmApi("rtm.tasks.notes.add",{timeline:f,list_id:S,taskseries_id:L,task_id:D,note_title:"Obsidian Link",note_text:`From Obsidian Note: [[${u}]]`})}catch(t){console.error("Failed to add note to RTM task",t)}let s=`- [ ] ${`[\u{1F42E}](rtm:${S}:${L}:${D})`} ${c}`;r.setLine(e.line,s),new m.Notice("Added to RTM!")}catch(f){console.error("Add Task Error:",f),new m.Notice("Add error.")}}async completeTaskInEditor(r){let d=r.getCursor(),e=r.getLine(d.line),l=/\(rtm:([\w\d]+):([\w\d]+):([\w\d]+)\)/,c=e.match(l);if(!c){new m.Notice("Error: No RTM Link found.");return}let u=c[1],p=c[2],f=c[3];if(!u||u==="MISSING"){new m.Notice("Error: List ID invalid.");return}new m.Notice("Completing task...");try{let g=await this.getTimeline();await this.callRtmApi("rtm.tasks.complete",{timeline:g,list_id:u,taskseries_id:p,task_id:f});let y=e.replace("- [ ]","- [x]");r.setLine(d.line,y),new m.Notice("Task completed!")}catch(g){console.error("Completion Error:",g),new m.Notice("Completion error.")}}async getTimeline(){var e;if(this.timeline)return this.timeline;let d=(e=(await this.callRtmApi("rtm.timelines.create")).rsp.timeline)!=null?e:"";return this.timeline=d,d}async callRtmApi(r,d={}){var x;let e=this.settings.apiKey,l=this.settings.sharedSecret;if(!e||!l)throw new Error("API Key/Secret missing");let c={...d,method:r,api_key:e,format:"json",auth_token:this.settings.authToken},u=Object.keys(c).sort(),p=l;for(let S of u)p+=S+c[S];c.api_sig=M(p);let f=`${nt}?${new URLSearchParams(c).toString()}`,y=(await(0,m.requestUrl)({url:f})).json;if(y.rsp.stat!=="ok")throw console.error("API Error:",y),new Error(`API Error: ${(x=y.rsp.err)==null?void 0:x.msg}`);return y}async ensureFolderExists(r){if(!r)return;let d=r.split("/"),e="";for(let l of d)if(l&&(e=e===""?l:`${e}/${l}`,!this.app.vault.getAbstractFileByPath(e)))try{await this.app.vault.createFolder(e)}catch(c){console.error(`Failed to create folder: ${e}`,c)}}async loadSettings(){this.settings=Object.assign({},mt,await this.loadData())}async saveSettings(){await this.saveData(this.settings)}},Z=class extends m.Modal{constructor(h,r,d){super(h),this.tasks=r,this.selected=new Array(r.length).fill(!1),this.onSubmit=d}onOpen(){let{contentEl:h}=this;new m.Setting(h).setName(`Select Tasks (${this.tasks.length})`).setHeading();let r=h.createDiv({cls:"rtm-task-list"});this.tasks.forEach((c,u)=>{var y;let p=r.createDiv({cls:"rtm-task-item"}),f=p.createEl("input",{type:"checkbox"});f.checked=(y=this.selected[u])!=null?y:!1,f.onchange=x=>{this.selected[u]=x.target.checked};let g=p.createSpan({cls:"rtm-task-label"});g.createEl("b",{text:c.name}),c.listName&&g.createEl("small",{text:` [${c.listName}]`,cls:"rtm-task-list-name"}),c.due&&g.createEl("small",{text:` ${c.due}`,cls:"rtm-task-due"}),c.notes&&c.notes.length>0&&g.createEl("small",{text:" \u{1F4DD}"})});let d=h.createDiv({cls:"rtm-btn-row"}),e=d.createEl("button",{text:"Select All"});e.onclick=()=>{let c=this.selected.every(Boolean);this.selected.fill(!c),r.querySelectorAll('input[type="checkbox"]').forEach(p=>p.checked=!c),e.textContent=c?"Select All":"Deselect All"};let l=d.createEl("button",{text:"Process Selected"});l.className="mod-cta",l.onclick=()=>{let c=this.tasks.filter((u,p)=>this.selected[p]);this.onSubmit(c),this.close()}}onClose(){this.contentEl.empty()}},tt=class extends m.Modal{constructor(h,r){super(h),this.onSubmit=r}onOpen(){let{contentEl:h}=this;h.createEl("h3",{text:"Filter RTM Tasks"}),new m.Setting(h).setName("Search Query").setDesc("e.g. list:Inbox, due:today").addText(r=>r.setValue("status:incomplete").onChange(d=>{}).inputEl.addEventListener("keydown",d=>{d.key==="Enter"&&(this.onSubmit(r.getValue()),this.close())})),new m.Setting(h).addButton(r=>r.setButtonText("Search").setCta().onClick(()=>{let d=h.querySelector("input");d&&(this.onSubmit(d.value),this.close())}))}onClose(){this.contentEl.empty()}},et=class extends m.PluginSettingTab{constructor(h,r){super(h,r),this.plugin=r}display(){let{containerEl:h}=this;h.empty(),new m.Setting(h).setName("RTM Sync").setHeading(),h.createEl("p",{text:`Version: ${this.plugin.manifest.version} (Build: 6/13/2026, 6:25:17 PM)`,cls:"setting-item-description rtm-version-info"}),new m.Setting(h).setName("API Key").addText(e=>e.setValue(this.plugin.settings.apiKey).onChange(async l=>{this.plugin.settings.apiKey=l,await this.plugin.saveSettings()})),new m.Setting(h).setName("Shared Secret").addText(e=>e.setValue(this.plugin.settings.sharedSecret).onChange(async l=>{this.plugin.settings.sharedSecret=l,await this.plugin.saveSettings()}));let d=new m.Setting(h).setName("Auth");this.plugin.settings.authToken&&d.setDesc("\u2705 Authorized"),d.addButton(e=>e.setButtonText("Start Auth").onClick(async()=>await this.startAuthProcess())),new m.Setting(h).setName("Default Due Date").setDesc("Setting for new tasks created from editor").addDropdown(e=>e.addOption("none","No Due Date").addOption("today","Today").setValue(this.plugin.settings.defaultDueForNewTask).onChange(async l=>{this.plugin.settings.defaultDueForNewTask=l,await this.plugin.saveSettings()})),new m.Setting(h).setName("Note Creation Folder").setDesc("Folder to create notes from RTM tasks.").addDropdown(e=>{e.addOption("","/ (Vault Root)"),this.app.vault.getAllLoadedFiles().filter(c=>c instanceof m.TFolder).forEach(c=>{c.path!=="/"&&e.addOption(c.path,c.path)}),e.setValue(this.plugin.settings.noteCreationFolder),e.onChange(async c=>{this.plugin.settings.noteCreationFolder=c,await this.plugin.saveSettings()})}),new m.Setting(h).setName("Import with Notes and RTM Link").setDesc("When inserting tasks to the editor, also include RTM task notes and links as sub-items.").addToggle(e=>e.setValue(this.plugin.settings.importWithNotesAndLink).onChange(async l=>{this.plugin.settings.importWithNotesAndLink=l,await this.plugin.saveSettings()}))}async startAuthProcess(){var y;let h=this.plugin,r=h.settings.apiKey,d=h.settings.sharedSecret;if(!r||!d){new m.Notice("Enter keys first");return}let e={method:"rtm.auth.getFrob",api_key:r,format:"json"},l=d;Object.keys(e).sort().forEach(x=>l+=x+e[x]),e.api_sig=M(l);let u=(y=(await(0,m.requestUrl)({url:`${nt}?${new URLSearchParams(e).toString()}`})).json.rsp.frob)!=null?y:"",p={api_key:r,perms:"delete",frob:u},f=d;Object.keys(p).sort().forEach(x=>f+=x+p[x]);let g=M(f);window.open(`${dt}?api_key=${r}&perms=delete&frob=${u}&api_sig=${g}`),new st(this.app,u,h,()=>{this.display()}).open()}},st=class extends m.Modal{constructor(h,r,d,e){super(h),this.frob=r,this.plugin=d,this.onSuccess=e}onOpen(){let{contentEl:h}=this;new m.Setting(h).addButton(r=>r.setButtonText("Finish Auth").setCta().onClick(async()=>{let d=this.plugin.settings.apiKey,e=this.plugin.settings.sharedSecret,l={method:"rtm.auth.getToken",api_key:d,format:"json",frob:this.frob},c=e;Object.keys(l).sort().forEach(u=>c+=u+l[u]),l.api_sig=M(c);try{let p=(await(0,m.requestUrl)({url:`${nt}?${new URLSearchParams(l).toString()}`})).json;p.rsp.auth?(this.plugin.settings.authToken=p.rsp.auth.token,await this.plugin.saveSettings(),new m.Notice("Success!"),this.onSuccess(),this.close()):new m.Notice("Failed.")}catch(u){new m.Notice("Error.")}}))}onClose(){this.contentEl.empty()}}; diff --git a/src/main.ts b/src/main.ts index bbab07a..9553238 100644 --- a/src/main.ts +++ b/src/main.ts @@ -210,7 +210,7 @@ export default class RtmPlugin extends Plugin { for (const s of seriesArray) { const name = s.name; - const task: RtmTask = Array.isArray(s.task) ? s.task[0] : s.task; + const task: RtmTask = Array.isArray(s.task) ? s.task[0] as RtmTask : s.task; let realListId = list.id; if (!realListId && s.list_id) realListId = s.list_id; @@ -372,12 +372,12 @@ export default class RtmPlugin extends Plugin { const res = await this.callRtmApi('rtm.tasks.add', { timeline: timeline, name: taskName, parse: '1' }); const rawList = res.rsp.tasks?.list; - const list: RtmTaskList = Array.isArray(rawList) ? rawList[0] : (rawList ?? { id: '', taskseries: undefined }); + const list: RtmTaskList = (Array.isArray(rawList) ? rawList[0] : rawList) as RtmTaskList; const listId = list.id; const seriesRaw = list.taskseries; - const series: RtmTaskSeries = Array.isArray(seriesRaw) ? seriesRaw[0] : (seriesRaw ?? { id: '', name: '', task: { id: '', due: '', start: '', priority: '', completed: '' } }); + const series: RtmTaskSeries = (Array.isArray(seriesRaw) ? seriesRaw[0] : seriesRaw) as RtmTaskSeries; const taskSeriesId = series.id; - const taskObj: RtmTask = Array.isArray(series.task) ? series.task[0] : series.task; + const taskObj: RtmTask = (Array.isArray(series.task) ? series.task[0] : series.task) as RtmTask; const taskId = taskObj.id; // 現在の設定に従ってデフォルト期日を設定 @@ -428,9 +428,9 @@ export default class RtmPlugin extends Plugin { if (!match) { new Notice(`Error: No RTM Link found.`); return; } - const listId = match[1]; - const seriesId = match[2]; - const taskId = match[3]; + const listId = match[1] as string; + const seriesId = match[2] as string; + const taskId = match[3] as string; if (!listId || listId === 'MISSING') { new Notice('Error: List ID invalid.'); return; } @@ -452,8 +452,9 @@ export default class RtmPlugin extends Plugin { async getTimeline(): Promise { if (this.timeline) return this.timeline; const res = await this.callRtmApi('rtm.timelines.create'); - this.timeline = res.rsp.timeline ?? ''; - return this.timeline; + const tl = res.rsp.timeline ?? ''; + this.timeline = tl; + return tl; } async callRtmApi(method: string, params: Record = {}): Promise {