@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.
Files changed (33) hide show
  1. package/dist/cjs/clients/add-comment-helper.js +1 -2
  2. package/dist/cjs/clients/base-client.js +8 -0
  3. package/dist/cjs/clients/channels-client.js +19 -8
  4. package/dist/cjs/clients/comments-client.js +24 -5
  5. package/dist/cjs/clients/conversation-messages-client.js +15 -4
  6. package/dist/cjs/clients/conversations-client.js +23 -12
  7. package/dist/cjs/clients/inbox-client.js +15 -2
  8. package/dist/cjs/clients/threads-client.js +27 -8
  9. package/dist/cjs/clients/workspaces-client.js +9 -1
  10. package/dist/cjs/types/entities.js +119 -98
  11. package/dist/cjs/utils/url-helpers.js +3 -1
  12. package/dist/esm/clients/add-comment-helper.js +1 -2
  13. package/dist/esm/clients/base-client.js +8 -0
  14. package/dist/esm/clients/channels-client.js +20 -9
  15. package/dist/esm/clients/comments-client.js +25 -6
  16. package/dist/esm/clients/conversation-messages-client.js +16 -5
  17. package/dist/esm/clients/conversations-client.js +24 -13
  18. package/dist/esm/clients/inbox-client.js +15 -2
  19. package/dist/esm/clients/threads-client.js +28 -9
  20. package/dist/esm/clients/workspaces-client.js +10 -2
  21. package/dist/esm/types/entities.js +111 -97
  22. package/dist/esm/utils/url-helpers.js +3 -1
  23. package/dist/types/clients/add-comment-helper.d.ts +3 -1
  24. package/dist/types/clients/base-client.d.ts +6 -0
  25. package/dist/types/clients/channels-client.d.ts +3 -0
  26. package/dist/types/clients/comments-client.d.ts +4 -0
  27. package/dist/types/clients/conversation-messages-client.d.ts +3 -0
  28. package/dist/types/clients/conversations-client.d.ts +3 -0
  29. package/dist/types/clients/inbox-client.d.ts +382 -0
  30. package/dist/types/clients/threads-client.d.ts +4 -0
  31. package/dist/types/clients/workspaces-client.d.ts +2 -0
  32. package/dist/types/types/entities.d.ts +1654 -126
  33. package/package.json +1 -1
@@ -1,6 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SearchResultSchema = exports.SEARCH_RESULT_TYPES = exports.UnreadConversationSchema = exports.UnreadThreadSchema = exports.InboxThreadSchema = exports.ConversationMessageSchema = exports.WorkspaceUserSchema = exports.CommentSchema = exports.ConversationSchema = exports.GroupSchema = exports.ThreadSchema = exports.ChannelSchema = exports.WorkspaceSchema = exports.UserSchema = exports.BaseUserSchema = exports.AttachmentSchema = exports.StatusOkSchema = exports.SystemMessageSchema = void 0;
3
+ exports.SearchResultSchema = exports.SEARCH_RESULT_TYPES = exports.UnreadConversationSchema = exports.UnreadThreadSchema = exports.InboxThreadSchema = exports.ConversationMessageSchema = exports.ConversationMessageObjectSchema = exports.WorkspaceUserSchema = exports.CommentSchema = exports.CommentObjectSchema = exports.ConversationSchema = exports.ConversationObjectSchema = exports.GroupSchema = exports.ThreadSchema = exports.ThreadObjectSchema = exports.ChannelSchema = exports.ChannelObjectSchema = exports.WorkspaceSchema = exports.UserSchema = exports.BaseUserSchema = exports.AttachmentSchema = exports.StatusOkSchema = exports.SystemMessageSchema = void 0;
4
+ exports.createChannelSchema = createChannelSchema;
5
+ exports.createThreadSchema = createThreadSchema;
6
+ exports.createConversationSchema = createConversationSchema;
7
+ exports.createCommentSchema = createCommentSchema;
8
+ exports.createConversationMessageSchema = createConversationMessageSchema;
9
+ exports.createInboxThreadObjectSchema = createInboxThreadObjectSchema;
10
+ exports.createInboxThreadSchema = createInboxThreadSchema;
4
11
  const zod_1 = require("zod");
