@doist/todoist-sdk 9.1.2 → 9.2.0-next.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 (43) hide show
  1. package/dist/cjs/clients/goals-client.js +145 -0
  2. package/dist/cjs/consts/endpoints.js +6 -1
  3. package/dist/cjs/test-utils/test-defaults.js +26 -2
  4. package/dist/cjs/todoist-api.js +33 -0
  5. package/dist/cjs/types/goals/index.js +18 -0
  6. package/dist/cjs/types/goals/requests.js +2 -0
  7. package/dist/cjs/types/goals/types.js +56 -0
  8. package/dist/cjs/types/index.js +1 -0
  9. package/dist/cjs/types/sync/commands/goals.js +2 -0
  10. package/dist/cjs/types/sync/commands/index.js +1 -0
  11. package/dist/cjs/types/sync/resource-types.js +1 -0
  12. package/dist/cjs/types/sync/response.js +12 -10
  13. package/dist/cjs/utils/validators.js +53 -51
  14. package/dist/esm/clients/goals-client.js +141 -0
  15. package/dist/esm/consts/endpoints.js +5 -0
  16. package/dist/esm/test-utils/test-defaults.js +24 -0
  17. package/dist/esm/todoist-api.js +33 -0
  18. package/dist/esm/types/goals/index.js +2 -0
  19. package/dist/esm/types/goals/requests.js +1 -0
  20. package/dist/esm/types/goals/types.js +53 -0
  21. package/dist/esm/types/index.js +1 -0
  22. package/dist/esm/types/sync/commands/goals.js +1 -0
  23. package/dist/esm/types/sync/commands/index.js +1 -0
  24. package/dist/esm/types/sync/resource-types.js +1 -0
  25. package/dist/esm/types/sync/response.js +2 -0
  26. package/dist/esm/utils/validators.js +2 -0
  27. package/dist/types/clients/goals-client.d.ts +20 -0
  28. package/dist/types/consts/endpoints.d.ts +5 -0
  29. package/dist/types/test-utils/msw-setup.d.ts +1 -1
  30. package/dist/types/test-utils/test-defaults.d.ts +4 -1
  31. package/dist/types/todoist-api.d.ts +12 -0
  32. package/dist/types/types/goals/index.d.ts +2 -0
  33. package/dist/types/types/goals/requests.d.ts +33 -0
  34. package/dist/types/types/goals/types.d.ts +51 -0
  35. package/dist/types/types/index.d.ts +1 -0
  36. package/dist/types/types/sync/commands/goals.d.ts +33 -0
  37. package/dist/types/types/sync/commands/index.d.ts +9 -0
  38. package/dist/types/types/sync/resource-types.d.ts +1 -1
  39. package/dist/types/types/sync/resources/view-options.d.ts +6 -6
  40. package/dist/types/types/sync/response.d.ts +29 -4
  41. package/dist/types/types/tasks/requests.d.ts +1 -0
  42. package/dist/types/utils/validators.d.ts +55 -8
  43. package/package.json +5 -5
