ticktick-mcp 0.1.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.
- package/README.md +112 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1156 -0
- package/dist/index.js.map +1 -0
- package/dist/oauth.d.ts +228 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +415 -0
- package/dist/oauth.js.map +1 -0
- package/dist/sdk/client.d.ts +280 -0
- package/dist/sdk/client.d.ts.map +1 -0
- package/dist/sdk/client.js +388 -0
- package/dist/sdk/client.js.map +1 -0
- package/dist/sdk/errors.d.ts +92 -0
- package/dist/sdk/errors.d.ts.map +1 -0
- package/dist/sdk/errors.js +187 -0
- package/dist/sdk/errors.js.map +1 -0
- package/dist/sdk/index.d.ts +38 -0
- package/dist/sdk/index.d.ts.map +1 -0
- package/dist/sdk/index.js +46 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/sdk/types.d.ts +308 -0
- package/dist/sdk/types.d.ts.map +1 -0
- package/dist/sdk/types.js +28 -0
- package/dist/sdk/types.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TickTick SDK Client
|
|
3
|
+
*
|
|
4
|
+
* Main client class for interacting with the TickTick Open API.
|
|
5
|
+
* Provides typed methods for all documented API endpoints.
|
|
6
|
+
*/
|
|
7
|
+
import type { CreateProjectInput, CreateTaskInput, Project, ProjectWithTasks, Task, TickTickClientConfig, UpdateProjectInput, UpdateTaskInput, User } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* TickTick API Client
|
|
10
|
+
*
|
|
11
|
+
* Provides methods for interacting with the TickTick Open API.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const client = new TickTickClient({
|
|
16
|
+
* accessToken: 'your-oauth-access-token',
|
|
17
|
+
* region: 'global', // or 'china' for dida365.com
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* // Get user info
|
|
21
|
+
* const user = await client.getUser();
|
|
22
|
+
*
|
|
23
|
+
* // List all projects
|
|
24
|
+
* const projects = await client.listProjects();
|
|
25
|
+
*
|
|
26
|
+
* // Create a task
|
|
27
|
+
* const task = await client.createTask({
|
|
28
|
+
* title: 'My new task',
|
|
29
|
+
* projectId: 'project-id',
|
|
30
|
+
* priority: Priority.High,
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare class TickTickClient {
|
|
35
|
+
private readonly accessToken;
|
|
36
|
+
private readonly baseUrl;
|
|
37
|
+
private readonly timeout;
|
|
38
|
+
/**
|
|
39
|
+
* Create a new TickTick API client.
|
|
40
|
+
*
|
|
41
|
+
* @param config - Client configuration options
|
|
42
|
+
*/
|
|
43
|
+
constructor(config: TickTickClientConfig);
|
|
44
|
+
/**
|
|
45
|
+
* Make an HTTP request to the TickTick API.
|
|
46
|
+
*/
|
|
47
|
+
private request;
|
|
48
|
+
/**
|
|
49
|
+
* Make a GET request.
|
|
50
|
+
*/
|
|
51
|
+
private get;
|
|
52
|
+
/**
|
|
53
|
+
* Make a POST request.
|
|
54
|
+
*/
|
|
55
|
+
private post;
|
|
56
|
+
/**
|
|
57
|
+
* Make a DELETE request.
|
|
58
|
+
*/
|
|
59
|
+
private delete;
|
|
60
|
+
/**
|
|
61
|
+
* Get the current authenticated user's information.
|
|
62
|
+
*
|
|
63
|
+
* @returns The user's profile information
|
|
64
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* const user = await client.getUser();
|
|
69
|
+
* console.log(`Logged in as: ${user.name} (${user.username})`);
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
getUser(): Promise<User>;
|
|
73
|
+
/**
|
|
74
|
+
* List all projects for the authenticated user.
|
|
75
|
+
*
|
|
76
|
+
* @returns Array of all projects
|
|
77
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* const projects = await client.listProjects();
|
|
82
|
+
* for (const project of projects) {
|
|
83
|
+
* console.log(`${project.name} (${project.id})`);
|
|
84
|
+
* }
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
listProjects(): Promise<Project[]>;
|
|
88
|
+
/**
|
|
89
|
+
* Get a specific project by ID.
|
|
90
|
+
*
|
|
91
|
+
* @param projectId - The unique identifier of the project
|
|
92
|
+
* @returns The project details
|
|
93
|
+
* @throws {TickTickNotFoundError} If the project doesn't exist
|
|
94
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* const project = await client.getProject('project-id');
|
|
99
|
+
* console.log(`Project: ${project.name}`);
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
getProject(projectId: string): Promise<Project>;
|
|
103
|
+
/**
|
|
104
|
+
* Get a project with all its tasks.
|
|
105
|
+
*
|
|
106
|
+
* @param projectId - The unique identifier of the project
|
|
107
|
+
* @returns The project and all its tasks
|
|
108
|
+
* @throws {TickTickNotFoundError} If the project doesn't exist
|
|
109
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* const { project, tasks } = await client.getProjectWithTasks('project-id');
|
|
114
|
+
* console.log(`${project.name} has ${tasks.length} tasks`);
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
getProjectWithTasks(projectId: string): Promise<ProjectWithTasks>;
|
|
118
|
+
/**
|
|
119
|
+
* Create a new project.
|
|
120
|
+
*
|
|
121
|
+
* @param input - The project creation parameters
|
|
122
|
+
* @returns The created project
|
|
123
|
+
* @throws {TickTickBadRequestError} If the input is invalid
|
|
124
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```typescript
|
|
128
|
+
* const project = await client.createProject({
|
|
129
|
+
* name: 'My New Project',
|
|
130
|
+
* color: '#ff6b6b',
|
|
131
|
+
* viewMode: 'list',
|
|
132
|
+
* });
|
|
133
|
+
* console.log(`Created project: ${project.id}`);
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
createProject(input: CreateProjectInput): Promise<Project>;
|
|
137
|
+
/**
|
|
138
|
+
* Update an existing project.
|
|
139
|
+
*
|
|
140
|
+
* @param projectId - The unique identifier of the project to update
|
|
141
|
+
* @param input - The fields to update
|
|
142
|
+
* @returns The updated project
|
|
143
|
+
* @throws {TickTickNotFoundError} If the project doesn't exist
|
|
144
|
+
* @throws {TickTickBadRequestError} If the input is invalid
|
|
145
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```typescript
|
|
149
|
+
* const project = await client.updateProject('project-id', {
|
|
150
|
+
* name: 'Updated Name',
|
|
151
|
+
* color: '#4dabf7',
|
|
152
|
+
* });
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
updateProject(projectId: string, input: UpdateProjectInput): Promise<Project>;
|
|
156
|
+
/**
|
|
157
|
+
* Delete a project.
|
|
158
|
+
*
|
|
159
|
+
* @param projectId - The unique identifier of the project to delete
|
|
160
|
+
* @throws {TickTickNotFoundError} If the project doesn't exist
|
|
161
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```typescript
|
|
165
|
+
* await client.deleteProject('project-id');
|
|
166
|
+
* console.log('Project deleted');
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
deleteProject(projectId: string): Promise<void>;
|
|
170
|
+
/**
|
|
171
|
+
* Get a specific task by project ID and task ID.
|
|
172
|
+
*
|
|
173
|
+
* @param projectId - The project ID containing the task
|
|
174
|
+
* @param taskId - The unique identifier of the task
|
|
175
|
+
* @returns The task details
|
|
176
|
+
* @throws {TickTickNotFoundError} If the task or project doesn't exist
|
|
177
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```typescript
|
|
181
|
+
* const task = await client.getTask('project-id', 'task-id');
|
|
182
|
+
* console.log(`Task: ${task.title}`);
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
getTask(projectId: string, taskId: string): Promise<Task>;
|
|
186
|
+
/**
|
|
187
|
+
* Create a new task.
|
|
188
|
+
*
|
|
189
|
+
* @param input - The task creation parameters
|
|
190
|
+
* @returns The created task
|
|
191
|
+
* @throws {TickTickBadRequestError} If the input is invalid
|
|
192
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```typescript
|
|
196
|
+
* const task = await client.createTask({
|
|
197
|
+
* title: 'Complete report',
|
|
198
|
+
* projectId: 'project-id',
|
|
199
|
+
* content: 'Finish the quarterly report',
|
|
200
|
+
* dueDate: '2024-01-15T17:00:00+0000',
|
|
201
|
+
* priority: Priority.High,
|
|
202
|
+
* items: [
|
|
203
|
+
* { title: 'Write introduction', status: Status.Normal },
|
|
204
|
+
* { title: 'Add charts', status: Status.Normal },
|
|
205
|
+
* ],
|
|
206
|
+
* });
|
|
207
|
+
* console.log(`Created task: ${task.id}`);
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
createTask(input: CreateTaskInput): Promise<Task>;
|
|
211
|
+
/**
|
|
212
|
+
* Update an existing task.
|
|
213
|
+
*
|
|
214
|
+
* @param taskId - The unique identifier of the task to update
|
|
215
|
+
* @param input - The fields to update
|
|
216
|
+
* @returns The updated task
|
|
217
|
+
* @throws {TickTickNotFoundError} If the task doesn't exist
|
|
218
|
+
* @throws {TickTickBadRequestError} If the input is invalid
|
|
219
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* ```typescript
|
|
223
|
+
* const task = await client.updateTask('task-id', {
|
|
224
|
+
* title: 'Updated task title',
|
|
225
|
+
* priority: Priority.Medium,
|
|
226
|
+
* });
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
updateTask(taskId: string, input: UpdateTaskInput): Promise<Task>;
|
|
230
|
+
/**
|
|
231
|
+
* Mark a task as complete.
|
|
232
|
+
*
|
|
233
|
+
* @param projectId - The project ID containing the task
|
|
234
|
+
* @param taskId - The unique identifier of the task to complete
|
|
235
|
+
* @throws {TickTickNotFoundError} If the task or project doesn't exist
|
|
236
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
237
|
+
*
|
|
238
|
+
* @example
|
|
239
|
+
* ```typescript
|
|
240
|
+
* await client.completeTask('project-id', 'task-id');
|
|
241
|
+
* console.log('Task completed!');
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
244
|
+
completeTask(projectId: string, taskId: string): Promise<void>;
|
|
245
|
+
/**
|
|
246
|
+
* Delete a task.
|
|
247
|
+
*
|
|
248
|
+
* @param projectId - The project ID containing the task
|
|
249
|
+
* @param taskId - The unique identifier of the task to delete
|
|
250
|
+
* @throws {TickTickNotFoundError} If the task or project doesn't exist
|
|
251
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* ```typescript
|
|
255
|
+
* await client.deleteTask('project-id', 'task-id');
|
|
256
|
+
* console.log('Task deleted');
|
|
257
|
+
* ```
|
|
258
|
+
*/
|
|
259
|
+
deleteTask(projectId: string, taskId: string): Promise<void>;
|
|
260
|
+
/**
|
|
261
|
+
* Create multiple tasks at once.
|
|
262
|
+
*
|
|
263
|
+
* @param tasks - Array of tasks to create
|
|
264
|
+
* @returns Array of created tasks
|
|
265
|
+
* @throws {TickTickBadRequestError} If the input is invalid
|
|
266
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```typescript
|
|
270
|
+
* const tasks = await client.batchCreateTasks([
|
|
271
|
+
* { title: 'Task 1', projectId: 'project-id', priority: Priority.Low },
|
|
272
|
+
* { title: 'Task 2', projectId: 'project-id', priority: Priority.Medium },
|
|
273
|
+
* { title: 'Task 3', projectId: 'project-id', priority: Priority.High },
|
|
274
|
+
* ]);
|
|
275
|
+
* console.log(`Created ${tasks.length} tasks`);
|
|
276
|
+
* ```
|
|
277
|
+
*/
|
|
278
|
+
batchCreateTasks(tasks: CreateTaskInput[]): Promise<Task[]>;
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/sdk/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAEV,kBAAkB,EAClB,eAAe,EACf,OAAO,EACP,gBAAgB,EAChB,IAAI,EACJ,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EACf,IAAI,EACL,MAAM,YAAY,CAAC;AAepB;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC;;;;OAIG;gBACS,MAAM,EAAE,oBAAoB;IAWxC;;OAEG;YACW,OAAO;IAuErB;;OAEG;IACH,OAAO,CAAC,GAAG;IAIX;;OAEG;IACH,OAAO,CAAC,IAAI;IAIZ;;OAEG;IACH,OAAO,CAAC,MAAM;IAQd;;;;;;;;;;;OAWG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;;;;;;;;;;;;OAaG;IACG,YAAY,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAIxC;;;;;;;;;;;;;OAaG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrD;;;;;;;;;;;;;OAaG;IACG,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAMvE;;;;;;;;;;;;;;;;;OAiBG;IACG,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;IAIhE;;;;;;;;;;;;;;;;;OAiBG;IACG,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,OAAO,CAAC;IAOnB;;;;;;;;;;;;OAYG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQrD;;;;;;;;;;;;;;OAcG;IACG,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/D;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACG,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvD;;;;;;;;;;;;;;;;;OAiBG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvE;;;;;;;;;;;;;OAaG;IACG,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMpE;;;;;;;;;;;;;OAaG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMlE;;;;;;;;;;;;;;;;;OAiBG;IACG,gBAAgB,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;CAIlE"}
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TickTick SDK Client
|
|
3
|
+
*
|
|
4
|
+
* Main client class for interacting with the TickTick Open API.
|
|
5
|
+
* Provides typed methods for all documented API endpoints.
|
|
6
|
+
*/
|
|
7
|
+
import { createErrorFromResponse, TickTickNetworkError, TickTickTimeoutError, } from "./errors.js";
|
|
8
|
+
/**
|
|
9
|
+
* Base URLs for different regions.
|
|
10
|
+
*/
|
|
11
|
+
const BASE_URLS = {
|
|
12
|
+
global: "https://api.ticktick.com/open/v1",
|
|
13
|
+
china: "https://api.dida365.com/open/v1",
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Default timeout for API requests (30 seconds).
|
|
17
|
+
*/
|
|
18
|
+
const DEFAULT_TIMEOUT = 30000;
|
|
19
|
+
/**
|
|
20
|
+
* TickTick API Client
|
|
21
|
+
*
|
|
22
|
+
* Provides methods for interacting with the TickTick Open API.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const client = new TickTickClient({
|
|
27
|
+
* accessToken: 'your-oauth-access-token',
|
|
28
|
+
* region: 'global', // or 'china' for dida365.com
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* // Get user info
|
|
32
|
+
* const user = await client.getUser();
|
|
33
|
+
*
|
|
34
|
+
* // List all projects
|
|
35
|
+
* const projects = await client.listProjects();
|
|
36
|
+
*
|
|
37
|
+
* // Create a task
|
|
38
|
+
* const task = await client.createTask({
|
|
39
|
+
* title: 'My new task',
|
|
40
|
+
* projectId: 'project-id',
|
|
41
|
+
* priority: Priority.High,
|
|
42
|
+
* });
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export class TickTickClient {
|
|
46
|
+
accessToken;
|
|
47
|
+
baseUrl;
|
|
48
|
+
timeout;
|
|
49
|
+
/**
|
|
50
|
+
* Create a new TickTick API client.
|
|
51
|
+
*
|
|
52
|
+
* @param config - Client configuration options
|
|
53
|
+
*/
|
|
54
|
+
constructor(config) {
|
|
55
|
+
this.accessToken = config.accessToken;
|
|
56
|
+
this.baseUrl =
|
|
57
|
+
config.baseUrl ?? BASE_URLS[config.region ?? "global"];
|
|
58
|
+
this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
|
|
59
|
+
}
|
|
60
|
+
// ===========================================================================
|
|
61
|
+
// Private Helper Methods
|
|
62
|
+
// ===========================================================================
|
|
63
|
+
/**
|
|
64
|
+
* Make an HTTP request to the TickTick API.
|
|
65
|
+
*/
|
|
66
|
+
async request(method, path, body) {
|
|
67
|
+
const url = `${this.baseUrl}${path}`;
|
|
68
|
+
const controller = new AbortController();
|
|
69
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
70
|
+
const headers = {
|
|
71
|
+
Authorization: `Bearer ${this.accessToken}`,
|
|
72
|
+
Accept: "application/json",
|
|
73
|
+
};
|
|
74
|
+
if (body !== undefined) {
|
|
75
|
+
headers["Content-Type"] = "application/json";
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
const response = await fetch(url, {
|
|
79
|
+
method,
|
|
80
|
+
headers,
|
|
81
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
82
|
+
signal: controller.signal,
|
|
83
|
+
});
|
|
84
|
+
clearTimeout(timeoutId);
|
|
85
|
+
if (!response.ok) {
|
|
86
|
+
throw await createErrorFromResponse(response);
|
|
87
|
+
}
|
|
88
|
+
// Handle 204 No Content responses
|
|
89
|
+
if (response.status === 204) {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
// Parse JSON response
|
|
93
|
+
const text = await response.text();
|
|
94
|
+
if (!text) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
return JSON.parse(text);
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
clearTimeout(timeoutId);
|
|
101
|
+
// Handle abort errors (timeout)
|
|
102
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
103
|
+
throw new TickTickTimeoutError(`Request timed out after ${this.timeout}ms`, this.timeout);
|
|
104
|
+
}
|
|
105
|
+
// Handle network errors
|
|
106
|
+
if (error instanceof TypeError &&
|
|
107
|
+
error.message.includes("fetch")) {
|
|
108
|
+
throw new TickTickNetworkError(`Network error: ${error.message}`, error);
|
|
109
|
+
}
|
|
110
|
+
// Re-throw TickTick errors as-is
|
|
111
|
+
throw error;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Make a GET request.
|
|
116
|
+
*/
|
|
117
|
+
get(path) {
|
|
118
|
+
return this.request("GET", path);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Make a POST request.
|
|
122
|
+
*/
|
|
123
|
+
post(path, body) {
|
|
124
|
+
return this.request("POST", path, body);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Make a DELETE request.
|
|
128
|
+
*/
|
|
129
|
+
delete(path) {
|
|
130
|
+
return this.request("DELETE", path);
|
|
131
|
+
}
|
|
132
|
+
// ===========================================================================
|
|
133
|
+
// User Endpoints
|
|
134
|
+
// ===========================================================================
|
|
135
|
+
/**
|
|
136
|
+
* Get the current authenticated user's information.
|
|
137
|
+
*
|
|
138
|
+
* @returns The user's profile information
|
|
139
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* const user = await client.getUser();
|
|
144
|
+
* console.log(`Logged in as: ${user.name} (${user.username})`);
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
async getUser() {
|
|
148
|
+
return this.get("/user");
|
|
149
|
+
}
|
|
150
|
+
// ===========================================================================
|
|
151
|
+
// Project Endpoints
|
|
152
|
+
// ===========================================================================
|
|
153
|
+
/**
|
|
154
|
+
* List all projects for the authenticated user.
|
|
155
|
+
*
|
|
156
|
+
* @returns Array of all projects
|
|
157
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```typescript
|
|
161
|
+
* const projects = await client.listProjects();
|
|
162
|
+
* for (const project of projects) {
|
|
163
|
+
* console.log(`${project.name} (${project.id})`);
|
|
164
|
+
* }
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
async listProjects() {
|
|
168
|
+
return this.get("/project");
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Get a specific project by ID.
|
|
172
|
+
*
|
|
173
|
+
* @param projectId - The unique identifier of the project
|
|
174
|
+
* @returns The project details
|
|
175
|
+
* @throws {TickTickNotFoundError} If the project doesn't exist
|
|
176
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```typescript
|
|
180
|
+
* const project = await client.getProject('project-id');
|
|
181
|
+
* console.log(`Project: ${project.name}`);
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
async getProject(projectId) {
|
|
185
|
+
return this.get(`/project/${encodeURIComponent(projectId)}`);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Get a project with all its tasks.
|
|
189
|
+
*
|
|
190
|
+
* @param projectId - The unique identifier of the project
|
|
191
|
+
* @returns The project and all its tasks
|
|
192
|
+
* @throws {TickTickNotFoundError} If the project doesn't exist
|
|
193
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
194
|
+
*
|
|
195
|
+
* @example
|
|
196
|
+
* ```typescript
|
|
197
|
+
* const { project, tasks } = await client.getProjectWithTasks('project-id');
|
|
198
|
+
* console.log(`${project.name} has ${tasks.length} tasks`);
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
async getProjectWithTasks(projectId) {
|
|
202
|
+
return this.get(`/project/${encodeURIComponent(projectId)}/data`);
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Create a new project.
|
|
206
|
+
*
|
|
207
|
+
* @param input - The project creation parameters
|
|
208
|
+
* @returns The created project
|
|
209
|
+
* @throws {TickTickBadRequestError} If the input is invalid
|
|
210
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```typescript
|
|
214
|
+
* const project = await client.createProject({
|
|
215
|
+
* name: 'My New Project',
|
|
216
|
+
* color: '#ff6b6b',
|
|
217
|
+
* viewMode: 'list',
|
|
218
|
+
* });
|
|
219
|
+
* console.log(`Created project: ${project.id}`);
|
|
220
|
+
* ```
|
|
221
|
+
*/
|
|
222
|
+
async createProject(input) {
|
|
223
|
+
return this.post("/project", input);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Update an existing project.
|
|
227
|
+
*
|
|
228
|
+
* @param projectId - The unique identifier of the project to update
|
|
229
|
+
* @param input - The fields to update
|
|
230
|
+
* @returns The updated project
|
|
231
|
+
* @throws {TickTickNotFoundError} If the project doesn't exist
|
|
232
|
+
* @throws {TickTickBadRequestError} If the input is invalid
|
|
233
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
234
|
+
*
|
|
235
|
+
* @example
|
|
236
|
+
* ```typescript
|
|
237
|
+
* const project = await client.updateProject('project-id', {
|
|
238
|
+
* name: 'Updated Name',
|
|
239
|
+
* color: '#4dabf7',
|
|
240
|
+
* });
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
243
|
+
async updateProject(projectId, input) {
|
|
244
|
+
return this.post(`/project/${encodeURIComponent(projectId)}`, input);
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Delete a project.
|
|
248
|
+
*
|
|
249
|
+
* @param projectId - The unique identifier of the project to delete
|
|
250
|
+
* @throws {TickTickNotFoundError} If the project doesn't exist
|
|
251
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* ```typescript
|
|
255
|
+
* await client.deleteProject('project-id');
|
|
256
|
+
* console.log('Project deleted');
|
|
257
|
+
* ```
|
|
258
|
+
*/
|
|
259
|
+
async deleteProject(projectId) {
|
|
260
|
+
await this.delete(`/project/${encodeURIComponent(projectId)}`);
|
|
261
|
+
}
|
|
262
|
+
// ===========================================================================
|
|
263
|
+
// Task Endpoints
|
|
264
|
+
// ===========================================================================
|
|
265
|
+
/**
|
|
266
|
+
* Get a specific task by project ID and task ID.
|
|
267
|
+
*
|
|
268
|
+
* @param projectId - The project ID containing the task
|
|
269
|
+
* @param taskId - The unique identifier of the task
|
|
270
|
+
* @returns The task details
|
|
271
|
+
* @throws {TickTickNotFoundError} If the task or project doesn't exist
|
|
272
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
273
|
+
*
|
|
274
|
+
* @example
|
|
275
|
+
* ```typescript
|
|
276
|
+
* const task = await client.getTask('project-id', 'task-id');
|
|
277
|
+
* console.log(`Task: ${task.title}`);
|
|
278
|
+
* ```
|
|
279
|
+
*/
|
|
280
|
+
async getTask(projectId, taskId) {
|
|
281
|
+
return this.get(`/project/${encodeURIComponent(projectId)}/task/${encodeURIComponent(taskId)}`);
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Create a new task.
|
|
285
|
+
*
|
|
286
|
+
* @param input - The task creation parameters
|
|
287
|
+
* @returns The created task
|
|
288
|
+
* @throws {TickTickBadRequestError} If the input is invalid
|
|
289
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
290
|
+
*
|
|
291
|
+
* @example
|
|
292
|
+
* ```typescript
|
|
293
|
+
* const task = await client.createTask({
|
|
294
|
+
* title: 'Complete report',
|
|
295
|
+
* projectId: 'project-id',
|
|
296
|
+
* content: 'Finish the quarterly report',
|
|
297
|
+
* dueDate: '2024-01-15T17:00:00+0000',
|
|
298
|
+
* priority: Priority.High,
|
|
299
|
+
* items: [
|
|
300
|
+
* { title: 'Write introduction', status: Status.Normal },
|
|
301
|
+
* { title: 'Add charts', status: Status.Normal },
|
|
302
|
+
* ],
|
|
303
|
+
* });
|
|
304
|
+
* console.log(`Created task: ${task.id}`);
|
|
305
|
+
* ```
|
|
306
|
+
*/
|
|
307
|
+
async createTask(input) {
|
|
308
|
+
return this.post("/task", input);
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Update an existing task.
|
|
312
|
+
*
|
|
313
|
+
* @param taskId - The unique identifier of the task to update
|
|
314
|
+
* @param input - The fields to update
|
|
315
|
+
* @returns The updated task
|
|
316
|
+
* @throws {TickTickNotFoundError} If the task doesn't exist
|
|
317
|
+
* @throws {TickTickBadRequestError} If the input is invalid
|
|
318
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
319
|
+
*
|
|
320
|
+
* @example
|
|
321
|
+
* ```typescript
|
|
322
|
+
* const task = await client.updateTask('task-id', {
|
|
323
|
+
* title: 'Updated task title',
|
|
324
|
+
* priority: Priority.Medium,
|
|
325
|
+
* });
|
|
326
|
+
* ```
|
|
327
|
+
*/
|
|
328
|
+
async updateTask(taskId, input) {
|
|
329
|
+
return this.post(`/task/${encodeURIComponent(taskId)}`, input);
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Mark a task as complete.
|
|
333
|
+
*
|
|
334
|
+
* @param projectId - The project ID containing the task
|
|
335
|
+
* @param taskId - The unique identifier of the task to complete
|
|
336
|
+
* @throws {TickTickNotFoundError} If the task or project doesn't exist
|
|
337
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
338
|
+
*
|
|
339
|
+
* @example
|
|
340
|
+
* ```typescript
|
|
341
|
+
* await client.completeTask('project-id', 'task-id');
|
|
342
|
+
* console.log('Task completed!');
|
|
343
|
+
* ```
|
|
344
|
+
*/
|
|
345
|
+
async completeTask(projectId, taskId) {
|
|
346
|
+
await this.post(`/project/${encodeURIComponent(projectId)}/task/${encodeURIComponent(taskId)}/complete`);
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Delete a task.
|
|
350
|
+
*
|
|
351
|
+
* @param projectId - The project ID containing the task
|
|
352
|
+
* @param taskId - The unique identifier of the task to delete
|
|
353
|
+
* @throws {TickTickNotFoundError} If the task or project doesn't exist
|
|
354
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
355
|
+
*
|
|
356
|
+
* @example
|
|
357
|
+
* ```typescript
|
|
358
|
+
* await client.deleteTask('project-id', 'task-id');
|
|
359
|
+
* console.log('Task deleted');
|
|
360
|
+
* ```
|
|
361
|
+
*/
|
|
362
|
+
async deleteTask(projectId, taskId) {
|
|
363
|
+
await this.delete(`/project/${encodeURIComponent(projectId)}/task/${encodeURIComponent(taskId)}`);
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Create multiple tasks at once.
|
|
367
|
+
*
|
|
368
|
+
* @param tasks - Array of tasks to create
|
|
369
|
+
* @returns Array of created tasks
|
|
370
|
+
* @throws {TickTickBadRequestError} If the input is invalid
|
|
371
|
+
* @throws {TickTickAuthError} If the access token is invalid or expired
|
|
372
|
+
*
|
|
373
|
+
* @example
|
|
374
|
+
* ```typescript
|
|
375
|
+
* const tasks = await client.batchCreateTasks([
|
|
376
|
+
* { title: 'Task 1', projectId: 'project-id', priority: Priority.Low },
|
|
377
|
+
* { title: 'Task 2', projectId: 'project-id', priority: Priority.Medium },
|
|
378
|
+
* { title: 'Task 3', projectId: 'project-id', priority: Priority.High },
|
|
379
|
+
* ]);
|
|
380
|
+
* console.log(`Created ${tasks.length} tasks`);
|
|
381
|
+
* ```
|
|
382
|
+
*/
|
|
383
|
+
async batchCreateTasks(tasks) {
|
|
384
|
+
const input = { add: tasks };
|
|
385
|
+
return this.post("/batch/task", input);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/sdk/client.ts"],"names":[],"mappings":"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"}
|