@doist/todoist-sdk 9.0.0 → 9.1.0-next.2
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/dist/cjs/clients/activity-client.js +63 -0
- package/dist/cjs/clients/backup-client.js +65 -0
- package/dist/cjs/clients/base-client.js +30 -0
- package/dist/cjs/clients/comment-client.js +92 -0
- package/dist/cjs/clients/email-client.js +43 -0
- package/dist/cjs/clients/folder-client.js +80 -0
- package/dist/cjs/clients/goals-client.js +145 -0
- package/dist/cjs/clients/id-mapping-client.js +39 -0
- package/dist/cjs/clients/insights-client.js +88 -0
- package/dist/cjs/clients/label-client.js +127 -0
- package/dist/cjs/clients/productivity-client.js +27 -0
- package/dist/cjs/clients/project-client.js +232 -0
- package/dist/cjs/clients/reminder-client.js +198 -0
- package/dist/cjs/clients/section-client.js +118 -0
- package/dist/cjs/clients/task-client.js +255 -0
- package/dist/cjs/clients/template-client.js +89 -0
- package/dist/cjs/clients/upload-client.js +102 -0
- package/dist/cjs/clients/workspace-client.js +367 -0
- package/dist/cjs/consts/endpoints.js +6 -1
- package/dist/cjs/test-utils/test-defaults.js +25 -1
- package/dist/cjs/todoist-api.js +186 -1537
- package/dist/cjs/transport/sync-request.js +75 -0
- package/dist/cjs/types/goals/index.js +18 -0
- package/dist/cjs/types/goals/requests.js +2 -0
- package/dist/cjs/types/goals/types.js +56 -0
- package/dist/cjs/types/index.js +1 -0
- package/dist/cjs/types/sync/commands/goals.js +2 -0
- package/dist/cjs/types/sync/commands/index.js +1 -0
- package/dist/cjs/types/sync/resource-types.js +1 -0
- package/dist/cjs/types/sync/response.js +12 -10
- package/dist/cjs/utils/headers.js +16 -0
- package/dist/cjs/utils/request-helpers.js +21 -0
- package/dist/cjs/utils/validators.js +48 -46
- package/dist/esm/clients/activity-client.js +59 -0
- package/dist/esm/clients/backup-client.js +61 -0
- package/dist/esm/clients/base-client.js +26 -0
- package/dist/esm/clients/comment-client.js +88 -0
- package/dist/esm/clients/email-client.js +39 -0
- package/dist/esm/clients/folder-client.js +76 -0
- package/dist/esm/clients/goals-client.js +141 -0
- package/dist/esm/clients/id-mapping-client.js +35 -0
- package/dist/esm/clients/insights-client.js +84 -0
- package/dist/esm/clients/label-client.js +123 -0
- package/dist/esm/clients/productivity-client.js +23 -0
- package/dist/esm/clients/project-client.js +228 -0
- package/dist/esm/clients/reminder-client.js +194 -0
- package/dist/esm/clients/section-client.js +114 -0
- package/dist/esm/clients/task-client.js +251 -0
- package/dist/esm/clients/template-client.js +85 -0
- package/dist/esm/clients/upload-client.js +98 -0
- package/dist/esm/clients/workspace-client.js +363 -0
- package/dist/esm/consts/endpoints.js +5 -0
- package/dist/esm/test-utils/test-defaults.js +24 -0
- package/dist/esm/todoist-api.js +189 -1540
- package/dist/esm/transport/sync-request.js +72 -0
- package/dist/esm/types/goals/index.js +2 -0
- package/dist/esm/types/goals/requests.js +1 -0
- package/dist/esm/types/goals/types.js +53 -0
- package/dist/esm/types/index.js +1 -0
- package/dist/esm/types/sync/commands/goals.js +1 -0
- package/dist/esm/types/sync/commands/index.js +1 -0
- package/dist/esm/types/sync/resource-types.js +1 -0
- package/dist/esm/types/sync/response.js +2 -0
- package/dist/esm/utils/headers.js +13 -0
- package/dist/esm/utils/request-helpers.js +17 -0
- package/dist/esm/utils/validators.js +2 -0
- package/dist/types/clients/activity-client.d.ts +12 -0
- package/dist/types/clients/backup-client.d.ts +14 -0
- package/dist/types/clients/base-client.d.ts +21 -0
- package/dist/types/clients/comment-client.d.ts +15 -0
- package/dist/types/clients/email-client.d.ts +13 -0
- package/dist/types/clients/folder-client.d.ts +16 -0
- package/dist/types/clients/goals-client.d.ts +20 -0
- package/dist/types/clients/id-mapping-client.d.ts +13 -0
- package/dist/types/clients/insights-client.d.ts +18 -0
- package/dist/types/clients/label-client.d.ts +19 -0
- package/dist/types/clients/productivity-client.d.ts +12 -0
- package/dist/types/clients/project-client.d.ts +26 -0
- package/dist/types/clients/reminder-client.d.ts +25 -0
- package/dist/types/clients/section-client.d.ts +18 -0
- package/dist/types/clients/task-client.d.ts +25 -0
- package/dist/types/clients/template-client.d.ts +17 -0
- package/dist/types/clients/upload-client.d.ts +17 -0
- package/dist/types/clients/workspace-client.d.ts +43 -0
- package/dist/types/consts/endpoints.d.ts +5 -0
- package/dist/types/test-utils/test-defaults.d.ts +4 -1
- package/dist/types/todoist-api.d.ts +48 -17
- package/dist/types/transport/sync-request.d.ts +27 -0
- package/dist/types/types/goals/index.d.ts +2 -0
- package/dist/types/types/goals/requests.d.ts +33 -0
- package/dist/types/types/goals/types.d.ts +51 -0
- package/dist/types/types/http.d.ts +7 -0
- package/dist/types/types/index.d.ts +1 -0
- package/dist/types/types/sync/commands/goals.d.ts +33 -0
- package/dist/types/types/sync/commands/index.d.ts +9 -0
- package/dist/types/types/sync/resource-types.d.ts +1 -1
- package/dist/types/types/sync/resources/view-options.d.ts +6 -6
- package/dist/types/types/sync/response.d.ts +29 -4
- package/dist/types/types/tasks/requests.d.ts +1 -0
- package/dist/types/utils/headers.d.ts +7 -0
- package/dist/types/utils/request-helpers.d.ts +13 -0
- package/dist/types/utils/validators.d.ts +55 -8
- package/package.json +1 -1
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SectionClient = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const endpoints_1 = require("../consts/endpoints");
|
|
6
|
+
const http_client_1 = require("../transport/http-client");
|
|
7
|
+
const request_helpers_1 = require("../utils/request-helpers");
|
|
8
|
+
const validators_1 = require("../utils/validators");
|
|
9
|
+
const base_client_1 = require("./base-client");
|
|
10
|
+
/**
|
|
11
|
+
* Internal sub-client handling all section-domain endpoints.
|
|
12
|
+
*
|
|
13
|
+
* Instantiated by `TodoistApi`; every public section method on `TodoistApi`
|
|
14
|
+
* delegates here. See `todoist-api.ts` for the user-facing JSDoc.
|
|
15
|
+
*/
|
|
16
|
+
class SectionClient extends base_client_1.BaseClient {
|
|
17
|
+
async getSections(args) {
|
|
18
|
+
const { data: { results, nextCursor }, } = await (0, http_client_1.request)({
|
|
19
|
+
httpMethod: 'GET',
|
|
20
|
+
baseUri: this.syncApiBase,
|
|
21
|
+
relativePath: endpoints_1.ENDPOINT_REST_SECTIONS,
|
|
22
|
+
apiToken: this.authToken,
|
|
23
|
+
customFetch: this.customFetch,
|
|
24
|
+
payload: args,
|
|
25
|
+
});
|
|
26
|
+
return {
|
|
27
|
+
results: (0, validators_1.validateSectionArray)(results),
|
|
28
|
+
nextCursor,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
async searchSections(args) {
|
|
32
|
+
const { data: { results, nextCursor }, } = await (0, http_client_1.request)({
|
|
33
|
+
httpMethod: 'GET',
|
|
34
|
+
baseUri: this.syncApiBase,
|
|
35
|
+
relativePath: endpoints_1.ENDPOINT_REST_SECTIONS_SEARCH,
|
|
36
|
+
apiToken: this.authToken,
|
|
37
|
+
customFetch: this.customFetch,
|
|
38
|
+
payload: args,
|
|
39
|
+
});
|
|
40
|
+
return {
|
|
41
|
+
results: (0, validators_1.validateSectionArray)(results),
|
|
42
|
+
nextCursor,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
async getSection(id) {
|
|
46
|
+
zod_1.z.string().parse(id);
|
|
47
|
+
const response = await (0, http_client_1.request)({
|
|
48
|
+
httpMethod: 'GET',
|
|
49
|
+
baseUri: this.syncApiBase,
|
|
50
|
+
relativePath: (0, request_helpers_1.generatePath)(endpoints_1.ENDPOINT_REST_SECTIONS, id),
|
|
51
|
+
apiToken: this.authToken,
|
|
52
|
+
customFetch: this.customFetch,
|
|
53
|
+
});
|
|
54
|
+
return (0, validators_1.validateSection)(response.data);
|
|
55
|
+
}
|
|
56
|
+
async addSection(args, requestId) {
|
|
57
|
+
const response = await (0, http_client_1.request)({
|
|
58
|
+
httpMethod: 'POST',
|
|
59
|
+
baseUri: this.syncApiBase,
|
|
60
|
+
relativePath: endpoints_1.ENDPOINT_REST_SECTIONS,
|
|
61
|
+
apiToken: this.authToken,
|
|
62
|
+
customFetch: this.customFetch,
|
|
63
|
+
payload: args,
|
|
64
|
+
requestId: requestId,
|
|
65
|
+
});
|
|
66
|
+
return (0, validators_1.validateSection)(response.data);
|
|
67
|
+
}
|
|
68
|
+
async updateSection(id, args, requestId) {
|
|
69
|
+
zod_1.z.string().parse(id);
|
|
70
|
+
const response = await (0, http_client_1.request)({
|
|
71
|
+
httpMethod: 'POST',
|
|
72
|
+
baseUri: this.syncApiBase,
|
|
73
|
+
relativePath: (0, request_helpers_1.generatePath)(endpoints_1.ENDPOINT_REST_SECTIONS, id),
|
|
74
|
+
apiToken: this.authToken,
|
|
75
|
+
customFetch: this.customFetch,
|
|
76
|
+
payload: args,
|
|
77
|
+
requestId: requestId,
|
|
78
|
+
});
|
|
79
|
+
return (0, validators_1.validateSection)(response.data);
|
|
80
|
+
}
|
|
81
|
+
async deleteSection(id, requestId) {
|
|
82
|
+
zod_1.z.string().parse(id);
|
|
83
|
+
const response = await (0, http_client_1.request)({
|
|
84
|
+
httpMethod: 'DELETE',
|
|
85
|
+
baseUri: this.syncApiBase,
|
|
86
|
+
relativePath: (0, request_helpers_1.generatePath)(endpoints_1.ENDPOINT_REST_SECTIONS, id),
|
|
87
|
+
apiToken: this.authToken,
|
|
88
|
+
customFetch: this.customFetch,
|
|
89
|
+
requestId: requestId,
|
|
90
|
+
});
|
|
91
|
+
return (0, http_client_1.isSuccess)(response);
|
|
92
|
+
}
|
|
93
|
+
async archiveSection(id, requestId) {
|
|
94
|
+
zod_1.z.string().parse(id);
|
|
95
|
+
const response = await (0, http_client_1.request)({
|
|
96
|
+
httpMethod: 'POST',
|
|
97
|
+
baseUri: this.syncApiBase,
|
|
98
|
+
relativePath: (0, request_helpers_1.generatePath)(endpoints_1.ENDPOINT_REST_SECTIONS, id, endpoints_1.SECTION_ARCHIVE),
|
|
99
|
+
apiToken: this.authToken,
|
|
100
|
+
customFetch: this.customFetch,
|
|
101
|
+
requestId: requestId,
|
|
102
|
+
});
|
|
103
|
+
return (0, validators_1.validateSection)(response.data);
|
|
104
|
+
}
|
|
105
|
+
async unarchiveSection(id, requestId) {
|
|
106
|
+
zod_1.z.string().parse(id);
|
|
107
|
+
const response = await (0, http_client_1.request)({
|
|
108
|
+
httpMethod: 'POST',
|
|
109
|
+
baseUri: this.syncApiBase,
|
|
110
|
+
relativePath: (0, request_helpers_1.generatePath)(endpoints_1.ENDPOINT_REST_SECTIONS, id, endpoints_1.SECTION_UNARCHIVE),
|
|
111
|
+
apiToken: this.authToken,
|
|
112
|
+
customFetch: this.customFetch,
|
|
113
|
+
requestId: requestId,
|
|
114
|
+
});
|
|
115
|
+
return (0, validators_1.validateSection)(response.data);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.SectionClient = SectionClient;
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.TaskClient = void 0;
|
|
15
|
+
const uuid_1 = require("uuid");
|
|
16
|
+
const zod_1 = require("zod");
|
|
17
|
+
const endpoints_1 = require("../consts/endpoints");
|
|
18
|
+
const http_client_1 = require("../transport/http-client");
|
|
19
|
+
const sync_request_1 = require("../transport/sync-request");
|
|
20
|
+
const types_1 = require("../types");
|
|
21
|
+
const request_helpers_1 = require("../utils/request-helpers");
|
|
22
|
+
const uncompletable_helpers_1 = require("../utils/uncompletable-helpers");
|
|
23
|
+
const validators_1 = require("../utils/validators");
|
|
24
|
+
const base_client_1 = require("./base-client");
|
|
25
|
+
const MAX_COMMAND_COUNT = 100;
|
|
26
|
+
/**
|
|
27
|
+
* Internal sub-client handling all task-domain endpoints.
|
|
28
|
+
*
|
|
29
|
+
* Instantiated by `TodoistApi`; every public task method on `TodoistApi`
|
|
30
|
+
* delegates here. See `todoist-api.ts` for the user-facing JSDoc.
|
|
31
|
+
*/
|
|
32
|
+
class TaskClient extends base_client_1.BaseClient {
|
|
33
|
+
async getTask(id) {
|
|
34
|
+
zod_1.z.string().parse(id);
|
|
35
|
+
const response = await (0, http_client_1.request)({
|
|
36
|
+
httpMethod: 'GET',
|
|
37
|
+
baseUri: this.syncApiBase,
|
|
38
|
+
relativePath: (0, request_helpers_1.generatePath)(endpoints_1.ENDPOINT_REST_TASKS, id),
|
|
39
|
+
apiToken: this.authToken,
|
|
40
|
+
customFetch: this.customFetch,
|
|
41
|
+
});
|
|
42
|
+
return (0, validators_1.validateTask)(response.data);
|
|
43
|
+
}
|
|
44
|
+
async getTasks(args = {}) {
|
|
45
|
+
const { data: { results, nextCursor }, } = await (0, http_client_1.request)({
|
|
46
|
+
httpMethod: 'GET',
|
|
47
|
+
baseUri: this.syncApiBase,
|
|
48
|
+
relativePath: endpoints_1.ENDPOINT_REST_TASKS,
|
|
49
|
+
apiToken: this.authToken,
|
|
50
|
+
customFetch: this.customFetch,
|
|
51
|
+
payload: args,
|
|
52
|
+
});
|
|
53
|
+
return {
|
|
54
|
+
results: (0, validators_1.validateTaskArray)(results),
|
|
55
|
+
nextCursor,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
async getTasksByFilter(args) {
|
|
59
|
+
const { data: { results, nextCursor }, } = await (0, http_client_1.request)({
|
|
60
|
+
httpMethod: 'GET',
|
|
61
|
+
baseUri: this.syncApiBase,
|
|
62
|
+
relativePath: endpoints_1.ENDPOINT_REST_TASKS_FILTER,
|
|
63
|
+
apiToken: this.authToken,
|
|
64
|
+
customFetch: this.customFetch,
|
|
65
|
+
payload: args,
|
|
66
|
+
});
|
|
67
|
+
return {
|
|
68
|
+
results: (0, validators_1.validateTaskArray)(results),
|
|
69
|
+
nextCursor,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
async getCompletedTasksByCompletionDate(args) {
|
|
73
|
+
const { data: { items, nextCursor }, } = await (0, http_client_1.request)({
|
|
74
|
+
httpMethod: 'GET',
|
|
75
|
+
baseUri: this.syncApiBase,
|
|
76
|
+
relativePath: endpoints_1.ENDPOINT_REST_TASKS_COMPLETED_BY_COMPLETION_DATE,
|
|
77
|
+
apiToken: this.authToken,
|
|
78
|
+
customFetch: this.customFetch,
|
|
79
|
+
payload: args,
|
|
80
|
+
});
|
|
81
|
+
return {
|
|
82
|
+
items: (0, validators_1.validateTaskArray)(items),
|
|
83
|
+
nextCursor,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
async getCompletedTasksByDueDate(args) {
|
|
87
|
+
const { data: { items, nextCursor }, } = await (0, http_client_1.request)({
|
|
88
|
+
httpMethod: 'GET',
|
|
89
|
+
baseUri: this.syncApiBase,
|
|
90
|
+
relativePath: endpoints_1.ENDPOINT_REST_TASKS_COMPLETED_BY_DUE_DATE,
|
|
91
|
+
apiToken: this.authToken,
|
|
92
|
+
customFetch: this.customFetch,
|
|
93
|
+
payload: args,
|
|
94
|
+
});
|
|
95
|
+
return {
|
|
96
|
+
items: (0, validators_1.validateTaskArray)(items),
|
|
97
|
+
nextCursor,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
async searchCompletedTasks(args) {
|
|
101
|
+
const { data: { items, nextCursor }, } = await (0, http_client_1.request)({
|
|
102
|
+
httpMethod: 'GET',
|
|
103
|
+
baseUri: this.syncApiBase,
|
|
104
|
+
relativePath: endpoints_1.ENDPOINT_REST_TASKS_COMPLETED_SEARCH,
|
|
105
|
+
apiToken: this.authToken,
|
|
106
|
+
customFetch: this.customFetch,
|
|
107
|
+
payload: args,
|
|
108
|
+
});
|
|
109
|
+
return {
|
|
110
|
+
items: (0, validators_1.validateTaskArray)(items),
|
|
111
|
+
nextCursor,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
async getAllCompletedTasks(args = {}) {
|
|
115
|
+
const { since, until } = args, rest = __rest(args, ["since", "until"]);
|
|
116
|
+
const { data } = await (0, http_client_1.request)({
|
|
117
|
+
httpMethod: 'GET',
|
|
118
|
+
baseUri: this.syncApiBase,
|
|
119
|
+
relativePath: endpoints_1.ENDPOINT_REST_TASKS_COMPLETED,
|
|
120
|
+
apiToken: this.authToken,
|
|
121
|
+
customFetch: this.customFetch,
|
|
122
|
+
payload: Object.assign(Object.assign(Object.assign({}, rest), (since ? { since: since.toISOString() } : {})), (until ? { until: until.toISOString() } : {})),
|
|
123
|
+
});
|
|
124
|
+
return {
|
|
125
|
+
projects: data.projects,
|
|
126
|
+
sections: data.sections,
|
|
127
|
+
items: (0, validators_1.validateTaskArray)(data.items),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
async addTask(args, requestId) {
|
|
131
|
+
// Process content based on isUncompletable flag
|
|
132
|
+
const processedArgs = Object.assign(Object.assign({}, args), { content: (0, uncompletable_helpers_1.processTaskContent)(args.content, args.isUncompletable) });
|
|
133
|
+
const response = await (0, http_client_1.request)({
|
|
134
|
+
httpMethod: 'POST',
|
|
135
|
+
baseUri: this.syncApiBase,
|
|
136
|
+
relativePath: endpoints_1.ENDPOINT_REST_TASKS,
|
|
137
|
+
apiToken: this.authToken,
|
|
138
|
+
customFetch: this.customFetch,
|
|
139
|
+
payload: processedArgs,
|
|
140
|
+
requestId: requestId,
|
|
141
|
+
});
|
|
142
|
+
return (0, validators_1.validateTask)(response.data);
|
|
143
|
+
}
|
|
144
|
+
async quickAddTask(args) {
|
|
145
|
+
// Process text based on isUncompletable flag
|
|
146
|
+
const processedArgs = Object.assign(Object.assign({}, args), { text: (0, uncompletable_helpers_1.processTaskContent)(args.text, args.isUncompletable) });
|
|
147
|
+
const response = await (0, http_client_1.request)({
|
|
148
|
+
httpMethod: 'POST',
|
|
149
|
+
baseUri: this.syncApiBase,
|
|
150
|
+
relativePath: endpoints_1.ENDPOINT_SYNC_QUICK_ADD,
|
|
151
|
+
apiToken: this.authToken,
|
|
152
|
+
customFetch: this.customFetch,
|
|
153
|
+
payload: processedArgs,
|
|
154
|
+
});
|
|
155
|
+
return (0, validators_1.validateTask)(response.data);
|
|
156
|
+
}
|
|
157
|
+
async updateTask(id, args, requestId) {
|
|
158
|
+
zod_1.z.string().parse(id);
|
|
159
|
+
// Translate SDK alias for due-date clearing to Todoist's accepted payload value.
|
|
160
|
+
const normalizedArgs = args.dueString === null ? Object.assign(Object.assign({}, args), { dueString: 'no date' }) : args;
|
|
161
|
+
// Process content if both content and isUncompletable are provided
|
|
162
|
+
const processedArgs = normalizedArgs.content && normalizedArgs.isUncompletable !== undefined
|
|
163
|
+
? Object.assign(Object.assign({}, normalizedArgs), { content: (0, uncompletable_helpers_1.processTaskContent)(normalizedArgs.content, normalizedArgs.isUncompletable) }) : normalizedArgs;
|
|
164
|
+
// Remap `order` → `childOrder` so snakeCaseKeys() produces `child_order`
|
|
165
|
+
const { order } = processedArgs, argsWithoutOrder = __rest(processedArgs, ["order"]);
|
|
166
|
+
const remappedArgs = order !== undefined ? Object.assign(Object.assign({}, argsWithoutOrder), { childOrder: order }) : argsWithoutOrder;
|
|
167
|
+
const response = await (0, http_client_1.request)({
|
|
168
|
+
httpMethod: 'POST',
|
|
169
|
+
baseUri: this.syncApiBase,
|
|
170
|
+
relativePath: (0, request_helpers_1.generatePath)(endpoints_1.ENDPOINT_REST_TASKS, id),
|
|
171
|
+
apiToken: this.authToken,
|
|
172
|
+
customFetch: this.customFetch,
|
|
173
|
+
payload: remappedArgs,
|
|
174
|
+
requestId: requestId,
|
|
175
|
+
});
|
|
176
|
+
return (0, validators_1.validateTask)(response.data);
|
|
177
|
+
}
|
|
178
|
+
async moveTasks(ids, args, requestId) {
|
|
179
|
+
var _a;
|
|
180
|
+
if (ids.length > MAX_COMMAND_COUNT) {
|
|
181
|
+
throw new types_1.TodoistRequestError(`Maximum number of items is ${MAX_COMMAND_COUNT}`, 400);
|
|
182
|
+
}
|
|
183
|
+
const commands = ids.map((id) => ({
|
|
184
|
+
type: 'item_move',
|
|
185
|
+
uuid: (0, uuid_1.v4)(),
|
|
186
|
+
args: Object.assign(Object.assign(Object.assign({ id }, (0, request_helpers_1.spreadIfDefined)(args.projectId, (v) => ({ projectId: v }))), (0, request_helpers_1.spreadIfDefined)(args.sectionId, (v) => ({ sectionId: v }))), (0, request_helpers_1.spreadIfDefined)(args.parentId, (v) => ({ parentId: v }))),
|
|
187
|
+
}));
|
|
188
|
+
const syncRequest = {
|
|
189
|
+
commands,
|
|
190
|
+
resourceTypes: ['items'],
|
|
191
|
+
};
|
|
192
|
+
const syncResponse = await (0, sync_request_1.performSyncRequest)(this.syncContext, syncRequest, {
|
|
193
|
+
requestId,
|
|
194
|
+
hasSyncCommands: true,
|
|
195
|
+
});
|
|
196
|
+
if (!((_a = syncResponse.items) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
197
|
+
throw new types_1.TodoistRequestError('Tasks not found', 404);
|
|
198
|
+
}
|
|
199
|
+
const syncTasks = syncResponse.items.filter((task) => ids.includes(task.id));
|
|
200
|
+
if (!syncTasks.length) {
|
|
201
|
+
throw new types_1.TodoistRequestError('Tasks not found', 404);
|
|
202
|
+
}
|
|
203
|
+
return (0, validators_1.validateTaskArray)(syncTasks);
|
|
204
|
+
}
|
|
205
|
+
async moveTask(id, args, requestId) {
|
|
206
|
+
zod_1.z.string().parse(id);
|
|
207
|
+
const response = await (0, http_client_1.request)({
|
|
208
|
+
httpMethod: 'POST',
|
|
209
|
+
baseUri: this.syncApiBase,
|
|
210
|
+
relativePath: (0, request_helpers_1.generatePath)(endpoints_1.ENDPOINT_REST_TASKS, id, endpoints_1.ENDPOINT_REST_TASK_MOVE),
|
|
211
|
+
apiToken: this.authToken,
|
|
212
|
+
customFetch: this.customFetch,
|
|
213
|
+
payload: Object.assign(Object.assign(Object.assign({}, (0, request_helpers_1.spreadIfDefined)(args.projectId, (v) => ({ project_id: v }))), (0, request_helpers_1.spreadIfDefined)(args.sectionId, (v) => ({ section_id: v }))), (0, request_helpers_1.spreadIfDefined)(args.parentId, (v) => ({ parent_id: v }))),
|
|
214
|
+
requestId: requestId,
|
|
215
|
+
});
|
|
216
|
+
return (0, validators_1.validateTask)(response.data);
|
|
217
|
+
}
|
|
218
|
+
async closeTask(id, requestId) {
|
|
219
|
+
zod_1.z.string().parse(id);
|
|
220
|
+
const response = await (0, http_client_1.request)({
|
|
221
|
+
httpMethod: 'POST',
|
|
222
|
+
baseUri: this.syncApiBase,
|
|
223
|
+
relativePath: (0, request_helpers_1.generatePath)(endpoints_1.ENDPOINT_REST_TASKS, id, endpoints_1.ENDPOINT_REST_TASK_CLOSE),
|
|
224
|
+
apiToken: this.authToken,
|
|
225
|
+
customFetch: this.customFetch,
|
|
226
|
+
requestId: requestId,
|
|
227
|
+
});
|
|
228
|
+
return (0, http_client_1.isSuccess)(response);
|
|
229
|
+
}
|
|
230
|
+
async reopenTask(id, requestId) {
|
|
231
|
+
zod_1.z.string().parse(id);
|
|
232
|
+
const response = await (0, http_client_1.request)({
|
|
233
|
+
httpMethod: 'POST',
|
|
234
|
+
baseUri: this.syncApiBase,
|
|
235
|
+
relativePath: (0, request_helpers_1.generatePath)(endpoints_1.ENDPOINT_REST_TASKS, id, endpoints_1.ENDPOINT_REST_TASK_REOPEN),
|
|
236
|
+
apiToken: this.authToken,
|
|
237
|
+
customFetch: this.customFetch,
|
|
238
|
+
requestId: requestId,
|
|
239
|
+
});
|
|
240
|
+
return (0, http_client_1.isSuccess)(response);
|
|
241
|
+
}
|
|
242
|
+
async deleteTask(id, requestId) {
|
|
243
|
+
zod_1.z.string().parse(id);
|
|
244
|
+
const response = await (0, http_client_1.request)({
|
|
245
|
+
httpMethod: 'DELETE',
|
|
246
|
+
baseUri: this.syncApiBase,
|
|
247
|
+
relativePath: (0, request_helpers_1.generatePath)(endpoints_1.ENDPOINT_REST_TASKS, id),
|
|
248
|
+
apiToken: this.authToken,
|
|
249
|
+
customFetch: this.customFetch,
|
|
250
|
+
requestId: requestId,
|
|
251
|
+
});
|
|
252
|
+
return (0, http_client_1.isSuccess)(response);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
exports.TaskClient = TaskClient;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TemplateClient = void 0;
|
|
4
|
+
const endpoints_1 = require("../consts/endpoints");
|
|
5
|
+
const http_client_1 = require("../transport/http-client");
|
|
6
|
+
const case_conversion_1 = require("../utils/case-conversion");
|
|
7
|
+
const multipart_upload_1 = require("../utils/multipart-upload");
|
|
8
|
+
const validators_1 = require("../utils/validators");
|
|
9
|
+
const base_client_1 = require("./base-client");
|
|
10
|
+
/**
|
|
11
|
+
* Internal sub-client handling all template-domain endpoints.
|
|
12
|
+
*
|
|
13
|
+
* Instantiated by `TodoistApi`; every public template method on
|
|
14
|
+
* `TodoistApi` delegates here. See `todoist-api.ts` for user-facing
|
|
15
|
+
* JSDoc.
|
|
16
|
+
*/
|
|
17
|
+
class TemplateClient extends base_client_1.BaseClient {
|
|
18
|
+
async exportTemplateAsFile(args) {
|
|
19
|
+
const response = await (0, http_client_1.request)({
|
|
20
|
+
httpMethod: 'GET',
|
|
21
|
+
baseUri: this.syncApiBase,
|
|
22
|
+
relativePath: endpoints_1.ENDPOINT_REST_TEMPLATES_FILE,
|
|
23
|
+
apiToken: this.authToken,
|
|
24
|
+
customFetch: this.customFetch,
|
|
25
|
+
payload: args,
|
|
26
|
+
});
|
|
27
|
+
return response.data;
|
|
28
|
+
}
|
|
29
|
+
async exportTemplateAsUrl(args) {
|
|
30
|
+
const { data } = await (0, http_client_1.request)({
|
|
31
|
+
httpMethod: 'GET',
|
|
32
|
+
baseUri: this.syncApiBase,
|
|
33
|
+
relativePath: endpoints_1.ENDPOINT_REST_TEMPLATES_URL,
|
|
34
|
+
apiToken: this.authToken,
|
|
35
|
+
customFetch: this.customFetch,
|
|
36
|
+
payload: args,
|
|
37
|
+
});
|
|
38
|
+
return data;
|
|
39
|
+
}
|
|
40
|
+
async createProjectFromTemplate(args, requestId) {
|
|
41
|
+
const { file, fileName, name, workspaceId } = args;
|
|
42
|
+
const additionalFields = { name };
|
|
43
|
+
if (workspaceId !== undefined && workspaceId !== null) {
|
|
44
|
+
additionalFields.workspace_id = workspaceId;
|
|
45
|
+
}
|
|
46
|
+
const data = await (0, multipart_upload_1.uploadMultipartFile)({
|
|
47
|
+
baseUrl: this.syncApiBase,
|
|
48
|
+
authToken: this.authToken,
|
|
49
|
+
endpoint: endpoints_1.ENDPOINT_REST_TEMPLATES_CREATE_FROM_FILE,
|
|
50
|
+
file,
|
|
51
|
+
fileName,
|
|
52
|
+
additionalFields,
|
|
53
|
+
customFetch: this.customFetch,
|
|
54
|
+
requestId,
|
|
55
|
+
});
|
|
56
|
+
return this.validateTemplateResponse((0, case_conversion_1.camelCaseKeys)(data));
|
|
57
|
+
}
|
|
58
|
+
async importTemplateIntoProject(args, requestId) {
|
|
59
|
+
const { file, fileName, projectId } = args;
|
|
60
|
+
const data = await (0, multipart_upload_1.uploadMultipartFile)({
|
|
61
|
+
baseUrl: this.syncApiBase,
|
|
62
|
+
authToken: this.authToken,
|
|
63
|
+
endpoint: endpoints_1.ENDPOINT_REST_TEMPLATES_IMPORT_FROM_FILE,
|
|
64
|
+
file,
|
|
65
|
+
fileName,
|
|
66
|
+
additionalFields: { project_id: projectId },
|
|
67
|
+
customFetch: this.customFetch,
|
|
68
|
+
requestId,
|
|
69
|
+
});
|
|
70
|
+
return this.validateTemplateResponse((0, case_conversion_1.camelCaseKeys)(data));
|
|
71
|
+
}
|
|
72
|
+
async importTemplateFromId(args, requestId) {
|
|
73
|
+
const { data } = await (0, http_client_1.request)({
|
|
74
|
+
httpMethod: 'POST',
|
|
75
|
+
baseUri: this.syncApiBase,
|
|
76
|
+
relativePath: endpoints_1.ENDPOINT_REST_TEMPLATES_IMPORT_FROM_ID,
|
|
77
|
+
apiToken: this.authToken,
|
|
78
|
+
customFetch: this.customFetch,
|
|
79
|
+
payload: args,
|
|
80
|
+
requestId: requestId,
|
|
81
|
+
});
|
|
82
|
+
return this.validateTemplateResponse(data);
|
|
83
|
+
}
|
|
84
|
+
validateTemplateResponse(data) {
|
|
85
|
+
var _a, _b, _c, _d;
|
|
86
|
+
return Object.assign(Object.assign({}, data), { projects: (0, validators_1.validateProjectArray)((_a = data.projects) !== null && _a !== void 0 ? _a : []), sections: (0, validators_1.validateSectionArray)((_b = data.sections) !== null && _b !== void 0 ? _b : []), tasks: (0, validators_1.validateTaskArray)((_c = data.tasks) !== null && _c !== void 0 ? _c : []), comments: (0, validators_1.validateCommentArray)((_d = data.comments) !== null && _d !== void 0 ? _d : []) });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
exports.TemplateClient = TemplateClient;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UploadClient = void 0;
|
|
4
|
+
const endpoints_1 = require("../consts/endpoints");
|
|
5
|
+
const http_client_1 = require("../transport/http-client");
|
|
6
|
+
const headers_1 = require("../utils/headers");
|
|
7
|
+
const multipart_upload_1 = require("../utils/multipart-upload");
|
|
8
|
+
const validators_1 = require("../utils/validators");
|
|
9
|
+
const base_client_1 = require("./base-client");
|
|
10
|
+
/**
|
|
11
|
+
* Internal sub-client handling upload + attachment endpoints
|
|
12
|
+
* (file upload, upload delete, attachment view).
|
|
13
|
+
*
|
|
14
|
+
* Instantiated by `TodoistApi`; every public upload method on
|
|
15
|
+
* `TodoistApi` delegates here. See `todoist-api.ts` for user-facing
|
|
16
|
+
* JSDoc.
|
|
17
|
+
*/
|
|
18
|
+
class UploadClient extends base_client_1.BaseClient {
|
|
19
|
+
async uploadFile(args, requestId) {
|
|
20
|
+
const additionalFields = {};
|
|
21
|
+
if (args.projectId) {
|
|
22
|
+
additionalFields.project_id = args.projectId;
|
|
23
|
+
}
|
|
24
|
+
const data = await (0, multipart_upload_1.uploadMultipartFile)({
|
|
25
|
+
baseUrl: this.syncApiBase,
|
|
26
|
+
authToken: this.authToken,
|
|
27
|
+
endpoint: endpoints_1.ENDPOINT_REST_UPLOADS,
|
|
28
|
+
file: args.file,
|
|
29
|
+
fileName: args.fileName,
|
|
30
|
+
additionalFields: additionalFields,
|
|
31
|
+
requestId: requestId,
|
|
32
|
+
customFetch: this.customFetch,
|
|
33
|
+
});
|
|
34
|
+
return (0, validators_1.validateAttachment)(data);
|
|
35
|
+
}
|
|
36
|
+
async deleteUpload(args, requestId) {
|
|
37
|
+
const response = await (0, http_client_1.request)({
|
|
38
|
+
httpMethod: 'DELETE',
|
|
39
|
+
baseUri: this.syncApiBase,
|
|
40
|
+
relativePath: endpoints_1.ENDPOINT_REST_UPLOADS,
|
|
41
|
+
apiToken: this.authToken,
|
|
42
|
+
customFetch: this.customFetch,
|
|
43
|
+
payload: args,
|
|
44
|
+
requestId: requestId,
|
|
45
|
+
});
|
|
46
|
+
return (0, http_client_1.isSuccess)(response);
|
|
47
|
+
}
|
|
48
|
+
async viewAttachment(commentOrUrl) {
|
|
49
|
+
var _a;
|
|
50
|
+
let fileUrl;
|
|
51
|
+
if (typeof commentOrUrl === 'string') {
|
|
52
|
+
fileUrl = commentOrUrl;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
if (!((_a = commentOrUrl.fileAttachment) === null || _a === void 0 ? void 0 : _a.fileUrl)) {
|
|
56
|
+
throw new Error('Comment does not have a file attachment');
|
|
57
|
+
}
|
|
58
|
+
fileUrl = commentOrUrl.fileAttachment.fileUrl;
|
|
59
|
+
}
|
|
60
|
+
// Validate the URL belongs to Todoist to prevent leaking the auth token
|
|
61
|
+
const urlHostname = new URL(fileUrl).hostname;
|
|
62
|
+
if (!urlHostname.endsWith('.todoist.com')) {
|
|
63
|
+
throw new Error('Attachment URLs must be on a todoist.com domain');
|
|
64
|
+
}
|
|
65
|
+
const fetchOptions = {
|
|
66
|
+
method: 'GET',
|
|
67
|
+
headers: { Authorization: `Bearer ${this.authToken}` },
|
|
68
|
+
};
|
|
69
|
+
if (this.customFetch) {
|
|
70
|
+
const response = await this.customFetch(fileUrl, fetchOptions);
|
|
71
|
+
if (!response.ok) {
|
|
72
|
+
throw new Error(`Failed to fetch attachment: ${response.status} ${response.statusText}`);
|
|
73
|
+
}
|
|
74
|
+
// Convert text to ArrayBuffer for custom fetch implementations that lack arrayBuffer()
|
|
75
|
+
const text = await response.text();
|
|
76
|
+
const buffer = new TextEncoder().encode(text).buffer;
|
|
77
|
+
return {
|
|
78
|
+
ok: response.ok,
|
|
79
|
+
status: response.status,
|
|
80
|
+
statusText: response.statusText,
|
|
81
|
+
headers: response.headers,
|
|
82
|
+
text: () => Promise.resolve(text),
|
|
83
|
+
json: () => response.json(),
|
|
84
|
+
arrayBuffer: () => Promise.resolve(buffer),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const response = await fetch(fileUrl, fetchOptions);
|
|
88
|
+
if (!response.ok) {
|
|
89
|
+
throw new Error(`Failed to fetch attachment: ${response.status} ${response.statusText}`);
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
ok: response.ok,
|
|
93
|
+
status: response.status,
|
|
94
|
+
statusText: response.statusText,
|
|
95
|
+
headers: (0, headers_1.headersToRecord)(response.headers),
|
|
96
|
+
text: () => response.text(),
|
|
97
|
+
json: () => response.json(),
|
|
98
|
+
arrayBuffer: () => response.arrayBuffer(),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.UploadClient = UploadClient;
|