@doist/comms-sdk 0.2.0 → 0.2.1
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/clients/add-comment-helper.js +1 -2
- package/dist/cjs/clients/base-client.js +8 -0
- package/dist/cjs/clients/channels-client.js +19 -8
- package/dist/cjs/clients/comments-client.js +24 -5
- package/dist/cjs/clients/conversation-messages-client.js +15 -4
- package/dist/cjs/clients/conversations-client.js +23 -12
- package/dist/cjs/clients/inbox-client.js +15 -2
- package/dist/cjs/clients/threads-client.js +27 -8
- package/dist/cjs/clients/workspaces-client.js +9 -1
- package/dist/cjs/types/entities.js +119 -98
- package/dist/cjs/utils/url-helpers.js +3 -1
- package/dist/esm/clients/add-comment-helper.js +1 -2
- package/dist/esm/clients/base-client.js +8 -0
- package/dist/esm/clients/channels-client.js +20 -9
- package/dist/esm/clients/comments-client.js +25 -6
- package/dist/esm/clients/conversation-messages-client.js +16 -5
- package/dist/esm/clients/conversations-client.js +24 -13
- package/dist/esm/clients/inbox-client.js +15 -2
- package/dist/esm/clients/threads-client.js +28 -9
- package/dist/esm/clients/workspaces-client.js +10 -2
- package/dist/esm/types/entities.js +111 -97
- package/dist/esm/utils/url-helpers.js +3 -1
- package/dist/types/clients/add-comment-helper.d.ts +3 -1
- package/dist/types/clients/base-client.d.ts +6 -0
- package/dist/types/clients/channels-client.d.ts +3 -0
- package/dist/types/clients/comments-client.d.ts +4 -0
- package/dist/types/clients/conversation-messages-client.d.ts +3 -0
- package/dist/types/clients/conversations-client.d.ts +3 -0
- package/dist/types/clients/inbox-client.d.ts +382 -0
- package/dist/types/clients/threads-client.d.ts +4 -0
- package/dist/types/clients/workspaces-client.d.ts +2 -0
- package/dist/types/types/entities.d.ts +1654 -126
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { ENDPOINT_CONVERSATIONS } from '../consts/endpoints.js';
|
|
3
3
|
import { request } from '../transport/http-client.js';
|
|
4
|
-
import { ConversationSchema, StatusOkSchema, UnreadConversationSchema, } from '../types/entities.js';
|
|
4
|
+
import { ConversationSchema, createConversationSchema, StatusOkSchema, UnreadConversationSchema, } from '../types/entities.js';
|
|
5
5
|
import { resolveCreateId } from '../utils/uuidv7.js';
|
|
6
6
|
import { BaseClient } from './base-client.js';
|
|
7
7
|
export const ConversationListSchema = z.array(ConversationSchema);
|
|
@@ -16,6 +16,17 @@ const GetUnreadResponseSchema = z.object({
|
|
|
16
16
|
* already-assigned `id` and your generated one is silently dropped.
|
|
17
17
|
*/
|
|
18
18
|
export class ConversationsClient extends BaseClient {
|
|
19
|
+
constructor() {
|
|
20
|
+
super(...arguments);
|
|
21
|
+
this.linkBaseUrl = this.getLinkBaseUrl();
|
|
22
|
+
// Reuse the shared singletons when no custom base is configured.
|
|
23
|
+
this.conversationSchema = this.linkBaseUrl
|
|
24
|
+
? createConversationSchema(this.linkBaseUrl)
|
|
25
|
+
: ConversationSchema;
|
|
26
|
+
this.conversationListSchema = this.linkBaseUrl
|
|
27
|
+
? z.array(this.conversationSchema)
|
|
28
|
+
: ConversationListSchema;
|
|
29
|
+
}
|
|
19
30
|
/**
|
|
20
31
|
* Gets all conversations for a workspace.
|
|
21
32
|
*
|
|
@@ -38,7 +49,7 @@ export class ConversationsClient extends BaseClient {
|
|
|
38
49
|
apiToken: this.apiToken,
|
|
39
50
|
payload: args,
|
|
40
51
|
customFetch: this.customFetch,
|
|
41
|
-
}).then((response) =>
|
|
52
|
+
}).then((response) => this.conversationListSchema.parse(response.data));
|
|
42
53
|
}
|
|
43
54
|
/**
|
|
44
55
|
* Gets a single conversation object by id.
|
|
@@ -47,7 +58,7 @@ export class ConversationsClient extends BaseClient {
|
|
|
47
58
|
* @returns The conversation object.
|
|
48
59
|
*/
|
|
49
60
|
getConversation(id) {
|
|
50
|
-
return this.simple('GET', 'getone', { id },
|
|
61
|
+
return this.simple('GET', 'getone', { id }, this.conversationSchema);
|
|
51
62
|
}
|
|
52
63
|
/**
|
|
53
64
|
* Gets an existing 1:1 / group conversation with `userIds`, or creates a
|
|
@@ -68,7 +79,7 @@ export class ConversationsClient extends BaseClient {
|
|
|
68
79
|
* ```
|
|
69
80
|
*/
|
|
70
81
|
getOrCreateConversation(args) {
|
|
71
|
-
return this.simple('GET', 'get_or_create', { ...args, id: resolveCreateId(args.id) },
|
|
82
|
+
return this.simple('GET', 'get_or_create', { ...args, id: resolveCreateId(args.id) }, this.conversationSchema);
|
|
72
83
|
}
|
|
73
84
|
/**
|
|
74
85
|
* Updates a conversation's title.
|
|
@@ -91,7 +102,7 @@ export class ConversationsClient extends BaseClient {
|
|
|
91
102
|
const params = { id: args.id, title: args.title };
|
|
92
103
|
if (args.archived !== undefined)
|
|
93
104
|
params.archived = args.archived;
|
|
94
|
-
return this.simple('POST', 'update', params,
|
|
105
|
+
return this.simple('POST', 'update', params, this.conversationSchema);
|
|
95
106
|
}
|
|
96
107
|
/**
|
|
97
108
|
* Archives a conversation.
|
|
@@ -100,7 +111,7 @@ export class ConversationsClient extends BaseClient {
|
|
|
100
111
|
* @returns The updated conversation object.
|
|
101
112
|
*/
|
|
102
113
|
archiveConversation(id) {
|
|
103
|
-
return this.simple('GET', 'archive', { id },
|
|
114
|
+
return this.simple('GET', 'archive', { id }, this.conversationSchema);
|
|
104
115
|
}
|
|
105
116
|
/**
|
|
106
117
|
* Unarchives a conversation.
|
|
@@ -109,7 +120,7 @@ export class ConversationsClient extends BaseClient {
|
|
|
109
120
|
* @returns The updated conversation object.
|
|
110
121
|
*/
|
|
111
122
|
unarchiveConversation(id) {
|
|
112
|
-
return this.simple('GET', 'unarchive', { id },
|
|
123
|
+
return this.simple('GET', 'unarchive', { id }, this.conversationSchema);
|
|
113
124
|
}
|
|
114
125
|
/**
|
|
115
126
|
* Adds a user to a conversation.
|
|
@@ -120,7 +131,7 @@ export class ConversationsClient extends BaseClient {
|
|
|
120
131
|
* @returns The updated conversation object.
|
|
121
132
|
*/
|
|
122
133
|
addUser(args) {
|
|
123
|
-
return this.simple('POST', 'add_user', { ...args },
|
|
134
|
+
return this.simple('POST', 'add_user', { ...args }, this.conversationSchema);
|
|
124
135
|
}
|
|
125
136
|
/**
|
|
126
137
|
* Adds multiple users to a conversation.
|
|
@@ -136,7 +147,7 @@ export class ConversationsClient extends BaseClient {
|
|
|
136
147
|
* ```
|
|
137
148
|
*/
|
|
138
149
|
addUsers(args) {
|
|
139
|
-
return this.simple('POST', 'add_users', { ...args },
|
|
150
|
+
return this.simple('POST', 'add_users', { ...args }, this.conversationSchema);
|
|
140
151
|
}
|
|
141
152
|
/**
|
|
142
153
|
* Removes a user from a conversation.
|
|
@@ -147,7 +158,7 @@ export class ConversationsClient extends BaseClient {
|
|
|
147
158
|
* @returns The updated conversation object.
|
|
148
159
|
*/
|
|
149
160
|
removeUser(args) {
|
|
150
|
-
return this.simple('POST', 'remove_user', { ...args },
|
|
161
|
+
return this.simple('POST', 'remove_user', { ...args }, this.conversationSchema);
|
|
151
162
|
}
|
|
152
163
|
/**
|
|
153
164
|
* Removes multiple users from a conversation.
|
|
@@ -158,7 +169,7 @@ export class ConversationsClient extends BaseClient {
|
|
|
158
169
|
* @returns The updated conversation object.
|
|
159
170
|
*/
|
|
160
171
|
removeUsers(args) {
|
|
161
|
-
return this.simple('POST', 'remove_users', { ...args },
|
|
172
|
+
return this.simple('POST', 'remove_users', { ...args }, this.conversationSchema);
|
|
162
173
|
}
|
|
163
174
|
/**
|
|
164
175
|
* Marks a conversation as read.
|
|
@@ -215,7 +226,7 @@ export class ConversationsClient extends BaseClient {
|
|
|
215
226
|
* ```
|
|
216
227
|
*/
|
|
217
228
|
muteConversation(args) {
|
|
218
|
-
return this.simple('GET', 'mute', { ...args },
|
|
229
|
+
return this.simple('GET', 'mute', { ...args }, this.conversationSchema);
|
|
219
230
|
}
|
|
220
231
|
/**
|
|
221
232
|
* Unmutes a conversation.
|
|
@@ -224,7 +235,7 @@ export class ConversationsClient extends BaseClient {
|
|
|
224
235
|
* @returns The updated conversation object.
|
|
225
236
|
*/
|
|
226
237
|
unmuteConversation(id) {
|
|
227
|
-
return this.simple('GET', 'unmute', { id },
|
|
238
|
+
return this.simple('GET', 'unmute', { id }, this.conversationSchema);
|
|
228
239
|
}
|
|
229
240
|
simple(httpMethod, suffix, params, schema) {
|
|
230
241
|
return request({
|
|
@@ -1,9 +1,22 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
1
2
|
import { ENDPOINT_INBOX } from '../consts/endpoints.js';
|
|
2
3
|
import { request } from '../transport/http-client.js';
|
|
3
|
-
import { InboxThreadSchema } from '../types/entities.js';
|
|
4
|
+
import { createInboxThreadSchema, InboxThreadSchema } from '../types/entities.js';
|
|
4
5
|
import { BaseClient } from './base-client.js';
|
|
6
|
+
export const InboxThreadListSchema = z.array(InboxThreadSchema);
|
|
5
7
|
/** Client for `/api/v1/inbox/`. */
|
|
6
8
|
export class InboxClient extends BaseClient {
|
|
9
|
+
constructor() {
|
|
10
|
+
super(...arguments);
|
|
11
|
+
this.linkBaseUrl = this.getLinkBaseUrl();
|
|
12
|
+
// Reuse the shared singletons when no custom base is configured.
|
|
13
|
+
this.inboxThreadSchema = this.linkBaseUrl
|
|
14
|
+
? createInboxThreadSchema(this.linkBaseUrl)
|
|
15
|
+
: InboxThreadSchema;
|
|
16
|
+
this.inboxThreadListSchema = this.linkBaseUrl
|
|
17
|
+
? z.array(this.inboxThreadSchema)
|
|
18
|
+
: InboxThreadListSchema;
|
|
19
|
+
}
|
|
7
20
|
/**
|
|
8
21
|
* Gets inbox items (threads).
|
|
9
22
|
*
|
|
@@ -49,7 +62,7 @@ export class InboxClient extends BaseClient {
|
|
|
49
62
|
apiToken: this.apiToken,
|
|
50
63
|
payload: params,
|
|
51
64
|
customFetch: this.customFetch,
|
|
52
|
-
}).then((response) =>
|
|
65
|
+
}).then((response) => this.inboxThreadListSchema.parse(response.data));
|
|
53
66
|
}
|
|
54
67
|
/**
|
|
55
68
|
* Gets unread count for inbox.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { ENDPOINT_THREADS } from '../consts/endpoints.js';
|
|
3
3
|
import { request } from '../transport/http-client.js';
|
|
4
|
-
import { StatusOkSchema, ThreadSchema, UnreadThreadSchema, } from '../types/entities.js';
|
|
4
|
+
import { CommentSchema, createCommentSchema, createThreadSchema, StatusOkSchema, ThreadSchema, UnreadThreadSchema, } from '../types/entities.js';
|
|
5
5
|
import { resolveCreateId } from '../utils/uuidv7.js';
|
|
6
6
|
import { addCommentRequest } from './add-comment-helper.js';
|
|
7
7
|
import { BaseClient } from './base-client.js';
|
|
@@ -16,6 +16,20 @@ const GetUnreadResponseSchema = z.object({
|
|
|
16
16
|
* `createThread` when the caller doesn't supply one.
|
|
17
17
|
*/
|
|
18
18
|
export class ThreadsClient extends BaseClient {
|
|
19
|
+
constructor() {
|
|
20
|
+
super(...arguments);
|
|
21
|
+
this.linkBaseUrl = this.getLinkBaseUrl();
|
|
22
|
+
// Reuse the shared singletons when no custom base is configured.
|
|
23
|
+
this.threadSchema = this.linkBaseUrl
|
|
24
|
+
? createThreadSchema(this.linkBaseUrl)
|
|
25
|
+
: ThreadSchema;
|
|
26
|
+
this.threadListSchema = this.linkBaseUrl
|
|
27
|
+
? z.array(this.threadSchema)
|
|
28
|
+
: ThreadListSchema;
|
|
29
|
+
this.commentSchema = this.linkBaseUrl
|
|
30
|
+
? createCommentSchema(this.linkBaseUrl)
|
|
31
|
+
: CommentSchema;
|
|
32
|
+
}
|
|
19
33
|
/**
|
|
20
34
|
* Gets threads. At least one of `channelId` / `workspaceId` is required.
|
|
21
35
|
* `newerThan` / `olderThan` (`Date`) are converted to the
|
|
@@ -58,7 +72,7 @@ export class ThreadsClient extends BaseClient {
|
|
|
58
72
|
apiToken: this.apiToken,
|
|
59
73
|
payload: params,
|
|
60
74
|
customFetch: this.customFetch,
|
|
61
|
-
}).then((response) =>
|
|
75
|
+
}).then((response) => this.threadListSchema.parse(response.data));
|
|
62
76
|
}
|
|
63
77
|
/**
|
|
64
78
|
* Gets a single thread object by id.
|
|
@@ -67,7 +81,7 @@ export class ThreadsClient extends BaseClient {
|
|
|
67
81
|
* @returns The thread object.
|
|
68
82
|
*/
|
|
69
83
|
getThread(id) {
|
|
70
|
-
return this.simple('GET', 'getone', { id },
|
|
84
|
+
return this.simple('GET', 'getone', { id }, this.threadSchema);
|
|
71
85
|
}
|
|
72
86
|
/**
|
|
73
87
|
* Creates a new thread in a channel. `id` is auto-generated if not supplied.
|
|
@@ -90,7 +104,7 @@ export class ThreadsClient extends BaseClient {
|
|
|
90
104
|
* ```
|
|
91
105
|
*/
|
|
92
106
|
createThread(args) {
|
|
93
|
-
return this.simple('POST', 'add', { ...args, id: resolveCreateId(args.id) },
|
|
107
|
+
return this.simple('POST', 'add', { ...args, id: resolveCreateId(args.id) }, this.threadSchema);
|
|
94
108
|
}
|
|
95
109
|
/**
|
|
96
110
|
* Partial update of an existing thread.
|
|
@@ -102,7 +116,7 @@ export class ThreadsClient extends BaseClient {
|
|
|
102
116
|
* @returns The updated thread object.
|
|
103
117
|
*/
|
|
104
118
|
updateThread(args) {
|
|
105
|
-
return this.simple('POST', 'update', { ...args },
|
|
119
|
+
return this.simple('POST', 'update', { ...args }, this.threadSchema);
|
|
106
120
|
}
|
|
107
121
|
/**
|
|
108
122
|
* Permanently deletes a thread.
|
|
@@ -153,7 +167,7 @@ export class ThreadsClient extends BaseClient {
|
|
|
153
167
|
* @returns The updated thread object.
|
|
154
168
|
*/
|
|
155
169
|
moveToChannel(args) {
|
|
156
|
-
return this.simple('GET', 'move_to_channel', { ...args },
|
|
170
|
+
return this.simple('GET', 'move_to_channel', { ...args }, this.threadSchema);
|
|
157
171
|
}
|
|
158
172
|
/**
|
|
159
173
|
* Marks a thread as read.
|
|
@@ -241,7 +255,7 @@ export class ThreadsClient extends BaseClient {
|
|
|
241
255
|
* ```
|
|
242
256
|
*/
|
|
243
257
|
muteThread(args) {
|
|
244
|
-
return this.simple('GET', 'mute', { ...args },
|
|
258
|
+
return this.simple('GET', 'mute', { ...args }, this.threadSchema);
|
|
245
259
|
}
|
|
246
260
|
/**
|
|
247
261
|
* Unmutes a thread.
|
|
@@ -251,7 +265,7 @@ export class ThreadsClient extends BaseClient {
|
|
|
251
265
|
* @returns The updated thread object.
|
|
252
266
|
*/
|
|
253
267
|
unmuteThread(id) {
|
|
254
|
-
return this.simple('GET', 'unmute', { id },
|
|
268
|
+
return this.simple('GET', 'unmute', { id }, this.threadSchema);
|
|
255
269
|
}
|
|
256
270
|
/**
|
|
257
271
|
* Closes a thread by adding a comment with a close action.
|
|
@@ -311,7 +325,12 @@ export class ThreadsClient extends BaseClient {
|
|
|
311
325
|
}
|
|
312
326
|
addCommentWithAction(args, threadAction) {
|
|
313
327
|
const { id, ...rest } = args;
|
|
314
|
-
return addCommentRequest({
|
|
328
|
+
return addCommentRequest({
|
|
329
|
+
baseUri: this.getBaseUri(),
|
|
330
|
+
apiToken: this.apiToken,
|
|
331
|
+
customFetch: this.customFetch,
|
|
332
|
+
schema: this.commentSchema,
|
|
333
|
+
}, { threadId: id, ...rest }, { threadAction });
|
|
315
334
|
}
|
|
316
335
|
simple(httpMethod, suffix, params, schema) {
|
|
317
336
|
return request({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { ENDPOINT_WORKSPACES } from '../consts/endpoints.js';
|
|
3
3
|
import { request } from '../transport/http-client.js';
|
|
4
|
-
import { ChannelSchema, WorkspaceSchema } from '../types/entities.js';
|
|
4
|
+
import { ChannelSchema, createChannelSchema, WorkspaceSchema, } from '../types/entities.js';
|
|
5
5
|
import { BaseClient } from './base-client.js';
|
|
6
6
|
export const ChannelListSchema = z.array(ChannelSchema);
|
|
7
7
|
/**
|
|
@@ -9,6 +9,14 @@ export const ChannelListSchema = z.array(ChannelSchema);
|
|
|
9
9
|
* currently rejects any `color` other than `1` on add/update.
|
|
10
10
|
*/
|
|
11
11
|
export class WorkspacesClient extends BaseClient {
|
|
12
|
+
constructor() {
|
|
13
|
+
super(...arguments);
|
|
14
|
+
this.linkBaseUrl = this.getLinkBaseUrl();
|
|
15
|
+
// Reuse the shared singleton when no custom base is configured.
|
|
16
|
+
this.channelListSchema = this.linkBaseUrl
|
|
17
|
+
? z.array(createChannelSchema(this.linkBaseUrl))
|
|
18
|
+
: ChannelListSchema;
|
|
19
|
+
}
|
|
12
20
|
/**
|
|
13
21
|
* Gets all the user's workspaces.
|
|
14
22
|
*
|
|
@@ -157,6 +165,6 @@ export class WorkspacesClient extends BaseClient {
|
|
|
157
165
|
apiToken: this.apiToken,
|
|
158
166
|
payload: { id },
|
|
159
167
|
customFetch: this.customFetch,
|
|
160
|
-
}).then((response) =>
|
|
168
|
+
}).then((response) => this.channelListSchema.parse(response.data));
|
|
161
169
|
}
|
|
162
170
|
}
|
|
@@ -97,8 +97,7 @@ export const WorkspaceSchema = z.object({
|
|
|
97
97
|
.optional(),
|
|
98
98
|
plan: z.string().nullable().optional(),
|
|
99
99
|
});
|
|
100
|
-
export const
|
|
101
|
-
.object({
|
|
100
|
+
export const ChannelObjectSchema = z.object({
|
|
102
101
|
id: z.string(),
|
|
103
102
|
name: z.string(),
|
|
104
103
|
description: z.string().nullable().optional(),
|
|
@@ -116,15 +115,17 @@ export const ChannelSchema = z
|
|
|
116
115
|
icon: z.number().nullable().optional(),
|
|
117
116
|
version: z.number(),
|
|
118
117
|
filters: z.record(z.string(), z.string()).nullable().optional(),
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
})
|
|
118
|
+
});
|
|
119
|
+
export function createChannelSchema(linkBaseUrl) {
|
|
120
|
+
return ChannelObjectSchema.transform((data) => ({
|
|
121
|
+
...data,
|
|
122
|
+
url: getFullCommsURL({ workspaceId: data.workspaceId, channelId: data.id }, linkBaseUrl),
|
|
123
|
+
}));
|
|
124
|
+
}
|
|
125
|
+
export const ChannelSchema = createChannelSchema();
|
|
124
126
|
// Thread entity from API. `pinned` (boolean) and `pinnedTs` (epoch ms or
|
|
125
127
|
// null) are both surfaced — `pinned` is kept for Zapier/webhook clients.
|
|
126
|
-
export const
|
|
127
|
-
.object({
|
|
128
|
+
export const ThreadObjectSchema = z.object({
|
|
128
129
|
id: z.string(),
|
|
129
130
|
title: z.string(),
|
|
130
131
|
content: z.string(),
|
|
@@ -188,15 +189,18 @@ export const ThreadSchema = z
|
|
|
188
189
|
})
|
|
189
190
|
.nullable()
|
|
190
191
|
.optional(),
|
|
191
|
-
})
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
})
|
|
192
|
+
});
|
|
193
|
+
export function createThreadSchema(linkBaseUrl) {
|
|
194
|
+
return ThreadObjectSchema.transform((data) => ({
|
|
195
|
+
...data,
|
|
196
|
+
url: getFullCommsURL({
|
|
197
|
+
workspaceId: data.workspaceId,
|
|
198
|
+
channelId: data.channelId,
|
|
199
|
+
threadId: data.id,
|
|
200
|
+
}, linkBaseUrl),
|
|
201
|
+
}));
|
|
202
|
+
}
|
|
203
|
+
export const ThreadSchema = createThreadSchema();
|
|
200
204
|
// Group entity from API. The broadcast markers `EVERYONE` and
|
|
201
205
|
// `EVERYONE_IN_THREAD` can appear in place of a real `id` in group-bearing
|
|
202
206
|
// fields on threads/comments/channels.
|
|
@@ -209,8 +213,7 @@ export const GroupSchema = z.object({
|
|
|
209
213
|
version: z.number(),
|
|
210
214
|
});
|
|
211
215
|
// Conversation entity from API.
|
|
212
|
-
export const
|
|
213
|
-
.object({
|
|
216
|
+
export const ConversationObjectSchema = z.object({
|
|
214
217
|
id: z.string(),
|
|
215
218
|
workspaceId: z.number(),
|
|
216
219
|
userIds: z.array(z.number()),
|
|
@@ -247,13 +250,15 @@ export const ConversationSchema = z
|
|
|
247
250
|
})
|
|
248
251
|
.nullable()
|
|
249
252
|
.optional(),
|
|
250
|
-
})
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
})
|
|
255
|
-
|
|
256
|
-
|
|
253
|
+
});
|
|
254
|
+
export function createConversationSchema(linkBaseUrl) {
|
|
255
|
+
return ConversationObjectSchema.transform((data) => ({
|
|
256
|
+
...data,
|
|
257
|
+
url: getFullCommsURL({ workspaceId: data.workspaceId, conversationId: data.id }, linkBaseUrl),
|
|
258
|
+
}));
|
|
259
|
+
}
|
|
260
|
+
export const ConversationSchema = createConversationSchema();
|
|
261
|
+
export const CommentObjectSchema = z.object({
|
|
257
262
|
id: z.string(),
|
|
258
263
|
content: z.string(),
|
|
259
264
|
creator: z.number(),
|
|
@@ -277,16 +282,19 @@ export const CommentSchema = z
|
|
|
277
282
|
deletedBy: z.number().nullable().optional(),
|
|
278
283
|
version: z.number().nullable().optional(),
|
|
279
284
|
actions: z.array(z.unknown()).nullable().optional(),
|
|
280
|
-
})
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
})
|
|
285
|
+
});
|
|
286
|
+
export function createCommentSchema(linkBaseUrl) {
|
|
287
|
+
return CommentObjectSchema.transform((data) => ({
|
|
288
|
+
...data,
|
|
289
|
+
url: getFullCommsURL({
|
|
290
|
+
workspaceId: data.workspaceId,
|
|
291
|
+
channelId: data.channelId,
|
|
292
|
+
threadId: data.threadId,
|
|
293
|
+
commentId: data.id,
|
|
294
|
+
}, linkBaseUrl),
|
|
295
|
+
}));
|
|
296
|
+
}
|
|
297
|
+
export const CommentSchema = createCommentSchema();
|
|
290
298
|
export const WorkspaceUserSchema = BaseUserSchema.extend({
|
|
291
299
|
email: z.string().nullable().optional(),
|
|
292
300
|
userType: z.enum(USER_TYPES),
|
|
@@ -299,8 +307,7 @@ export const WorkspaceUserSchema = BaseUserSchema.extend({
|
|
|
299
307
|
// (coerced to a string post-parse) because the backend currently emits
|
|
300
308
|
// either shape depending on the endpoint; the URL/reaction helpers accept
|
|
301
309
|
// both.
|
|
302
|
-
export const
|
|
303
|
-
.object({
|
|
310
|
+
export const ConversationMessageObjectSchema = z.object({
|
|
304
311
|
id: z.union([z.string(), z.number()]).transform(String),
|
|
305
312
|
content: z.string(),
|
|
306
313
|
creator: z.number(),
|
|
@@ -317,65 +324,72 @@ export const ConversationMessageSchema = z
|
|
|
317
324
|
directMentions: z.array(z.number()).nullable().optional(),
|
|
318
325
|
version: z.number().nullable().optional(),
|
|
319
326
|
workspaceId: z.number(),
|
|
320
|
-
})
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
})
|
|
327
|
+
});
|
|
328
|
+
export function createConversationMessageSchema(linkBaseUrl) {
|
|
329
|
+
return ConversationMessageObjectSchema.transform((data) => ({
|
|
330
|
+
...data,
|
|
331
|
+
url: getFullCommsURL({
|
|
332
|
+
workspaceId: data.workspaceId,
|
|
333
|
+
conversationId: data.conversationId,
|
|
334
|
+
messageId: data.id,
|
|
335
|
+
}, linkBaseUrl),
|
|
336
|
+
}));
|
|
337
|
+
}
|
|
338
|
+
export const ConversationMessageSchema = createConversationMessageSchema();
|
|
329
339
|
// InboxThread entity from API - returns full Thread objects with additional inbox metadata.
|
|
330
|
-
export
|
|
331
|
-
.object({
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
})
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
340
|
+
export function createInboxThreadObjectSchema(linkBaseUrl) {
|
|
341
|
+
return z.object({
|
|
342
|
+
id: z.string(),
|
|
343
|
+
title: z.string(),
|
|
344
|
+
content: z.string(),
|
|
345
|
+
creator: z.number(),
|
|
346
|
+
creatorName: z.string().nullable().optional(),
|
|
347
|
+
channelId: z.string(),
|
|
348
|
+
workspaceId: z.number(),
|
|
349
|
+
actions: z.array(z.unknown()).nullable().optional(),
|
|
350
|
+
attachments: z.array(AttachmentSchema).nullable().optional(),
|
|
351
|
+
commentCount: z.number(),
|
|
352
|
+
directGroupMentions: z.array(z.string()).nullable().optional(),
|
|
353
|
+
directMentions: z.array(z.number()).nullable().optional(),
|
|
354
|
+
groups: z.array(z.string()).nullable().optional(),
|
|
355
|
+
lastEdited: z.date().nullable().optional(),
|
|
356
|
+
lastObjIndex: z.number().nullable().optional(),
|
|
357
|
+
lastUpdated: z.date(),
|
|
358
|
+
mutedUntil: z.date().nullable().optional(),
|
|
359
|
+
participants: z.array(z.number()).nullable().optional(),
|
|
360
|
+
// Backend wire shape only includes `pinned_ts` (epoch ms or null);
|
|
361
|
+
// derive `pinned` from `pinnedTs != null` if you need a bool.
|
|
362
|
+
pinned: z.boolean().optional(),
|
|
363
|
+
pinnedTs: z.number().int().nullable().optional(),
|
|
364
|
+
posted: z.date(),
|
|
365
|
+
reactions: z.record(z.string(), z.array(z.number())).nullable().optional(),
|
|
366
|
+
recipients: z.array(z.number()).nullable().optional(),
|
|
367
|
+
snippet: z.string(),
|
|
368
|
+
snippetCreator: z.number(),
|
|
369
|
+
snippetMaskAvatarUrl: z.string().nullable().optional(),
|
|
370
|
+
snippetMaskPoster: z.string().nullable().optional(),
|
|
371
|
+
systemMessage: SystemMessageSchema,
|
|
372
|
+
isArchived: z.boolean(),
|
|
373
|
+
inInbox: z.boolean(),
|
|
374
|
+
isSaved: z.boolean().nullable().optional(),
|
|
375
|
+
closed: z.boolean(),
|
|
376
|
+
responders: z.array(z.number()).nullable().optional(),
|
|
377
|
+
lastComment: createCommentSchema(linkBaseUrl).nullable().optional(),
|
|
378
|
+
toEmails: z.array(z.string()).nullable().optional(),
|
|
379
|
+
version: z.number().nullable().optional(),
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
export function createInboxThreadSchema(linkBaseUrl) {
|
|
383
|
+
return createInboxThreadObjectSchema(linkBaseUrl).transform((data) => ({
|
|
384
|
+
...data,
|
|
385
|
+
url: getFullCommsURL({
|
|
386
|
+
workspaceId: data.workspaceId,
|
|
387
|
+
channelId: data.channelId,
|
|
388
|
+
threadId: data.id,
|
|
389
|
+
}, linkBaseUrl),
|
|
390
|
+
}));
|
|
391
|
+
}
|
|
392
|
+
export const InboxThreadSchema = createInboxThreadSchema();
|
|
379
393
|
// UnreadThread entity from API - simplified thread reference.
|
|
380
394
|
export const UnreadThreadSchema = z.object({
|
|
381
395
|
threadId: z.string(),
|
|
@@ -45,7 +45,9 @@ export function getCommsURL(params) {
|
|
|
45
45
|
* @param baseUrl - Optional base URL (defaults to 'https://comms.todoist.com')
|
|
46
46
|
*/
|
|
47
47
|
export function getFullCommsURL(params, baseUrl = COMMS_BASE_URL) {
|
|
48
|
-
|
|
48
|
+
// Strip a trailing slash so links don't double up — `getCommsURL` paths start with '/'.
|
|
49
|
+
const normalizedBase = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
|
|
50
|
+
return `${normalizedBase}${getCommsURL(params)}`;
|
|
49
51
|
}
|
|
50
52
|
/** Returns the URL for a thread in a channel. */
|
|
51
53
|
export function getThreadURL(params) {
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { type Comment } from '../types/entities.js';
|
|
1
|
+
import { type Comment, type createCommentSchema } from '../types/entities.js';
|
|
2
2
|
import type { CustomFetch } from '../types/http.js';
|
|
3
3
|
import type { CreateCommentArgs, ThreadAction } from '../types/requests.js';
|
|
4
4
|
type ClientContext = {
|
|
5
5
|
baseUri: string;
|
|
6
6
|
apiToken: string;
|
|
7
7
|
customFetch?: CustomFetch;
|
|
8
|
+
/** Per-client Comment schema, base-bound for the returned comment's web `url`. */
|
|
9
|
+
schema: ReturnType<typeof createCommentSchema>;
|
|
8
10
|
};
|
|
9
11
|
/**
|
|
10
12
|
* Internal helper that powers `comments.createComment`,
|
|
@@ -25,4 +25,10 @@ export declare class BaseClient {
|
|
|
25
25
|
* slash so relative paths resolve cleanly through `URL`.
|
|
26
26
|
*/
|
|
27
27
|
protected getBaseUri(): string;
|
|
28
|
+
/**
|
|
29
|
+
* Base URL for entity web links, or `undefined` to use getFullCommsURL's
|
|
30
|
+
* default web app. Trailing-slash normalization happens in
|
|
31
|
+
* `getFullCommsURL`, so the configured value is returned verbatim.
|
|
32
|
+
*/
|
|
33
|
+
protected getLinkBaseUrl(): string | undefined;
|
|
28
34
|
}
|
|
@@ -64,6 +64,9 @@ export declare const ChannelListSchema: z.ZodArray<z.ZodPipe<z.ZodObject<{
|
|
|
64
64
|
* to keep an optimistic-UI ID stable through the round-trip.
|
|
65
65
|
*/
|
|
66
66
|
export declare class ChannelsClient extends BaseClient {
|
|
67
|
+
private readonly linkBaseUrl;
|
|
68
|
+
private readonly channelSchema;
|
|
69
|
+
private readonly channelListSchema;
|
|
67
70
|
/**
|
|
68
71
|
* Gets all channels for a given workspace.
|
|
69
72
|
*
|
|
@@ -134,6 +134,10 @@ export declare const CommentListSchema: z.ZodArray<z.ZodPipe<z.ZodObject<{
|
|
|
134
134
|
* on `createComment` when the caller doesn't supply one.
|
|
135
135
|
*/
|
|
136
136
|
export declare class CommentsClient extends BaseClient {
|
|
137
|
+
private readonly linkBaseUrl;
|
|
138
|
+
private readonly commentSchema;
|
|
139
|
+
private readonly commentListSchema;
|
|
140
|
+
private readonly wrappedCommentSchema;
|
|
137
141
|
/**
|
|
138
142
|
* Gets all comments for a thread. `newerThan` / `olderThan` (`Date`) are
|
|
139
143
|
* converted to `newer_than_ts` / `older_than_ts` epoch seconds on the
|
|
@@ -113,6 +113,9 @@ export declare const ConversationMessageListSchema: z.ZodArray<z.ZodPipe<z.ZodOb
|
|
|
113
113
|
* message `id` on `createMessage` when the caller doesn't supply one.
|
|
114
114
|
*/
|
|
115
115
|
export declare class ConversationMessagesClient extends BaseClient {
|
|
116
|
+
private readonly linkBaseUrl;
|
|
117
|
+
private readonly messageSchema;
|
|
118
|
+
private readonly messageListSchema;
|
|
116
119
|
/**
|
|
117
120
|
* Gets all messages in a conversation.
|
|
118
121
|
*
|
|
@@ -163,6 +163,9 @@ export declare const ConversationListSchema: z.ZodArray<z.ZodPipe<z.ZodObject<{
|
|
|
163
163
|
* already-assigned `id` and your generated one is silently dropped.
|
|
164
164
|
*/
|
|
165
165
|
export declare class ConversationsClient extends BaseClient {
|
|
166
|
+
private readonly linkBaseUrl;
|
|
167
|
+
private readonly conversationSchema;
|
|
168
|
+
private readonly conversationListSchema;
|
|
166
169
|
/**
|
|
167
170
|
* Gets all conversations for a workspace.
|
|
168
171
|
*
|