@@ -0,0 +1,141 @@
1
+ import { z } from 'zod';
2
+ import { ENDPOINT_REST_GOALS, ENDPOINT_REST_GOALS_SEARCH, GOAL_COMPLETE, GOAL_TASKS, GOAL_UNCOMPLETE, } from '../consts/endpoints.js';
3
+ import { isSuccess, request } from '../transport/http-client.js';
4
+ import { generatePath } from '../utils/request-helpers.js';
5
+ import { validateGoal, validateGoalArray } from '../utils/validators.js';
6
+ import { BaseClient } from './base-client.js';
7
+ /**
8
+ * Internal sub-client handling all goal-domain endpoints.
9
+ *
10
+ * Instantiated by `TodoistApi`; every public goal method on `TodoistApi`
11
+ * delegates here. See `todoist-api.ts` for the user-facing JSDoc.
12
+ */
13
+ export class GoalsClient extends BaseClient {
14
+ async getGoals(args) {
15
+ const { data: { results, nextCursor }, } = await request({
16
+ httpMethod: 'GET',
17
+ baseUri: this.syncApiBase,
18
+ relativePath: ENDPOINT_REST_GOALS,
19
+ apiToken: this.authToken,
20
+ customFetch: this.customFetch,
21
+ payload: args,
22
+ });
23
+ return {
24
+ results: validateGoalArray(results),
25
+ nextCursor,
26
+ };
27
+ }
28
+ async searchGoals(args) {
29
+ const { data: { results, nextCursor }, } = await request({
30
+ httpMethod: 'GET',
31
+ baseUri: this.syncApiBase,
32
+ relativePath: ENDPOINT_REST_GOALS_SEARCH,
33
+ apiToken: this.authToken,
34
+ customFetch: this.customFetch,
35
+ payload: args,
36
+ });
37
+ return {
38
+ results: validateGoalArray(results),
39
+ nextCursor,
40
+ };
41
+ }
42
+ async getGoal(id) {
43
+ z.string().parse(id);
44
+ const response = await request({
45
+ httpMethod: 'GET',
46
+ baseUri: this.syncApiBase,
47
+ relativePath: generatePath(ENDPOINT_REST_GOALS, id),
48
+ apiToken: this.authToken,
49
+ customFetch: this.customFetch,
50
+ });
51
+ return validateGoal(response.data);
52
+ }
53
+ async addGoal(args, requestId) {
54
+ const response = await request({
55
+ httpMethod: 'POST',
56
+ baseUri: this.syncApiBase,
57
+ relativePath: ENDPOINT_REST_GOALS,
58
+ apiToken: this.authToken,
59
+ customFetch: this.customFetch,
60
+ payload: args,
61
+ requestId: requestId,
62
+ });
63
+ return validateGoal(response.data);
64
+ }
65
+ async updateGoal(id, args, requestId) {
66
+ z.string().parse(id);
67
+ const response = await request({
68
+ httpMethod: 'POST',
69
+ baseUri: this.syncApiBase,
70
+ relativePath: generatePath(ENDPOINT_REST_GOALS, id),
71
+ apiToken: this.authToken,
72
+ customFetch: this.customFetch,
73
+ payload: args,
74
+ requestId: requestId,
75
+ });
76
+ return validateGoal(response.data);
77
+ }
78
+ async deleteGoal(id, requestId) {
79
+ z.string().parse(id);
80
+ const response = await request({
81
+ httpMethod: 'DELETE',
82
+ baseUri: this.syncApiBase,
83
+ relativePath: generatePath(ENDPOINT_REST_GOALS, id),
84
+ apiToken: this.authToken,
85
+ customFetch: this.customFetch,
86
+ requestId: requestId,
87
+ });
88
+ return isSuccess(response);
89
+ }
90
+ async completeGoal(id, requestId) {
91
+ z.string().parse(id);
92
+ const response = await request({
93
+ httpMethod: 'POST',
94
+ baseUri: this.syncApiBase,
95
+ relativePath: generatePath(ENDPOINT_REST_GOALS, id, GOAL_COMPLETE),
96
+ apiToken: this.authToken,
97
+ customFetch: this.customFetch,
98
+ requestId: requestId,
99
+ });
100
+ return validateGoal(response.data);
101
+ }
102
+ async uncompleteGoal(id, requestId) {
103
+ z.string().parse(id);
104
+ const response = await request({
105
+ httpMethod: 'POST',
106
+ baseUri: this.syncApiBase,
107
+ relativePath: generatePath(ENDPOINT_REST_GOALS, id, GOAL_UNCOMPLETE),
108
+ apiToken: this.authToken,
109
+ customFetch: this.customFetch,
110
+ requestId: requestId,
111
+ });
112
+ return validateGoal(response.data);
113
+ }
114
+ async linkTaskToGoal({ goalId, taskId }, requestId) {
115
+ z.string().parse(goalId);
116
+ z.string().parse(taskId);
117
+ const response = await request({
118
+ httpMethod: 'POST',
119
+ baseUri: this.syncApiBase,
120
+ relativePath: generatePath(ENDPOINT_REST_GOALS, goalId, GOAL_TASKS),
121
+ apiToken: this.authToken,
122
+ customFetch: this.customFetch,
123
+ payload: { itemId: taskId },
124
+ requestId: requestId,
125
+ });
126
+ return validateGoal(response.data);
127
+ }
128
+ async unlinkTaskFromGoal({ goalId, taskId }, requestId) {
129
+ z.string().parse(goalId);
130
+ z.string().parse(taskId);
131
+ const response = await request({
132
+ httpMethod: 'DELETE',
133
+ baseUri: this.syncApiBase,
134
+ relativePath: generatePath(ENDPOINT_REST_GOALS, goalId, GOAL_TASKS, taskId),
135
+ apiToken: this.authToken,
136
+ customFetch: this.customFetch,
137
+ requestId: requestId,
138
+ });
139
+ return isSuccess(response);
140
+ }
141
+ }
@@ -70,6 +70,11 @@ export const ENDPOINT_GET_TOKEN = 'access_token';
70
70
  export const ENDPOINT_REVOKE = 'revoke';
71
71
  export const ENDPOINT_REGISTER = 'register';
72
72
  export const ENDPOINT_REST_FOLDERS = 'folders';
73
+ export const ENDPOINT_REST_GOALS = 'goals';
74
+ export const ENDPOINT_REST_GOALS_SEARCH = ENDPOINT_REST_GOALS + '/search';
75
+ export const GOAL_COMPLETE = 'complete';
76
+ export const GOAL_UNCOMPLETE = 'uncomplete';
77
+ export const GOAL_TASKS = 'items';
73
78
  // Workspace endpoints
