Skip to content

Commit f546fe0

Browse files
fix: Corrects the call when an array of ids is used (#138)
* fix: Corrects the call when an array of ids is used * chore: Updates package version * tests: Fixes test * tests: Updates tests to ensure that paramsSerializer is included
1 parent 92b272e commit f546fe0

File tree

7 files changed

+47
-7
lines changed

7 files changed

+47
-7
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@doist/todoist-api-typescript",
3-
"version": "2.0.2",
3+
"version": "2.0.3",
44
"description": "A typescript wrapper for the Todoist REST API.",
55
"author": "Doist developers",
66
"repository": "git@github.com:doist/todoist-api-typescript.git",

src/TodoistApi.projects.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ describe('TodoistApi project endpoints', () => {
150150
getRestBaseUri(),
151151
`${ENDPOINT_REST_PROJECTS}/${projectId}`,
152152
DEFAULT_AUTH_TOKEN,
153+
undefined,
153154
DEFAULT_REQUEST_ID,
154155
)
155156
})

src/TodoistApi.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ export class TodoistApi {
240240
this.restApiBase,
241241
generatePath(ENDPOINT_REST_PROJECTS, id),
242242
this.authToken,
243+
undefined,
243244
requestId,
244245
)
245246
return isSuccess(response)
@@ -263,7 +264,7 @@ export class TodoistApi {
263264
this.restApiBase,
264265
ENDPOINT_REST_SECTIONS,
265266
this.authToken,
266-
projectId && { projectId },
267+
projectId ? { projectId } : undefined,
267268
)
268269

269270
return validateSectionArray(response.data)

src/restClient.axios.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import axios from 'axios'
2+
import { paramsSerializer } from './restClient'
3+
4+
const DEFAULT_BASE_URI = 'https://api.todoist.com/rest/v2/tasks'
5+
6+
describe('axios tests without mocking', () => {
7+
test('GET calls serialise arrays correctly', () => {
8+
const requestUri = axios.create().getUri({
9+
method: 'GET',
10+
baseURL: DEFAULT_BASE_URI,
11+
params: {
12+
ids: ['12345', '56789'],
13+
},
14+
paramsSerializer,
15+
})
16+
expect(requestUri).toEqual('https://api.todoist.com/rest/v2/tasks?ids=12345%2C56789')
17+
})
18+
})

src/restClient.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import Axios, { AxiosStatic, AxiosResponse, AxiosError } from 'axios'
2-
import { request, isSuccess } from './restClient'
2+
import { request, isSuccess, paramsSerializer } from './restClient'
33
import { TodoistRequestError } from './types/errors'
44
import * as caseConverter from 'axios-case-converter'
55
import { assertInstance } from './testUtils/asserts'
@@ -120,6 +120,7 @@ describe('restClient', () => {
120120
expect(axiosMock.get).toBeCalledTimes(1)
121121
expect(axiosMock.get).toBeCalledWith(DEFAULT_ENDPOINT, {
122122
params: undefined,
123+
paramsSerializer,
123124
})
124125
})
125126

@@ -135,6 +136,7 @@ describe('restClient', () => {
135136
expect(axiosMock.get).toBeCalledTimes(1)
136137
expect(axiosMock.get).toBeCalledWith(DEFAULT_ENDPOINT, {
137138
params: DEFAULT_PAYLOAD,
139+
paramsSerializer,
138140
})
139141
})
140142

src/restClient.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,21 @@ import { HttpMethod } from './types/http'
55
import { v4 as uuidv4 } from 'uuid'
66
import axiosRetry from 'axios-retry'
77

8+
export function paramsSerializer(params: Record<string, unknown>) {
9+
const qs = new URLSearchParams()
10+
11+
Object.keys(params).forEach((key) => {
12+
const value = params[key]
13+
if (Array.isArray(value)) {
14+
qs.append(key, value.join(','))
15+
} else {
16+
qs.append(key, String(value))
17+
}
18+
})
19+
20+
return qs.toString()
21+
}
22+
823
const defaultHeaders = {
924
'Content-Type': 'application/json',
1025
}
@@ -71,7 +86,7 @@ export async function request<T>(
7186
baseUri: string,
7287
relativePath: string,
7388
apiToken?: string,
74-
payload?: unknown,
89+
payload?: Record<string, unknown>,
7590
requestId?: string,
7691
): Promise<AxiosResponse<T>> {
7792
// axios loses the original stack when returning errors, for the sake of better reporting
@@ -88,7 +103,10 @@ export async function request<T>(
88103

89104
switch (httpMethod) {
90105
case 'GET':
91-
return await axiosClient.get<T>(relativePath, { params: payload })
106+
return await axiosClient.get<T>(relativePath, {
107+
params: payload,
108+
paramsSerializer,
109+
})
92110
case 'POST':
93111
return await axiosClient.post<T>(relativePath, payload)
94112
case 'DELETE':

0 commit comments

Comments
 (0)