5
12
  const url_helpers_1 = require("../utils/url-helpers");
6
13
  const enums_1 = require("./enums");
@@ -100,8 +107,7 @@ exports.WorkspaceSchema = zod_1.z.object({
100
107
  .optional(),
101
108
  plan: zod_1.z.string().nullable().optional(),
102
109
  });
103
- exports.ChannelSchema = zod_1.z
104
- .object({
110
+ exports.ChannelObjectSchema = zod_1.z.object({
105
111
  id: zod_1.z.string(),
106
112
  name: zod_1.z.string(),
107
113
  description: zod_1.z.string().nullable().optional(),
@@ -119,15 +125,17 @@ exports.ChannelSchema = zod_1.z
119
125
  icon: zod_1.z.number().nullable().optional(),
120
126
  version: zod_1.z.number(),
121
127
  filters: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).nullable().optional(),
122
- })
123
- .transform((data) => ({
124
- ...data,
125
- url: (0, url_helpers_1.getFullCommsURL)({ workspaceId: data.workspaceId, channelId: data.id }),
126
- }));
128
+ });
129
+ function createChannelSchema(linkBaseUrl) {
130
+ return exports.ChannelObjectSchema.transform((data) => ({
131
+ ...data,
132
+ url: (0, url_helpers_1.getFullCommsURL)({ workspaceId: data.workspaceId, channelId: data.id }, linkBaseUrl),
133
+ }));
134
+ }
135
+ exports.ChannelSchema = createChannelSchema();
127
136
  // Thread entity from API. `pinned` (boolean) and `pinnedTs` (epoch ms or
128
137
  // null) are both surfaced — `pinned` is kept for Zapier/webhook clients.
129
- exports.ThreadSchema = zod_1.z
130
- .object({
138
+ exports.ThreadObjectSchema = zod_1.z.object({
131
139
  id: zod_1.z.string(),
132
140
  title: zod_1.z.string(),
133
141
  content: zod_1.z.string(),
@@ -191,15 +199,18 @@ exports.ThreadSchema = zod_1.z
191
199
  })
192
200
  .nullable()
193
201
  .optional(),
194
- })
195
- .transform((data) => ({
196
- ...data,
197
- url: (0, url_helpers_1.getFullCommsURL)({
198
- workspaceId: data.workspaceId,
199
- channelId: data.channelId,
200
- threadId: data.id,
201
- }),
202
- }));
202
+ });
203
+ function createThreadSchema(linkBaseUrl) {
204
+ return exports.ThreadObjectSchema.transform((data) => ({
205
+ ...data,
206
+ url: (0, url_helpers_1.getFullCommsURL)({
207
+ workspaceId: data.workspaceId,
208
+ channelId: data.channelId,
209
+ threadId: data.id,
210
+ }, linkBaseUrl),
211
+ }));
212
+ }
213
+ exports.ThreadSchema = createThreadSchema();
203
214
  // Group entity from API. The broadcast markers `EVERYONE` and
204
215
  // `EVERYONE_IN_THREAD` can appear in place of a real `id` in group-bearing
205
216
  // fields on threads/comments/channels.
@@ -212,8 +223,7 @@ exports.GroupSchema = zod_1.z.object({
212
223
  version: zod_1.z.number(),
213
224
  });
214
225
  // Conversation entity from API.