74
79
  export const ENDPOINT_REST_WORKSPACES = 'workspaces';
75
80
  export const ENDPOINT_WORKSPACE_INVITATIONS = 'workspaces/invitations';
@@ -277,6 +277,30 @@ export const DEFAULT_COLLABORATOR_STATE = {
277
277
  state: 'active',
278
278
  isDeleted: false,
279
279
  };
280
+ export const DEFAULT_GOAL_ID = '550e8400-e29b-41d4-a716-446655440000';
281
+ export const DEFAULT_GOAL = {
282
+ id: DEFAULT_GOAL_ID,
283
+ ownerType: 'USER',
284
+ ownerId: DEFAULT_USER_ID,
285
+ name: 'Ship v2',
286
+ description: 'Launch the new version',
287
+ deadline: '2026-04-03',
288
+ parentGoalId: null,
289
+ childOrder: 0,
290
+ isCompleted: false,
291
+ completedAt: null,
292
+ responsibleUid: null,
293
+ isDeleted: false,
294
+ progress: {
295
+ totalTaskCount: 5,
296
+ completedTaskCount: 2,
297
+ percentage: 40,
298
+ },
299
+ creatorUid: DEFAULT_USER_ID,
300
+ createdAt: defaultDate(),
301
+ updatedAt: defaultDate(),
302
+ };
303
+ export const DEFAULT_GOAL_NO_PROGRESS = Object.assign(Object.assign({}, DEFAULT_GOAL), { id: 'e5f6g7h8-e29b-41d4-a716-446655440001', progress: undefined });
280
304
  export const DEFAULT_APP_ID = '42';
281
305
  export const DEFAULT_INSTALLATION_ID = '1001';
282
306
  export const DEFAULT_UI_EXTENSION_ID = '2002';
@@ -4,6 +4,7 @@ import { BackupClient } from './clients/backup-client.js';
4
4
  import { CommentClient } from './clients/comment-client.js';
5
5
  import { EmailClient } from './clients/email-client.js';
6
6
  import { FolderClient } from './clients/folder-client.js';
7
+ import { GoalsClient } from './clients/goals-client.js';
7
8
  import { IdMappingClient } from './clients/id-mapping-client.js';
8
9
  import { InsightsClient } from './clients/insights-client.js';
9
10
  import { LabelClient } from './clients/label-client.js';
@@ -58,6 +59,7 @@ export class TodoistApi {
58
59
  this.activityClient = new ActivityClient(clientDeps);
59
60
  this.productivityClient = new ProductivityClient(clientDeps);
60
61
  this.workspaceClient = new WorkspaceClient(clientDeps);
62
+ this.goalsClient = new GoalsClient(clientDeps);
61
63
  this.appClient = new AppClient(clientDeps);
62
64
  this.uiExtensionClient = new UiExtensionClient(clientDeps);
63
65
  }
