Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 0 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,25 +103,6 @@ const api = new CommsApi(tokenResponse.accessToken)
const user = await api.users.getSessionUser()
```

### Batch requests

Pass `{ batch: true }` to any API method to get a descriptor instead of
executing the request. Hand the descriptors to `api.batch(...)` to run them
in a single HTTP call:

```typescript
const results = await api.batch(
api.channels.getChannels({ workspaceId: 1 }, { batch: true }),
api.workspaceUsers.getUserById({ workspaceId: 1, userId: 42 }, { batch: true }),
)

if (results[0].code === 200) console.log(results[0].data.length, 'channels')
if (results[1].code === 200) console.log(results[1].data.fullName)
```

GET-only batches run in parallel on the server. Mixed GET/POST batches run
sequentially.

## Development

- `npm install`
Expand Down
243 changes: 0 additions & 243 deletions src/batch-builder.ts

This file was deleted.

71 changes: 53 additions & 18 deletions src/clients/add-comment-helper.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
import { http, HttpResponse } from 'msw'
import { describe, expect, it } from 'vitest'
import { getCommsBaseUri } from '../consts/endpoints'
import { apiUrl } from '../testUtils/msw-handlers'
import { server } from '../testUtils/msw-setup'
import { TEST_API_TOKEN, TEST_THREAD_ID } from '../testUtils/test-defaults'
import { EVERYONE, EVERYONE_IN_THREAD } from '../types/enums'
import { addCommentRequest } from './add-comment-helper'

const ctx = { baseUri: 'https://comms.todoist.com/api/v3/', apiToken: TEST_API_TOKEN }
const ctx = { baseUri: getCommsBaseUri(), apiToken: TEST_API_TOKEN }
const COMMENT_ADD = apiUrl('api/v1/comments/add')

const COMMENT_RESPONSE = {
id: 'AAAAAAAAAAAAAAAAAAAAAA',
thread_id: TEST_THREAD_ID,
channel_id: 'BBBBBBBBBBBBBBBBBBBBBB',
creator: 1,
content: 'hello',
posted_ts: Math.floor(Date.now() / 1000),
workspace_id: 1,
system_message: null,
}

describe('addCommentRequest — reserved broadcast marker validation', () => {
it('throws when a marker is passed in `groups`', () => {
Expand Down Expand Up @@ -44,26 +60,45 @@ describe('addCommentRequest — reserved broadcast marker validation', () => {
expect(caught?.message).toMatch(/notifyAudience/)
})

it('translates notifyAudience: channel into the EVERYONE marker', () => {
const descriptor = addCommentRequest(
ctx,
{ threadId: TEST_THREAD_ID, content: 'hello', notifyAudience: 'channel' },
{ batch: true },
it('translates notifyAudience: channel into the EVERYONE marker', async () => {
let capturedBody: Record<string, unknown> | null = null
server.use(
http.post(COMMENT_ADD, async ({ request }) => {
capturedBody = (await request.json()) as Record<string, unknown>
return HttpResponse.json(COMMENT_RESPONSE)
}),
)
expect('params' in descriptor).toBe(true)
if (!('params' in descriptor)) return
const groups = (descriptor.params as Record<string, unknown>)?.groups as string[]
expect(groups).toEqual([EVERYONE])

await addCommentRequest(ctx, {
threadId: TEST_THREAD_ID,
content: 'hello',
notifyAudience: 'channel',
})

const body = capturedBody as Record<string, unknown> | null
expect(body?.groups).toEqual([EVERYONE])
expect(body).not.toHaveProperty('notify_audience')
expect(body).not.toHaveProperty('notifyAudience')
})

it('translates notifyAudience: thread into the EVERYONE_IN_THREAD marker', () => {
const descriptor = addCommentRequest(
ctx,
{ threadId: TEST_THREAD_ID, content: 'hello', notifyAudience: 'thread' },
{ batch: true },
it('translates notifyAudience: thread into the EVERYONE_IN_THREAD marker', async () => {
let capturedBody: Record<string, unknown> | null = null
server.use(
http.post(COMMENT_ADD, async ({ request }) => {
capturedBody = (await request.json()) as Record<string, unknown>
return HttpResponse.json(COMMENT_RESPONSE)
}),
)
if (!('params' in descriptor)) return
const groups = (descriptor.params as Record<string, unknown>)?.groups as string[]
expect(groups).toEqual([EVERYONE_IN_THREAD])

await addCommentRequest(ctx, {
threadId: TEST_THREAD_ID,
content: 'hello',
notifyAudience: 'thread',
})

const body = capturedBody as Record<string, unknown> | null
expect(body?.groups).toEqual([EVERYONE_IN_THREAD])
expect(body).not.toHaveProperty('notify_audience')
expect(body).not.toHaveProperty('notifyAudience')
})
})
18 changes: 5 additions & 13 deletions src/clients/add-comment-helper.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ENDPOINT_COMMENTS } from '../consts/endpoints'
import { request } from '../transport/http-client'
import type { BatchRequestDescriptor } from '../types/batch'
import { type Comment, CommentSchema } from '../types/entities'
import { NOTIFY_AUDIENCE_GROUP_IDS, NOTIFY_AUDIENCES, type NotifyAudience } from '../types/enums'
import type { CustomFetch } from '../types/http'
Expand Down Expand Up @@ -59,27 +58,20 @@ function applyNotifyAudience(params: CreateCommentArgs): Omit<CreateCommentArgs,
export function addCommentRequest(
context: ClientContext,
params: CreateCommentArgs,
options?: { batch?: boolean; threadAction?: ThreadAction },
): Promise<Comment> | BatchRequestDescriptor<Comment> {
const method = 'POST'
const url = `${ENDPOINT_COMMENTS}/add`
options?: { threadAction?: ThreadAction },
): Promise<Comment> {
const normalized = applyNotifyAudience(params)
const withId = { ...normalized, id: resolveCreateId(normalized.id) }
const payload = options?.threadAction
? { ...withId, threadAction: options.threadAction }
: withId
const schema = CommentSchema

if (options?.batch) {
return { method, url, params: payload, schema }
}

return request<Comment>({
httpMethod: method,
httpMethod: 'POST',
baseUri: context.baseUri,
relativePath: url,
relativePath: `${ENDPOINT_COMMENTS}/add`,
apiToken: context.apiToken,
payload,
customFetch: context.customFetch,
}).then((response) => schema.parse(response.data))
}).then((response) => CommentSchema.parse(response.data))
}
Loading
Loading