@beauraines/rtm-api 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +285 -0
  3. package/config.js +22 -0
  4. package/docs/RTMClient.html +2798 -0
  5. package/docs/RTMError.html +1029 -0
  6. package/docs/RTMList.html +966 -0
  7. package/docs/RTMResponse.html +868 -0
  8. package/docs/RTMSuccess.html +337 -0
  9. package/docs/RTMTask.html +2461 -0
  10. package/docs/RTMUser.html +6761 -0
  11. package/docs/client_auth.js.html +123 -0
  12. package/docs/client_index.js.html +241 -0
  13. package/docs/client_user.js.html +170 -0
  14. package/docs/global.html +386 -0
  15. package/docs/index.html +305 -0
  16. package/docs/list_index.js.html +159 -0
  17. package/docs/response_error.js.html +172 -0
  18. package/docs/response_response.js.html +160 -0
  19. package/docs/response_success.js.html +104 -0
  20. package/docs/scripts/linenumber.js +25 -0
  21. package/docs/scripts/prettify/Apache-License-2.0.txt +202 -0
  22. package/docs/scripts/prettify/lang-css.js +2 -0
  23. package/docs/scripts/prettify/prettify.js +28 -0
  24. package/docs/styles/jsdoc.css +664 -0
  25. package/docs/styles/prettify.css +79 -0
  26. package/docs/task_helper.js.html +531 -0
  27. package/docs/task_index.js.html +304 -0
  28. package/docs/user_index.js.html +347 -0
  29. package/docs/user_lists.js.html +208 -0
  30. package/docs/user_tasks.js.html +703 -0
  31. package/jsdoc.json +13 -0
  32. package/package.json +33 -0
  33. package/src/client/auth.js +65 -0
  34. package/src/client/index.js +182 -0
  35. package/src/client/user.js +112 -0
  36. package/src/list/helper.js +131 -0
  37. package/src/list/index.js +101 -0
  38. package/src/response/error.js +114 -0
  39. package/src/response/index.js +8 -0
  40. package/src/response/parse.js +51 -0
  41. package/src/response/response.js +102 -0
  42. package/src/response/success.js +46 -0
  43. package/src/task/helper.js +469 -0
  44. package/src/task/index.js +264 -0
  45. package/src/user/index.js +288 -0
  46. package/src/user/lists.js +150 -0
  47. package/src/user/tasks.js +708 -0
  48. package/src/utils/auth.js +188 -0
  49. package/src/utils/fetch.js +67 -0
  50. package/src/utils/get.js +247 -0
  51. package/src/utils/sign.js +93 -0
  52. package/src/utils/taskIds.js +188 -0
