@doist/todoist-api-typescript 7.5.0 → 7.6.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/dist/cjs/authentication.js +46 -2
- package/dist/cjs/consts/endpoints.js +54 -2
- package/dist/cjs/todoist-api.js +518 -0
- package/dist/cjs/types/entities.js +116 -1
- package/dist/cjs/types/requests.js +22 -1
- package/dist/cjs/utils/validators.js +19 -2
- package/dist/esm/authentication.js +46 -3
- package/dist/esm/consts/endpoints.js +43 -0
- package/dist/esm/todoist-api.js +520 -2
- package/dist/esm/types/entities.js +114 -0
- package/dist/esm/types/requests.js +21 -0
- package/dist/esm/utils/validators.js +19 -2
- package/dist/types/authentication.d.ts +51 -6
- package/dist/types/consts/endpoints.d.ts +22 -0
- package/dist/types/todoist-api.d.ts +195 -4
- package/dist/types/types/entities.d.ts +254 -14
- package/dist/types/types/requests.d.ts +383 -51
- package/dist/types/types/sync/resources/user.d.ts +2 -2
- package/dist/types/types/sync/resources/view-options.d.ts +5 -5
- package/dist/types/types/sync/user-preferences.d.ts +1 -1
- package/dist/types/utils/validators.d.ts +198 -6
- package/package.json +1 -1
package/dist/esm/todoist-api.js
CHANGED
|
@@ -13,10 +13,11 @@ import { DueDateSchema, } from './types/entities.js';
|
|
|
13
13
|
import { LOCATION_TRIGGERS } from './types/sync/resources/reminders.js';
|
|
14
14
|
import { REMINDER_DELIVERY_SERVICES, } from './types/requests.js';
|
|
15
15
|
import { request, isSuccess } from './transport/http-client.js';
|
|
16
|
-
import { getSyncBaseUri, ENDPOINT_REST_TASKS, ENDPOINT_REST_TASKS_FILTER, ENDPOINT_REST_TASKS_COMPLETED_BY_COMPLETION_DATE, ENDPOINT_REST_TASKS_COMPLETED_BY_DUE_DATE, ENDPOINT_REST_TASKS_COMPLETED_SEARCH, ENDPOINT_REST_PROJECTS, ENDPOINT_REST_PROJECTS_SEARCH, ENDPOINT_SYNC_QUICK_ADD, ENDPOINT_REST_TASK_CLOSE, ENDPOINT_REST_TASK_REOPEN, ENDPOINT_REST_TASK_MOVE, ENDPOINT_REST_LABELS, ENDPOINT_REST_LABELS_SEARCH, ENDPOINT_REST_PROJECT_COLLABORATORS, ENDPOINT_REST_SECTIONS, ENDPOINT_REST_SECTIONS_SEARCH, ENDPOINT_REST_COMMENTS, ENDPOINT_REST_LOCATION_REMINDERS, ENDPOINT_REST_REMINDERS, ENDPOINT_REST_LABELS_SHARED, ENDPOINT_REST_LABELS_SHARED_RENAME, ENDPOINT_REST_LABELS_SHARED_REMOVE, ENDPOINT_SYNC, PROJECT_ARCHIVE, PROJECT_UNARCHIVE, ENDPOINT_REST_PROJECTS_MOVE_TO_WORKSPACE, ENDPOINT_REST_PROJECTS_MOVE_TO_PERSONAL, ENDPOINT_REST_PROJECTS_ARCHIVED, ENDPOINT_REST_PROJECTS_ARCHIVED_COUNT, ENDPOINT_REST_PROJECTS_PERMISSIONS, ENDPOINT_REST_PROJECT_FULL, ENDPOINT_REST_PROJECT_JOIN, SECTION_ARCHIVE, SECTION_UNARCHIVE, ENDPOINT_REST_USER, ENDPOINT_REST_PRODUCTIVITY, ENDPOINT_REST_ACTIVITIES, ENDPOINT_REST_UPLOADS, ENDPOINT_REST_WORKSPACES, ENDPOINT_WORKSPACE_INVITATIONS, ENDPOINT_WORKSPACE_INVITATIONS_ALL, ENDPOINT_WORKSPACE_INVITATIONS_DELETE, getWorkspaceInvitationAcceptEndpoint, getWorkspaceInvitationRejectEndpoint, ENDPOINT_WORKSPACE_JOIN, ENDPOINT_WORKSPACE_LOGO, ENDPOINT_WORKSPACE_PLAN_DETAILS, ENDPOINT_WORKSPACE_USERS, getWorkspaceActiveProjectsEndpoint, getWorkspaceArchivedProjectsEndpoint, } from './consts/endpoints.js';
|
|
17
|
-
import { validateAttachment, validateComment, validateCommentArray, validateCurrentUser, validateLabel, validateLabelArray, validateProject, validateProjectArray, validateSection, validateSectionArray, validateTask, validateTaskArray, validateUserArray, validateProductivityStats, validateReminder, validateActivityEventArray, validateWorkspaceUserArray, validateWorkspaceInvitation, validateWorkspaceInvitationArray, validateWorkspacePlanDetails, validateJoinWorkspaceResult, validateWorkspace, validateWorkspaceArray, } from './utils/validators.js';
|
|
16
|
+
import { getSyncBaseUri, ENDPOINT_REST_TASKS, ENDPOINT_REST_TASKS_FILTER, ENDPOINT_REST_TASKS_COMPLETED_BY_COMPLETION_DATE, ENDPOINT_REST_TASKS_COMPLETED_BY_DUE_DATE, ENDPOINT_REST_TASKS_COMPLETED_SEARCH, ENDPOINT_REST_TASKS_COMPLETED, ENDPOINT_REST_TEMPLATES_FILE, ENDPOINT_REST_TEMPLATES_URL, ENDPOINT_REST_TEMPLATES_CREATE_FROM_FILE, ENDPOINT_REST_TEMPLATES_IMPORT_FROM_FILE, ENDPOINT_REST_TEMPLATES_IMPORT_FROM_ID, ENDPOINT_REST_PROJECTS, ENDPOINT_REST_PROJECTS_SEARCH, ENDPOINT_SYNC_QUICK_ADD, ENDPOINT_REST_TASK_CLOSE, ENDPOINT_REST_TASK_REOPEN, ENDPOINT_REST_TASK_MOVE, ENDPOINT_REST_LABELS, ENDPOINT_REST_LABELS_SEARCH, ENDPOINT_REST_PROJECT_COLLABORATORS, ENDPOINT_REST_SECTIONS, ENDPOINT_REST_SECTIONS_SEARCH, ENDPOINT_REST_COMMENTS, ENDPOINT_REST_LOCATION_REMINDERS, ENDPOINT_REST_REMINDERS, ENDPOINT_REST_LABELS_SHARED, ENDPOINT_REST_LABELS_SHARED_RENAME, ENDPOINT_REST_LABELS_SHARED_REMOVE, ENDPOINT_SYNC, PROJECT_ARCHIVE, PROJECT_UNARCHIVE, ENDPOINT_REST_PROJECTS_MOVE_TO_WORKSPACE, ENDPOINT_REST_PROJECTS_MOVE_TO_PERSONAL, ENDPOINT_REST_PROJECTS_ARCHIVED, ENDPOINT_REST_PROJECTS_ARCHIVED_COUNT, ENDPOINT_REST_PROJECTS_PERMISSIONS, ENDPOINT_REST_PROJECT_FULL, ENDPOINT_REST_PROJECT_JOIN, SECTION_ARCHIVE, SECTION_UNARCHIVE, ENDPOINT_REST_USER, ENDPOINT_REST_PRODUCTIVITY, ENDPOINT_REST_ACTIVITIES, ENDPOINT_REST_UPLOADS, getProjectInsightsActivityStatsEndpoint, getProjectInsightsHealthEndpoint, getProjectInsightsHealthContextEndpoint, getProjectInsightsProgressEndpoint, getProjectInsightsHealthAnalyzeEndpoint, getWorkspaceInsightsEndpoint, ENDPOINT_REST_BACKUPS, ENDPOINT_REST_BACKUPS_DOWNLOAD, ENDPOINT_REST_EMAILS, ENDPOINT_REST_ID_MAPPINGS, ENDPOINT_REST_MOVED_IDS, ENDPOINT_REST_WORKSPACES, ENDPOINT_WORKSPACE_MEMBERS, getWorkspaceUserTasksEndpoint, getWorkspaceInviteUsersEndpoint, getWorkspaceUserEndpoint, ENDPOINT_WORKSPACE_INVITATIONS, ENDPOINT_WORKSPACE_INVITATIONS_ALL, ENDPOINT_WORKSPACE_INVITATIONS_DELETE, getWorkspaceInvitationAcceptEndpoint, getWorkspaceInvitationRejectEndpoint, ENDPOINT_WORKSPACE_JOIN, ENDPOINT_WORKSPACE_LOGO, ENDPOINT_WORKSPACE_PLAN_DETAILS, ENDPOINT_WORKSPACE_USERS, getWorkspaceActiveProjectsEndpoint, getWorkspaceArchivedProjectsEndpoint, } from './consts/endpoints.js';
|
|
17
|
+
import { validateAttachment, validateComment, validateCommentArray, validateCurrentUser, validateLabel, validateLabelArray, validateProject, validateProjectArray, validateSection, validateSectionArray, validateTask, validateTaskArray, validateUserArray, validateProductivityStats, validateReminder, validateReminderArray, validateLocationReminderArray, validateActivityEventArray, validateWorkspaceUserArray, validateWorkspaceInvitation, validateWorkspaceInvitationArray, validateWorkspacePlanDetails, validateJoinWorkspaceResult, validateWorkspace, validateWorkspaceArray, validateMemberActivityInfoArray, validateWorkspaceUserTaskArray, validateProjectActivityStats, validateProjectHealth, validateProjectHealthContext, validateProjectProgress, validateWorkspaceInsights, validateBackupArray, validateIdMappingArray, validateMovedIdArray, } from './utils/validators.js';
|
|
18
18
|
import { formatDateToYYYYMMDD } from './utils/url-helpers.js';
|
|
19
19
|
import { uploadMultipartFile } from './utils/multipart-upload.js';
|
|
20
|
+
import { camelCaseKeys } from './utils/case-conversion.js';
|
|
20
21
|
import { normalizeObjectEventTypeForApi, denormalizeObjectTypeFromApi, } from './utils/activity-helpers.js';
|
|
21
22
|
import { processTaskContent } from './utils/uncompletable-helpers.js';
|
|
22
23
|
import { z } from 'zod';
|
|
@@ -344,6 +345,30 @@ export class TodoistApi {
|
|
|
344
345
|
nextCursor,
|
|
345
346
|
};
|
|
346
347
|
}
|
|
348
|
+
/**
|
|
349
|
+
* Retrieves all completed tasks with optional filters.
|
|
350
|
+
*
|
|
351
|
+
* Uses offset-based pagination rather than cursor-based.
|
|
352
|
+
*
|
|
353
|
+
* @param args - Optional parameters including project ID, label, date range, and pagination.
|
|
354
|
+
* @returns A promise that resolves to completed tasks with associated project and section data.
|
|
355
|
+
*/
|
|
356
|
+
async getAllCompletedTasks(args = {}) {
|
|
357
|
+
const { since, until } = args, rest = __rest(args, ["since", "until"]);
|
|
358
|
+
const { data } = await request({
|
|
359
|
+
httpMethod: 'GET',
|
|
360
|
+
baseUri: this.syncApiBase,
|
|
361
|
+
relativePath: ENDPOINT_REST_TASKS_COMPLETED,
|
|
362
|
+
apiToken: this.authToken,
|
|
363
|
+
customFetch: this.customFetch,
|
|
364
|
+
payload: Object.assign(Object.assign(Object.assign({}, rest), (since ? { since: since.toISOString() } : {})), (until ? { until: until.toISOString() } : {})),
|
|
365
|
+
});
|
|
366
|
+
return {
|
|
367
|
+
projects: data.projects,
|
|
368
|
+
sections: data.sections,
|
|
369
|
+
items: validateTaskArray(data.items),
|
|
370
|
+
};
|
|
371
|
+
}
|
|
347
372
|
/**
|
|
348
373
|
* Creates a new task with the provided parameters.
|
|
349
374
|
*
|
|
@@ -835,6 +860,116 @@ export class TodoistApi {
|
|
|
835
860
|
nextCursor,
|
|
836
861
|
};
|
|
837
862
|
}
|
|
863
|
+
// ── Insights ──
|
|
864
|
+
/**
|
|
865
|
+
* Retrieves activity statistics for a project.
|
|
866
|
+
*
|
|
867
|
+
* @param projectId - The unique identifier of the project.
|
|
868
|
+
* @param args - Optional parameters including weeks and weekly counts flag.
|
|
869
|
+
* @returns A promise that resolves to the project activity stats.
|
|
870
|
+
*/
|
|
871
|
+
async getProjectActivityStats(projectId, args = {}) {
|
|
872
|
+
z.string().parse(projectId);
|
|
873
|
+
const response = await request({
|
|
874
|
+
httpMethod: 'GET',
|
|
875
|
+
baseUri: this.syncApiBase,
|
|
876
|
+
relativePath: getProjectInsightsActivityStatsEndpoint(projectId),
|
|
877
|
+
apiToken: this.authToken,
|
|
878
|
+
customFetch: this.customFetch,
|
|
879
|
+
payload: Object.assign({ objectType: 'ITEM', eventType: 'COMPLETED' }, args),
|
|
880
|
+
});
|
|
881
|
+
return validateProjectActivityStats(response.data);
|
|
882
|
+
}
|
|
883
|
+
/**
|
|
884
|
+
* Retrieves the health status of a project.
|
|
885
|
+
*
|
|
886
|
+
* @param projectId - The unique identifier of the project.
|
|
887
|
+
* @returns A promise that resolves to the project health data.
|
|
888
|
+
*/
|
|
889
|
+
async getProjectHealth(projectId) {
|
|
890
|
+
z.string().parse(projectId);
|
|
891
|
+
const response = await request({
|
|
892
|
+
httpMethod: 'GET',
|
|
893
|
+
baseUri: this.syncApiBase,
|
|
894
|
+
relativePath: getProjectInsightsHealthEndpoint(projectId),
|
|
895
|
+
apiToken: this.authToken,
|
|
896
|
+
customFetch: this.customFetch,
|
|
897
|
+
});
|
|
898
|
+
return validateProjectHealth(response.data);
|
|
899
|
+
}
|
|
900
|
+
/**
|
|
901
|
+
* Retrieves the health context for a project, including metrics and task details.
|
|
902
|
+
*
|
|
903
|
+
* @param projectId - The unique identifier of the project.
|
|
904
|
+
* @returns A promise that resolves to the project health context.
|
|
905
|
+
*/
|
|
906
|
+
async getProjectHealthContext(projectId) {
|
|
907
|
+
z.string().parse(projectId);
|
|
908
|
+
const response = await request({
|
|
909
|
+
httpMethod: 'GET',
|
|
910
|
+
baseUri: this.syncApiBase,
|
|
911
|
+
relativePath: getProjectInsightsHealthContextEndpoint(projectId),
|
|
912
|
+
apiToken: this.authToken,
|
|
913
|
+
customFetch: this.customFetch,
|
|
914
|
+
});
|
|
915
|
+
return validateProjectHealthContext(response.data);
|
|
916
|
+
}
|
|
917
|
+
/**
|
|
918
|
+
* Retrieves progress information for a project.
|
|
919
|
+
*
|
|
920
|
+
* @param projectId - The unique identifier of the project.
|
|
921
|
+
* @returns A promise that resolves to the project progress data.
|
|
922
|
+
*/
|
|
923
|
+
async getProjectProgress(projectId) {
|
|
924
|
+
z.string().parse(projectId);
|
|
925
|
+
const response = await request({
|
|
926
|
+
httpMethod: 'GET',
|
|
927
|
+
baseUri: this.syncApiBase,
|
|
928
|
+
relativePath: getProjectInsightsProgressEndpoint(projectId),
|
|
929
|
+
apiToken: this.authToken,
|
|
930
|
+
customFetch: this.customFetch,
|
|
931
|
+
});
|
|
932
|
+
return validateProjectProgress(response.data);
|
|
933
|
+
}
|
|
934
|
+
/**
|
|
935
|
+
* Retrieves insights for all projects in a workspace.
|
|
936
|
+
*
|
|
937
|
+
* @param workspaceId - The unique identifier of the workspace.
|
|
938
|
+
* @param args - Optional parameters including project IDs filter.
|
|
939
|
+
* @returns A promise that resolves to workspace insights data.
|
|
940
|
+
*/
|
|
941
|
+
async getWorkspaceInsights(workspaceId, args = {}) {
|
|
942
|
+
z.string().parse(workspaceId);
|
|
943
|
+
const response = await request({
|
|
944
|
+
httpMethod: 'GET',
|
|
945
|
+
baseUri: this.syncApiBase,
|
|
946
|
+
relativePath: getWorkspaceInsightsEndpoint(workspaceId),
|
|
947
|
+
apiToken: this.authToken,
|
|
948
|
+
customFetch: this.customFetch,
|
|
949
|
+
payload: Object.assign(Object.assign({}, args), (args.projectIds ? { projectIds: args.projectIds.join(',') } : {})),
|
|
950
|
+
});
|
|
951
|
+
return validateWorkspaceInsights(response.data);
|
|
952
|
+
}
|
|
953
|
+
/**
|
|
954
|
+
* Triggers a health analysis for a project.
|
|
955
|
+
*
|
|
956
|
+
* @param projectId - The unique identifier of the project.
|
|
957
|
+
* @param requestId - Optional custom identifier for the request.
|
|
958
|
+
* @returns A promise that resolves to the updated project health data.
|
|
959
|
+
*/
|
|
960
|
+
async analyzeProjectHealth(projectId, requestId) {
|
|
961
|
+
z.string().parse(projectId);
|
|
962
|
+
const response = await request({
|
|
963
|
+
httpMethod: 'POST',
|
|
964
|
+
baseUri: this.syncApiBase,
|
|
965
|
+
relativePath: getProjectInsightsHealthAnalyzeEndpoint(projectId),
|
|
966
|
+
apiToken: this.authToken,
|
|
967
|
+
customFetch: this.customFetch,
|
|
968
|
+
requestId: requestId,
|
|
969
|
+
});
|
|
970
|
+
return validateProjectHealth(response.data);
|
|
971
|
+
}
|
|
972
|
+
// ── Sections ──
|
|
838
973
|
/**
|
|
839
974
|
* Retrieves all sections within a specific project or matching criteria.
|
|
840
975
|
*
|
|
@@ -1253,6 +1388,46 @@ export class TodoistApi {
|
|
|
1253
1388
|
});
|
|
1254
1389
|
return isSuccess(response);
|
|
1255
1390
|
}
|
|
1391
|
+
/**
|
|
1392
|
+
* Retrieves a paginated list of time-based reminders.
|
|
1393
|
+
*
|
|
1394
|
+
* @param args - Optional parameters including task ID filter and pagination.
|
|
1395
|
+
* @returns A promise that resolves to a paginated list of reminders.
|
|
1396
|
+
*/
|
|
1397
|
+
async getReminders(args = {}) {
|
|
1398
|
+
const { data: { results, nextCursor }, } = await request({
|
|
1399
|
+
httpMethod: 'GET',
|
|
1400
|
+
baseUri: this.syncApiBase,
|
|
1401
|
+
relativePath: ENDPOINT_REST_REMINDERS,
|
|
1402
|
+
apiToken: this.authToken,
|
|
1403
|
+
customFetch: this.customFetch,
|
|
1404
|
+
payload: args,
|
|
1405
|
+
});
|
|
1406
|
+
return {
|
|
1407
|
+
results: validateReminderArray(results),
|
|
1408
|
+
nextCursor,
|
|
1409
|
+
};
|
|
1410
|
+
}
|
|
1411
|
+
/**
|
|
1412
|
+
* Retrieves a paginated list of location-based reminders.
|
|
1413
|
+
*
|
|
1414
|
+
* @param args - Optional parameters including task ID filter and pagination.
|
|
1415
|
+
* @returns A promise that resolves to a paginated list of location reminders.
|
|
1416
|
+
*/
|
|
1417
|
+
async getLocationReminders(args = {}) {
|
|
1418
|
+
const { data: { results, nextCursor }, } = await request({
|
|
1419
|
+
httpMethod: 'GET',
|
|
1420
|
+
baseUri: this.syncApiBase,
|
|
1421
|
+
relativePath: ENDPOINT_REST_LOCATION_REMINDERS,
|
|
1422
|
+
apiToken: this.authToken,
|
|
1423
|
+
customFetch: this.customFetch,
|
|
1424
|
+
payload: args,
|
|
1425
|
+
});
|
|
1426
|
+
return {
|
|
1427
|
+
results: validateLocationReminderArray(results),
|
|
1428
|
+
nextCursor,
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1256
1431
|
/**
|
|
1257
1432
|
* Retrieves a time-based reminder by its ID.
|
|
1258
1433
|
*
|
|
@@ -1666,6 +1841,246 @@ export class TodoistApi {
|
|
|
1666
1841
|
arrayBuffer: () => response.arrayBuffer(),
|
|
1667
1842
|
};
|
|
1668
1843
|
}
|
|
1844
|
+
// ── Backups ──
|
|
1845
|
+
/**
|
|
1846
|
+
* Retrieves a list of available backups.
|
|
1847
|
+
*
|
|
1848
|
+
* @param args - Optional parameters including MFA token.
|
|
1849
|
+
* @returns A promise that resolves to an array of backups.
|
|
1850
|
+
*/
|
|
1851
|
+
async getBackups(args = {}) {
|
|
1852
|
+
const response = await request({
|
|
1853
|
+
httpMethod: 'GET',
|
|
1854
|
+
baseUri: this.syncApiBase,
|
|
1855
|
+
relativePath: ENDPOINT_REST_BACKUPS,
|
|
1856
|
+
apiToken: this.authToken,
|
|
1857
|
+
customFetch: this.customFetch,
|
|
1858
|
+
payload: args,
|
|
1859
|
+
});
|
|
1860
|
+
return validateBackupArray(response.data);
|
|
1861
|
+
}
|
|
1862
|
+
/**
|
|
1863
|
+
* Downloads a backup file as binary data.
|
|
1864
|
+
*
|
|
1865
|
+
* @param args - Arguments including the backup file URL (from getBackups).
|
|
1866
|
+
* @returns A promise that resolves to a response with binary data accessible via arrayBuffer().
|
|
1867
|
+
*/
|
|
1868
|
+
async downloadBackup(args) {
|
|
1869
|
+
const url = `${this.syncApiBase}${ENDPOINT_REST_BACKUPS_DOWNLOAD}?file=${encodeURIComponent(args.file)}`;
|
|
1870
|
+
const fetchOptions = {
|
|
1871
|
+
headers: { Authorization: `Bearer ${this.authToken}` },
|
|
1872
|
+
};
|
|
1873
|
+
if (this.customFetch) {
|
|
1874
|
+
const response = await this.customFetch(url, fetchOptions);
|
|
1875
|
+
if (!response.ok) {
|
|
1876
|
+
throw new Error(`Failed to download backup: ${response.status} ${response.statusText}`);
|
|
1877
|
+
}
|
|
1878
|
+
const text = await response.text();
|
|
1879
|
+
const buffer = new TextEncoder().encode(text).buffer;
|
|
1880
|
+
return {
|
|
1881
|
+
ok: response.ok,
|
|
1882
|
+
status: response.status,
|
|
1883
|
+
statusText: response.statusText,
|
|
1884
|
+
headers: response.headers,
|
|
1885
|
+
text: () => Promise.resolve(text),
|
|
1886
|
+
json: () => response.json(),
|
|
1887
|
+
arrayBuffer: () => Promise.resolve(buffer),
|
|
1888
|
+
};
|
|
1889
|
+
}
|
|
1890
|
+
const response = await fetch(url, fetchOptions);
|
|
1891
|
+
if (!response.ok) {
|
|
1892
|
+
throw new Error(`Failed to download backup: ${response.status} ${response.statusText}`);
|
|
1893
|
+
}
|
|
1894
|
+
return {
|
|
1895
|
+
ok: response.ok,
|
|
1896
|
+
status: response.status,
|
|
1897
|
+
statusText: response.statusText,
|
|
1898
|
+
headers: headersToRecord(response.headers),
|
|
1899
|
+
text: () => response.text(),
|
|
1900
|
+
json: () => response.json(),
|
|
1901
|
+
arrayBuffer: () => response.arrayBuffer(),
|
|
1902
|
+
};
|
|
1903
|
+
}
|
|
1904
|
+
// ── Emails ──
|
|
1905
|
+
/**
|
|
1906
|
+
* Gets or creates an email forwarding address for an object.
|
|
1907
|
+
*
|
|
1908
|
+
* @param args - Arguments including object type and ID.
|
|
1909
|
+
* @param requestId - Optional custom identifier for the request.
|
|
1910
|
+
* @returns A promise that resolves to the email address.
|
|
1911
|
+
*/
|
|
1912
|
+
async getOrCreateEmailForwarding(args, requestId) {
|
|
1913
|
+
const { data } = await request({
|
|
1914
|
+
httpMethod: 'PUT',
|
|
1915
|
+
baseUri: this.syncApiBase,
|
|
1916
|
+
relativePath: ENDPOINT_REST_EMAILS,
|
|
1917
|
+
apiToken: this.authToken,
|
|
1918
|
+
customFetch: this.customFetch,
|
|
1919
|
+
payload: args,
|
|
1920
|
+
requestId: requestId,
|
|
1921
|
+
});
|
|
1922
|
+
return data;
|
|
1923
|
+
}
|
|
1924
|
+
/**
|
|
1925
|
+
* Disables email forwarding for an object.
|
|
1926
|
+
*
|
|
1927
|
+
* @param args - Arguments including object type and ID.
|
|
1928
|
+
* @param requestId - Optional custom identifier for the request.
|
|
1929
|
+
* @returns A promise that resolves to `true` if successful.
|
|
1930
|
+
*/
|
|
1931
|
+
async disableEmailForwarding(args, requestId) {
|
|
1932
|
+
const queryParams = new URLSearchParams({
|
|
1933
|
+
obj_type: args.objType,
|
|
1934
|
+
obj_id: args.objId,
|
|
1935
|
+
});
|
|
1936
|
+
const response = await request({
|
|
1937
|
+
httpMethod: 'DELETE',
|
|
1938
|
+
baseUri: this.syncApiBase,
|
|
1939
|
+
relativePath: `${ENDPOINT_REST_EMAILS}?${queryParams.toString()}`,
|
|
1940
|
+
apiToken: this.authToken,
|
|
1941
|
+
customFetch: this.customFetch,
|
|
1942
|
+
requestId: requestId,
|
|
1943
|
+
});
|
|
1944
|
+
return isSuccess(response);
|
|
1945
|
+
}
|
|
1946
|
+
// ── ID Mappings ──
|
|
1947
|
+
/**
|
|
1948
|
+
* Retrieves ID mappings between old and new IDs.
|
|
1949
|
+
*
|
|
1950
|
+
* @param args - Arguments including object type and IDs to look up.
|
|
1951
|
+
* @returns A promise that resolves to an array of ID mappings.
|
|
1952
|
+
*/
|
|
1953
|
+
async getIdMappings(args) {
|
|
1954
|
+
const response = await request({
|
|
1955
|
+
httpMethod: 'GET',
|
|
1956
|
+
baseUri: this.syncApiBase,
|
|
1957
|
+
relativePath: generatePath(ENDPOINT_REST_ID_MAPPINGS, args.objName, args.objIds.join(',')),
|
|
1958
|
+
apiToken: this.authToken,
|
|
1959
|
+
customFetch: this.customFetch,
|
|
1960
|
+
});
|
|
1961
|
+
return validateIdMappingArray(response.data);
|
|
1962
|
+
}
|
|
1963
|
+
/**
|
|
1964
|
+
* Retrieves moved IDs for objects that have been migrated.
|
|
1965
|
+
*
|
|
1966
|
+
* @param args - Arguments including object type and optional old IDs to look up.
|
|
1967
|
+
* @returns A promise that resolves to an array of moved ID pairs.
|
|
1968
|
+
*/
|
|
1969
|
+
async getMovedIds(args) {
|
|
1970
|
+
const response = await request({
|
|
1971
|
+
httpMethod: 'GET',
|
|
1972
|
+
baseUri: this.syncApiBase,
|
|
1973
|
+
relativePath: generatePath(ENDPOINT_REST_MOVED_IDS, args.objName),
|
|
1974
|
+
apiToken: this.authToken,
|
|
1975
|
+
customFetch: this.customFetch,
|
|
1976
|
+
payload: args.oldIds ? { oldIds: args.oldIds.join(',') } : undefined,
|
|
1977
|
+
});
|
|
1978
|
+
return validateMovedIdArray(response.data);
|
|
1979
|
+
}
|
|
1980
|
+
// ── Templates ──
|
|
1981
|
+
/**
|
|
1982
|
+
* Exports a project as a template file (CSV format).
|
|
1983
|
+
*
|
|
1984
|
+
* @param args - Arguments including project ID and optional date format preference.
|
|
1985
|
+
* @returns A promise that resolves to the template file content as a string.
|
|
1986
|
+
*/
|
|
1987
|
+
async exportTemplateAsFile(args) {
|
|
1988
|
+
const response = await request({
|
|
1989
|
+
httpMethod: 'GET',
|
|
1990
|
+
baseUri: this.syncApiBase,
|
|
1991
|
+
relativePath: ENDPOINT_REST_TEMPLATES_FILE,
|
|
1992
|
+
apiToken: this.authToken,
|
|
1993
|
+
customFetch: this.customFetch,
|
|
1994
|
+
payload: args,
|
|
1995
|
+
});
|
|
1996
|
+
return response.data;
|
|
1997
|
+
}
|
|
1998
|
+
/**
|
|
1999
|
+
* Exports a project as a template URL.
|
|
2000
|
+
*
|
|
2001
|
+
* @param args - Arguments including project ID and optional date format preference.
|
|
2002
|
+
* @returns A promise that resolves to the file name and URL.
|
|
2003
|
+
*/
|
|
2004
|
+
async exportTemplateAsUrl(args) {
|
|
2005
|
+
const { data } = await request({
|
|
2006
|
+
httpMethod: 'GET',
|
|
2007
|
+
baseUri: this.syncApiBase,
|
|
2008
|
+
relativePath: ENDPOINT_REST_TEMPLATES_URL,
|
|
2009
|
+
apiToken: this.authToken,
|
|
2010
|
+
customFetch: this.customFetch,
|
|
2011
|
+
payload: args,
|
|
2012
|
+
});
|
|
2013
|
+
return data;
|
|
2014
|
+
}
|
|
2015
|
+
/**
|
|
2016
|
+
* Creates a new project from a template file.
|
|
2017
|
+
*
|
|
2018
|
+
* @param args - Arguments including project name, template file, and optional workspace ID.
|
|
2019
|
+
* @param requestId - Optional custom identifier for the request.
|
|
2020
|
+
* @returns A promise that resolves to the created project data.
|
|
2021
|
+
*/
|
|
2022
|
+
async createProjectFromTemplate(args, requestId) {
|
|
2023
|
+
const { file, fileName, name, workspaceId } = args;
|
|
2024
|
+
const additionalFields = { name };
|
|
2025
|
+
if (workspaceId !== undefined && workspaceId !== null) {
|
|
2026
|
+
additionalFields.workspace_id = workspaceId;
|
|
2027
|
+
}
|
|
2028
|
+
const data = await uploadMultipartFile({
|
|
2029
|
+
baseUrl: this.syncApiBase,
|
|
2030
|
+
authToken: this.authToken,
|
|
2031
|
+
endpoint: ENDPOINT_REST_TEMPLATES_CREATE_FROM_FILE,
|
|
2032
|
+
file,
|
|
2033
|
+
fileName,
|
|
2034
|
+
additionalFields,
|
|
2035
|
+
customFetch: this.customFetch,
|
|
2036
|
+
requestId,
|
|
2037
|
+
});
|
|
2038
|
+
return this.validateTemplateResponse(camelCaseKeys(data));
|
|
2039
|
+
}
|
|
2040
|
+
/**
|
|
2041
|
+
* Imports a template file into an existing project.
|
|
2042
|
+
*
|
|
2043
|
+
* @param args - Arguments including project ID and template file.
|
|
2044
|
+
* @param requestId - Optional custom identifier for the request.
|
|
2045
|
+
* @returns A promise that resolves to the import result.
|
|
2046
|
+
*/
|
|
2047
|
+
async importTemplateIntoProject(args, requestId) {
|
|
2048
|
+
const { file, fileName, projectId } = args;
|
|
2049
|
+
const data = await uploadMultipartFile({
|
|
2050
|
+
baseUrl: this.syncApiBase,
|
|
2051
|
+
authToken: this.authToken,
|
|
2052
|
+
endpoint: ENDPOINT_REST_TEMPLATES_IMPORT_FROM_FILE,
|
|
2053
|
+
file,
|
|
2054
|
+
fileName,
|
|
2055
|
+
additionalFields: { project_id: projectId },
|
|
2056
|
+
customFetch: this.customFetch,
|
|
2057
|
+
requestId,
|
|
2058
|
+
});
|
|
2059
|
+
return this.validateTemplateResponse(camelCaseKeys(data));
|
|
2060
|
+
}
|
|
2061
|
+
/**
|
|
2062
|
+
* Imports a template by ID into an existing project.
|
|
2063
|
+
*
|
|
2064
|
+
* @param args - Arguments including project ID, template ID, and optional locale.
|
|
2065
|
+
* @param requestId - Optional custom identifier for the request.
|
|
2066
|
+
* @returns A promise that resolves to the import result.
|
|
2067
|
+
*/
|
|
2068
|
+
async importTemplateFromId(args, requestId) {
|
|
2069
|
+
const { data } = await request({
|
|
2070
|
+
httpMethod: 'POST',
|
|
2071
|
+
baseUri: this.syncApiBase,
|
|
2072
|
+
relativePath: ENDPOINT_REST_TEMPLATES_IMPORT_FROM_ID,
|
|
2073
|
+
apiToken: this.authToken,
|
|
2074
|
+
customFetch: this.customFetch,
|
|
2075
|
+
payload: args,
|
|
2076
|
+
requestId: requestId,
|
|
2077
|
+
});
|
|
2078
|
+
return this.validateTemplateResponse(data);
|
|
2079
|
+
}
|
|
2080
|
+
validateTemplateResponse(data) {
|
|
2081
|
+
var _a, _b, _c, _d;
|
|
2082
|
+
return Object.assign(Object.assign({}, data), { projects: validateProjectArray((_a = data.projects) !== null && _a !== void 0 ? _a : []), sections: validateSectionArray((_b = data.sections) !== null && _b !== void 0 ? _b : []), tasks: validateTaskArray((_c = data.tasks) !== null && _c !== void 0 ? _c : []), comments: validateCommentArray((_d = data.comments) !== null && _d !== void 0 ? _d : []) });
|
|
2083
|
+
}
|
|
1669
2084
|
/* Workspace methods */
|
|
1670
2085
|
/**
|
|
1671
2086
|
* Gets pending invitations for a workspace.
|
|
@@ -1990,6 +2405,109 @@ export class TodoistApi {
|
|
|
1990
2405
|
});
|
|
1991
2406
|
return isSuccess(response);
|
|
1992
2407
|
}
|
|
2408
|
+
/**
|
|
2409
|
+
* Retrieves activity information for workspace members.
|
|
2410
|
+
*
|
|
2411
|
+
* @param args - Arguments including workspace ID and optional user/project filters.
|
|
2412
|
+
* @param requestId - Optional custom identifier for the request.
|
|
2413
|
+
* @returns A promise that resolves to workspace members activity data.
|
|
2414
|
+
*/
|
|
2415
|
+
async getWorkspaceMembersActivity(args, requestId) {
|
|
2416
|
+
const { workspaceId } = args, queryParams = __rest(args, ["workspaceId"]);
|
|
2417
|
+
const { data } = await request({
|
|
2418
|
+
httpMethod: 'GET',
|
|
2419
|
+
baseUri: this.syncApiBase,
|
|
2420
|
+
relativePath: ENDPOINT_WORKSPACE_MEMBERS,
|
|
2421
|
+
apiToken: this.authToken,
|
|
2422
|
+
customFetch: this.customFetch,
|
|
2423
|
+
payload: Object.assign({ workspaceId }, queryParams),
|
|
2424
|
+
requestId: requestId,
|
|
2425
|
+
});
|
|
2426
|
+
return {
|
|
2427
|
+
members: validateMemberActivityInfoArray(data.members),
|
|
2428
|
+
};
|
|
2429
|
+
}
|
|
2430
|
+
/**
|
|
2431
|
+
* Retrieves tasks assigned to a specific user in a workspace.
|
|
2432
|
+
*
|
|
2433
|
+
* @param args - Arguments including workspace ID, user ID, and optional project filter.
|
|
2434
|
+
* @param requestId - Optional custom identifier for the request.
|
|
2435
|
+
* @returns A promise that resolves to workspace user tasks.
|
|
2436
|
+
*/
|
|
2437
|
+
async getWorkspaceUserTasks(args, requestId) {
|
|
2438
|
+
const { workspaceId, userId } = args, queryParams = __rest(args, ["workspaceId", "userId"]);
|
|
2439
|
+
const { data } = await request({
|
|
2440
|
+
httpMethod: 'GET',
|
|
2441
|
+
baseUri: this.syncApiBase,
|
|
2442
|
+
relativePath: getWorkspaceUserTasksEndpoint(workspaceId, userId),
|
|
2443
|
+
apiToken: this.authToken,
|
|
2444
|
+
customFetch: this.customFetch,
|
|
2445
|
+
payload: queryParams,
|
|
2446
|
+
requestId: requestId,
|
|
2447
|
+
});
|
|
2448
|
+
return {
|
|
2449
|
+
tasks: validateWorkspaceUserTaskArray(data.tasks),
|
|
2450
|
+
};
|
|
2451
|
+
}
|
|
2452
|
+
/**
|
|
2453
|
+
* Invites users to a workspace by email.
|
|
2454
|
+
*
|
|
2455
|
+
* @param args - Arguments including workspace ID, email list, and optional role.
|
|
2456
|
+
* @param requestId - Optional custom identifier for the request.
|
|
2457
|
+
* @returns A promise that resolves to the list of invited emails.
|
|
2458
|
+
*/
|
|
2459
|
+
async inviteWorkspaceUsers(args, requestId) {
|
|
2460
|
+
const { workspaceId } = args, payload = __rest(args, ["workspaceId"]);
|
|
2461
|
+
const { data } = await request({
|
|
2462
|
+
httpMethod: 'POST',
|
|
2463
|
+
baseUri: this.syncApiBase,
|
|
2464
|
+
relativePath: getWorkspaceInviteUsersEndpoint(workspaceId),
|
|
2465
|
+
apiToken: this.authToken,
|
|
2466
|
+
customFetch: this.customFetch,
|
|
2467
|
+
payload: payload,
|
|
2468
|
+
requestId: requestId,
|
|
2469
|
+
});
|
|
2470
|
+
return data;
|
|
2471
|
+
}
|
|
2472
|
+
/**
|
|
2473
|
+
* Updates a workspace user's role.
|
|
2474
|
+
*
|
|
2475
|
+
* @param args - Arguments including workspace ID, user ID, and new role.
|
|
2476
|
+
* @param requestId - Optional custom identifier for the request.
|
|
2477
|
+
* @returns A promise that resolves to the updated workspace user view.
|
|
2478
|
+
*/
|
|
2479
|
+
async updateWorkspaceUser(args, requestId) {
|
|
2480
|
+
const { workspaceId, userId } = args, payload = __rest(args, ["workspaceId", "userId"]);
|
|
2481
|
+
const response = await request({
|
|
2482
|
+
httpMethod: 'POST',
|
|
2483
|
+
baseUri: this.syncApiBase,
|
|
2484
|
+
relativePath: getWorkspaceUserEndpoint(workspaceId, userId),
|
|
2485
|
+
apiToken: this.authToken,
|
|
2486
|
+
customFetch: this.customFetch,
|
|
2487
|
+
payload: payload,
|
|
2488
|
+
requestId: requestId,
|
|
2489
|
+
});
|
|
2490
|
+
return validateJoinWorkspaceResult(response.data);
|
|
2491
|
+
}
|
|
2492
|
+
/**
|
|
2493
|
+
* Removes a user from a workspace.
|
|
2494
|
+
*
|
|
2495
|
+
* @param args - Arguments including workspace ID and user ID.
|
|
2496
|
+
* @param requestId - Optional custom identifier for the request.
|
|
2497
|
+
* @returns A promise that resolves to `true` if successful.
|
|
2498
|
+
*/
|
|
2499
|
+
async removeWorkspaceUser(args, requestId) {
|
|
2500
|
+
const { workspaceId, userId } = args;
|
|
2501
|
+
const response = await request({
|
|
2502
|
+
httpMethod: 'DELETE',
|
|
2503
|
+
baseUri: this.syncApiBase,
|
|
2504
|
+
relativePath: getWorkspaceUserEndpoint(workspaceId, userId),
|
|
2505
|
+
apiToken: this.authToken,
|
|
2506
|
+
customFetch: this.customFetch,
|
|
2507
|
+
requestId: requestId,
|
|
2508
|
+
});
|
|
2509
|
+
return isSuccess(response);
|
|
2510
|
+
}
|
|
1993
2511
|
/**
|
|
1994
2512
|
* Gets active projects in a workspace with pagination.
|
|
1995
2513
|
*
|
|
@@ -432,3 +432,117 @@ export const WorkspaceSchema = z.object({
|
|
|
432
432
|
creatorId: z.string(),
|
|
433
433
|
properties: WorkspacePropertiesSchema,
|
|
434
434
|
});
|
|
435
|
+
export const MemberActivityInfoSchema = z.object({
|
|
436
|
+
userId: z.string(),
|
|
437
|
+
tasksAssigned: z.number().int(),
|
|
438
|
+
tasksOverdue: z.number().int(),
|
|
439
|
+
});
|
|
440
|
+
export const WorkspaceUserTaskSchema = z.object({
|
|
441
|
+
id: z.string(),
|
|
442
|
+
content: z.string(),
|
|
443
|
+
responsibleUid: z.string().nullable(),
|
|
444
|
+
due: DueDateSchema.nullable(),
|
|
445
|
+
deadline: DeadlineSchema.nullable(),
|
|
446
|
+
labels: z.array(z.string()),
|
|
447
|
+
notesCount: z.number().int(),
|
|
448
|
+
projectId: z.string(),
|
|
449
|
+
projectName: z.string(),
|
|
450
|
+
priority: z.number().int(),
|
|
451
|
+
description: z.string(),
|
|
452
|
+
isOverdue: z.boolean(),
|
|
453
|
+
});
|
|
454
|
+
// Insights entities
|
|
455
|
+
export const DayActivitySchema = z.object({
|
|
456
|
+
date: z.string(),
|
|
457
|
+
totalCount: z.number().int(),
|
|
458
|
+
});
|
|
459
|
+
export const WeekRollupSchema = z.object({
|
|
460
|
+
fromDate: z.string(),
|
|
461
|
+
toDate: z.string(),
|
|
462
|
+
totalCount: z.number().int(),
|
|
463
|
+
});
|
|
464
|
+
export const ProjectActivityStatsSchema = z.object({
|
|
465
|
+
dayItems: z.array(DayActivitySchema),
|
|
466
|
+
weekItems: z.array(WeekRollupSchema).nullable(),
|
|
467
|
+
});
|
|
468
|
+
/** Available project health statuses. */
|
|
469
|
+
export const HEALTH_STATUSES = [
|
|
470
|
+
'UNKNOWN',
|
|
471
|
+
'ON_TRACK',
|
|
472
|
+
'AT_RISK',
|
|
473
|
+
'CRITICAL',
|
|
474
|
+
'EXCELLENT',
|
|
475
|
+
'ERROR',
|
|
476
|
+
];
|
|
477
|
+
export const TaskRecommendationSchema = z.object({
|
|
478
|
+
taskId: z.string(),
|
|
479
|
+
recommendation: z.string(),
|
|
480
|
+
});
|
|
481
|
+
export const ProjectHealthSchema = z.object({
|
|
482
|
+
status: z.enum(HEALTH_STATUSES),
|
|
483
|
+
description: z.string().nullable().optional(),
|
|
484
|
+
descriptionSummary: z.string().nullable().optional(),
|
|
485
|
+
taskRecommendations: z.array(TaskRecommendationSchema).nullable().optional(),
|
|
486
|
+
projectId: z.string().nullable().optional(),
|
|
487
|
+
updatedAt: z.string().nullable().optional(),
|
|
488
|
+
isStale: z.boolean().default(false),
|
|
489
|
+
updateInProgress: z.boolean().default(false),
|
|
490
|
+
});
|
|
491
|
+
export const ProjectMetricsSchema = z.object({
|
|
492
|
+
totalTasks: z.number().int(),
|
|
493
|
+
completedTasks: z.number().int(),
|
|
494
|
+
overdueTasks: z.number().int(),
|
|
495
|
+
tasksCreatedThisWeek: z.number().int(),
|
|
496
|
+
tasksCompletedThisWeek: z.number().int(),
|
|
497
|
+
averageCompletionTime: z.number().nullable(),
|
|
498
|
+
});
|
|
499
|
+
export const TaskContextSchema = z.object({
|
|
500
|
+
id: z.string(),
|
|
501
|
+
content: z.string(),
|
|
502
|
+
due: z.string().nullable().optional(),
|
|
503
|
+
deadline: z.string().nullable().optional(),
|
|
504
|
+
priority: z.string(),
|
|
505
|
+
isCompleted: z.boolean(),
|
|
506
|
+
createdAt: z.string(),
|
|
507
|
+
updatedAt: z.string(),
|
|
508
|
+
completedAt: z.string().nullable(),
|
|
509
|
+
completedByUid: z.string().nullable(),
|
|
510
|
+
labels: z.array(z.string()),
|
|
511
|
+
});
|
|
512
|
+
export const ProjectHealthContextSchema = z.object({
|
|
513
|
+
projectId: z.string(),
|
|
514
|
+
projectName: z.string(),
|
|
515
|
+
projectDescription: z.string().nullable(),
|
|
516
|
+
projectMetrics: ProjectMetricsSchema,
|
|
517
|
+
tasks: z.array(TaskContextSchema),
|
|
518
|
+
language: z.string().nullable().optional(),
|
|
519
|
+
});
|
|
520
|
+
export const ProjectProgressSchema = z.object({
|
|
521
|
+
projectId: z.string(),
|
|
522
|
+
completedCount: z.number().int(),
|
|
523
|
+
activeCount: z.number().int(),
|
|
524
|
+
progressPercent: z.number().int(),
|
|
525
|
+
});
|
|
526
|
+
export const ProjectInsightSchema = z.object({
|
|
527
|
+
projectId: z.string(),
|
|
528
|
+
health: ProjectHealthSchema.nullable(),
|
|
529
|
+
progress: ProjectProgressSchema.nullable(),
|
|
530
|
+
});
|
|
531
|
+
export const WorkspaceInsightsSchema = z.object({
|
|
532
|
+
folderId: z.string().nullable(),
|
|
533
|
+
projectInsights: z.array(ProjectInsightSchema),
|
|
534
|
+
});
|
|
535
|
+
// Backups
|
|
536
|
+
export const BackupSchema = z.object({
|
|
537
|
+
version: z.string(),
|
|
538
|
+
url: z.string(),
|
|
539
|
+
});
|
|
540
|
+
// ID Mappings
|
|
541
|
+
export const IdMappingSchema = z.object({
|
|
542
|
+
oldId: z.string().nullable(),
|
|
543
|
+
newId: z.string().nullable(),
|
|
544
|
+
});
|
|
545
|
+
export const MovedIdSchema = z.object({
|
|
546
|
+
oldId: z.string(),
|
|
547
|
+
newId: z.string(),
|
|
548
|
+
});
|