diff --git a/bin/ticktick.js b/bin/ticktick.js index 6041cb8..661a476 100755 --- a/bin/ticktick.js +++ b/bin/ticktick.js @@ -199,6 +199,7 @@ async function handleTasks() { process.exit(1); } return await tasks.update(args.positional[0], { + projectId: args.options.project, title: args.options.title, content: args.options.content, dueDate: args.options.due, diff --git a/lib/tasks.js b/lib/tasks.js index 18d4900..054c3c1 100644 --- a/lib/tasks.js +++ b/lib/tasks.js @@ -131,7 +131,8 @@ export async function update(taskId, options = {}, deps = {}) { parseReminder = coreFunctions.parseReminder, parsePriority = coreFunctions.parsePriority, } = deps; - const resolvedTaskId = await resolveTaskId(taskId, null, deps); + const projectId = options.projectId || null; + const resolvedTaskId = await resolveTaskId(taskId, projectId, deps); const input = { id: resolvedTaskId }; if (options.title) input.title = options.title; @@ -145,9 +146,10 @@ export async function update(taskId, options = {}, deps = {}) { } const task = await apiRequest('POST', `/task/${encodeURIComponent(resolvedTaskId)}`, input, deps); + // API returns 204 No Content on success, re-fetch if we need details return { success: true, - task: { + task: task ? { id: shortId(task.id), fullId: task.id, projectId: shortId(task.projectId), @@ -155,6 +157,10 @@ export async function update(taskId, options = {}, deps = {}) { dueDate: task.dueDate, priority: formatPriority(task.priority), tags: task.tags || [], + } : { + id: shortId(resolvedTaskId), + fullId: resolvedTaskId, + title: input.title || '(updated)', }, }; } @@ -466,7 +472,7 @@ async function resolveTaskId(taskId, projectId = null, deps = {}) { // Search within specific project try { const data = await apiRequest('GET', `/project/${encodeURIComponent(projectId)}/data`, undefined, deps); - const match = data.tasks.find((t) => t.id.startsWith(taskId)); + const match = (data && data.tasks || []).find((t) => t && t.id && t.id.startsWith(taskId)); if (match) { return match.id; } @@ -478,10 +484,10 @@ async function resolveTaskId(taskId, projectId = null, deps = {}) { // Search all projects const projects = await apiRequest('GET', '/project', undefined, deps); - for (const project of projects) { + for (const project of (projects || [])) { try { const data = await apiRequest('GET', `/project/${encodeURIComponent(project.id)}/data`, undefined, deps); - const match = data.tasks.find((t) => t.id.startsWith(taskId)); + const match = (data && data.tasks || []).find((t) => t && t.id && t.id.startsWith(taskId)); if (match) { return match.id; } diff --git a/test/tasks.test.js b/test/tasks.test.js index b5da8b7..a508b8b 100644 --- a/test/tasks.test.js +++ b/test/tasks.test.js @@ -500,7 +500,7 @@ describe('tasks.due', () => { return {}; }); - const result = await tasks.due(7, makeDeps(mockApiRequest)); + const result = await tasks.due(7, {}, makeDeps(mockApiRequest)); assert.equal(result.days, 7); // Should include tomorrow and next week, but not next month, no due date, or completed @@ -528,7 +528,7 @@ describe('tasks.due', () => { return {}; }); - const result = await tasks.due(7, makeDeps(mockApiRequest)); + const result = await tasks.due(7, {}, makeDeps(mockApiRequest)); assert.equal(result.tasks[0].title, 'Day 1'); assert.equal(result.tasks[1].title, 'Day 2'); @@ -543,7 +543,7 @@ describe('tasks.due', () => { return {}; }); - const result = await tasks.due(undefined, makeDeps(mockApiRequest)); + const result = await tasks.due(undefined, {}, makeDeps(mockApiRequest)); assert.equal(result.days, 7); }); @@ -567,7 +567,7 @@ describe('tasks.due', () => { return {}; }); - const result = await tasks.due(7, makeDeps(mockApiRequest)); + const result = await tasks.due(7, {}, makeDeps(mockApiRequest)); // Overdue tasks should be included - they're the most urgent assert.equal(result.count, 2);