diff --git a/README.md b/README.md index a0b42c3..39e6fc7 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ This is the official TypeScript API client for the Todoist REST API. +> [!IMPORTANT] +> This library is currently being migrated from the Todoist REST API to the Todoist Sync API. As a result, parts of the documentation may be outdated. However, the client API remains consistent with the latest stable release, [v3.0.3](https://github.com/Doist/todoist-api-typescript/releases/tag/v3.0.3). Please note that some client methods may return unexpected data or encounter failures during this transition. + ## Installation ``` diff --git a/src/TodoistApi.comments.test.ts b/src/TodoistApi.comments.test.ts index 5aa6159..8263ada 100644 --- a/src/TodoistApi.comments.test.ts +++ b/src/TodoistApi.comments.test.ts @@ -7,7 +7,7 @@ import { DEFAULT_COMMENT, DEFAULT_REQUEST_ID, } from './testUtils/testDefaults' -import { getRestBaseUri, ENDPOINT_REST_COMMENTS } from './consts/endpoints' +import { getSyncBaseUri, ENDPOINT_REST_COMMENTS } from './consts/endpoints' import { setupRestClientMock } from './testUtils/mocks' function getTarget() { @@ -17,8 +17,11 @@ function getTarget() { describe('TodoistApi comment endpoints', () => { describe('getComments', () => { test('calls get request with expected params', async () => { - const getCommentsArgs = { projectId: '12' } - const requestMock = setupRestClientMock([DEFAULT_COMMENT]) + const getCommentsArgs = { projectId: '12', limit: 10, cursor: '0' } + const requestMock = setupRestClientMock({ + results: [DEFAULT_COMMENT], + nextCursor: '123', + }) const api = getTarget() await api.getComments(getCommentsArgs) @@ -26,7 +29,7 @@ describe('TodoistApi comment endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'GET', - getRestBaseUri(), + getSyncBaseUri(), ENDPOINT_REST_COMMENTS, DEFAULT_AUTH_TOKEN, getCommentsArgs, @@ -40,12 +43,13 @@ describe('TodoistApi comment endpoints', () => { COMMENT_WITH_OPTIONALS_AS_NULL_PROJECT, COMMENT_WITH_ATTACHMENT_WITH_OPTIONALS_AS_NULL, ] - setupRestClientMock(expectedComments) + setupRestClientMock({ results: expectedComments, nextCursor: '123' }) const api = getTarget() - const comments = await api.getComments({ taskId: '12' }) + const { results: comments, nextCursor } = await api.getComments({ taskId: '12' }) expect(comments).toEqual(expectedComments) + expect(nextCursor).toBe('123') }) }) @@ -60,7 +64,7 @@ describe('TodoistApi comment endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'GET', - getRestBaseUri(), + getSyncBaseUri(), `${ENDPOINT_REST_COMMENTS}/${commentId}`, DEFAULT_AUTH_TOKEN, ) @@ -92,7 +96,7 @@ describe('TodoistApi comment endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'POST', - getRestBaseUri(), + getSyncBaseUri(), ENDPOINT_REST_COMMENTS, DEFAULT_AUTH_TOKEN, addCommentArgs, @@ -126,7 +130,7 @@ describe('TodoistApi comment endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'POST', - getRestBaseUri(), + getSyncBaseUri(), `${ENDPOINT_REST_COMMENTS}/${taskId}`, DEFAULT_AUTH_TOKEN, updateCommentArgs, @@ -156,7 +160,7 @@ describe('TodoistApi comment endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'DELETE', - getRestBaseUri(), + getSyncBaseUri(), `${ENDPOINT_REST_COMMENTS}/${taskId}`, DEFAULT_AUTH_TOKEN, undefined, diff --git a/src/TodoistApi.labels.test.ts b/src/TodoistApi.labels.test.ts index 42a42e7..61d0617 100644 --- a/src/TodoistApi.labels.test.ts +++ b/src/TodoistApi.labels.test.ts @@ -1,6 +1,6 @@ import { TodoistApi } from '.' import { DEFAULT_AUTH_TOKEN, DEFAULT_LABEL, DEFAULT_REQUEST_ID } from './testUtils/testDefaults' -import { getRestBaseUri, ENDPOINT_REST_LABELS } from './consts/endpoints' +import { getSyncBaseUri, ENDPOINT_REST_LABELS } from './consts/endpoints' import { setupRestClientMock } from './testUtils/mocks' function getTarget() { @@ -19,7 +19,7 @@ describe('TodoistApi label endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'GET', - getRestBaseUri(), + getSyncBaseUri(), `${ENDPOINT_REST_LABELS}/${labelId}`, DEFAULT_AUTH_TOKEN, ) @@ -37,28 +37,39 @@ describe('TodoistApi label endpoints', () => { describe('getLabels', () => { test('calls get on labels endpoint', async () => { - const requestMock = setupRestClientMock([DEFAULT_LABEL]) + const requestMock = setupRestClientMock({ + results: [DEFAULT_LABEL], + nextCursor: '123', + }) const api = getTarget() - await api.getLabels() + await api.getLabels({ limit: 10, cursor: '0' }) expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'GET', - getRestBaseUri(), + getSyncBaseUri(), ENDPOINT_REST_LABELS, DEFAULT_AUTH_TOKEN, + { + limit: 10, + cursor: '0', + }, ) }) test('returns result from rest client', async () => { const labels = [DEFAULT_LABEL] - setupRestClientMock(labels) + setupRestClientMock({ + results: [DEFAULT_LABEL], + nextCursor: '123', + }) const api = getTarget() - const response = await api.getLabels() + const { results, nextCursor } = await api.getLabels() - expect(response).toEqual(labels) + expect(results).toEqual(labels) + expect(nextCursor).toBe('123') }) }) @@ -76,7 +87,7 @@ describe('TodoistApi label endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'POST', - getRestBaseUri(), + getSyncBaseUri(), ENDPOINT_REST_LABELS, DEFAULT_AUTH_TOKEN, DEFAULT_ADD_LABEL_ARGS, @@ -109,7 +120,7 @@ describe('TodoistApi label endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'POST', - getRestBaseUri(), + getSyncBaseUri(), `${ENDPOINT_REST_LABELS}/${labelId}`, DEFAULT_AUTH_TOKEN, DEFAULT_UPDATE_LABEL_ARGS, @@ -139,7 +150,7 @@ describe('TodoistApi label endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'DELETE', - getRestBaseUri(), + getSyncBaseUri(), `${ENDPOINT_REST_LABELS}/${labelId}`, DEFAULT_AUTH_TOKEN, undefined, diff --git a/src/TodoistApi.projects.test.ts b/src/TodoistApi.projects.test.ts index cc07b69..5e0a61c 100644 --- a/src/TodoistApi.projects.test.ts +++ b/src/TodoistApi.projects.test.ts @@ -7,7 +7,7 @@ import { PROJECT_WITH_OPTIONALS_AS_NULL, } from './testUtils/testDefaults' import { - getRestBaseUri, + getSyncBaseUri, ENDPOINT_REST_PROJECTS, ENDPOINT_REST_PROJECT_COLLABORATORS, } from './consts/endpoints' @@ -29,7 +29,7 @@ describe('TodoistApi project endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'GET', - getRestBaseUri(), + getSyncBaseUri(), `${ENDPOINT_REST_PROJECTS}/${projectId}`, DEFAULT_AUTH_TOKEN, ) @@ -47,28 +47,34 @@ describe('TodoistApi project endpoints', () => { describe('getProjects', () => { test('calls get on projects endpoint', async () => { - const requestMock = setupRestClientMock([DEFAULT_PROJECT]) + const requestMock = setupRestClientMock({ + results: [DEFAULT_PROJECT], + nextCursor: '123', + }) const api = getTarget() - await api.getProjects() + const args = { limit: 10, cursor: '0' } + await api.getProjects(args) expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'GET', - getRestBaseUri(), + getSyncBaseUri(), ENDPOINT_REST_PROJECTS, DEFAULT_AUTH_TOKEN, + args, ) }) test('returns result from rest client', async () => { const projects = [DEFAULT_PROJECT, PROJECT_WITH_OPTIONALS_AS_NULL] - setupRestClientMock(projects) + setupRestClientMock({ results: projects, nextCursor: '123' }) const api = getTarget() - const response = await api.getProjects() + const { results, nextCursor } = await api.getProjects() - expect(response).toEqual(projects) + expect(results).toEqual(projects) + expect(nextCursor).toBe('123') }) }) @@ -86,7 +92,7 @@ describe('TodoistApi project endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'POST', - getRestBaseUri(), + getSyncBaseUri(), ENDPOINT_REST_PROJECTS, DEFAULT_AUTH_TOKEN, DEFAULT_ADD_PROJECT_ARGS, @@ -117,7 +123,7 @@ describe('TodoistApi project endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'POST', - getRestBaseUri(), + getSyncBaseUri(), `${ENDPOINT_REST_PROJECTS}/${projectId}`, DEFAULT_AUTH_TOKEN, updateArgs, @@ -147,7 +153,7 @@ describe('TodoistApi project endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'DELETE', - getRestBaseUri(), + getSyncBaseUri(), `${ENDPOINT_REST_PROJECTS}/${projectId}`, DEFAULT_AUTH_TOKEN, undefined, @@ -170,27 +176,30 @@ describe('TodoistApi project endpoints', () => { const users = [DEFAULT_USER] test('calls get on expected endpoint', async () => { - const requestMock = setupRestClientMock(users) + const requestMock = setupRestClientMock({ results: users, nextCursor: '123' }) const api = getTarget() - await api.getProjectCollaborators(projectId) + const args = { limit: 10, cursor: '0' } + await api.getProjectCollaborators(projectId, args) expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'GET', - getRestBaseUri(), + getSyncBaseUri(), `${ENDPOINT_REST_PROJECTS}/${projectId}/${ENDPOINT_REST_PROJECT_COLLABORATORS}`, DEFAULT_AUTH_TOKEN, + args, ) }) test('returns result from rest client', async () => { - setupRestClientMock(users) + setupRestClientMock({ results: users, nextCursor: '123' }) const api = getTarget() - const returnedUsers = await api.getProjectCollaborators(projectId) + const { results, nextCursor } = await api.getProjectCollaborators(projectId) - expect(returnedUsers).toEqual(users) + expect(results).toEqual(users) + expect(nextCursor).toBe('123') }) }) }) diff --git a/src/TodoistApi.sections.test.ts b/src/TodoistApi.sections.test.ts index ec4f211..0068ee1 100644 --- a/src/TodoistApi.sections.test.ts +++ b/src/TodoistApi.sections.test.ts @@ -1,6 +1,6 @@ import { TodoistApi } from '.' import { DEFAULT_AUTH_TOKEN, DEFAULT_REQUEST_ID, DEFAULT_SECTION } from './testUtils/testDefaults' -import { getRestBaseUri, ENDPOINT_REST_SECTIONS } from './consts/endpoints' +import { getSyncBaseUri, ENDPOINT_REST_SECTIONS } from './consts/endpoints' import { setupRestClientMock } from './testUtils/mocks' function getTarget() { @@ -19,7 +19,7 @@ describe('TodoistApi section endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'GET', - getRestBaseUri(), + getSyncBaseUri(), `${ENDPOINT_REST_SECTIONS}/${sectionId}`, DEFAULT_AUTH_TOKEN, ) @@ -38,29 +38,34 @@ describe('TodoistApi section endpoints', () => { describe('getSections', () => { test('calls get on sections endpoint', async () => { const projectId = '123' - const requestMock = setupRestClientMock([DEFAULT_SECTION]) + const requestMock = setupRestClientMock({ + results: [DEFAULT_SECTION], + nextCursor: '123', + }) const api = getTarget() - await api.getSections(projectId) + const args = { projectId, limit: 10, cursor: '0' } + await api.getSections(args) expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'GET', - getRestBaseUri(), + getSyncBaseUri(), ENDPOINT_REST_SECTIONS, DEFAULT_AUTH_TOKEN, - { projectId }, + args, ) }) test('returns result from rest client', async () => { const sections = [DEFAULT_SECTION] - setupRestClientMock(sections) + setupRestClientMock({ results: sections, nextCursor: '123' }) const api = getTarget() - const response = await api.getSections() + const { results, nextCursor } = await api.getSections({ projectId: '123' }) - expect(response).toEqual(sections) + expect(results).toEqual(sections) + expect(nextCursor).toBe('123') }) }) @@ -79,7 +84,7 @@ describe('TodoistApi section endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'POST', - getRestBaseUri(), + getSyncBaseUri(), ENDPOINT_REST_SECTIONS, DEFAULT_AUTH_TOKEN, DEFAULT_ADD_SECTION_ARGS, @@ -110,7 +115,7 @@ describe('TodoistApi section endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'POST', - getRestBaseUri(), + getSyncBaseUri(), `${ENDPOINT_REST_SECTIONS}/${sectionId}`, DEFAULT_AUTH_TOKEN, DEFAULT_UPDATE_SECTION_ARGS, @@ -140,7 +145,7 @@ describe('TodoistApi section endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'DELETE', - getRestBaseUri(), + getSyncBaseUri(), `${ENDPOINT_REST_SECTIONS}/${sectionId}`, DEFAULT_AUTH_TOKEN, undefined, diff --git a/src/TodoistApi.tasks.test.ts b/src/TodoistApi.tasks.test.ts index 886f7a8..9c3cbbe 100644 --- a/src/TodoistApi.tasks.test.ts +++ b/src/TodoistApi.tasks.test.ts @@ -9,7 +9,6 @@ import { TASK_WITH_OPTIONALS_AS_NULL, } from './testUtils/testDefaults' import { - getRestBaseUri, getSyncBaseUri, ENDPOINT_REST_TASK_CLOSE, ENDPOINT_REST_TASK_REOPEN, @@ -41,7 +40,7 @@ describe('TodoistApi task endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'POST', - getRestBaseUri(), + getSyncBaseUri(), ENDPOINT_REST_TASKS, DEFAULT_AUTH_TOKEN, DEFAULT_ADD_TASK_ARGS, @@ -58,7 +57,7 @@ describe('TodoistApi task endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'POST', - getRestBaseUri('https://staging.todoist.com'), + getSyncBaseUri('https://staging.todoist.com'), ENDPOINT_REST_TASKS, DEFAULT_AUTH_TOKEN, DEFAULT_ADD_TASK_ARGS, @@ -89,7 +88,7 @@ describe('TodoistApi task endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'POST', - getRestBaseUri(), + getSyncBaseUri(), `${ENDPOINT_REST_TASKS}/${taskId}`, DEFAULT_AUTH_TOKEN, DEFAULT_UPDATE_TASK_ARGS, @@ -119,7 +118,7 @@ describe('TodoistApi task endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'POST', - getRestBaseUri(), + getSyncBaseUri(), `${ENDPOINT_REST_TASKS}/${taskId}/${ENDPOINT_REST_TASK_CLOSE}`, DEFAULT_AUTH_TOKEN, undefined, @@ -148,7 +147,7 @@ describe('TodoistApi task endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'POST', - getRestBaseUri(), + getSyncBaseUri(), `${ENDPOINT_REST_TASKS}/${taskId}/${ENDPOINT_REST_TASK_REOPEN}`, DEFAULT_AUTH_TOKEN, undefined, @@ -177,7 +176,7 @@ describe('TodoistApi task endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'DELETE', - getRestBaseUri(), + getSyncBaseUri(), `${ENDPOINT_REST_TASKS}/${taskId}`, DEFAULT_AUTH_TOKEN, undefined, @@ -243,7 +242,7 @@ describe('TodoistApi task endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'GET', - getRestBaseUri(), + getSyncBaseUri(), `${ENDPOINT_REST_TASKS}/${taskId}`, DEFAULT_AUTH_TOKEN, ) @@ -253,10 +252,15 @@ describe('TodoistApi task endpoints', () => { describe('getTasks', () => { const DEFAULT_GET_TASKS_ARGS = { projectId: '123', + limit: 10, + cursor: '0', } test('calls get on expected endpoint with args', async () => { - const requestMock = setupRestClientMock([DEFAULT_TASK, TASK_WITH_OPTIONALS_AS_NULL]) + const requestMock = setupRestClientMock({ + results: [DEFAULT_TASK, TASK_WITH_OPTIONALS_AS_NULL], + nextCursor: '123', + }) const api = getTarget() await api.getTasks(DEFAULT_GET_TASKS_ARGS) @@ -264,7 +268,7 @@ describe('TodoistApi task endpoints', () => { expect(requestMock).toBeCalledTimes(1) expect(requestMock).toBeCalledWith( 'GET', - getRestBaseUri(), + getSyncBaseUri(), ENDPOINT_REST_TASKS, DEFAULT_AUTH_TOKEN, DEFAULT_GET_TASKS_ARGS, @@ -273,12 +277,13 @@ describe('TodoistApi task endpoints', () => { test('returns result from rest client', async () => { const tasks = [DEFAULT_TASK] - setupRestClientMock(tasks) + setupRestClientMock({ results: tasks, nextCursor: '123' }) const api = getTarget() - const response = await api.getTasks(DEFAULT_GET_TASKS_ARGS) + const { results, nextCursor } = await api.getTasks(DEFAULT_GET_TASKS_ARGS) - expect(response).toEqual(tasks) + expect(results).toEqual(tasks) + expect(nextCursor).toBe('123') }) }) }) 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