@doist/todoist-api-typescript 7.1.1 → 7.3.0

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 (32) hide show
  1. package/dist/cjs/test-utils/msw-setup.js +4 -3
  2. package/dist/cjs/todoist-api.js +105 -0
  3. package/dist/cjs/types/entities.js +43 -26
  4. package/dist/cjs/types/sync/resources/calendars.js +7 -3
  5. package/dist/cjs/types/sync/resources/collaborators.js +4 -2
  6. package/dist/cjs/types/sync/resources/reminders.js +8 -6
  7. package/dist/cjs/types/sync/resources/suggestions.js +11 -7
  8. package/dist/cjs/types/sync/resources/user-settings.js +5 -5
  9. package/dist/cjs/types/sync/resources/user.js +11 -15
  10. package/dist/cjs/types/sync/resources/view-options.js +33 -25
  11. package/dist/esm/test-utils/msw-setup.js +1 -0
  12. package/dist/esm/todoist-api.js +105 -0
  13. package/dist/esm/types/entities.js +32 -15
  14. package/dist/esm/types/sync/resources/calendars.js +6 -2
  15. package/dist/esm/types/sync/resources/collaborators.js +3 -1
  16. package/dist/esm/types/sync/resources/reminders.js +4 -2
  17. package/dist/esm/types/sync/resources/suggestions.js +8 -4
  18. package/dist/esm/types/sync/resources/user-settings.js +2 -2
  19. package/dist/esm/types/sync/resources/user.js +6 -10
  20. package/dist/esm/types/sync/resources/view-options.js +22 -14
  21. package/dist/types/todoist-api.d.ts +31 -20
  22. package/dist/types/types/entities.d.ts +48 -1
  23. package/dist/types/types/sync/commands/project-view-options.d.ts +2 -2
  24. package/dist/types/types/sync/commands/view-options.d.ts +3 -7
  25. package/dist/types/types/sync/resources/calendars.d.ts +8 -0
  26. package/dist/types/types/sync/resources/collaborators.d.ts +4 -0
  27. package/dist/types/types/sync/resources/reminders.d.ts +11 -0
  28. package/dist/types/types/sync/resources/suggestions.d.ts +42 -0
  29. package/dist/types/types/sync/resources/user-settings.d.ts +8 -0
  30. package/dist/types/types/sync/resources/user.d.ts +30 -0
  31. package/dist/types/types/sync/resources/view-options.d.ts +75 -0
  32. package/package.json +5 -5
@@ -1,3 +1,4 @@
1
+ import { beforeAll, afterEach, afterAll } from 'vitest';
1
2
  import { setupServer } from 'msw/node';
2
3
  import { http, HttpResponse } from 'msw';
3
4
  // Request capture storage
@@ -52,6 +52,34 @@ function preprocessSyncCommands(commands) {
52
52
  return cmd;
53
53
  });
54
54
  }
