From 78068387167a4775705c792cf35563a6ed2fd057 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Wed, 15 Jan 2025 15:58:37 +0100 Subject: [PATCH 1/4] feat: [BREAKING] migrate from REST API to Sync API --- src/TodoistApi.ts | 184 ++++++++++++++++++++++------------ src/consts/endpoints.ts | 16 +-- src/restClient.ts | 4 +- src/testUtils/testDefaults.ts | 16 ++- src/types/entities.ts | 67 ++++++------- src/types/requests.ts | 55 ++++++++-- src/utils/taskConverters.ts | 22 ++-- 7 files changed, 222 insertions(+), 142 deletions(-) diff --git a/src/TodoistApi.ts b/src/TodoistApi.ts index d48977a..a2215a9 100644 --- a/src/TodoistApi.ts +++ b/src/TodoistApi.ts @@ -26,11 +26,14 @@ import { GetSharedLabelsArgs, RenameSharedLabelArgs, RemoveSharedLabelArgs, + GetProjectsArgs, + GetProjectCollaboratorsArgs, + GetSections, + GetLabelsArgs, } from './types/requests' import { request, isSuccess } from './restClient' import { getTaskFromQuickAddResponse } from './utils/taskConverters' import { - getRestBaseUri, getSyncBaseUri, ENDPOINT_REST_TASKS, ENDPOINT_REST_PROJECTS, @@ -73,19 +76,16 @@ export class TodoistApi { constructor(authToken: string, baseUrl?: string) { this.authToken = authToken - - this.restApiBase = getRestBaseUri(baseUrl) this.syncApiBase = getSyncBaseUri(baseUrl) } - private restApiBase: string private syncApiBase: string async getTask(id: string): Promise { String.check(id) const response = await request( 'GET', - this.restApiBase, + this.syncApiBase, generatePath(ENDPOINT_REST_TASKS, id), this.authToken, ) @@ -93,22 +93,27 @@ export class TodoistApi { return validateTask(response.data) } - async getTasks(args?: GetTasksArgs): Promise { - const response = await request( - 'GET', - this.restApiBase, - ENDPOINT_REST_TASKS, - this.authToken, - args, - ) + async getTasks(args: GetTasksArgs = {}): Promise<{ + results: Task[] + nextCursor: string | null + }> { + const { + data: { results, nextCursor }, + } = await request<{ + results: Task[] + nextCursor: string | null + }>('GET', this.syncApiBase, ENDPOINT_REST_TASKS, this.authToken, args) - return validateTaskArray(response.data) + return { + results: validateTaskArray(results), + nextCursor, + } } async addTask(args: AddTaskArgs, requestId?: string): Promise { const response = await request( 'POST', - this.restApiBase, + this.syncApiBase, ENDPOINT_REST_TASKS, this.authToken, args, @@ -136,7 +141,7 @@ export class TodoistApi { String.check(id) const response = await request( 'POST', - this.restApiBase, + this.syncApiBase, generatePath(ENDPOINT_REST_TASKS, id), this.authToken, args, @@ -149,7 +154,7 @@ export class TodoistApi { String.check(id) const response = await request( 'POST', - this.restApiBase, + this.syncApiBase, generatePath(ENDPOINT_REST_TASKS, id, ENDPOINT_REST_TASK_CLOSE), this.authToken, undefined, @@ -162,7 +167,7 @@ export class TodoistApi { String.check(id) const response = await request( 'POST', - this.restApiBase, + this.syncApiBase, generatePath(ENDPOINT_REST_TASKS, id, ENDPOINT_REST_TASK_REOPEN), this.authToken, undefined, @@ -175,7 +180,7 @@ export class TodoistApi { String.check(id) const response = await request( 'DELETE', - this.restApiBase, + this.syncApiBase, generatePath(ENDPOINT_REST_TASKS, id), this.authToken, undefined, @@ -188,7 +193,7 @@ export class TodoistApi { String.check(id) const response = await request( 'GET', - this.restApiBase, + this.syncApiBase, generatePath(ENDPOINT_REST_PROJECTS, id), this.authToken, ) @@ -196,21 +201,29 @@ export class TodoistApi { return validateProject(response.data) } - async getProjects(): Promise { - const response = await request( + async getProjects( + args: GetProjectsArgs = {}, + ): Promise<{ results: Project[]; nextCursor: string | null }> { + const { + data: { results, nextCursor }, + } = await request<{ results: Project[]; nextCursor: string | null }>( 'GET', - this.restApiBase, + this.syncApiBase, ENDPOINT_REST_PROJECTS, this.authToken, + args, ) - return validateProjectArray(response.data) + return { + results: validateProjectArray(results), + nextCursor, + } } async addProject(args: AddProjectArgs, requestId?: string): Promise { const response = await request( 'POST', - this.restApiBase, + this.syncApiBase, ENDPOINT_REST_PROJECTS, this.authToken, args, @@ -224,7 +237,7 @@ export class TodoistApi { String.check(id) const response = await request( 'POST', - this.restApiBase, + this.syncApiBase, generatePath(ENDPOINT_REST_PROJECTS, id), this.authToken, args, @@ -237,7 +250,7 @@ export class TodoistApi { String.check(id) const response = await request( 'DELETE', - this.restApiBase, + this.syncApiBase, generatePath(ENDPOINT_REST_PROJECTS, id), this.authToken, undefined, @@ -246,35 +259,51 @@ export class TodoistApi { return isSuccess(response) } - async getProjectCollaborators(projectId: string): Promise { + async getProjectCollaborators( + projectId: string, + args: GetProjectCollaboratorsArgs = {}, + ): Promise<{ results: User[]; nextCursor: string | null }> { String.check(projectId) - const response = await request( + const { + data: { results, nextCursor }, + } = await request<{ results: User[]; nextCursor: string | null }>( 'GET', - this.restApiBase, + this.syncApiBase, generatePath(ENDPOINT_REST_PROJECTS, projectId, ENDPOINT_REST_PROJECT_COLLABORATORS), this.authToken, + args, ) - return validateUserArray(response.data) + return { + results: validateUserArray(results), + nextCursor, + } } - async getSections(projectId?: string): Promise { - const response = await request( + async getSections( + args: GetSections, + ): Promise<{ results: Section[]; nextCursor: string | null }> { + const { + data: { results, nextCursor }, + } = await request<{ results: Section[]; nextCursor: string | null }>( 'GET', - this.restApiBase, + this.syncApiBase, ENDPOINT_REST_SECTIONS, this.authToken, - projectId ? { projectId } : undefined, + args, ) - return validateSectionArray(response.data) + return { + results: validateSectionArray(results), + nextCursor, + } } async getSection(id: string): Promise
{ String.check(id) const response = await request
( 'GET', - this.restApiBase, + this.syncApiBase, generatePath(ENDPOINT_REST_SECTIONS, id), this.authToken, ) @@ -285,7 +314,7 @@ export class TodoistApi { async addSection(args: AddSectionArgs, requestId?: string): Promise
{ const response = await request
( 'POST', - this.restApiBase, + this.syncApiBase, ENDPOINT_REST_SECTIONS, this.authToken, args, @@ -299,7 +328,7 @@ export class TodoistApi { String.check(id) const response = await request( 'POST', - this.restApiBase, + this.syncApiBase, generatePath(ENDPOINT_REST_SECTIONS, id), this.authToken, args, @@ -312,7 +341,7 @@ export class TodoistApi { String.check(id) const response = await request( 'DELETE', - this.restApiBase, + this.syncApiBase, generatePath(ENDPOINT_REST_SECTIONS, id), this.authToken, undefined, @@ -328,7 +357,7 @@ export class TodoistApi { String.check(id) const response = await request