215
- exports.ConversationSchema = zod_1.z
216
- .object({
226
+ exports.ConversationObjectSchema = zod_1.z.object({
217
227
  id: zod_1.z.string(),
218
228
  workspaceId: zod_1.z.number(),
219
229
  userIds: zod_1.z.array(zod_1.z.number()),
@@ -250,13 +260,15 @@ exports.ConversationSchema = zod_1.z
250
260
  })
251
261
  .nullable()
252
262
  .optional(),
253
- })
254
- .transform((data) => ({
255
- ...data,
256
- url: (0, url_helpers_1.getFullCommsURL)({ workspaceId: data.workspaceId, conversationId: data.id }),
257
- }));
258
- exports.CommentSchema = zod_1.z
259
- .object({
263
+ });
264
+ function createConversationSchema(linkBaseUrl) {
265
+ return exports.ConversationObjectSchema.transform((data) => ({
266
+ ...data,
267
+ url: (0, url_helpers_1.getFullCommsURL)({ workspaceId: data.workspaceId, conversationId: data.id }, linkBaseUrl),
268
+ }));
269
+ }
270
+ exports.ConversationSchema = createConversationSchema();
271
+ exports.CommentObjectSchema = zod_1.z.object({
260
272
  id: zod_1.z.string(),
261
273
  content: zod_1.z.string(),
262
274
  creator: zod_1.z.number(),
@@ -280,16 +292,19 @@ exports.CommentSchema = zod_1.z
280
292
  deletedBy: zod_1.z.number().nullable().optional(),
281
293
  version: zod_1.z.number().nullable().optional(),
282
294
  actions: zod_1.z.array(zod_1.z.unknown()).nullable().optional(),
283
- })
284
- .transform((data) => ({
285
- ...data,
286
- url: (0, url_helpers_1.getFullCommsURL)({
287
- workspaceId: data.workspaceId,
288
- channelId: data.channelId,
289
- threadId: data.threadId,
290
- commentId: data.id,
291
- }),
292
- }));
295
+ });
296
+ function createCommentSchema(linkBaseUrl) {
297
+ return exports.CommentObjectSchema.transform((data) => ({
298
+ ...data,
299
+ url: (0, url_helpers_1.getFullCommsURL)({
300
+ workspaceId: data.workspaceId,
301
+ channelId: data.channelId,
302
+ threadId: data.threadId,
303
+ commentId: data.id,
304
+ }, linkBaseUrl),
305
+ }));
306
+ }
307
+ exports.CommentSchema = createCommentSchema();
293
308
  exports.WorkspaceUserSchema = exports.BaseUserSchema.extend({
294
309
  email: zod_1.z.string().nullable().optional(),
295
310
  userType: zod_1.z.enum(enums_1.USER_TYPES),
@@ -302,8 +317,7 @@ exports.WorkspaceUserSchema = exports.BaseUserSchema.extend({
302
317
  // (coerced to a string post-parse) because the backend currently emits
303
318
  // either shape depending on the endpoint; the URL/reaction helpers accept
304
319
  // both.
305
- exports.ConversationMessageSchema = zod_1.z
306
- .object({
320
+ exports.ConversationMessageObjectSchema = zod_1.z.object({
307
321
  id: zod_1.z.union([zod_1.z.string(), zod_1.z.number()]).transform(String),
308
322
  content: zod_1.z.string(),
309
323
  creator: zod_1.z.number(),
@@ -320,65 +334,72 @@ exports.ConversationMessageSchema = zod_1.z
320
334
  directMentions: zod_1.z.array(zod_1.z.number()).nullable().optional(),
321
335
  version: zod_1.z.number().nullable().optional(),
322
336
  workspaceId: zod_1.z.number(),
323
- })
324
- .transform((data) => ({
325
- ...data,
326
- url: (0, url_helpers_1.getFullCommsURL)({
327
- workspaceId: data.workspaceId,
328
- conversationId: data.conversationId,
329
- messageId: data.id,
330
- }),
331
- }));
337
+ });
338
+ function createConversationMessageSchema(linkBaseUrl) {
339
+ return exports.ConversationMessageObjectSchema.transform((data) => ({
340
+ ...data,
341
+ url: (0, url_helpers_1.getFullCommsURL)({
342
+ workspaceId: data.workspaceId,
343
+ conversationId: data.conversationId,
344
+ messageId: data.id,
345
+ }, linkBaseUrl),
346
+ }));
347
+ }
348
+ exports.ConversationMessageSchema = createConversationMessageSchema();
332
349
  // InboxThread entity from API - returns full Thread objects with additional inbox metadata.
333
- exports.InboxThreadSchema = zod_1.z
334
- .object({
335
- id: zod_1.z.string(),
336
- title: zod_1.z.string(),
337
- content: zod_1.z.string(),
338
- creator: zod_1.z.number(),
339
- creatorName: zod_1.z.string().nullable().optional(),
340
- channelId: zod_1.z.string(),
341
- workspaceId: zod_1.z.number(),
342
- actions: zod_1.z.array(zod_1.z.unknown()).nullable().optional(),
343
- attachments: zod_1.z.array(exports.AttachmentSchema).nullable().optional(),
344
- commentCount: zod_1.z.number(),
345
- directGroupMentions: zod_1.z.array(zod_1.z.string()).nullable().optional(),
346
- directMentions: zod_1.z.array(zod_1.z.number()).nullable().optional(),
347
- groups: zod_1.z.array(zod_1.z.string()).nullable().optional(),
348
- lastEdited: zod_1.z.date().nullable().optional(),
349
- lastObjIndex: zod_1.z.number().nullable().optional(),
350
- lastUpdated: zod_1.z.date(),
351
- mutedUntil: zod_1.z.date().nullable().optional(),
352
- participants: zod_1.z.array(zod_1.z.number()).nullable().optional(),
353
- // Backend wire shape only includes `pinned_ts` (epoch ms or null);
354
- // derive `pinned` from `pinnedTs != null` if you need a bool.
355
- pinned: zod_1.z.boolean().optional(),
356
- pinnedTs: zod_1.z.number().int().nullable().optional(),
357
- posted: zod_1.z.date(),
358
- reactions: zod_1.z.record(zod_1.z.string(), zod_1.z.array(zod_1.z.number())).nullable().optional(),
359
- recipients: zod_1.z.array(zod_1.z.number()).nullable().optional(),
360
- snippet: zod_1.z.string(),
361
- snippetCreator: zod_1.z.number(),
362
- snippetMaskAvatarUrl: zod_1.z.string().nullable().optional(),
363
- snippetMaskPoster: zod_1.z.string().nullable().optional(),
364
- systemMessage: exports.SystemMessageSchema,
365
- isArchived: zod_1.z.boolean(),
366
- inInbox: zod_1.z.boolean(),
367
- isSaved: zod_1.z.boolean().nullable().optional(),
368
- closed: zod_1.z.boolean(),
369
- responders: zod_1.z.array(zod_1.z.number()).nullable().optional(),
370
- lastComment: exports.CommentSchema.nullable().optional(),
371
- toEmails: zod_1.z.array(zod_1.z.string()).nullable().optional(),
372
- version: zod_1.z.number().nullable().optional(),
373
- })
374
- .transform((data) => ({
375
- ...data,
376
- url: (0, url_helpers_1.getFullCommsURL)({
377
- workspaceId: data.workspaceId,
378
- channelId: data.channelId,
379
- threadId: data.id,
380
- }),
381
- }));
350
+ function createInboxThreadObjectSchema(linkBaseUrl) {
351
+ return zod_1.z.object({
352
+ id: zod_1.z.string(),
353
+ title: zod_1.z.string(),
354
+ content: zod_1.z.string(),
355
+ creator: zod_1.z.number(),
356
+ creatorName: zod_1.z.string().nullable().optional(),
357
+ channelId: zod_1.z.string(),
358
+ workspaceId: zod_1.z.number(),
359
+ actions: zod_1.z.array(zod_1.z.unknown()).nullable().optional(),
360
+ attachments: zod_1.z.array(exports.AttachmentSchema).nullable().optional(),
361
+ commentCount: zod_1.z.number(),
362
+ directGroupMentions: zod_1.z.array(zod_1.z.string()).nullable().optional(),
363
+ directMentions: zod_1.z.array(zod_1.z.number()).nullable().optional(),
364
+ groups: zod_1.z.array(zod_1.z.string()).nullable().optional(),
365
+ lastEdited: zod_1.z.date().nullable().optional(),
366
+ lastObjIndex: zod_1.z.number().nullable().optional(),
367
+ lastUpdated: zod_1.z.date(),
368
+ mutedUntil: zod_1.z.date().nullable().optional(),
369
+ participants: zod_1.z.array(zod_1.z.number()).nullable().optional(),
370
+ // Backend wire shape only includes `pinned_ts` (epoch ms or null);
371
+ // derive `pinned` from `pinnedTs != null` if you need a bool.
372
+ pinned: zod_1.z.boolean().optional(),
373
+ pinnedTs: zod_1.z.number().int().nullable().optional(),
374
+ posted: zod_1.z.date(),
375
+ reactions: zod_1.z.record(zod_1.z.string(), zod_1.z.array(zod_1.z.number())).nullable().optional(),
376
+ recipients: zod_1.z.array(zod_1.z.number()).nullable().optional(),
377
+ snippet: zod_1.z.string(),
378
+ snippetCreator: zod_1.z.number(),
379
+ snippetMaskAvatarUrl: zod_1.z.string().nullable().optional(),
380
+ snippetMaskPoster: zod_1.z.string().nullable().optional(),
381
+ systemMessage: exports.SystemMessageSchema,
382
+ isArchived: zod_1.z.boolean(),
383
+ inInbox: zod_1.z.boolean(),
384
+ isSaved: zod_1.z.boolean().nullable().optional(),
385
+ closed: zod_1.z.boolean(),
386
+ responders: zod_1.z.array(zod_1.z.number()).nullable().optional(),
387
+ lastComment: createCommentSchema(linkBaseUrl).nullable().optional(),
388
+ toEmails: zod_1.z.array(zod_1.z.string()).nullable().optional(),
389
+ version: zod_1.z.number().nullable().optional(),
390
+ });
391
+ }
392
+ function createInboxThreadSchema(linkBaseUrl) {
393
+ return createInboxThreadObjectSchema(linkBaseUrl).transform((data) => ({
394
+ ...data,
395
+ url: (0, url_helpers_1.getFullCommsURL)({
396
+ workspaceId: data.workspaceId,
397
+ channelId: data.channelId,
398
+ threadId: data.id,
399
+ }, linkBaseUrl),
400
+ }));
401
+ }
402
+ exports.InboxThreadSchema = createInboxThreadSchema();
382
403
  // UnreadThread entity from API - simplified thread reference.
383
404
  exports.UnreadThreadSchema = zod_1.z.object({
384
405
  threadId: zod_1.z.string(),
@@ -64,7 +64,9 @@ function getCommsURL(params) {
64
64
  * @param baseUrl - Optional base URL (defaults to 'https://comms.todoist.com')
65
65
  */
66
66
  function getFullCommsURL(params, baseUrl = COMMS_BASE_URL) {
67
- return `${baseUrl}${getCommsURL(params)}`;
67
+ // Strip a trailing slash so links don't double up — `getCommsURL` paths start with '/'.
68
+ const normalizedBase = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
69
+ return `${normalizedBase}${getCommsURL(params)}`;
68
70
  }
69
71
  /** Returns the URL for a thread in a channel. */
70
72
  function getThreadURL(params) {
@@ -1,6 +1,5 @@
1
1
  import { ENDPOINT_COMMENTS } from '../consts/endpoints.js';
2
2
  import { request } from '../transport/http-client.js';
3
- import { CommentSchema } from '../types/entities.js';
4
3
  import { NOTIFY_AUDIENCE_GROUP_IDS, NOTIFY_AUDIENCES } from '../types/enums.js';
5
4
  import { resolveCreateId } from '../utils/uuidv7.js';
6
5
  const SENTINEL_GROUP_IDS = new Set(Object.values(NOTIFY_AUDIENCE_GROUP_IDS));
@@ -63,5 +62,5 @@ export function addCommentRequest(context, params, options) {
63
62
  apiToken: context.apiToken,
64
63
  payload,
65
64
  customFetch: context.customFetch,
66
- }).then((response) => CommentSchema.parse(response.data));
65
+ }).then((response) => context.schema.parse(response.data));
67
66
  }
@@ -18,4 +18,12 @@ export class BaseClient {
18
18
  getBaseUri() {
19
19
  return getCommsBaseUri(this.defaultVersion, this.baseUrl);
20
20
  }
21
+ /**
22
+ * Base URL for entity web links, or `undefined` to use getFullCommsURL's
23
+ * default web app. Trailing-slash normalization happens in
24
+ * `getFullCommsURL`, so the configured value is returned verbatim.
25
+ */
26
+ getLinkBaseUrl() {
27
+ return this.baseUrl;
28
+ }
21
29
  }
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { ENDPOINT_CHANNELS } from '../consts/endpoints.js';
3
3
  import { request } from '../transport/http-client.js';
4
- import { ChannelSchema, StatusOkSchema } from '../types/entities.js';
4
+ import { ChannelSchema, createChannelSchema, StatusOkSchema, } from '../types/entities.js';
5
5
  import { resolveCreateId } from '../utils/uuidv7.js';
6
6
  import { BaseClient } from './base-client.js';
7
7
  export const ChannelListSchema = z.array(ChannelSchema);
@@ -11,6 +11,17 @@ export const ChannelListSchema = z.array(ChannelSchema);
11
11
  * to keep an optimistic-UI ID stable through the round-trip.
12
12
  */
13
13
  export class ChannelsClient extends BaseClient {
14
+ constructor() {
15
+ super(...arguments);
16
+ this.linkBaseUrl = this.getLinkBaseUrl();
17
+ // Reuse the shared singletons when no custom base is configured.
18
+ this.channelSchema = this.linkBaseUrl
19
+ ? createChannelSchema(this.linkBaseUrl)
20
+ : ChannelSchema;
21
+ this.channelListSchema = this.linkBaseUrl
22
+ ? z.array(this.channelSchema)
23
+ : ChannelListSchema;
24
+ }
14
25
  /**
15
26
  * Gets all channels for a given workspace.
16
27
  *
@@ -33,7 +44,7 @@ export class ChannelsClient extends BaseClient {
33
44
  apiToken: this.apiToken,
34
45
  payload: args,
35
46
  customFetch: this.customFetch,
36
- }).then((response) => ChannelListSchema.parse(response.data));
47
+ }).then((response) => this.channelListSchema.parse(response.data));
37
48
  }
38
49
  /**
39
50
  * Gets a single channel object by id.
@@ -42,7 +53,7 @@ export class ChannelsClient extends BaseClient {
42
53
  * @returns The channel object.
43
54
  */
44
55
  getChannel(id) {
45
- return this.simple('GET', 'getone', { id }, ChannelSchema);
56
+ return this.simple('GET', 'getone', { id }, this.channelSchema);
46
57
  }
47
58
  /**
48
59
  * Creates a new channel. `id` is auto-generated if not supplied — pass your
@@ -67,7 +78,7 @@ export class ChannelsClient extends BaseClient {
67
78
  * ```
68
79
  */
69
80
  createChannel(args) {
70
- return this.simple('POST', 'add', { ...args, id: resolveCreateId(args.id) }, ChannelSchema);
81
+ return this.simple('POST', 'add', { ...args, id: resolveCreateId(args.id) }, this.channelSchema);
71
82
  }
72
83
  /**
73
84
  * Partial update of an existing channel.
@@ -81,7 +92,7 @@ export class ChannelsClient extends BaseClient {
81
92
  * @returns The updated channel object.
82
93
  */
83
94
  updateChannel(args) {
84
- return this.simple('POST', 'update', { ...args }, ChannelSchema);
95
+ return this.simple('POST', 'update', { ...args }, this.channelSchema);
85
96
  }
86
97
  /**
87
98
  * Updates the channel's view filter (`only_open` / `all` / `only_closed`).
@@ -146,7 +157,7 @@ export class ChannelsClient extends BaseClient {
146
157
  * ```
147
158
  */
148
159
  addUser(args) {
149
- return this.simple('POST', 'add_user', { ...args }, ChannelSchema);
160
+ return this.simple('POST', 'add_user', { ...args }, this.channelSchema);
150
161
  }
151
162
  /**
152
163
  * Adds multiple users to a channel.
@@ -161,7 +172,7 @@ export class ChannelsClient extends BaseClient {
161
172
  * ```
162
173
  */
163
174
  addUsers(args) {
164
- return this.simple('POST', 'add_users', { ...args }, ChannelSchema);
175
+ return this.simple('POST', 'add_users', { ...args }, this.channelSchema);
165
176
  }
166
177
  /**
167
178
  * Removes a user from a channel.
@@ -171,7 +182,7 @@ export class ChannelsClient extends BaseClient {
171
182
  * @param args.userId - The user ID to remove.
172
183
  */
173
184
  removeUser(args) {
174
- return this.simple('POST', 'remove_user', { ...args }, ChannelSchema);
185
+ return this.simple('POST', 'remove_user', { ...args }, this.channelSchema);
175
186
  }
176
187
  /**
177
188
  * Removes multiple users from a channel.
@@ -181,7 +192,7 @@ export class ChannelsClient extends BaseClient {
181
192
  * @param args.userIds - Array of user IDs to remove.
182
193
  */
183
194
  removeUsers(args) {
184
- return this.simple('POST', 'remove_users', { ...args }, ChannelSchema);
195
+ return this.simple('POST', 'remove_users', { ...args }, this.channelSchema);
185
196
  }
186
197
  simple(httpMethod, suffix, params, schema) {
187
198
  return request({
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { ENDPOINT_COMMENTS } from '../consts/endpoints.js';
3
3
  import { request } from '../transport/http-client.js';
4
- import { CommentSchema, StatusOkSchema } from '../types/entities.js';
4
+ import { CommentSchema, createCommentSchema, StatusOkSchema, } from '../types/entities.js';
5
5
  import { addCommentRequest } from './add-comment-helper.js';
6
6
  import { BaseClient } from './base-client.js';
7
7
  export const CommentListSchema = z.array(CommentSchema);
@@ -10,6 +10,21 @@ export const CommentListSchema = z.array(CommentSchema);
10
10
  * on `createComment` when the caller doesn't supply one.
11
11
  */
12
12
  export class CommentsClient extends BaseClient {
13
+ constructor() {
14
+ super(...arguments);
15
+ this.linkBaseUrl = this.getLinkBaseUrl();
16
+ // Reuse the shared singletons when no custom base is configured.
17
+ this.commentSchema = this.linkBaseUrl
18
+ ? createCommentSchema(this.linkBaseUrl)
19
+ : CommentSchema;
20
+ this.commentListSchema = this.linkBaseUrl
21
+ ? z.array(this.commentSchema)
22
+ : CommentListSchema;
23
+ // `getone` wraps the comment in `{ comment: ... }`; built once per client.
24
+ this.wrappedCommentSchema = z
25
+ .object({ comment: this.commentSchema })
26
+ .transform((data) => data.comment);
27
+ }
13
28
  /**
14
29
  * Gets all comments for a thread. `newerThan` / `olderThan` (`Date`) are
15
30
  * converted to `newer_than_ts` / `older_than_ts` epoch seconds on the
@@ -46,7 +61,7 @@ export class CommentsClient extends BaseClient {
46
61
  apiToken: this.apiToken,
47
62
  payload: params,
48
63
  customFetch: this.customFetch,
49
- }).then((response) => CommentListSchema.parse(response.data));
64
+ }).then((response) => this.commentListSchema.parse(response.data));
50
65
  }
51
66
  /**
52
67
  * Gets a single comment object by id. The API wraps it in `{comment: ...}`.
@@ -55,7 +70,6 @@ export class CommentsClient extends BaseClient {
55
70
  * @returns The comment object.
56
71
  */
57
72
  getComment(id) {
58
- const wrappedSchema = z.object({ comment: CommentSchema }).transform((data) => data.comment);
59
73
  return request({
60
74
  httpMethod: 'GET',
61
75
  baseUri: this.getBaseUri(),
@@ -63,7 +77,7 @@ export class CommentsClient extends BaseClient {
63
77
  apiToken: this.apiToken,
64
78
  payload: { id },
65
79
  customFetch: this.customFetch,
66
- }).then((response) => wrappedSchema.parse(response.data));
80
+ }).then((response) => this.wrappedCommentSchema.parse(response.data));
67
81
  }
68
82
  /**
69
83
  * Creates a new comment on a thread. `id` is auto-generated if not supplied.
@@ -93,7 +107,12 @@ export class CommentsClient extends BaseClient {
93
107
  * ```
94
108
  */
95
109
  createComment(args) {
96
- return addCommentRequest({ baseUri: this.getBaseUri(), apiToken: this.apiToken, customFetch: this.customFetch }, args);
110
+ return addCommentRequest({
111
+ baseUri: this.getBaseUri(),
112
+ apiToken: this.apiToken,
113
+ customFetch: this.customFetch,
114
+ schema: this.commentSchema,
115
+ }, args);
97
116
  }
98
117
  /**
99
118
  * Updates a comment's properties.
@@ -111,7 +130,7 @@ export class CommentsClient extends BaseClient {
111
130
  apiToken: this.apiToken,
112
131
  payload: { ...args },
113
132
  customFetch: this.customFetch,
114
- }).then((response) => CommentSchema.parse(response.data));
133
+ }).then((response) => this.commentSchema.parse(response.data));
115
134
  }
116
135
  /**
117
136
  * Permanently deletes a comment.
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { ENDPOINT_CONVERSATION_MESSAGES } from '../consts/endpoints.js';
3
3
  import { request } from '../transport/http-client.js';
4
- import { ConversationMessageSchema, StatusOkSchema, } from '../types/entities.js';
4
+ import { ConversationMessageSchema, createConversationMessageSchema, StatusOkSchema, } from '../types/entities.js';
5
5
  import { resolveCreateId } from '../utils/uuidv7.js';
6
6
  import { BaseClient } from './base-client.js';
7
7
  export const ConversationMessageListSchema = z.array(ConversationMessageSchema);
@@ -10,6 +10,17 @@ export const ConversationMessageListSchema = z.array(ConversationMessageSchema);
10
10
  * message `id` on `createMessage` when the caller doesn't supply one.
11
11
  */
12
12
  export class ConversationMessagesClient extends BaseClient {
13
+ constructor() {
14
+ super(...arguments);
15
+ this.linkBaseUrl = this.getLinkBaseUrl();
16
+ // Reuse the shared singletons when no custom base is configured.
17
+ this.messageSchema = this.linkBaseUrl
18
+ ? createConversationMessageSchema(this.linkBaseUrl)
19
+ : ConversationMessageSchema;
20
+ this.messageListSchema = this.linkBaseUrl
21
+ ? z.array(this.messageSchema)
22
+ : ConversationMessageListSchema;
23
+ }
13
24
  /**
14
25
  * Gets all messages in a conversation.
15
26
  *
@@ -46,7 +57,7 @@ export class ConversationMessagesClient extends BaseClient {
46
57
  apiToken: this.apiToken,
47
58
  payload: params,
48
59
  customFetch: this.customFetch,
49
- }).then((response) => ConversationMessageListSchema.parse(response.data));
60
+ }).then((response) => this.messageListSchema.parse(response.data));
50
61
  }
51
62
  /**
52
63
  * Gets a single conversation message by id.
@@ -60,7 +71,7 @@ export class ConversationMessagesClient extends BaseClient {
60
71
  * ```
61
72
  */
62
73
  getMessage(id) {
63
- return this.simple('GET', 'getone', { id }, ConversationMessageSchema);
74
+ return this.simple('GET', 'getone', { id }, this.messageSchema);
64
75
  }
65
76
  /**
66
77
  * Creates a new message in a conversation. `id` is auto-generated if not
@@ -97,7 +108,7 @@ export class ConversationMessagesClient extends BaseClient {
97
108
  params.directGroupMentions = args.directGroupMentions;
98
109
  if (args.notify !== undefined)
99
110
  params.notify = args.notify;
100
- return this.simple('POST', 'add', params, ConversationMessageSchema);
111
+ return this.simple('POST', 'add', params, this.messageSchema);
101
112
  }
102
113
  /**
103
114
  * Updates a conversation message.
@@ -126,7 +137,7 @@ export class ConversationMessagesClient extends BaseClient {
126
137
  params.directMentions = args.directMentions;
127
138
  if (args.directGroupMentions)
128
139
  params.directGroupMentions = args.directGroupMentions;
129
- return this.simple('POST', 'update', params, ConversationMessageSchema);
140
+ return this.simple('POST', 'update', params, this.messageSchema);
130
141
  }
131
142
  /**
132
143
  * Permanently deletes a conversation message.