@doist/twist-sdk 2.5.0 → 2.6.0

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.
@@ -10,16 +10,58 @@ var __assign = (this && this.__assign) || function () {
10
10
  };
11
11
  return __assign.apply(this, arguments);
12
12
  };
13
+ var __rest = (this && this.__rest) || function (s, e) {
14
+ var t = {};
15
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
16
+ t[p] = s[p];
17
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
18
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
19
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
20
+ t[p[i]] = s[p[i]];
21
+ }
22
+ return t;
23
+ };
24
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
25
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
26
+ if (ar || !(i in from)) {
27
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
28
+ ar[i] = from[i];
29
+ }
30
+ }
31
+ return to.concat(ar || Array.prototype.slice.call(from));
32
+ };
13
33
  Object.defineProperty(exports, "__esModule", { value: true });
14
34
  exports.addCommentRequest = addCommentRequest;
15
35
  var endpoints_1 = require("../consts/endpoints");
16
36
  var http_client_1 = require("../transport/http-client");
17
37
  var entities_1 = require("../types/entities");
38
+ var enums_1 = require("../types/enums");
39
+ var SENTINEL_GROUP_IDS = new Set(Object.values(enums_1.NOTIFY_AUDIENCE_GROUP_IDS));
40
+ function isNotifyAudience(value) {
41
+ return typeof value === 'string' && enums_1.NOTIFY_AUDIENCES.includes(value);
42
+ }
43
+ function applyNotifyAudience(params) {
44
+ if (params.groups) {
45
+ var offending = params.groups.filter(function (id) { return SENTINEL_GROUP_IDS.has(id); });
46
+ if (offending.length > 0) {
47
+ throw new Error("`groups` must not contain reserved sentinel IDs (".concat(offending.join(', '), "). Use `notifyAudience` instead."));
48
+ }
49
+ }
50
+ if (params.notifyAudience == null)
51
+ return params;
52
+ if (!isNotifyAudience(params.notifyAudience)) {
53
+ throw new Error("Invalid `notifyAudience` value \"".concat(String(params.notifyAudience), "\". Expected one of: ").concat(enums_1.NOTIFY_AUDIENCES.join(', '), "."));
54
+ }
55
+ var sentinel = enums_1.NOTIFY_AUDIENCE_GROUP_IDS[params.notifyAudience];
56
+ var _stripped = params.notifyAudience, groups = params.groups, rest = __rest(params, ["notifyAudience", "groups"]);
57
+ return __assign(__assign({}, rest), { groups: __spreadArray(__spreadArray([], (groups !== null && groups !== void 0 ? groups : []), true), [sentinel], false) });
58
+ }
18
59
  function addCommentRequest(context, params, options) {
19
60
  var method = 'POST';
20
61
  var url = "".concat(endpoints_1.ENDPOINT_COMMENTS, "/add");
62
+ var normalized = applyNotifyAudience(params);
21
63
  var payload = (options === null || options === void 0 ? void 0 : options.threadAction)
22
- ? __assign(__assign({}, params), { threadAction: options.threadAction }) : params;
64
+ ? __assign(__assign({}, normalized), { threadAction: options.threadAction }) : normalized;
23
65
  var schema = entities_1.CommentSchema;
24
66
  if (options === null || options === void 0 ? void 0 : options.batch) {
25
67
  return { method: method, url: url, params: payload, schema: schema };
@@ -68,9 +68,19 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
68
68
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
69
69
  }
70
70
  };
71
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
72
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
73
+ if (ar || !(i in from)) {
74
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
75
+ ar[i] = from[i];
76
+ }
77
+ }
78
+ return to.concat(ar || Array.prototype.slice.call(from));
79
+ };
71
80
  Object.defineProperty(exports, "__esModule", { value: true });
72
81
  exports.getDefaultDispatcher = getDefaultDispatcher;
73
82
  exports.resetDefaultDispatcherForTests = resetDefaultDispatcherForTests;
83
+ exports.suppressExperimentalWarningsSync = suppressExperimentalWarningsSync;
74
84
  // Use effectively-disabled keep-alive so short-lived CLI processes do not stay