@@ -939,6 +941,37 @@ export class TodoistApi {
939
941
  async deleteFolder(id, requestId) {
940
942
  return this.folderClient.deleteFolder(id, requestId);
941
943
  }
944
+ // ── Goals ──
945
+ async getGoals(args) {
946
+ return this.goalsClient.getGoals(args);
947
+ }
948
+ async searchGoals(args) {
949
+ return this.goalsClient.searchGoals(args);
950
+ }
951
+ async getGoal(id) {
952
+ return this.goalsClient.getGoal(id);
953
+ }
954
+ async addGoal(args, requestId) {
955
+ return this.goalsClient.addGoal(args, requestId);
956
+ }
957
+ async updateGoal(id, args, requestId) {
958
+ return this.goalsClient.updateGoal(id, args, requestId);
959
+ }
960
+ async deleteGoal(id, requestId) {
961
+ return this.goalsClient.deleteGoal(id, requestId);
962
+ }
963
+ async completeGoal(id, requestId) {
964
+ return this.goalsClient.completeGoal(id, requestId);
965
+ }
966
+ async uncompleteGoal(id, requestId) {
967
+ return this.goalsClient.uncompleteGoal(id, requestId);
968
+ }
969
+ async linkTaskToGoal(args, requestId) {
970
+ return this.goalsClient.linkTaskToGoal(args, requestId);
971
+ }
972
+ async unlinkTaskFromGoal(args, requestId) {
973
+ return this.goalsClient.unlinkTaskFromGoal(args, requestId);
974
+ }
942
975
  // ── Backups ──
943
976
  /**
944
977
  * Retrieves a list of available backups.
@@ -0,0 +1,2 @@
1
+ export * from './types.js';
2
+ export * from './requests.js';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,53 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { z } from 'zod';
13
+ /** Available goal owner types. */
14
+ export const GOAL_OWNER_TYPES = ['USER', 'WORKSPACE'];
15
+ /**
16
+ * Progress of a {@link Goal}.
17
+ *
18
+ * The REST API returns these counts under `total_item_count` / `completed_item_count`,
19
+ * reflecting the backend's generic "item" terminology. The SDK normalizes them to
20
+ * `totalTaskCount` / `completedTaskCount` so the public surface consistently speaks
21
+ * in "tasks" (matching the rest of the SDK). The `preprocess` step below performs
22
+ * that rename after the transport layer's snake_case → camelCase conversion — do not
23
+ * remove it without also changing the downstream field names.
24
+ */
25
+ export const GoalProgressSchema = z.preprocess((raw) => {
26
+ if (raw === null || raw === undefined || typeof raw !== 'object' || Array.isArray(raw)) {
27
+ return raw;
28
+ }
29
+ const _a = raw, { totalItemCount, completedItemCount, totalTaskCount, completedTaskCount } = _a, rest = __rest(_a, ["totalItemCount", "completedItemCount", "totalTaskCount", "completedTaskCount"]);
30
+ return Object.assign(Object.assign({}, rest), { totalTaskCount: totalTaskCount !== null && totalTaskCount !== void 0 ? totalTaskCount : totalItemCount, completedTaskCount: completedTaskCount !== null && completedTaskCount !== void 0 ? completedTaskCount : completedItemCount });
31
+ }, z.looseObject({
32
+ totalTaskCount: z.number().int(),
33
+ completedTaskCount: z.number().int(),
34
+ percentage: z.number(),
35
+ }));
36
+ export const GoalSchema = z.looseObject({
37
+ id: z.string(),
38
+ ownerType: z.enum(GOAL_OWNER_TYPES),
39
+ ownerId: z.string(),
40
+ name: z.string(),
41
+ description: z.string().nullable(),
42
+ deadline: z.string().nullable(),
43
+ parentGoalId: z.string().nullable(),
44
+ childOrder: z.number().int(),
45
+ isCompleted: z.boolean(),
46
+ completedAt: z.coerce.date().nullable(),
47
+ responsibleUid: z.string().nullable(),
48
+ isDeleted: z.boolean(),
49
+ progress: GoalProgressSchema.optional(),
50
+ creatorUid: z.string(),
51
+ createdAt: z.coerce.date(),
52
+ updatedAt: z.coerce.date(),
53
+ });
@@ -9,6 +9,7 @@ export * from './productivity/index.js';
9
9
  export * from './activity/index.js';
10
10
  export * from './workspaces/index.js';
11
11
  export * from './folders/index.js';
12
+ export * from './goals/index.js';
12
13
  export * from './insights/index.js';
13
14
  export * from './backups/index.js';
14
15
  export * from './id-mappings/index.js';
@@ -0,0 +1 @@
1
+ export {};
@@ -11,6 +11,7 @@ export * from './workspaces.js';
11
11
  export * from './folders.js';
12
12
  export * from './workspace-filters.js';
13
13
  export * from './workspace-goals.js';
14
+ export * from './goals.js';
14
15
  export * from './notifications.js';
15
16
  export * from './sharing.js';
16
17
  export * from './view-options.js';
@@ -29,6 +29,7 @@ export const SYNC_RESOURCE_TYPES = [
29
29
  'role_actions',
30
30
  'folders',
31
31
  'workspace_goals',
32
+ 'goals',
32
33
  'day_orders',
33
34
  'calendars',
34
35
  'calendar_accounts',
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { GoalSchema } from '../goals/types.js';
2
3
  import { LabelSchema } from '../labels/types.js';
3
4
  import { ProjectSchema } from '../projects/types.js';
4
5
  import { SectionSchema } from '../sections/types.js';
@@ -43,6 +44,7 @@ export const SyncResponseSchema = z.looseObject({
43
44
  projectViewOptionsDefaults: z.array(ProjectViewOptionsDefaultsSchema).optional(),
44
45
  roleActions: z.array(z.record(z.string(), z.unknown())).optional(),
45
46
  folders: z.array(FolderSchema).optional(),
47
+ goals: z.array(GoalSchema).optional(),
46
48
  workspaceGoals: z.array(WorkspaceGoalSchema).optional(),
47
49
  dayOrders: z.record(z.string(), z.number()).optional(),
48
50
  calendars: z.array(CalendarSchema).optional(),
@@ -3,6 +3,7 @@ import { ActivityEventSchema } from '../types/activity/types.js';
3
3
  import { AppSchema, AppWithUserCountSchema, AppSecretsSchema, AppVerificationTokenSchema, AppTestTokenSchema, AppDistributionTokenSchema, AppByDistributionTokenSchema, AppWebhookSchema, AppInstallationSchema, UserAuthorizationSchema, } from '../types/apps/types.js';
4
4
  import { BackupSchema } from '../types/backups/types.js';
5
5
  import { AttachmentSchema, CommentSchema } from '../types/comments/types.js';
6
+ import { GoalSchema } from '../types/goals/types.js';
6
7
  import { IdMappingSchema, MovedIdSchema } from '../types/id-mappings/types.js';
7
8
  import { ProjectActivityStatsSchema, ProjectHealthSchema, ProjectHealthContextSchema, ProjectProgressSchema, WorkspaceInsightsSchema, } from '../types/insights/types.js';
8
9
  import { LabelSchema } from '../types/labels/types.js';
@@ -58,6 +59,7 @@ export const { validate: validateFilter, validateArray: validateFilterArray } =
58
59
  export const { validate: validateCollaborator, validateArray: validateCollaboratorArray } = createValidator(CollaboratorSchema);
59
60
  export const { validate: validateCollaboratorState, validateArray: validateCollaboratorStateArray, } = createValidator(CollaboratorStateSchema);
60
61
  export const { validate: validateFolder, validateArray: validateFolderArray } = createValidator(FolderSchema);
62
+ export const { validate: validateGoal, validateArray: validateGoalArray } = createValidator(GoalSchema);
61
63
  export const { validate: validateNote, validateArray: validateNoteArray } = createValidator(NoteSchema);
62
64
  export const { validate: validateTooltips } = createValidator(TooltipsSchema);
63
65
  export const { validate: validateWorkspaceFilter, validateArray: validateWorkspaceFilterArray } = createValidator(WorkspaceFilterSchema);
@@ -0,0 +1,20 @@
1
+ import type { AddGoalArgs, GetGoalsArgs, GetGoalsResponse, Goal, SearchGoalsArgs, TaskLinkingArgs, UpdateGoalArgs } from '../types/goals/index.js';
2
+ import { BaseClient } from './base-client.js';
3
+ /**
4
+ * Internal sub-client handling all goal-domain endpoints.
5
+ *
6
+ * Instantiated by `TodoistApi`; every public goal method on `TodoistApi`
7
+ * delegates here. See `todoist-api.ts` for the user-facing JSDoc.
8
+ */
9
+ export declare class GoalsClient extends BaseClient {
10
+ getGoals(args?: GetGoalsArgs): Promise<GetGoalsResponse>;
11
+ searchGoals(args: SearchGoalsArgs): Promise<GetGoalsResponse>;
12
+ getGoal(id: string): Promise<Goal>;
13
+ addGoal(args: AddGoalArgs, requestId?: string): Promise<Goal>;
14
+ updateGoal(id: string, args: UpdateGoalArgs, requestId?: string): Promise<Goal>;
15
+ deleteGoal(id: string, requestId?: string): Promise<boolean>;
16
+ completeGoal(id: string, requestId?: string): Promise<Goal>;
17
+ uncompleteGoal(id: string, requestId?: string): Promise<Goal>;
18
+ linkTaskToGoal({ goalId, taskId }: TaskLinkingArgs, requestId?: string): Promise<Goal>;
19
+ unlinkTaskFromGoal({ goalId, taskId }: TaskLinkingArgs, requestId?: string): Promise<boolean>;
20
+ }
@@ -59,6 +59,11 @@ export declare const ENDPOINT_GET_TOKEN = "access_token";
59
59
  export declare const ENDPOINT_REVOKE = "revoke";
60
60
  export declare const ENDPOINT_REGISTER = "register";
61
61
  export declare const ENDPOINT_REST_FOLDERS = "folders";
62
+ export declare const ENDPOINT_REST_GOALS = "goals";
63
+ export declare const ENDPOINT_REST_GOALS_SEARCH: string;
64
+ export declare const GOAL_COMPLETE = "complete";
65
+ export declare const GOAL_UNCOMPLETE = "uncomplete";
66
+ export declare const GOAL_TASKS = "items";
62
67
  export declare const ENDPOINT_REST_WORKSPACES = "workspaces";
63
68
  export declare const ENDPOINT_WORKSPACE_INVITATIONS = "workspaces/invitations";
64
69
  export declare const ENDPOINT_WORKSPACE_INVITATIONS_ALL = "workspaces/invitations/all";
@@ -18,7 +18,7 @@ export declare function getLastRequest(): CapturedRequest | undefined;
18
18
  export declare function getAllRequests(): CapturedRequest[];
19
19
  export declare function clearCapturedRequests(): void;
20
20
  export declare const handlers: never[];
21
- export declare const server: import("msw/node").SetupServerApi;
21
+ export declare const server: import("msw/node").SetupServer;
22
22
  export declare function mockApiResponse<T extends DefaultBodyType>({ endpoint, data, options, }: {
23
23
  endpoint: string;
24
24
  data: T;
@@ -1,4 +1,4 @@
1
- import { Label, Section, Task, User, Attachment, Duration, Deadline, RawComment, PersonalProject, WorkspaceProject, Reminder, Folder, App, AppWithUserCount, AppSecrets, AppVerificationToken, AppTestToken, AppDistributionToken, AppWebhook, AppInstallation, UserAuthorization, UiExtension } from '../types/index.js';
1
+ import { Label, Section, Task, User, Attachment, Duration, Deadline, RawComment, PersonalProject, WorkspaceProject, Reminder, Folder, Goal, App, AppWithUserCount, AppSecrets, AppVerificationToken, AppTestToken, AppDistributionToken, AppWebhook, AppInstallation, UserAuthorization, UiExtension } from '../types/index.js';
2
2
  import type { Collaborator, CollaboratorState } from '../types/sync/resources/collaborators.js';
3
3
  import type { Note } from '../types/sync/resources/notes.js';
4
4
  export declare const DEFAULT_TASK_ID = "1234";
@@ -264,6 +264,9 @@ export declare const COMMENT_WITH_OPTIONALS_AS_NULL_PROJECT: {
264
264
  export declare const DEFAULT_FOLDER: Folder;
265
265
  export declare const DEFAULT_COLLABORATOR: Collaborator;
266
266
  export declare const DEFAULT_COLLABORATOR_STATE: CollaboratorState;
267
+ export declare const DEFAULT_GOAL_ID = "550e8400-e29b-41d4-a716-446655440000";
268
+ export declare const DEFAULT_GOAL: Goal;
269
+ export declare const DEFAULT_GOAL_NO_PROGRESS: Goal;
267
270
  export declare const DEFAULT_APP_ID = "42";
268
271
  export declare const DEFAULT_INSTALLATION_ID = "1001";
269
272
  export declare const DEFAULT_UI_EXTENSION_ID = "2002";
@@ -5,6 +5,7 @@ import { Backup, GetBackupsArgs, DownloadBackupArgs } from './types/backups/inde
5
5
  import { Attachment, Comment, AddCommentArgs, UpdateCommentArgs, GetProjectCommentsArgs, GetTaskCommentsArgs, GetCommentsResponse } from './types/comments/index.js';
6
6
  import { GetOrCreateEmailArgs, GetOrCreateEmailResponse, DisableEmailArgs } from './types/emails/index.js';
7
7
  import { GetFoldersArgs, GetFoldersResponse, AddFolderArgs, UpdateFolderArgs } from './types/folders/index.js';
8
+ import type { AddGoalArgs, GetGoalsArgs, GetGoalsResponse, Goal, SearchGoalsArgs, TaskLinkingArgs, UpdateGoalArgs } from './types/goals/index.js';
8
9
  import { CustomFetch, FileResponse } from './types/http.js';
9
10
  import { IdMapping, MovedId, GetIdMappingsArgs, GetMovedIdsArgs } from './types/id-mappings/index.js';
10
11
  import { ProjectActivityStats, ProjectHealth, ProjectHealthContext, ProjectProgress, WorkspaceInsights, GetProjectActivityStatsArgs, GetWorkspaceInsightsArgs } from './types/insights/index.js';
@@ -75,6 +76,7 @@ export declare class TodoistApi {
75
76
  private readonly activityClient;
76
77
  private readonly productivityClient;
77
78
  private readonly workspaceClient;
79
+ private readonly goalsClient;
78
80
  private readonly appClient;
79
81
  private readonly uiExtensionClient;
80
82
  constructor(
@@ -787,6 +789,16 @@ export declare class TodoistApi {
787
789
  * @returns A promise that resolves to `true` if successful.
788
790
  */
789
791
  deleteFolder(id: string, requestId?: string): Promise<boolean>;
792
+ getGoals(args?: GetGoalsArgs): Promise<GetGoalsResponse>;
793
+ searchGoals(args: SearchGoalsArgs): Promise<GetGoalsResponse>;
794
+ getGoal(id: string): Promise<Goal>;
795
+ addGoal(args: AddGoalArgs, requestId?: string): Promise<Goal>;
796
+ updateGoal(id: string, args: UpdateGoalArgs, requestId?: string): Promise<Goal>;
797
+ deleteGoal(id: string, requestId?: string): Promise<boolean>;
798
+ completeGoal(id: string, requestId?: string): Promise<Goal>;
799
+ uncompleteGoal(id: string, requestId?: string): Promise<Goal>;
800
+ linkTaskToGoal(args: TaskLinkingArgs, requestId?: string): Promise<Goal>;
801
+ unlinkTaskFromGoal(args: TaskLinkingArgs, requestId?: string): Promise<boolean>;
790
802
  /**
791
803
  * Retrieves a list of available backups.
792
804
  *
@@ -0,0 +1,2 @@
1
+ export * from './types.js';
2
+ export * from './requests.js';
@@ -0,0 +1,33 @@
1
+ import type { SearchArgs } from '../common.js';
2
+ import type { Workspace } from '../workspaces/index.js';
3
+ import type { Goal, GoalOwnerType } from './types.js';
4
+ export type GetGoalsArgs = {
5
+ ownerType?: GoalOwnerType;
6
+ workspaceId?: Workspace['id'];
7
+ cursor?: string | null;
8
+ limit?: number;
9
+ };
10
+ export type SearchGoalsArgs = SearchArgs & {
11
+ ownerType?: GoalOwnerType;
12
+ };
13
+ export type GetGoalsResponse = {
14
+ results: Goal[];
15
+ nextCursor: string | null;
16
+ };
17
+ export type AddGoalArgs = {
18
+ name: string;
19
+ workspaceId?: string;
20
+ description?: string | null;
21
+ deadline?: string | null;
22
+ responsibleUid?: string | null;
23
+ };
24
+ export type UpdateGoalArgs = {
25
+ name?: string;
26
+ description?: string | null;
27
+ deadline?: string | null;
28
+ responsibleUid?: string | null;
29
+ };
30
+ export type TaskLinkingArgs = {
31
+ goalId: string;
32
+ taskId: string;
33
+ };
@@ -0,0 +1,51 @@
1
+ import { z } from 'zod';
2
+ /** Available goal owner types. */
3
+ export declare const GOAL_OWNER_TYPES: readonly ["USER", "WORKSPACE"];
4
+ /** Goal owner type. */
5
+ export type GoalOwnerType = (typeof GOAL_OWNER_TYPES)[number];
6
+ /**
7
+ * Progress of a {@link Goal}.
8
+ *
9
+ * The REST API returns these counts under `total_item_count` / `completed_item_count`,
10
+ * reflecting the backend's generic "item" terminology. The SDK normalizes them to
11
+ * `totalTaskCount` / `completedTaskCount` so the public surface consistently speaks
12
+ * in "tasks" (matching the rest of the SDK). The `preprocess` step below performs
13
+ * that rename after the transport layer's snake_case → camelCase conversion — do not
14
+ * remove it without also changing the downstream field names.
15
+ */
16
+ export declare const GoalProgressSchema: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodObject<{
17
+ totalTaskCount: z.ZodNumber;
18
+ completedTaskCount: z.ZodNumber;
19
+ percentage: z.ZodNumber;
20
+ }, z.core.$loose>>;
21
+ export type GoalProgress = z.infer<typeof GoalProgressSchema>;
22
+ export declare const GoalSchema: z.ZodObject<{
23
+ id: z.ZodString;
24
+ ownerType: z.ZodEnum<{
25
+ USER: "USER";
26
+ WORKSPACE: "WORKSPACE";
27
+ }>;
28
+ ownerId: z.ZodString;
29
+ name: z.ZodString;
30
+ description: z.ZodNullable<z.ZodString>;
31
+ deadline: z.ZodNullable<z.ZodString>;
32
+ parentGoalId: z.ZodNullable<z.ZodString>;
33
+ childOrder: z.ZodNumber;
34
+ isCompleted: z.ZodBoolean;
35
+ completedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
36
+ responsibleUid: z.ZodNullable<z.ZodString>;
37
+ isDeleted: z.ZodBoolean;
38
+ progress: z.ZodOptional<z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodObject<{
39
+ totalTaskCount: z.ZodNumber;
40
+ completedTaskCount: z.ZodNumber;
41
+ percentage: z.ZodNumber;
42
+ }, z.core.$loose>>>;
43
+ creatorUid: z.ZodString;
44
+ createdAt: z.ZodCoercedDate<unknown>;
45
+ updatedAt: z.ZodCoercedDate<unknown>;
46
+ }, z.core.$loose>;
47
+ /**
48
+ * Represents a goal in Todoist.
49
+ * Goals support dual ownership: personal (ownerType=USER) and workspace (ownerType=WORKSPACE).
50
+ */
51
+ export type Goal = z.infer<typeof GoalSchema>;
@@ -9,6 +9,7 @@ export * from './productivity/index.js';
9
9
  export * from './activity/index.js';
10
10
  export * from './workspaces/index.js';
11
11
  export * from './folders/index.js';
12
+ export * from './goals/index.js';
12
13
  export * from './insights/index.js';
13
14
  export * from './backups/index.js';
14
15
  export * from './id-mappings/index.js';
@@ -0,0 +1,33 @@
1
+ import type { GoalOwnerType } from '../../goals/types.js';
2
+ export type GoalAddArgs = {
3
+ ownerType: GoalOwnerType;
4
+ ownerId: string;
5
+ name: string;
6
+ description?: string | null;
7
+ deadline?: string | null;
8
+ responsibleUid?: string | null;
9
+ };
10
+ export type GoalUpdateArgs = {
11
+ id: string;
12
+ name?: string;
13
+ description?: string | null;
14
+ deadline?: string | null;
15
+ responsibleUid?: string | null;
16
+ };
17
+ export type GoalCompleteArgs = {
18
+ id: string;
19
+ };
20
+ export type GoalUncompleteArgs = {
21
+ id: string;
22
+ };
23
+ export type GoalDeleteArgs = {
24
+ id: string;
25
+ };
26
+ export type GoalLinkItemArgs = {
27
+ goalId: string;
28
+ itemId: string;
29
+ };
30
+ export type GoalUnlinkItemArgs = {
31
+ goalId: string;
32
+ itemId: string;
33
+ };
@@ -1,6 +1,7 @@
1
1
  import type { CalendarUpdateArgs, CalendarAccountUpdateArgs, CalendarAccountRestoreTaskCalendarArgs } from './calendars.js';
2
2
  import type { FilterAddArgs, FilterUpdateArgs, FilterUpdateOrdersArgs, FilterDeleteArgs } from './filters.js';
3
3
  import type { FolderAddArgs, FolderUpdateArgs, FolderDeleteArgs } from './folders.js';
4
+ import type { GoalAddArgs, GoalUpdateArgs, GoalCompleteArgs, GoalUncompleteArgs, GoalDeleteArgs, GoalLinkItemArgs, GoalUnlinkItemArgs } from './goals.js';
4
5
  import type { LabelAddArgs, LabelRenameArgs, LabelUpdateArgs, LabelUpdateOrdersArgs, LabelDeleteArgs, LabelDeleteOccurrencesArgs } from './labels.js';
5
6
  import type { NoteAddArgs, NoteUpdateArgs, NoteDeleteArgs, NoteReactionAddArgs, NoteReactionRemoveArgs } from './notes.js';
6
7
  import type { LiveNotificationsMarkUnreadArgs, LiveNotificationsMarkReadArgs, LiveNotificationsMarkReadAllArgs, LiveNotificationsSetLastReadArgs } from './notifications.js';
@@ -96,6 +97,13 @@ export type SyncCommandsMap = {
96
97
  workspace_goal_delete: WorkspaceGoalDeleteArgs;
97
98
  workspace_goal_project_add: WorkspaceGoalProjectAddArgs;
98
99
  workspace_goal_project_remove: WorkspaceGoalProjectRemoveArgs;
100
+ goal_add: GoalAddArgs;
101
+ goal_update: GoalUpdateArgs;
102
+ goal_complete: GoalCompleteArgs;
103
+ goal_uncomplete: GoalUncompleteArgs;
104
+ goal_delete: GoalDeleteArgs;
105
+ goal_link_item: GoalLinkItemArgs;
106
+ goal_unlink_item: GoalUnlinkItemArgs;
99
107
  live_notifications_mark_unread: LiveNotificationsMarkUnreadArgs;
100
108
  live_notifications_mark_read: LiveNotificationsMarkReadArgs;
101
109
  live_notifications_mark_read_all: LiveNotificationsMarkReadAllArgs;
@@ -163,6 +171,7 @@ export * from './workspaces.js';
163
171
  export * from './folders.js';
164
172
  export * from './workspace-filters.js';
165
173
  export * from './workspace-goals.js';
174
+ export * from './goals.js';
166
175
  export * from './notifications.js';
167
176
  export * from './sharing.js';
168
177
  export * from './view-options.js';
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * All available Sync API resource types.
3
3
  */
4
- export declare const SYNC_RESOURCE_TYPES: readonly ["labels", "projects", "items", "notes", "project_notes", "sections", "filters", "reminders", "reminders_location", "locations", "user", "live_notifications", "collaborators", "collaborator_states", "user_settings", "notification_settings", "user_plan_limits", "completed_info", "stats", "workspaces", "workspace_users", "workspace_filters", "view_options", "project_view_options_defaults", "role_actions", "folders", "workspace_goals", "day_orders", "calendars", "calendar_accounts", "suggestions", "tooltips"];
4
+ export declare const SYNC_RESOURCE_TYPES: readonly ["labels", "projects", "items", "notes", "project_notes", "sections", "filters", "reminders", "reminders_location", "locations", "user", "live_notifications", "collaborators", "collaborator_states", "user_settings", "notification_settings", "user_plan_limits", "completed_info", "stats", "workspaces", "workspace_users", "workspace_filters", "view_options", "project_view_options_defaults", "role_actions", "folders", "workspace_goals", "goals", "day_orders", "calendars", "calendar_accounts", "suggestions", "tooltips"];
5
5
  export type SyncResourceType = (typeof SYNC_RESOURCE_TYPES)[number];