55
+ /**
56
+ * A client for interacting with the Todoist API v1.
57
+ * This class provides methods to manage tasks, projects, sections, labels, and comments in Todoist.
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * const api = new TodoistApi('your-api-token');
62
+ *
63
+ * // Get all tasks
64
+ * const tasks = await api.getTasks();
65
+ *
66
+ * // Create a new task
67
+ * const newTask = await api.addTask({
68
+ * content: 'My new task',
69
+ * projectId: '12345'
70
+ * });
71
+ * ```
72
+ *
73
+ * For more information about the Todoist API v1, see the [official documentation](https://todoist.com/api/v1).
74
+ * If you're migrating from v9, please refer to the [migration guide](https://todoist.com/api/v1/docs#tag/Migrating-from-v9).
75
+ */
76
+ function headersToRecord(headers) {
77
+ const result = {};
78
+ headers.forEach((value, key) => {
79
+ result[key] = value;
80
+ });
81
+ return result;
82
+ }
55
83
  export class TodoistApi {
56
84
  constructor(
57
85
  /**
@@ -1191,6 +1219,83 @@ export class TodoistApi {
1191
1219
  });
1192
1220
  return isSuccess(response);
1193
1221
  }
1222
+ /**
1223
+ * Fetches the content of a file attachment from a Todoist comment.
1224
+ *
1225
+ * Accepts either a Comment object (extracts the file URL from its attachment)
1226
+ * or a direct file URL string. Returns the raw Response object so the caller
1227
+ * can read the body in the appropriate format (.arrayBuffer(), .text(), etc.).
1228
+ *
1229
+ * @param commentOrUrl - A Comment object with a file attachment, or a file URL string.
1230
+ * @returns The raw fetch Response for the file content.
1231
+ * @throws Error if a Comment is provided without a file attachment or file URL.
1232
+ *
1233
+ * @example
1234
+ * ```typescript
1235
+ * // From a comment object
1236
+ * const comments = await api.getComments({ taskId: '12345' })
1237
+ * const comment = comments.results[0]
1238
+ * const response = await api.viewAttachment(comment)
1239
+ * const imageData = await response.arrayBuffer()
1240
+ *
1241
+ * // From a URL string
1242
+ * const response = await api.viewAttachment('https://files.todoist.com/...')
1243
+ * const text = await response.text()
1244
+ * ```
1245
+ */
1246
+ async viewAttachment(commentOrUrl) {
1247
+ var _a;
1248
+ let fileUrl;
1249
+ if (typeof commentOrUrl === 'string') {
1250
+ fileUrl = commentOrUrl;
1251
+ }
1252
+ else {
1253
+ if (!((_a = commentOrUrl.fileAttachment) === null || _a === void 0 ? void 0 : _a.fileUrl)) {
1254
+ throw new Error('Comment does not have a file attachment');
1255
+ }
1256
+ fileUrl = commentOrUrl.fileAttachment.fileUrl;
1257
+ }
1258
+ // Validate the URL belongs to Todoist to prevent leaking the auth token
1259
+ const urlHostname = new URL(fileUrl).hostname;
1260
+ if (!urlHostname.endsWith('.todoist.com')) {
1261
+ throw new Error('Attachment URLs must be on a todoist.com domain');
1262
+ }
1263
+ const fetchOptions = {
1264
+ method: 'GET',
1265
+ headers: { Authorization: `Bearer ${this.authToken}` },
1266
+ };
1267
+ if (this.customFetch) {
1268
+ const response = await this.customFetch(fileUrl, fetchOptions);
1269
+ if (!response.ok) {
1270
+ throw new Error(`Failed to fetch attachment: ${response.status} ${response.statusText}`);
1271
+ }
1272
+ // Convert text to ArrayBuffer for custom fetch implementations that lack arrayBuffer()
1273
+ const text = await response.text();
1274
+ const buffer = new TextEncoder().encode(text).buffer;
1275
+ return {
1276
+ ok: response.ok,
1277
+ status: response.status,
1278
+ statusText: response.statusText,
1279
+ headers: response.headers,
1280
+ text: () => Promise.resolve(text),
1281
+ json: () => response.json(),
1282
+ arrayBuffer: () => Promise.resolve(buffer),
1283
+ };
1284
+ }
1285
+ const response = await fetch(fileUrl, fetchOptions);
1286
+ if (!response.ok) {
1287
+ throw new Error(`Failed to fetch attachment: ${response.status} ${response.statusText}`);
1288
+ }
1289
+ return {
1290
+ ok: response.ok,
1291
+ status: response.status,
1292
+ statusText: response.statusText,
1293
+ headers: headersToRecord(response.headers),
1294
+ text: () => response.text(),
1295
+ json: () => response.json(),
1296
+ arrayBuffer: () => response.arrayBuffer(),
1297
+ };
1298
+ }
1194
1299
  /* Workspace methods */
1195
1300
  /**
1196
1301
  * Gets pending invitations for a workspace.
@@ -23,9 +23,11 @@ export const DueDateSchema = z
23
23
  timezone: z.string().nullable().optional(),
24
24
  lang: z.string().nullable().optional(),
25
25
  });
26
+ /** Available duration units for task deadlines. */
27
+ export const DURATION_UNITS = ['minute', 'day'];
26
28
  export const DurationSchema = z.object({
27
29
  amount: z.number().positive('Value should be greater than zero'),
28
- unit: z.enum(['minute', 'day']),
30
+ unit: z.enum(DURATION_UNITS),
29
31
  });
30
32
  export const DeadlineSchema = z.object({
31
33
  date: z.string(),
@@ -94,7 +96,9 @@ export const PersonalProjectSchema = BaseProjectSchema.extend({
94
96
  }).transform((data) => {
95
97
  return Object.assign(Object.assign({}, data), { url: getProjectUrl(data.id, data.name) });
96
98
  });
97
- export const ProjectVisibilitySchema = z.enum(['restricted', 'team', 'public']);
99
+ /** Available project visibility levels. */
100
+ export const PROJECT_VISIBILITIES = ['restricted', 'team', 'public'];
101
+ export const ProjectVisibilitySchema = z.enum(PROJECT_VISIBILITIES);
98
102
  /**
99
103
  * Schema for workspace projects in Todoist.
100
104
  */
@@ -134,6 +138,8 @@ export const LabelSchema = z.object({
134
138
  color: z.string(),
135
139
  isFavorite: z.boolean(),
136
140
  });
141
+ /** Available file attachment upload states. */
142
+ export const UPLOAD_STATES = ['pending', 'completed'];
137
143
  export const AttachmentSchema = z
138
144
  .object({
139
145
  resourceType: z.string(),
@@ -144,7 +150,7 @@ export const AttachmentSchema = z
144
150
  fileType: z.string().nullable().optional(),
145
151
  fileUrl: z.string().nullable().optional(),
146
152
  fileDuration: z.number().int().nullable().optional(),
147
- uploadState: z.enum(['pending', 'completed']).nullable().optional(),
153
+ uploadState: z.enum(UPLOAD_STATES).nullable().optional(),
148
154
  image: z.string().nullable().optional(),
149
155
  imageWidth: z.number().int().nullable().optional(),
150
156
  imageHeight: z.number().int().nullable().optional(),
@@ -189,6 +195,13 @@ export const TimezoneInfoSchema = z.object({
189
195
  minutes: z.number().int(),
190
196
  timezone: z.string(),
191
197
  });
198
+ /** Available user premium statuses. */
199
+ export const PREMIUM_STATUSES = [
200
+ 'not_premium',
201
+ 'current_personal_plan',
202
+ 'legacy_personal_plan',
203
+ 'teams_business_member',
204
+ ];
192
205
  export const CurrentUserSchema = z.object({
193
206
  id: z.string(),
194
207
  email: z.string(),
@@ -199,12 +212,7 @@ export const CurrentUserSchema = z.object({
199
212
  avatarSmall: z.string().nullish(),
200
213
  businessAccountId: z.string().nullable(),
201
214
  isPremium: z.boolean(),
202
- premiumStatus: z.enum([
203
- 'not_premium',
204
- 'current_personal_plan',
205
- 'legacy_personal_plan',
206
- 'teams_business_member',
207
- ]),
215
+ premiumStatus: z.enum(PREMIUM_STATUSES),
208
216
  dateFormat: z.number().int(),
209
217
  timeFormat: z.number().int(),
210
218
  weeklyGoal: z.number().int(),
@@ -222,20 +230,20 @@ export const CurrentUserSchema = z.object({
222
230
  daysOff: z.array(z.number().int()),
223
231
  weekendStartDay: z.number().int(),
224
232
  });
225
- const StreakSchema = z.object({
233
+ export const StreakSchema = z.object({
226
234
  count: z.number(),
227
235
  start: z.string(),
228
236
  end: z.string(),
229
237
  });
230
- const CompletedItemSchema = z.object({
238
+ export const CompletedItemSchema = z.object({
231
239
  id: z.string(),
232
240
  completed: z.number(),
233
241
  });
234
- const ItemsWithDateSchema = z.object({
242
+ export const ItemsWithDateSchema = z.object({
235
243
  items: z.array(CompletedItemSchema),
236
244
  totalCompleted: z.number(),
237
245
  });
238
- const KarmaUpdateSchema = z.object({
246
+ export const KarmaUpdateSchema = z.object({
239
247
  time: z.string(),
240
248
  newKarma: z.number(),
241
249
  positiveKarma: z.number(),
@@ -343,10 +351,19 @@ export const FormattedPriceListingSchema = z.object({
343
351
  interval: z.string().optional(),
344
352
  formatted: z.string().optional(),
345
353
  });
354
+ /** Available workspace plan names. */
355
+ export const WORKSPACE_CURRENT_PLANS = ['Business', 'Starter'];
356
+ /** Available workspace plan statuses. */
357
+ export const WORKSPACE_PLAN_STATUSES = [
358
+ 'Active',
359
+ 'Downgraded',
360
+ 'Cancelled',
361
+ 'NeverSubscribed',
362
+ ];
346
363
  export const WorkspacePlanDetailsSchema = z.object({
347
364
  currentMemberCount: z.number(),
348
- currentPlan: z.enum(['Business', 'Starter']),
349
- currentPlanStatus: z.enum(['Active', 'Downgraded', 'Cancelled', 'NeverSubscribed']),
365
+ currentPlan: z.enum(WORKSPACE_CURRENT_PLANS),
366
+ currentPlanStatus: z.enum(WORKSPACE_PLAN_STATUSES),
350
367
  downgradeAt: z.string().nullable(),
351
368
  currentActiveProjects: z.number(),
352
369
  maximumActiveProjects: z.number(),
@@ -9,16 +9,20 @@ export const CalendarSchema = z
9
9
  isTaskCalendar: z.boolean().optional(),
10
10
  })
11
11
  .passthrough();
12
+ /** Available calendar account provider types. */
13
+ export const CALENDAR_ACCOUNT_TYPES = ['google', 'microsoft', 'apple'];
14
+ /** Available calendar sync states. */
15
+ export const CALENDAR_SYNC_STATES = ['synced', 'syncing', 'error'];
12
16
  export const CalendarAccountSchema = z
13
17
  .object({
14
18
  id: z.string(),
15
19
  name: z.string(),
16
- type: z.enum(['google', 'microsoft', 'apple']),
20
+ type: z.enum(CALENDAR_ACCOUNT_TYPES),
17
21
  isDeleted: z.boolean().optional(),
18
22
  isEventsEnabled: z.boolean().optional(),
19
23
  isTasksEnabled: z.boolean().optional(),
20
24
  isAllDayTasksEnabled: z.boolean().optional(),
21
25
  pendingOperationUntil: z.string().nullable().optional(),
22
- calendarsSyncState: z.enum(['synced', 'syncing', 'error']).optional(),
26
+ calendarsSyncState: z.enum(CALENDAR_SYNC_STATES).optional(),
23
27
  })
24
28
  .passthrough();
@@ -9,11 +9,13 @@ export const CollaboratorSchema = z
9
9
  imageId: z.string().nullable(),
10
10
  })
11
11
  .passthrough();
12
+ /** Available collaborator statuses. */
13
+ export const COLLABORATOR_STATUSES = ['active', 'invited'];
12
14
  export const CollaboratorStateSchema = z
13
15
  .object({
14
16
  userId: z.string(),
15
17
  projectId: z.string(),
16
- state: z.enum(['active', 'invited']),
18
+ state: z.enum(COLLABORATOR_STATUSES),
17
19
  isDeleted: z.boolean(),
18
20
  workspaceRole: WorkspaceRoleSchema.optional(),
19
21
  })
@@ -1,18 +1,20 @@
1
1
  import { z } from 'zod';
2
2
  import { DueDateSchema } from '../../entities.js';
3
- const ReminderBaseSchema = z.object({
3
+ export const ReminderBaseSchema = z.object({
4
4
  id: z.string(),
5
5
  notifyUid: z.string(),
6
6
  itemId: z.string(),
7
7
  projectId: z.string().optional(),
8
8
  isDeleted: z.boolean(),
9
9
  });
10
+ /** Available location reminder triggers. */
11
+ export const LOCATION_TRIGGERS = ['on_enter', 'on_leave'];
10
12
  export const LocationReminderSchema = ReminderBaseSchema.extend({
11
13
  type: z.literal('location'),
12
14
  name: z.string(),
13
15
  locLat: z.string(),
14
16
  locLong: z.string(),
15
- locTrigger: z.enum(['on_enter', 'on_leave']),
17
+ locTrigger: z.enum(LOCATION_TRIGGERS),
16
18
  radius: z.number().int(),
17
19
  }).passthrough();
18
20
  export const AbsoluteReminderSchema = ReminderBaseSchema.extend({
@@ -1,17 +1,21 @@
1
1
  import { z } from 'zod';
2
+ /** Available template types. */
3
+ export const TEMPLATE_TYPES = ['project', 'setup'];
2
4
  export const TemplateSuggestionSchema = z
3
5
  .object({
4
6
  id: z.string(),
5
7
  name: z.string(),
6
- templateType: z.enum(['project', 'setup']),
8
+ templateType: z.enum(TEMPLATE_TYPES),
7
9
  })
8
10
  .passthrough();
9
11
  export const WorkspaceTemplateSuggestionSchema = TemplateSuggestionSchema.extend({
10
12
  workspaceId: z.string().nullable(),
11
13
  });
12
- const SyncTemplateSuggestionsSchema = z
14
+ /** Available suggestion section types. */
15
+ export const SUGGESTION_SECTION_TYPES = ['templates', 'most_used_user_templates'];
16
+ export const SyncTemplateSuggestionsSchema = z
13
17
  .object({
14
- type: z.enum(['templates', 'most_used_user_templates']),
18
+ type: z.enum(SUGGESTION_SECTION_TYPES),
15
19
  content: z.object({
16
20
  templates: z.array(TemplateSuggestionSchema),
17
21
  locale: z.string(),
@@ -19,7 +23,7 @@ const SyncTemplateSuggestionsSchema = z
19
23
  isDeleted: z.boolean(),
20
24
  })
21
25
  .passthrough();
22
- const SyncWorkspaceTemplateSuggestionsSchema = z
26
+ export const SyncWorkspaceTemplateSuggestionsSchema = z
23
27
  .object({
24
28
  type: z.literal('most_used_workspace_templates'),
25
29
  content: z.object({
@@ -1,9 +1,9 @@
1
1
  import { z } from 'zod';
2
- const NavigationFeatureSchema = z.object({
2
+ export const NavigationFeatureSchema = z.object({
3
3
  name: z.string(),
4
4
  shown: z.boolean(),
5
5
  });
6
- const QuickAddFeatureSchema = z.object({
6
+ export const QuickAddFeatureSchema = z.object({
7
7
  name: z.string(),
8
8
  shown: z.boolean(),
9
9
  });
@@ -1,6 +1,7 @@
1
1
  import { z } from 'zod';
2
+ import { PREMIUM_STATUSES } from '../../entities.js';
2
3
  import { BooleanFromZeroOneSchema, DateFormatSchema, DayOfWeekSchema, TimeFormatSchema, } from '../user-preferences.js';
3
- const FeaturesSchema = z
4
+ export const FeaturesSchema = z
4
5
  .object({
5
6
  karmaDisabled: z.boolean(),
6
7
  restriction: z.number().int(),
@@ -14,7 +15,7 @@ const FeaturesSchema = z
14
15
  migratedFromTdb: z.boolean().optional(),
15
16
  })
16
17
  .passthrough();
17
- const TzInfoSchema = z
18
+ export const TzInfoSchema = z
18
19
  .object({
19
20
  timezone: z.string(),
20
21
  hours: z.number().int(),
@@ -23,14 +24,14 @@ const TzInfoSchema = z
23
24
  gmtString: z.string(),
24
25
  })
25
26
  .passthrough();
26
- const JoinableWorkspaceSchema = z
27
+ export const JoinableWorkspaceSchema = z
27
28
  .object({
28
29
  workspaceId: z.string(),
29
30
  workspaceName: z.string(),
30
31
  memberCount: z.number().int(),
31
32
  })
32
33
  .passthrough();
33
- const GettingStartedGuideProjectSchema = z
34
+ export const GettingStartedGuideProjectSchema = z
34
35
  .object({
35
36
  onboardingUseCase: z.string(),
36
37
  projectId: z.string(),
@@ -88,12 +89,7 @@ export const SyncUserSchema = z
88
89
  onboardingSkipped: z.boolean().optional(),
89
90
  onboardingTeamMode: z.boolean().nullable().optional(),
90
91
  onboardingUseCases: z.array(z.string()).nullable().optional(),
91
- premiumStatus: z.enum([
92
- 'not_premium',
93
- 'current_personal_plan',
94
- 'legacy_personal_plan',
95
- 'teams_business_member',
96
- ]),
92
+ premiumStatus: z.enum(PREMIUM_STATUSES),
97
93
  premiumUntil: z.string().nullable(),
98
94
  rambleSessionsUsage: z
99
95
  .object({
@@ -1,5 +1,6 @@
1
1
  import { z } from 'zod';
2
- const ViewTypeSchema = z.enum([
2
+ /** Available view types. */
3
+ export const VIEW_TYPES = [
3
4
  'TODAY',
4
5
  'UPCOMING',
5
6
  'PROJECT',
@@ -13,10 +14,13 @@ const ViewTypeSchema = z.enum([
13
14
  'ASSIGNED',
14
15
  'OVERDUE',
15
16
  'WORKSPACE_OVERVIEW',
16
- ]);
17
- const ViewModeSchema = z.enum(['LIST', 'BOARD', 'CALENDAR']);
18
- const GroupedBySchema = z
19
- .enum([
17
+ ];
18
+ export const ViewTypeSchema = z.enum(VIEW_TYPES);
19
+ /** Available view modes. */
20
+ export const VIEW_MODES = ['LIST', 'BOARD', 'CALENDAR'];
21
+ export const ViewModeSchema = z.enum(VIEW_MODES);
22
+ /** Available grouping options. */
23
+ export const GROUPED_BY_OPTIONS = [
20
24
  'ASSIGNEE',
21
25
  'ADDED_DATE',
22
26
  'DUE_DATE',
@@ -25,10 +29,10 @@ const GroupedBySchema = z
25
29
  'PRIORITY',
26
30
  'PROJECT',
27
31
  'WORKSPACE',
28
- ])
29
- .nullable();
30
- const SortedBySchema = z
31
- .enum([
32
+ ];
33
+ export const GroupedBySchema = z.enum(GROUPED_BY_OPTIONS).nullable();
34
+ /** Available sorting options. */
35
+ export const SORTED_BY_OPTIONS = [
32
36
  'MANUAL',
33
37
  'ALPHABETICALLY',
34
38
  'ASSIGNEE',
@@ -38,12 +42,16 @@ const SortedBySchema = z
38
42
  'PRIORITY',
39
43
  'PROJECT',
40
44
  'WORKSPACE',
41
- ])
42
- .nullable();
43
- const SortOrderSchema = z.enum(['ASC', 'DESC']).nullable();
44
- const CalendarSettingsSchema = z
45
+ ];
46
+ export const SortedBySchema = z.enum(SORTED_BY_OPTIONS).nullable();
47
+ /** Available sort directions. */
48
+ export const SORT_ORDERS = ['ASC', 'DESC'];
49
+ export const SortOrderSchema = z.enum(SORT_ORDERS).nullable();
50
+ /** Available calendar layout modes. */
51
+ export const CALENDAR_LAYOUTS = ['WEEK', 'MONTH'];
52
+ export const CalendarSettingsSchema = z
45
53
  .object({
46
- layout: z.enum(['WEEK', 'MONTH']).optional(),
54
+ layout: z.enum(CALENDAR_LAYOUTS).optional(),
47
55
  })
48
56
  .passthrough();
49
57
  export const ViewOptionsSchema = z
@@ -1,28 +1,14 @@
1
1
  import { Attachment, PersonalProject, WorkspaceProject, Label, Section, Comment, Task, CurrentUser, ProductivityStats, WorkspaceInvitation, WorkspacePlanDetails, JoinWorkspaceResult, Workspace } from './types/entities.js';
2
2
  import { AddCommentArgs, AddLabelArgs, AddProjectArgs, AddSectionArgs, AddTaskArgs, GetProjectCommentsArgs, GetTaskCommentsArgs, GetTasksArgs, GetTasksByFilterArgs, UpdateCommentArgs, UpdateLabelArgs, UpdateProjectArgs, UpdateSectionArgs, UpdateTaskArgs, QuickAddTaskArgs, GetSharedLabelsArgs, RenameSharedLabelArgs, RemoveSharedLabelArgs, GetProjectsArgs, SearchProjectsArgs, GetProjectCollaboratorsArgs, GetLabelsArgs, SearchLabelsArgs, GetLabelsResponse, GetTasksResponse, GetProjectsResponse, GetProjectCollaboratorsResponse, GetSectionsArgs, SearchSectionsArgs, GetSectionsResponse, GetSharedLabelsResponse, GetCommentsResponse, type MoveTaskArgs, GetCompletedTasksByCompletionDateArgs, GetCompletedTasksByDueDateArgs, GetCompletedTasksResponse, GetArchivedProjectsArgs, GetArchivedProjectsResponse, SearchCompletedTasksArgs, GetActivityLogsArgs, GetActivityLogsResponse, UploadFileArgs, DeleteUploadArgs, GetWorkspaceInvitationsArgs, DeleteWorkspaceInvitationArgs, WorkspaceInvitationActionArgs, JoinWorkspaceArgs, WorkspaceLogoArgs, GetWorkspacePlanDetailsArgs, GetWorkspaceUsersArgs, GetWorkspaceUsersResponse, GetWorkspaceProjectsArgs, WorkspaceInvitationsResponse, AllWorkspaceInvitationsResponse, WorkspaceLogoResponse, MoveProjectToWorkspaceArgs, MoveProjectToPersonalArgs } from './types/requests.js';
3
- import { CustomFetch } from './types/http.js';
3
+ import { CustomFetch, CustomFetchResponse } from './types/http.js';
4
4
  import { type SyncResponse, type SyncRequest } from './types/sync/index.js';
5
5
  /**
6
- * A client for interacting with the Todoist API v1.
7
- * This class provides methods to manage tasks, projects, sections, labels, and comments in Todoist.
8
- *
9
- * @example
10
- * ```typescript
11
- * const api = new TodoistApi('your-api-token');
12
- *
13
- * // Get all tasks
14
- * const tasks = await api.getTasks();
15
- *
16
- * // Create a new task
17
- * const newTask = await api.addTask({
18
- * content: 'My new task',
19
- * projectId: '12345'
20
- * });
21
- * ```
22
- *
23
- * For more information about the Todoist API v1, see the [official documentation](https://todoist.com/api/v1).
24
- * If you're migrating from v9, please refer to the [migration guide](https://todoist.com/api/v1/docs#tag/Migrating-from-v9).
6
+ * Response from viewAttachment, extending CustomFetchResponse with
7
+ * arrayBuffer() support for binary file content.
25
8
  */
9
+ export type ViewAttachmentResponse = CustomFetchResponse & {
10
+ arrayBuffer(): Promise<ArrayBuffer>;
11
+ };
26
12
  /**
27
13
  * Configuration options for the TodoistApi constructor
28
14
  */
@@ -511,6 +497,31 @@ export declare class TodoistApi {
511
497
  * ```
512
498
  */
513
499
  deleteUpload(args: DeleteUploadArgs, requestId?: string): Promise<boolean>;
500
+ /**
501
+ * Fetches the content of a file attachment from a Todoist comment.
502
+ *
503
+ * Accepts either a Comment object (extracts the file URL from its attachment)
504
+ * or a direct file URL string. Returns the raw Response object so the caller
505
+ * can read the body in the appropriate format (.arrayBuffer(), .text(), etc.).
506
+ *
507
+ * @param commentOrUrl - A Comment object with a file attachment, or a file URL string.
508
+ * @returns The raw fetch Response for the file content.
509
+ * @throws Error if a Comment is provided without a file attachment or file URL.
510
+ *
511
+ * @example
512
+ * ```typescript
513
+ * // From a comment object
514
+ * const comments = await api.getComments({ taskId: '12345' })
515
+ * const comment = comments.results[0]
516
+ * const response = await api.viewAttachment(comment)
517
+ * const imageData = await response.arrayBuffer()
518
+ *
519
+ * // From a URL string
520
+ * const response = await api.viewAttachment('https://files.todoist.com/...')
521
+ * const text = await response.text()
522
+ * ```
523
+ */
524
+ viewAttachment(commentOrUrl: Comment | string): Promise<ViewAttachmentResponse>;
514
525
  /**
515
526
  * Gets pending invitations for a workspace.
516
527
  *
@@ -12,6 +12,10 @@ export declare const DueDateSchema: z.ZodObject<{
12
12
  * @see https://todoist.com/api/v1/docs#tag/Tasks/operation/get_tasks_api_v1_tasks_get
13
13
  */
14
14
  export type DueDate = z.infer<typeof DueDateSchema>;
15
+ /** Available duration units for task deadlines. */
16
+ export declare const DURATION_UNITS: readonly ["minute", "day"];
17
+ /** Unit of time for a task duration. */
18
+ export type DurationUnit = (typeof DURATION_UNITS)[number];
15
19
  export declare const DurationSchema: z.ZodObject<{
16
20
  amount: z.ZodNumber;
17
21
  unit: z.ZodEnum<{
@@ -240,12 +244,15 @@ export declare const PersonalProjectSchema: z.ZodPipe<z.ZodObject<{
240
244
  parentId: string | null;
241
245
  inboxProject: boolean;
242
246
  }>>;
247
+ /** Available project visibility levels. */
248
+ export declare const PROJECT_VISIBILITIES: readonly ["restricted", "team", "public"];
249
+ /** Visibility level of a workspace project. */
250
+ export type ProjectVisibility = (typeof PROJECT_VISIBILITIES)[number];
243
251
  export declare const ProjectVisibilitySchema: z.ZodEnum<{
244
252
  restricted: "restricted";
245
253
  team: "team";
246
254
  public: "public";
247
255
  }>;
248
- export type ProjectVisibility = z.infer<typeof ProjectVisibilitySchema>;
249
256
  /**
250
257
  * Schema for workspace projects in Todoist.
251
258
  */
@@ -405,6 +412,10 @@ export declare const LabelSchema: z.ZodObject<{
405
412
  * @see https://todoist.com/api/v1/docs#tag/Labels
406
413
  */
407
414
  export type Label = z.infer<typeof LabelSchema>;
415
+ /** Available file attachment upload states. */
416
+ export declare const UPLOAD_STATES: readonly ["pending", "completed"];
417
+ /** Upload state of a file attachment. */
418
+ export type UploadState = (typeof UPLOAD_STATES)[number];
408
419
  export declare const AttachmentSchema: z.ZodObject<{
409
420
  resourceType: z.ZodString;
410
421
  fileName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
@@ -558,6 +569,10 @@ export declare const TimezoneInfoSchema: z.ZodObject<{
558
569
  minutes: z.ZodNumber;
559
570
  timezone: z.ZodString;
560
571
  }, z.core.$strip>;
572
+ /** Available user premium statuses. */
573
+ export declare const PREMIUM_STATUSES: readonly ["not_premium", "current_personal_plan", "legacy_personal_plan", "teams_business_member"];
574
+ /** Premium subscription status of a user. */
575
+ export type PremiumStatus = (typeof PREMIUM_STATUSES)[number];
561
576
  export declare const CurrentUserSchema: z.ZodObject<{
562
577
  id: z.ZodString;
563
578
  email: z.ZodString;
@@ -602,6 +617,30 @@ export declare const CurrentUserSchema: z.ZodObject<{
602
617
  * @see https://todoist.com/api/v1/docs#tag/User
603
618
  */
604
619
  export type CurrentUser = z.infer<typeof CurrentUserSchema>;
620
+ export declare const StreakSchema: z.ZodObject<{
621
+ count: z.ZodNumber;
622
+ start: z.ZodString;
623
+ end: z.ZodString;
624
+ }, z.core.$strip>;
625
+ export declare const CompletedItemSchema: z.ZodObject<{
626
+ id: z.ZodString;
627
+ completed: z.ZodNumber;
628
+ }, z.core.$strip>;
629
+ export declare const ItemsWithDateSchema: z.ZodObject<{
630
+ items: z.ZodArray<z.ZodObject<{
631
+ id: z.ZodString;
632
+ completed: z.ZodNumber;
633
+ }, z.core.$strip>>;
634
+ totalCompleted: z.ZodNumber;
635
+ }, z.core.$strip>;
636
+ export declare const KarmaUpdateSchema: z.ZodObject<{
637
+ time: z.ZodString;
638
+ newKarma: z.ZodNumber;
639
+ positiveKarma: z.ZodNumber;
640
+ negativeKarma: z.ZodNumber;
641
+ positiveKarmaReasons: z.ZodArray<z.ZodAny>;
642
+ negativeKarmaReasons: z.ZodArray<z.ZodAny>;
643
+ }, z.core.$strip>;
605
644
  export declare const ProductivityStatsSchema: z.ZodObject<{
606
645
  completedCount: z.ZodNumber;
607
646
  daysItems: z.ZodArray<z.ZodObject<{
@@ -805,6 +844,14 @@ export declare const FormattedPriceListingSchema: z.ZodObject<{
805
844
  * Formatted price listing for workspace plans.
806
845
  */
807
846
  export type FormattedPriceListing = z.infer<typeof FormattedPriceListingSchema>;
847
+ /** Available workspace plan names. */
848
+ export declare const WORKSPACE_CURRENT_PLANS: readonly ["Business", "Starter"];
849
+ /** Display name of a workspace plan. */
850
+ export type WorkspaceCurrentPlan = (typeof WORKSPACE_CURRENT_PLANS)[number];
851
+ /** Available workspace plan statuses. */
852
+ export declare const WORKSPACE_PLAN_STATUSES: readonly ["Active", "Downgraded", "Cancelled", "NeverSubscribed"];
853
+ /** Subscription status of a workspace plan. */
854
+ export type WorkspacePlanStatus = (typeof WORKSPACE_PLAN_STATUSES)[number];
808
855
  export declare const WorkspacePlanDetailsSchema: z.ZodObject<{
809
856
  currentMemberCount: z.ZodNumber;
810
857
  currentPlan: z.ZodEnum<{
@@ -1,6 +1,6 @@
1
- import type { ViewMode, GroupedBy, SortedBy, SortOrder } from './view-options.js';
1
+ import type { ViewMode, GroupedBy, SortedBy, SortOrder, CalendarLayout } from '../resources/view-options.js';
2
2
  export type CalendarSettings = {
3
- layout?: 'WEEK' | 'MONTH';
3
+ layout?: CalendarLayout;
4
4
  };
5
5
  export type ProjectViewOptionsDefaultsSetArgs = {
6
6
  projectId: string;
@@ -1,16 +1,12 @@
1
- export type ViewType = 'TODAY' | 'UPCOMING' | 'PROJECT' | 'LABEL' | 'FILTER' | 'WORKSPACE_FILTER' | 'SEARCH' | 'TEMPLATE_PREVIEW' | 'TASK_DETAIL' | 'AUTOMATION' | 'ASSIGNED' | 'OVERDUE' | 'WORKSPACE_OVERVIEW';
2
- export type ViewMode = 'LIST' | 'BOARD' | 'CALENDAR';
3
- export type GroupedBy = null | 'ASSIGNEE' | 'ADDED_DATE' | 'DUE_DATE' | 'DEADLINE' | 'LABEL' | 'PRIORITY' | 'PROJECT' | 'WORKSPACE';
4
- export type SortedBy = null | 'MANUAL' | 'ALPHABETICALLY' | 'ASSIGNEE' | 'DUE_DATE' | 'DEADLINE' | 'ADDED_DATE' | 'PRIORITY' | 'PROJECT' | 'WORKSPACE';
5
- export type SortOrder = 'ASC' | 'DESC';
1
+ import type { ViewType, ViewMode, GroupedBy, SortedBy, SortOrder } from '../resources/view-options.js';
6
2
  export type ViewOptionsSetArgs = {
7
3
  viewType: ViewType;
8
4
  objectId?: string;
9
- groupedBy?: GroupedBy;
5
+ groupedBy?: GroupedBy | null;
10
6
  filteredBy?: string | null;
11
7
  viewMode?: ViewMode;
12
8
  showCompletedTasks?: boolean;
13
- sortedBy?: SortedBy;
9
+ sortedBy?: SortedBy | null;
14
10
  sortOrder?: SortOrder | null;
15
11
  };
16
12
  export type ViewOptionsDeleteArgs = {