75
85
  // open waiting on idle sockets. Undici requires positive values, so we use 1ms.
76
86
  var keepAliveOptions = {
@@ -111,18 +121,61 @@ function isNodeEnvironment() {
111
121
  }
112
122
  function createDefaultDispatcher() {
113
123
  return __awaiter(this, void 0, void 0, function () {
114
- var EnvHttpProxyAgent;
115
- return __generator(this, function (_a) {
116
- switch (_a.label) {
124
+ var _a, EnvHttpProxyAgent, interceptors, decompress;
125
+ return __generator(this, function (_b) {
126
+ switch (_b.label) {
117
127
  case 0:
118
128
  if (!isNodeEnvironment()) {
119
129
  return [2 /*return*/, undefined];
120
130
  }
121
131
  return [4 /*yield*/, Promise.resolve().then(function () { return __importStar(require('undici')); })];
122
132
  case 1:
123
- EnvHttpProxyAgent = (_a.sent()).EnvHttpProxyAgent;
124
- return [2 /*return*/, new EnvHttpProxyAgent(keepAliveOptions)];
133
+ _a = _b.sent(), EnvHttpProxyAgent = _a.EnvHttpProxyAgent, interceptors = _a.interceptors;
134
+ decompress = suppressExperimentalWarningsSync(function () { return interceptors.decompress(); });
135
+ return [2 /*return*/, new EnvHttpProxyAgent(keepAliveOptions).compose(decompress)];
125
136
  }
126
137
  });
127
138
  });
128
139
  }
140
+ // undici emits an `ExperimentalWarning` the first time `interceptors.decompress()`
141
+ // runs. The interceptor is stable for our gzipped-JSON-over-HTTPS use case;
142
+ // silence the warning during dispatcher init only so it does not leak to every
143
+ // consumer's stderr on the first request.
144
+ //
145
+ // `fn` must be synchronous so the override covers a single critical section
146
+ // (microseconds) — no unrelated `ExperimentalWarning` from elsewhere can
147
+ // interleave and be lost. We suppress every `ExperimentalWarning` rather than
148
+ // pattern-matching the message text: the message wording is an undici
149
+ // implementation detail (not a stable API), and the suppression window is
150
+ // narrow enough that a coarse type filter is safe.
151
+ //
152
+ // Exported for direct unit testing — the integration path through
153
+ // `getDefaultDispatcher()` cannot reliably exercise the helper because both
154
+ // the dispatcher singleton and undici's internal `warningEmitted` flag are
155
+ // once-per-process.
156
+ function suppressExperimentalWarningsSync(fn) {
157
+ var originalEmit = process.emitWarning;
158
+ process.emitWarning = (function (warning, typeOrOptions) {
159
+ var _a;
160
+ var rest = [];
161
+ for (var _i = 2; _i < arguments.length; _i++) {
162
+ rest[_i - 2] = arguments[_i];
163
+ }
164
+ var type = typeof typeOrOptions === 'string'
165
+ ? typeOrOptions
166
+ : typeof typeOrOptions === 'object' && typeOrOptions !== null
167
+ ? typeOrOptions.type
168
+ : undefined;
169
+ if (type === 'ExperimentalWarning')
170
+ return;
171
+ (_a = originalEmit).call.apply(_a, __spreadArray([process,
172
+ warning,
173
+ typeOrOptions], rest, false));
174
+ });
175
+ try {
176
+ return fn();
177
+ }
178
+ finally {
179
+ process.emitWarning = originalEmit;
180
+ }
181
+ }
@@ -1,7 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WORKSPACE_PLANS = exports.USER_TYPES = void 0;
3
+ exports.NOTIFY_AUDIENCE_GROUP_IDS = exports.NOTIFY_AUDIENCES = exports.WORKSPACE_PLANS = exports.USER_TYPES = void 0;
4
4
  // User types for workspace users
5
5
  exports.USER_TYPES = ['USER', 'GUEST', 'ADMIN'];
6
6
  // Workspace plans
7
7
  exports.WORKSPACE_PLANS = ['free', 'unlimited'];
8
+ // Audiences that comment-creating endpoints can target alongside (or instead
9
+ // of) individual `recipients` / custom `groups`.
10
+ exports.NOTIFY_AUDIENCES = ['channel', 'thread'];
11
+ /**
12
+ * Internal mapping from {@link NotifyAudience} to the magic group IDs that
13
+ * Twist's `comments/add` endpoint uses on the wire. Exposed here so the
14
+ * audience constants and their encoding stay in a single source of truth;
15
+ * SDK consumers should use {@link NotifyAudience} via `notifyAudience` on the
16
+ * request args rather than passing these IDs directly.
17
+ */
18
+ exports.NOTIFY_AUDIENCE_GROUP_IDS = {
19
+ channel: 1,
20
+ thread: 2,
21
+ };
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.THREAD_ACTIONS = exports.ARCHIVE_FILTER_VALUES = exports.AWAY_MODE_TYPES = exports.GetOrCreateConversationArgsSchema = exports.GetConversationsArgsSchema = exports.GetCommentsArgsSchema = exports.GetThreadsArgsSchema = exports.GetChannelsArgsSchema = exports.CreateMessageArgsSchema = exports.CreateConversationArgsSchema = exports.UpdateCommentArgsSchema = exports.CreateCommentArgsSchema = exports.UpdateThreadArgsSchema = exports.CreateThreadArgsSchema = exports.UpdateChannelArgsSchema = exports.CreateChannelArgsSchema = void 0;
4
4
  var zod_1 = require("zod");
5
+ var enums_1 = require("./enums");
5
6
  exports.CreateChannelArgsSchema = zod_1.z.object({
6
7
  workspaceId: zod_1.z.number(),
7
8
  name: zod_1.z.string(),
@@ -46,6 +47,9 @@ exports.CreateCommentArgsSchema = zod_1.z.object({
46
47
  attachments: zod_1.z.unknown().nullable().optional(),
47
48
  actions: zod_1.z.unknown().nullable().optional(),
48
49
  recipients: zod_1.z.array(zod_1.z.number()).nullable().optional(),
50
+ groups: zod_1.z.array(zod_1.z.number()).nullable().optional(),
51
+ directMentions: zod_1.z.array(zod_1.z.number()).nullable().optional(),
52
+ notifyAudience: zod_1.z.enum(enums_1.NOTIFY_AUDIENCES).nullable().optional(),
49
53
  });
50
54
  exports.UpdateCommentArgsSchema = zod_1.z.object({
51
55
  id: zod_1.z.number(),
@@ -9,14 +9,56 @@ var __assign = (this && this.__assign) || function () {
9
9
  };
10
10
  return __assign.apply(this, arguments);
11
11
  };
12
+ var __rest = (this && this.__rest) || function (s, e) {
13
+ var t = {};
14
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
15
+ t[p] = s[p];
16
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
17
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
18
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
19
+ t[p[i]] = s[p[i]];
20
+ }
21
+ return t;
22
+ };
23
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
24
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
25
+ if (ar || !(i in from)) {
26
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
27
+ ar[i] = from[i];
28
+ }
29
+ }
30
+ return to.concat(ar || Array.prototype.slice.call(from));
31
+ };
12
32
  import { ENDPOINT_COMMENTS } from '../consts/endpoints.js';
13
33
  import { request } from '../transport/http-client.js';
14
34
  import { CommentSchema } from '../types/entities.js';
35
+ import { NOTIFY_AUDIENCE_GROUP_IDS, NOTIFY_AUDIENCES } from '../types/enums.js';
36
+ var SENTINEL_GROUP_IDS = new Set(Object.values(NOTIFY_AUDIENCE_GROUP_IDS));
37
+ function isNotifyAudience(value) {
38
+ return typeof value === 'string' && NOTIFY_AUDIENCES.includes(value);
39
+ }
40
+ function applyNotifyAudience(params) {
41
+ if (params.groups) {
42
+ var offending = params.groups.filter(function (id) { return SENTINEL_GROUP_IDS.has(id); });
43
+ if (offending.length > 0) {
44
+ throw new Error("`groups` must not contain reserved sentinel IDs (".concat(offending.join(', '), "). Use `notifyAudience` instead."));
45
+ }
46
+ }
47
+ if (params.notifyAudience == null)
48
+ return params;
49
+ if (!isNotifyAudience(params.notifyAudience)) {
50
+ throw new Error("Invalid `notifyAudience` value \"".concat(String(params.notifyAudience), "\". Expected one of: ").concat(NOTIFY_AUDIENCES.join(', '), "."));
51
+ }
52
+ var sentinel = NOTIFY_AUDIENCE_GROUP_IDS[params.notifyAudience];
53
+ var _stripped = params.notifyAudience, groups = params.groups, rest = __rest(params, ["notifyAudience", "groups"]);
54
+ return __assign(__assign({}, rest), { groups: __spreadArray(__spreadArray([], (groups !== null && groups !== void 0 ? groups : []), true), [sentinel], false) });
55
+ }
15
56
  export function addCommentRequest(context, params, options) {
16
57
  var method = 'POST';
17
58
  var url = "".concat(ENDPOINT_COMMENTS, "/add");
59
+ var normalized = applyNotifyAudience(params);
18
60
  var payload = (options === null || options === void 0 ? void 0 : options.threadAction)
19
- ? __assign(__assign({}, params), { threadAction: options.threadAction }) : params;
61
+ ? __assign(__assign({}, normalized), { threadAction: options.threadAction }) : normalized;
20
62
  var schema = CommentSchema;
21
63
  if (options === null || options === void 0 ? void 0 : options.batch) {
22
64
  return { method: method, url: url, params: payload, schema: schema };
@@ -34,6 +34,15 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
34
34
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
35
  }
36
36
  };
37
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
38
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
39
+ if (ar || !(i in from)) {
40
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
41
+ ar[i] = from[i];
42
+ }
43
+ }
44
+ return to.concat(ar || Array.prototype.slice.call(from));
45
+ };
37
46
  // Use effectively-disabled keep-alive so short-lived CLI processes do not stay
38
47
  // open waiting on idle sockets. Undici requires positive values, so we use 1ms.
39
48
  var keepAliveOptions = {
@@ -74,18 +83,68 @@ function isNodeEnvironment() {
74
83
  }
75
84
  function createDefaultDispatcher() {
76
85
  return __awaiter(this, void 0, void 0, function () {
77
- var EnvHttpProxyAgent;
78
- return __generator(this, function (_a) {
79
- switch (_a.label) {
86
+ var _a, EnvHttpProxyAgent, interceptors, decompress;
87
+ return __generator(this, function (_b) {
88
+ switch (_b.label) {
80
89
  case 0:
81
90
  if (!isNodeEnvironment()) {
82
91
  return [2 /*return*/, undefined];
83
92
  }
84
- return [4 /*yield*/, import('undici')];
93
+ return [4 /*yield*/, import('undici')
94
+ // Compose the response-decompression interceptor so gzip/deflate/br/zstd
95
+ // bodies are decoded before consumers parse them. Required on Node 24+:
96
+ // attaching any custom dispatcher to the global `fetch` strips the
97
+ // `content-encoding` header but does not actually decompress the body,
98
+ // so callers receive raw gzipped bytes and `JSON.parse` fails.
99
+ // See https://github.com/Doist/todoist-cli/issues/318.
100
+ ];
85
101
  case 1:
86
- EnvHttpProxyAgent = (_a.sent()).EnvHttpProxyAgent;
87
- return [2 /*return*/, new EnvHttpProxyAgent(keepAliveOptions)];
102
+ _a = _b.sent(), EnvHttpProxyAgent = _a.EnvHttpProxyAgent, interceptors = _a.interceptors;
103
+ decompress = suppressExperimentalWarningsSync(function () { return interceptors.decompress(); });
104
+ return [2 /*return*/, new EnvHttpProxyAgent(keepAliveOptions).compose(decompress)];
88
105
  }
89
106
  });
90
107
  });
91
108
  }
109
+ // undici emits an `ExperimentalWarning` the first time `interceptors.decompress()`
110
+ // runs. The interceptor is stable for our gzipped-JSON-over-HTTPS use case;
111
+ // silence the warning during dispatcher init only so it does not leak to every
112
+ // consumer's stderr on the first request.
113
+ //
114
+ // `fn` must be synchronous so the override covers a single critical section
115
+ // (microseconds) — no unrelated `ExperimentalWarning` from elsewhere can
116
+ // interleave and be lost. We suppress every `ExperimentalWarning` rather than
117
+ // pattern-matching the message text: the message wording is an undici
118
+ // implementation detail (not a stable API), and the suppression window is
119
+ // narrow enough that a coarse type filter is safe.
120
+ //
121
+ // Exported for direct unit testing — the integration path through
122
+ // `getDefaultDispatcher()` cannot reliably exercise the helper because both
123
+ // the dispatcher singleton and undici's internal `warningEmitted` flag are
124
+ // once-per-process.
125
+ export function suppressExperimentalWarningsSync(fn) {
126
+ var originalEmit = process.emitWarning;
127
+ process.emitWarning = (function (warning, typeOrOptions) {
128
+ var _a;
129
+ var rest = [];
130
+ for (var _i = 2; _i < arguments.length; _i++) {
131
+ rest[_i - 2] = arguments[_i];
132
+ }
133
+ var type = typeof typeOrOptions === 'string'
134
+ ? typeOrOptions
135
+ : typeof typeOrOptions === 'object' && typeOrOptions !== null
136
+ ? typeOrOptions.type
137
+ : undefined;
138
+ if (type === 'ExperimentalWarning')
139
+ return;
140
+ (_a = originalEmit).call.apply(_a, __spreadArray([process,
141
+ warning,
142
+ typeOrOptions], rest, false));
143
+ });
144
+ try {
145
+ return fn();
146
+ }
147
+ finally {
148
+ process.emitWarning = originalEmit;
149
+ }
150
+ }
@@ -2,3 +2,17 @@
2
2
  export var USER_TYPES = ['USER', 'GUEST', 'ADMIN'];
3
3
  // Workspace plans
4
4
  export var WORKSPACE_PLANS = ['free', 'unlimited'];
5
+ // Audiences that comment-creating endpoints can target alongside (or instead
6
+ // of) individual `recipients` / custom `groups`.
7
+ export var NOTIFY_AUDIENCES = ['channel', 'thread'];
8
+ /**
9
+ * Internal mapping from {@link NotifyAudience} to the magic group IDs that
10
+ * Twist's `comments/add` endpoint uses on the wire. Exposed here so the
11
+ * audience constants and their encoding stay in a single source of truth;
12
+ * SDK consumers should use {@link NotifyAudience} via `notifyAudience` on the
13
+ * request args rather than passing these IDs directly.
14
+ */
15
+ export var NOTIFY_AUDIENCE_GROUP_IDS = {
16
+ channel: 1,
17
+ thread: 2,
18
+ };
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { NOTIFY_AUDIENCES } from './enums.js';
2
3
  export var CreateChannelArgsSchema = z.object({
3
4
  workspaceId: z.number(),
4
5
  name: z.string(),
@@ -43,6 +44,9 @@ export var CreateCommentArgsSchema = z.object({
43
44
  attachments: z.unknown().nullable().optional(),
44
45
  actions: z.unknown().nullable().optional(),
45
46
  recipients: z.array(z.number()).nullable().optional(),
47
+ groups: z.array(z.number()).nullable().optional(),
48
+ directMentions: z.array(z.number()).nullable().optional(),
49
+ notifyAudience: z.enum(NOTIFY_AUDIENCES).nullable().optional(),
46
50
  });
47
51
  export var UpdateCommentArgsSchema = z.object({
48
52
  id: z.number(),
@@ -1,13 +1,13 @@
1
1
  import type { BatchRequestDescriptor } from '../types/batch.js';
2
2
  import { type Comment } from '../types/entities.js';
3
3
  import type { CustomFetch } from '../types/http.js';
4
- import type { ThreadAction } from '../types/requests.js';
4
+ import type { CreateCommentArgs, ThreadAction } from '../types/requests.js';
5
5
  type ClientContext = {
6
6
  baseUri: string;
7
7
  apiToken: string;
8
8
  customFetch?: CustomFetch;
9
9
  };
10
- export declare function addCommentRequest(context: ClientContext, params: Record<string, unknown>, options?: {
10
+ export declare function addCommentRequest(context: ClientContext, params: CreateCommentArgs, options?: {
11
11
  batch?: boolean;
12
12
  threadAction?: ThreadAction;
13
13
  }): Promise<Comment> | BatchRequestDescriptor<Comment>;
@@ -52,7 +52,13 @@ export declare class CommentsClient extends BaseClient {
52
52
  * @param args - The arguments for creating a comment.
53
53
  * @param args.threadId - The thread ID.
54
54
  * @param args.content - The comment content.
55
- * @param args.recipients - Optional array of user IDs to notify.
55
+ * @param args.recipients - Optional array of user IDs to notify directly.
56
+ * @param args.groups - Optional array of custom group IDs to notify.
57
+ * @param args.directMentions - Optional array of user IDs that were @-mentioned in
58
+ * `content`.
59
+ * @param args.notifyAudience - Optional broader audience to notify in addition to
60
+ * `recipients` and `groups`. `'channel'` notifies everyone in the channel;
61
+ * `'thread'` notifies everyone who has interacted with the thread.
56
62
  * @param args.attachments - Optional array of attachment objects.
57
63
  * @param args.sendAsIntegration - Optional flag to send as integration.
58
64
  * @param options - Optional configuration. Set `batch: true` to return a descriptor for batch requests.
@@ -60,9 +66,12 @@ export declare class CommentsClient extends BaseClient {
60
66
  *
61
67
  * @example
62
68
  * ```typescript
69
+ * // Notify everyone who has interacted with the thread, plus two extra users.
63
70
  * const comment = await api.comments.createComment({
64
71
  * threadId: 789,
65
- * content: 'Great idea! Let\'s proceed with this approach.'
72
+ * content: 'Great idea! Let\'s proceed.',
73
+ * notifyAudience: 'thread',
74
+ * recipients: [12345, 67890],
66
75
  * })
67
76
  * ```
68
77
  */
@@ -330,7 +330,13 @@ export declare class ThreadsClient extends BaseClient {
330
330
  * @param args.tempId - Optional temporary identifier.
331
331
  * @param args.attachments - Optional array of attachment objects.
332
332
  * @param args.actions - Optional array of action objects.
333
- * @param args.recipients - Optional array of user IDs to notify.
333
+ * @param args.recipients - Optional array of user IDs to notify directly.
334
+ * @param args.groups - Optional array of custom group IDs to notify.
335
+ * @param args.directMentions - Optional array of user IDs that were @-mentioned in
336
+ * `content`.
337
+ * @param args.notifyAudience - Optional broader audience to notify in addition to
338
+ * `recipients` and `groups`. `'channel'` notifies everyone in the channel;
339
+ * `'thread'` notifies everyone who has interacted with the thread.
334
340
  * @param options - Optional configuration. Set `batch: true` to return a descriptor for batch requests.
335
341
  * @returns The created comment object.
336
342
  *
@@ -357,7 +363,13 @@ export declare class ThreadsClient extends BaseClient {
357
363
  * @param args.tempId - Optional temporary identifier.
358
364
  * @param args.attachments - Optional array of attachment objects.
359
365
  * @param args.actions - Optional array of action objects.
360
- * @param args.recipients - Optional array of user IDs to notify.
366
+ * @param args.recipients - Optional array of user IDs to notify directly.
367
+ * @param args.groups - Optional array of custom group IDs to notify.
368
+ * @param args.directMentions - Optional array of user IDs that were @-mentioned in
369
+ * `content`.
370
+ * @param args.notifyAudience - Optional broader audience to notify in addition to
371
+ * `recipients` and `groups`. `'channel'` notifies everyone in the channel;
372
+ * `'thread'` notifies everyone who has interacted with the thread.
361
373
  * @param options - Optional configuration. Set `batch: true` to return a descriptor for batch requests.
362
374
  * @returns The created comment object.
363
375
  *
@@ -1,3 +1,4 @@
1
1
  import type { Dispatcher } from 'undici';
2
2
  export declare function getDefaultDispatcher(): Promise<Dispatcher | undefined>;
3
3
  export declare function resetDefaultDispatcherForTests(): void;
4
+ export declare function suppressExperimentalWarningsSync<T>(fn: () => T): T;
@@ -19,3 +19,22 @@ export declare const WORKSPACE_PLANS: readonly ["free", "unlimited"];
19
19
  * - `'unlimited'` - Unlimited plan
20
20
  */
21
21
  export type WorkspacePlan = (typeof WORKSPACE_PLANS)[number];
22
+ export declare const NOTIFY_AUDIENCES: readonly ["channel", "thread"];
23
+ /**
24
+ * The audience to notify when posting a comment, in addition to any
25
+ * individual `recipients` or custom `groups`.
26
+ *
27
+ * @remarks
28
+ * Possible values:
29
+ * - `'channel'` - Notify everyone in the channel.
30
+ * - `'thread'` - Notify everyone who has interacted with the thread.
31
+ */
32
+ export type NotifyAudience = (typeof NOTIFY_AUDIENCES)[number];
33
+ /**
34
+ * Internal mapping from {@link NotifyAudience} to the magic group IDs that
35
+ * Twist's `comments/add` endpoint uses on the wire. Exposed here so the
36
+ * audience constants and their encoding stay in a single source of truth;
37
+ * SDK consumers should use {@link NotifyAudience} via `notifyAudience` on the
38
+ * request args rather than passing these IDs directly.
39
+ */
40
+ export declare const NOTIFY_AUDIENCE_GROUP_IDS: Readonly<Record<NotifyAudience, number>>;
@@ -47,6 +47,12 @@ export declare const CreateCommentArgsSchema: z.ZodObject<{
47
47
  attachments: z.ZodOptional<z.ZodNullable<z.ZodUnknown>>;
48
48
  actions: z.ZodOptional<z.ZodNullable<z.ZodUnknown>>;
49
49
  recipients: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodNumber>>>;
50
+ groups: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodNumber>>>;
51
+ directMentions: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodNumber>>>;
52
+ notifyAudience: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
53
+ channel: "channel";
54
+ thread: "thread";
55
+ }>>>;
50
56
  }, z.core.$strip>;
51
57
  export type CreateCommentArgs = z.infer<typeof CreateCommentArgsSchema>;
52
58
  export declare const UpdateCommentArgsSchema: z.ZodObject<{
@@ -234,22 +240,16 @@ export type RemoveChannelUsersArgs = {
234
240
  };
235
241
  export declare const THREAD_ACTIONS: readonly ["close", "reopen"];
236
242
  export type ThreadAction = (typeof THREAD_ACTIONS)[number];
237
- export type CloseThreadArgs = {
243
+ /**
244
+ * Shared shape for endpoints that post a comment as part of a thread action
245
+ * (close, reopen). Identical to {@link CreateCommentArgs} except the target
246
+ * is identified by `id` (the thread ID) instead of `threadId`.
247
+ */
248
+ type ThreadActionCommentArgs = Omit<CreateCommentArgs, 'threadId'> & {
238
249
  id: number;
239
- content: string;
240
- tempId?: number | null;
241
- attachments?: unknown | null;
242
- actions?: unknown | null;
243
- recipients?: number[] | null;
244
- };
245
- export type ReopenThreadArgs = {
246
- id: number;
247
- content: string;
248
- tempId?: number | null;
249
- attachments?: unknown | null;
250
- actions?: unknown | null;
251
- recipients?: number[] | null;
252
250
  };
251
+ export type CloseThreadArgs = ThreadActionCommentArgs;
252
+ export type ReopenThreadArgs = ThreadActionCommentArgs;
253
253
  export type MoveThreadToChannelArgs = {
254
254
  id: number;
255
255
  toChannel: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doist/twist-sdk",
3
- "version": "2.5.0",
3
+ "version": "2.6.0",
4
4
  "description": "A TypeScript wrapper for the Twist REST API.",
5
5
  "author": "Doist developers",
6
6
  "homepage": "https://doist.github.io/twist-sdk-typescript/",