@@ -0,0 +1,708 @@
1
+ 'use strict';
2
+
3
+ const _tasks = require('../task/helper.js');
4
+ const _lists = require('../list/helper.js');
5
+ const taskIds = require('../utils/taskIds.js');
6
+ const errors = require('../response/error.js');
7
+ const { getListId, getTaskId, getTaskSeriesId } = require('../utils/taskIds');
8
+ const { callAPI, buildUrl } = require('../utils/fetch')
9
+ const RTMTask = require('../task/index.js');
10
+
11
+ /**
12
+ * This module returns the RTM Tasks-related functions for the RTMUser
13
+ * @param {RTMUser} user The RTM User instance
14
+ * @returns {{get: function, add:function, remove: function, complete: function, uncomplete: function, addTags: function, removeTags: function, priority: function, decreasePriority: function, increasePriority: function, move: function, setDueDate: function, postpone: function, setName: function}}
15
+ * @private
16
+ */
17
+ module.exports = function(user) {
18
+ let rtn = {};
19
+
20
+ /**
21
+ * Get the list of RTM Tasks for this User.
22
+ * @param {string} [filter] Tasks Filter (RTM Advanced Search Syntax)
23
+ * @param {function} callback Callback function(err, tasks)
24
+ * @param {RTMError} callback.err RTM API Error Response, if encountered
25
+ * @param {RTMTask[]} callback.tasks List of User's RTM Tasks
26
+ * @function RTMUser~tasks/get
27
+ */
28
+ rtn.get = function(filter, callback) {
29
+ if ( callback === undefined && typeof filter === 'function' ) {
30
+ callback = filter;
31
+ filter = "";
32
+ }
33
+
34
+ // Callback counters
35
+ let count = 0;
36
+ let calls = 2;
37
+ let returned = false;
38
+
39
+ // Lists and Tasks
40
+ let LISTS = {};
41
+ let TASKS = [];
42
+
43
+ // Update the User's Lists and Tasks
44
+ _lists.get(user, function(err, lists) {
45
+ if ( lists ) {
46
+ for ( let i = 0; i < lists.length; i++ ) {
47
+ LISTS[lists[i].id] = lists[i];
48
+ }
49
+ }
50
+ _tasksUpdateCallback(err);
51
+ });
52
+ _tasks.get(user, filter, function(err, tasks) {
53
+ TASKS = tasks;
54
+ _tasksUpdateCallback(err);
55
+ });
56
+
57
+ // Callback for each of list and task updates
58
+ function _tasksUpdateCallback(err) {
59
+ count++;
60
+ if ( !returned ) {
61
+ if ( err ) {
62
+ returned = true;
63
+ return callback(err);
64
+ }
65
+ else if ( count === calls ) {
66
+ returned = true;
67
+ _parseTasks();
68
+ return callback(null, TASKS);
69
+ }
70
+ }
71
+ }
72
+
73
+ // Add the List to each Task
74
+ function _parseTasks() {
75
+ for ( let i = 0; i < TASKS.length; i++ ) {
76
+ let list = LISTS[TASKS[i].list_id];
77
+ if ( list === undefined ) {
78
+ list = {
79
+ id: TASKS[i].list_id,
80
+ name: "List #" + TASKS[i].list_id
81
+ }
82
+ }
83
+ TASKS[i]._list = list;
84
+ }
85
+ }
86
+ };
87
+
88
+ /**
89
+ * Get the an RTM response of lists, task series and tasks in a JSON
90
+ * @param {int} index Task Index
91
+ * @param {string} [filter] Tasks Filter (RTM Advanced Search Syntax)
92
+ * @return {JSON}
93
+ */
94
+ rtn.rtmFetch = async function(filter) {
95
+ let url = buildUrl(user,filter)
96
+ let response = await callAPI(url);
97
+ return await response.rsp.tasks?.list
98
+ }
99
+
100
+ /**
101
+ * Get the RTMTask specified by its index. Unlike getTask(), this will only create an RTMTask
102
+ * for the matching index, which is more performant.
103
+ * @param {int} index Task Index
104
+ * @param {string} [filter] Tasks Filter (RTM Advanced Search Syntax)
105
+ * @function RTMUser~tasks/getTask
106
+ * @return {RTMTask}
107
+ */
108
+ rtn.rtmIndexFetchTask = async function(index,filter) {
109
+
110
+ let url = buildUrl(user,filter)
111
+ let response = await callAPI(url,user);
112
+ const lists = response.rsp.tasks?.list
113
+
114
+
115
+ // index to ids
116
+ let listId = getListId(user.id,index)
117
+ let taskSeriesId = getTaskSeriesId(user.id,index)
118
+ let taskId = getTaskId(user.id,index)
119
+
120
+ if (listId == undefined || taskSeriesId == undefined || taskId == undefined) {
121
+ return {err: {code: -3}} // Not sure why this is the code
122
+ }
123
+ // filter the response for the matching index
124
+ let taskList = lists.filter(x => x.id == listId)[0].taskseries
125
+ let taskSeries = taskList ? taskList.filter(x => x.id == taskSeriesId)[0] : null
126
+ taskSeries
127
+ ? taskSeries.task = taskSeries.task.filter(x => x.id == taskId)[0]
128
+ : null
129
+
130
+
131
+ let err
132
+ let task
133
+ if (!taskSeries ) {
134
+ err = {code: -3} // Not sure why this is the code
135
+ } else {
136
+ task = new RTMTask(user.id,listId,taskSeries,taskSeries.task)
137
+ }
138
+ return {err,task}
139
+ }
140
+
141
+ /**
142
+ * Get the RTMTask specified by its index. While this will return only the matching RTMTask,
143
+ * this function will create RTMTasks, updating the index for every task returned. This can
144
+ * contribute to laggy performance. You may be better off using rtmIndexFetchTask()
145
+ * @param {int} index Task Index
146
+ * @param {string} [filter] Tasks Filter (RTM Advanced Search Syntax)
147
+ * @param {function} callback Callback function(err, task)
148
+ * @param {RTMError} callback.err RTM API Error Response, if encountered
149
+ * @param {RTMTask} callback.task Matching RTM Task
150
+ * @function RTMUser~tasks/getTask
151
+ * @deprecated use rtmIndexFetchTask instead
152
+ */
153
+ rtn.getTask = function(index, filter, callback) {
154
+ if ( callback === undefined && typeof filter === 'function' ) {
155
+ callback = filter;
156
+ filter = "";
157
+ }
158
+
159
+ // Get Task Info
160
+ _getTaskInfo(index, function(err, listId, taskSeriesId, taskId) {
161
+ if ( err ) {
162
+ return callback(err);
163
+ }
164
+
165
+ // Get Task From API
166
+ user.tasks.get(filter, function(err, tasks) {
167
+ if ( err ) {
168
+ return callback(err);
169
+ }
170
+
171
+ // Find Matching Task
172
+ let found = false;
173
+ for ( let i = 0; i < tasks.length; i++ ) {
174
+ if ( !found && tasks[i].task_id === taskId ) {
175
+ found = true;
176
+ return callback(null, tasks[i]);
177
+ }
178
+ }
179
+
180
+ // Task Not Found
181
+ if ( !found ) {
182
+ return callback(errors.referenceError());
183
+ }
184
+
185
+ });
186
+
187
+ });
188
+
189
+ };
190
+
191
+ /**
192
+ * Add a new RTM Task for this User
193
+ * @param {string} name Task Name (can include 'Smart Add' syntax)
194
+ * @param {object} [props] Task Properties
195
+ * @param {string} props.due Task Due Date (RTM supported date format)
196
+ * @param {int} props.priority Task Priority (1, 2, 3)
197
+ * @param {string} props.list Task List Name
198
+ * @param {string[]} props.tags Task Tags
199
+ * @param {string} props.location Task Location Name
200
+ * @param {string} props.start Task Start Date (RTM supported date format)
201
+ * @param {string} props.repeat Task Repeat Format (RTM supported repeat format)
202
+ * @param {string} props.estimate Task Time Estimate (RTM supported time estimate format)
203
+ * @param {string} props.to Contact Name to give Task to (existing contact or email address)
204
+ * @param {string} props.url Task Reference URL
205
+ * @param {string} props.note Task Note
206
+ * @param {function} callback Callback function(err)
207
+ * @param {RTMError} callback.err RTM API Error Response, if encountered
208
+ * @function RTMUser~tasks/add
209
+ */
210
+ rtn.add = function(name, props, callback) {
211
+ if ( callback === undefined && typeof props === 'function' ) {
212
+ callback = props;
213
+ props = {};
214
+ }
215
+ return _tasks.add(name, props, user, callback);
216
+ };
217
+
218
+ /**
219
+ * Mark the specified Task as complete
220
+ * @param {int} index Task Index
221
+ * @param {function} callback Callback function(err)
222
+ * @param {RTMError} callback.err RTM API Error Response, if encountered
223
+ * @function RTMUser~tasks/complete
224
+ */
225
+ rtn.complete = function(index, callback) {
226
+
227
+ // Get the Task
228
+ _getTaskInfo(index, function(err, listId, taskSeriesId, taskId) {
229
+ if ( err ) {
230
+ return callback(err);
231
+ }
232
+
233
+ // Complete the Task
234
+ return _tasks.complete(
235
+ listId,
236
+ taskSeriesId,
237
+ taskId,
238
+ user,
239
+ callback
240
+ );
241
+
242
+ });
243
+
244
+ };
245
+
246
+ /**
247
+ * Mark the specified Task as NOT complete
248
+ * @param {int} index Task Index
249
+ * @param {function} callback Callback function(err)
250
+ * @param {RTMError} callback.err RTM API Error Response, if encountered
251
+ * @function RTMUser~tasks/uncomplete
252
+ */
253
+ rtn.uncomplete = function(index, callback) {
254
+
255
+ // Get the Task
256
+ _getTaskInfo(index, function(err, listId, taskSeriesId, taskId) {
257
+ if ( err ) {
258
+ return callback(err);
259
+ }
260
+
261
+ // Complete the Task
262
+ return _tasks.uncomplete(
263
+ listId,
264
+ taskSeriesId,
265
+ taskId,
266
+ user,
267
+ callback
268
+ );
269
+
270
+ });
271
+
272
+ };
273
+
274
+ /**
275
+ * Set the priority of the specified Task
276
+ * @param {int} index Task Index
277
+ * @param {int} priority Task Priority
278
+ * @param {function} callback Callback function(err)
279
+ * @param {RTMError} callback.err RTM API Error Response, if encountered
280
+ * @function RTMUser~tasks/priority
281
+ */
282
+ rtn.priority = function(index, priority, callback) {
283
+
284
+ // Get the Task
285
+ _getTaskInfo(index, function(err, listId, taskSeriesId, taskId) {
286
+ if ( err ) {
287
+ return callback(err);
288
+ }
289
+
290
+ // Set the Priority
291
+ return _tasks.priority(
292
+ listId,
293
+ taskSeriesId,
294
+ taskId,
295
+ priority,
296
+ user,
297
+ callback
298
+ );
299
+
300
+ });
301
+
302
+ };
303
+
304
+ /**
305
+ * Add the specified tag(s) to the Task
306
+ * @param {int} index Task Index
307
+ * @param {string|string[]} tags Tag(s) to add to task
308
+ * @param {function} callback Callback function(err)
309
+ * @param {RTMError} callback.err RTM API Error Response, if encountered
310
+ * @function RTMUser~tasks/addTags
311
+ */
312
+ rtn.addTags = function(index, tags, callback) {
313
+
314
+ // Make sure tags is an array
315
+ if ( !Array.isArray(tags) ) {
316
+ tags = [tags];
317
+ }
318
+
319
+ // Get the Task
320
+ _getTaskInfo(index, function(err, listId, taskSeriesId, taskId) {
321
+ if ( err ) {
322
+ return callback(err);
323
+ }
324
+
325
+ // Add the Tags
326
+ return _tasks.addTags(
327
+ listId,
328
+ taskSeriesId,
329
+ taskId,
330
+ tags,
331
+ user,
332
+ callback
333
+ );
334
+
335
+ });
336
+
337
+ };
338
+
339
+
340
+ /**
341
+ * Add the specified note to the Task
342
+ * @param {int} index Task Index
343
+ * @param {string} title Title of the Note
344
+ * @param {string|string[]} notes Note(s) to add to task
345
+ * @param {function} callback Callback function(err)
346
+ * @param {RTMError} callback.err RTM API Error Response, if encountered
347
+ * @function RTMUser~tasks/addNotes
348
+ */
349
+ rtn.addNotes = function(index, title, notes, callback) {
350
+ var title = (typeof title !== 'undefined') ? title : "";
351
+
352
+ // Get the Task
353
+ _getTaskInfo(index, function(err, listId, taskSeriesId, taskId) {
354
+ if ( err ) {
355
+ return callback(err);
356
+ }
357
+
358
+ // Add the Note
359
+ return _tasks.addNotes(
360
+ listId,
361
+ taskSeriesId,
362
+ taskId,
363
+ title,
364
+ notes,
365
+ user,
366
+ callback
367
+ );
368
+
369
+ });
370
+
371
+ };
372
+
373
+ /**
374
+ * Remove the specified Task from the User's Account
375
+ * @param {int} index Task Index
376
+ * @param {function} callback Callback function(err)
377
+ * @param {RTMError} callback.err RTM API Error Response, if encountered
378
+ * @function RTMUser~tasks/remove
379
+ */
380
+ rtn.remove = function(index, callback) {
381
+
382
+ // Get the Task
383
+ _getTaskInfo(index, function(err, listId, taskSeriesId, taskId) {
384
+ if ( err ) {
385
+ return callback(err);
386
+ }
387
+
388
+ // Remove the Task
389
+ return _tasks.remove(
390
+ listId,
391
+ taskSeriesId,
392
+ taskId,
393
+ user,
394
+ callback
395
+ );
396
+
397
+ });
398
+
399
+ };
400
+
401
+ /**
402
+ * Increase the Priority of the specified Task
403
+ * @param {int} index Task Index
404
+ * @param {function} callback Callback function(err)
405
+ * @param {RTMError} callback.err RTM API Error Response, if encountered
406
+ * @function RTMUser~tasks/increasePriority
407
+ */
408
+ rtn.increasePriority = function(index, callback) {
409
+
410
+ // Get the Task
411
+ _getTaskInfo(index, function(err, listId, taskSeriesId, taskId) {
412
+ if ( err ) {
413
+ return callback(err);
414
+ }
415
+
416
+ // Increase the Priority of the Task
417
+ return _tasks.movePriority(
418
+ listId,
419
+ taskSeriesId,
420
+ taskId,
421
+ 'up',
422
+ user,
423
+ callback
424
+ );
425
+
426
+ });
427
+
428
+ };
429
+
430
+ /**
431
+ * Decrease the Priority of the specified Task
432
+ * @param {int} index Task Index
433
+ * @param {function} callback Callback function(err)
434
+ * @param {RTMError} callback.err RTM API Error Response, if encountered
435
+ * @function RTMUser~tasks/decreasePriority
436
+ */
437
+ rtn.decreasePriority = function(index, callback) {
438
+
439
+ // Get the Task
440
+ _getTaskInfo(index, function(err, listId, taskSeriesId, taskId) {
441
+ if ( err ) {
442
+ return callback(err);
443
+ }
444
+
445
+ // Decrease the Priority of the Task
446
+ return _tasks.movePriority(
447
+ listId,
448
+ taskSeriesId,
449
+ taskId,
450
+ 'down',
451
+ user,
452
+ callback
453
+ );
454
+
455
+ });
456
+
457
+ };
458
+
459
+ /**
460
+ * Move the specified Task to a different List
461
+ * @param {int} index Task Index
462
+ * @param {string} listName List Name to move Task to
463
+ * @param {function} callback Callback function(err)
464
+ * @param {RTMError} callback.err RTM API Error Response, if encountered
465
+ * @function RTMUser~tasks/move
466
+ */
467
+ rtn.move = function(index, listName, callback) {
468
+
469
+ // Get the Task
470
+ _getTaskInfo(index, function(err, listId, taskSeriesId, taskId) {
471
+ if ( err ) {
472
+ return callback(err);
473
+ }
474
+
475
+ // Get the List
476
+ user.lists.get(function(err, lists) {
477
+ if ( err ) {
478
+ return callback(err);
479
+ }
480
+
481
+ // Find the List
482
+ let id = [];
483
+ for ( let i = 0; i < lists.length; i++ ) {
484
+ if ( lists[i].name.toLowerCase() === listName.toLowerCase() ) {
485
+ id.push(lists[i].id);
486
+ }
487
+ }
488
+
489
+ // No List Match
490
+ if ( id.length !== 1 ) {
491
+ return callback(errors.referenceError());
492
+ }
493
+
494
+ // Move the Task
495
+ else {
496
+ return _tasks.move(
497
+ listId,
498
+ taskSeriesId,
499
+ taskId,
500
+ id[0],
501
+ user,
502
+ callback
503
+ );
504
+ }
505
+
506
+ });
507
+
508
+ });
509
+
510
+ };
511
+
512
+ /**
513
+ * Postpone the due date of the Task by 1 day
514
+ * @param {int} index Task Index
515
+ * @param {function} callback Callback function(err)
516
+ * @param {RTMError} callback.err RTM API Error Response, if encountered
517
+ * @function RTMUser~tasks/postpone
518
+ */
519
+ rtn.postpone = function(index, callback) {
520
+
521
+ // Get the Task
522
+ _getTaskInfo(index, function(err, listId, taskSeriesId, taskId) {
523
+ if ( err ) {
524
+ return callback(err);
525
+ }
526
+
527
+ // Postpone the Task
528
+ return _tasks.postpone(
529
+ listId,
530
+ taskSeriesId,
531
+ taskId,
532
+ user,
533
+ callback
534
+ );
535
+
536
+ });
537
+
538
+ };
539
+
540
+ /**
541
+ * Remove the specified tag(s) from the Task
542
+ * @param {int} index Task Index
543
+ * @param {string|string[]} tags Tags to remove from the Task
544
+ * @param {function} callback Callback function(err)
545
+ * @param {RTMError} callback.err RTM API Error Response, if encountered
546
+ * @function RTMUser~tasks/removeTags
547
+ */
548
+ rtn.removeTags = function(index, tags, callback) {
549
+
550
+ // Make sure tags is an array
551
+ if ( !Array.isArray(tags) ) {
552
+ tags = [tags];
553
+ }
554
+
555
+ // Get the Task
556
+ _getTaskInfo(index, function(err, listId, taskSeriesId, taskId) {
557
+ if ( err ) {
558
+ return callback(err);
559
+ }
560
+
561
+ // Remove the Tags
562
+ return _tasks.removeTags(
563
+ listId,
564
+ taskSeriesId,
565
+ taskId,
566
+ tags,
567
+ user,
568
+ callback
569
+ );
570
+
571
+ });
572
+
573
+ };
574
+
575
+ /**
576
+ * Set the Due Date of the specified Task
577
+ * @param {int} index Task Index
578
+ * @param {string} due The Due Date of the Task (RTM parsed date)
579
+ * @param {function} callback Callback function(err)
580
+ * @param {RTMError} callback.err RTM API Error Response, if encountered
581
+ * @function RTMUser~tasks/setDueDate
582
+ */
583
+ rtn.setDueDate = function(index, due, callback) {
584
+
585
+ // Get the Task
586
+ _getTaskInfo(index, function(err, listId, taskSeriesId, taskId) {
587
+ if ( err ) {
588
+ return callback(err);
589
+ }
590
+
591
+ // Decrease the Priority of the Task
592
+ return _tasks.setDueDate(
593
+ listId,
594
+ taskSeriesId,
595
+ taskId,
596
+ due,
597
+ user,
598
+ callback
599
+ );
600
+
601
+ });
602
+
603
+ };
604
+
605
+ /**
606
+ * Set the Name of the specified Task
607
+ * @param {int} index Task Index
608
+ * @param {string} name New Task Name
609
+ * @param {function} callback Callback function(err)
610
+ * @param {RTMError} callback.err RTM API Error Response, if encountered
611
+ * @function RTMUser~tasks/setName
612
+ */
613
+ rtn.setName = function(index, name, callback) {
614
+
615
+ // Get the Task
616
+ _getTaskInfo(index, function(err, listId, taskSeriesId, taskId) {
617
+ if ( err ) {
618
+ return callback(err);
619
+ }
620
+
621
+ // Decrease the Priority of the Task
622
+ return _tasks.setName(
623
+ listId,
624
+ taskSeriesId,
625
+ taskId,
626
+ name,
627
+ user,
628
+ callback
629
+ );
630
+
631
+ });
632
+
633
+ };
634
+
635
+ /**
636
+ * Set the URL of the specified Task
637
+ * @param {int} index Task Index
638
+ * @param {string} url New Task URL
639
+ * @param {function} callback Callback function(err)
640
+ * @param {RTMError} callback.err RTM API Error Response, if encountered
641
+ * @function RTMUser~tasks/setURL
642
+ */
643
+ rtn.setURL = function(index, url, callback) {
644
+
645
+ // Get the Task
646
+ _getTaskInfo(index, function(err, listId, taskSeriesId, taskId) {
647
+ if ( err ) {
648
+ return callback(err);
649
+ }
650
+
651
+ // Decrease the Priority of the Task
652
+ return _tasks.setURL(
653
+ listId,
654
+ taskSeriesId,
655
+ taskId,
656
+ url,
657
+ user,
658
+ callback
659
+ );
660
+
661
+ });
662
+
663
+ };
664
+
665
+
666
+
667
+ /**
668
+ * Get the Matching Task IDs by Index
669
+ * @param {int} index Task Index
670
+ * @param callback Callback function(err, list_id, taskseries_id, task_id)
671
+ * @private
672
+ */
673
+ function _getTaskInfo(index, callback) {
674
+
675
+ // Get IDs
676
+ let listId = taskIds.getListId(user.id, index);
677
+ let taskSeriesId = taskIds.getTaskSeriesId(user.id, index);
678
+ let taskId = taskIds.getTaskId(user.id, index);
679
+
680
+ // All IDs found...
681
+ if ( listId !== undefined && taskSeriesId !== undefined && taskId !== undefined ) {
682
+ return callback(null, listId, taskSeriesId, taskId);
683
+ }
684
+
685
+ // Get Task From API
686
+ user.tasks.get(function(err, tasks) {
687
+ if ( err ) {
688
+ return callback(err);
689
+ }
690
+
691
+ // Find Matching Task
692
+ let found = false;
693
+ for ( let i = 0; i < tasks.length; i++ ) {
694
+ if ( !found && tasks[i].task_id === taskId ) {
695
+ found = true;
696
+ return callback(null, tasks[i].list_id, tasks[i].taskseries_id, tasks[i].task_id);
697
+ }
698
+ }
699
+
700
+ // Task Not Found
701
+ if ( !found ) {
702
+ return callback(errors.referenceError());
703
+ }
704
+ });
705
+ }
706
+
707
+ return rtn;
708
+ };