@doist/twist-sdk 2.7.0 → 2.9.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.
- package/dist/cjs/clients/add-comment-helper.js +1 -2
- package/dist/cjs/clients/attachments-client.js +124 -0
- package/dist/cjs/clients/base-client.js +10 -0
- package/dist/cjs/clients/channels-client.js +9 -6
- package/dist/cjs/clients/comments-client.js +16 -6
- package/dist/cjs/clients/conversation-messages-client.js +9 -8
- package/dist/cjs/clients/conversations-client.js +11 -8
- package/dist/cjs/clients/inbox-client.js +6 -3
- package/dist/cjs/clients/threads-client.js +18 -9
- package/dist/cjs/clients/workspace-users-client.js +9 -2
- package/dist/cjs/clients/workspaces-client.js +7 -3
- package/dist/cjs/consts/endpoints.js +2 -1
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/twist-api.js +2 -0
- package/dist/cjs/types/entities.js +99 -79
- package/dist/cjs/utils/multipart-upload.js +154 -0
- package/dist/esm/clients/add-comment-helper.js +1 -2
- package/dist/esm/clients/attachments-client.js +121 -0
- package/dist/esm/clients/base-client.js +10 -0
- package/dist/esm/clients/channels-client.js +10 -7
- package/dist/esm/clients/comments-client.js +17 -7
- package/dist/esm/clients/conversation-messages-client.js +10 -9
- package/dist/esm/clients/conversations-client.js +12 -9
- package/dist/esm/clients/inbox-client.js +7 -4
- package/dist/esm/clients/threads-client.js +19 -10
- package/dist/esm/clients/workspace-users-client.js +9 -2
- package/dist/esm/clients/workspaces-client.js +8 -4
- package/dist/esm/consts/endpoints.js +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/twist-api.js +2 -0
- package/dist/esm/types/entities.js +92 -78
- package/dist/esm/utils/multipart-upload.js +150 -0
- package/dist/types/clients/add-comment-helper.d.ts +3 -1
- package/dist/types/clients/attachments-client.d.ts +39 -0
- package/dist/types/clients/base-client.d.ts +4 -0
- package/dist/types/clients/channels-client.d.ts +1 -0
- package/dist/types/clients/comments-client.d.ts +1 -0
- package/dist/types/clients/conversation-messages-client.d.ts +1 -0
- package/dist/types/clients/conversations-client.d.ts +1 -0
- package/dist/types/clients/inbox-client.d.ts +1 -0
- package/dist/types/clients/threads-client.d.ts +2 -0
- package/dist/types/clients/workspace-users-client.d.ts +5 -0
- package/dist/types/clients/workspaces-client.d.ts +1 -0
- package/dist/types/consts/endpoints.d.ts +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/twist-api.d.ts +2 -0
- package/dist/types/types/entities.d.ts +1539 -185
- package/dist/types/types/requests.d.ts +22 -0
- package/dist/types/utils/multipart-upload.d.ts +53 -0
- package/package.json +6 -2
package/dist/cjs/twist-api.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TwistApi = void 0;
|
|
4
4
|
var batch_builder_1 = require("./batch-builder");
|
|
5
|
+
var attachments_client_1 = require("./clients/attachments-client");
|
|
5
6
|
var channels_client_1 = require("./clients/channels-client");
|
|
6
7
|
var comments_client_1 = require("./clients/comments-client");
|
|
7
8
|
var conversation_messages_client_1 = require("./clients/conversation-messages-client");
|
|
@@ -73,6 +74,7 @@ var TwistApi = /** @class */ (function () {
|
|
|
73
74
|
this.inbox = new inbox_client_1.InboxClient(clientConfig);
|
|
74
75
|
this.reactions = new reactions_client_1.ReactionsClient(clientConfig);
|
|
75
76
|
this.search = new search_client_1.SearchClient(clientConfig);
|
|
77
|
+
this.attachments = new attachments_client_1.AttachmentsClient(clientConfig);
|
|
76
78
|
}
|
|
77
79
|
/**
|
|
78
80
|
* Executes multiple API requests in a single HTTP call using the batch endpoint.
|
|
@@ -11,7 +11,13 @@ var __assign = (this && this.__assign) || function () {
|
|
|
11
11
|
return __assign.apply(this, arguments);
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
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.SystemMessageSchema = void 0;
|
|
14
|
+
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.SystemMessageSchema = void 0;
|
|
15
|
+
exports.createChannelSchema = createChannelSchema;
|
|
16
|
+
exports.createThreadSchema = createThreadSchema;
|
|
17
|
+
exports.createConversationSchema = createConversationSchema;
|
|
18
|
+
exports.createCommentSchema = createCommentSchema;
|
|
19
|
+
exports.createConversationMessageSchema = createConversationMessageSchema;
|
|
20
|
+
exports.createInboxThreadSchema = createInboxThreadSchema;
|
|
15
21
|
var zod_1 = require("zod");
|
|
16
22
|
var url_helpers_1 = require("../utils/url-helpers");
|
|
17
23
|
var enums_1 = require("./enums");
|
|
@@ -112,8 +118,7 @@ exports.WorkspaceSchema = zod_1.z.object({
|
|
|
112
118
|
plan: zod_1.z.enum(enums_1.WORKSPACE_PLANS).nullable().optional(),
|
|
113
119
|
});
|
|
114
120
|
// Channel entity from API
|
|
115
|
-
exports.
|
|
116
|
-
.object({
|
|
121
|
+
exports.ChannelObjectSchema = zod_1.z.object({
|
|
117
122
|
id: zod_1.z.number(),
|
|
118
123
|
name: zod_1.z.string(),
|
|
119
124
|
description: zod_1.z.string().nullable().optional(),
|
|
@@ -131,11 +136,13 @@ exports.ChannelSchema = zod_1.z
|
|
|
131
136
|
icon: zod_1.z.number().nullable().optional(),
|
|
132
137
|
version: zod_1.z.number(),
|
|
133
138
|
filters: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).nullable().optional(),
|
|
134
|
-
})
|
|
135
|
-
|
|
139
|
+
});
|
|
140
|
+
function createChannelSchema(linkBaseUrl) {
|
|
141
|
+
return exports.ChannelObjectSchema.transform(function (data) { return (__assign(__assign({}, data), { url: (0, url_helpers_1.getFullTwistURL)({ workspaceId: data.workspaceId, channelId: data.id }, linkBaseUrl) })); });
|
|
142
|
+
}
|
|
143
|
+
exports.ChannelSchema = createChannelSchema();
|
|
136
144
|
// Thread entity from API
|
|
137
|
-
exports.
|
|
138
|
-
.object({
|
|
145
|
+
exports.ThreadObjectSchema = zod_1.z.object({
|
|
139
146
|
id: zod_1.z.number(),
|
|
140
147
|
title: zod_1.z.string(),
|
|
141
148
|
content: zod_1.z.string(),
|
|
@@ -198,12 +205,15 @@ exports.ThreadSchema = zod_1.z
|
|
|
198
205
|
})
|
|
199
206
|
.nullable()
|
|
200
207
|
.optional(),
|
|
201
|
-
})
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
208
|
+
});
|
|
209
|
+
function createThreadSchema(linkBaseUrl) {
|
|
210
|
+
return exports.ThreadObjectSchema.transform(function (data) { return (__assign(__assign({}, data), { url: (0, url_helpers_1.getFullTwistURL)({
|
|
211
|
+
workspaceId: data.workspaceId,
|
|
212
|
+
channelId: data.channelId,
|
|
213
|
+
threadId: data.id,
|
|
214
|
+
}, linkBaseUrl) })); });
|
|
215
|
+
}
|
|
216
|
+
exports.ThreadSchema = createThreadSchema();
|
|
207
217
|
// Group entity from API
|
|
208
218
|
exports.GroupSchema = zod_1.z.object({
|
|
209
219
|
id: zod_1.z.number(),
|
|
@@ -214,8 +224,7 @@ exports.GroupSchema = zod_1.z.object({
|
|
|
214
224
|
version: zod_1.z.number(),
|
|
215
225
|
});
|
|
216
226
|
// Conversation entity from API
|
|
217
|
-
exports.
|
|
218
|
-
.object({
|
|
227
|
+
exports.ConversationObjectSchema = zod_1.z.object({
|
|
219
228
|
id: zod_1.z.number(),
|
|
220
229
|
workspaceId: zod_1.z.number(),
|
|
221
230
|
userIds: zod_1.z.array(zod_1.z.number()),
|
|
@@ -251,11 +260,13 @@ exports.ConversationSchema = zod_1.z
|
|
|
251
260
|
})
|
|
252
261
|
.nullable()
|
|
253
262
|
.optional(),
|
|
254
|
-
})
|
|
255
|
-
|
|
263
|
+
});
|
|
264
|
+
function createConversationSchema(linkBaseUrl) {
|
|
265
|
+
return exports.ConversationObjectSchema.transform(function (data) { return (__assign(__assign({}, data), { url: (0, url_helpers_1.getFullTwistURL)({ workspaceId: data.workspaceId, conversationId: data.id }, linkBaseUrl) })); });
|
|
266
|
+
}
|
|
267
|
+
exports.ConversationSchema = createConversationSchema();
|
|
256
268
|
// Comment entity from API
|
|
257
|
-
exports.
|
|
258
|
-
.object({
|
|
269
|
+
exports.CommentObjectSchema = zod_1.z.object({
|
|
259
270
|
id: zod_1.z.number(),
|
|
260
271
|
content: zod_1.z.string(),
|
|
261
272
|
creator: zod_1.z.number(),
|
|
@@ -280,13 +291,16 @@ exports.CommentSchema = zod_1.z
|
|
|
280
291
|
deletedBy: zod_1.z.number().nullable().optional(),
|
|
281
292
|
version: zod_1.z.number().nullable().optional(),
|
|
282
293
|
actions: zod_1.z.array(zod_1.z.unknown()).nullable().optional(),
|
|
283
|
-
})
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
294
|
+
});
|
|
295
|
+
function createCommentSchema(linkBaseUrl) {
|
|
296
|
+
return exports.CommentObjectSchema.transform(function (data) { return (__assign(__assign({}, data), { url: (0, url_helpers_1.getFullTwistURL)({
|
|
297
|
+
workspaceId: data.workspaceId,
|
|
298
|
+
channelId: data.channelId,
|
|
299
|
+
threadId: data.threadId,
|
|
300
|
+
commentId: data.id,
|
|
301
|
+
}, linkBaseUrl) })); });
|
|
302
|
+
}
|
|
303
|
+
exports.CommentSchema = createCommentSchema();
|
|
290
304
|
// WorkspaceUser entity from v4 API
|
|
291
305
|
exports.WorkspaceUserSchema = exports.BaseUserSchema.extend({
|
|
292
306
|
email: zod_1.z.string().nullable().optional(),
|
|
@@ -298,8 +312,7 @@ exports.WorkspaceUserSchema = exports.BaseUserSchema.extend({
|
|
|
298
312
|
version: zod_1.z.number(),
|
|
299
313
|
});
|
|
300
314
|
// ConversationMessage entity from API
|
|
301
|
-
exports.
|
|
302
|
-
.object({
|
|
315
|
+
exports.ConversationMessageObjectSchema = zod_1.z.object({
|
|
303
316
|
id: zod_1.z.number(),
|
|
304
317
|
content: zod_1.z.string(),
|
|
305
318
|
creator: zod_1.z.number(),
|
|
@@ -316,58 +329,65 @@ exports.ConversationMessageSchema = zod_1.z
|
|
|
316
329
|
directMentions: zod_1.z.array(zod_1.z.number()).nullable().optional(),
|
|
317
330
|
version: zod_1.z.number().nullable().optional(),
|
|
318
331
|
workspaceId: zod_1.z.number(),
|
|
319
|
-
})
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
332
|
+
});
|
|
333
|
+
function createConversationMessageSchema(linkBaseUrl) {
|
|
334
|
+
return exports.ConversationMessageObjectSchema.transform(function (data) { return (__assign(__assign({}, data), { url: (0, url_helpers_1.getFullTwistURL)({
|
|
335
|
+
workspaceId: data.workspaceId,
|
|
336
|
+
conversationId: data.conversationId,
|
|
337
|
+
messageId: data.id,
|
|
338
|
+
}, linkBaseUrl) })); });
|
|
339
|
+
}
|
|
340
|
+
exports.ConversationMessageSchema = createConversationMessageSchema();
|
|
325
341
|
// InboxThread entity from API - returns full Thread objects with additional inbox metadata
|
|
326
|
-
|
|
327
|
-
.object({
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
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
|
-
|
|
342
|
+
function createInboxThreadObjectSchema(linkBaseUrl) {
|
|
343
|
+
return zod_1.z.object({
|
|
344
|
+
id: zod_1.z.number(),
|
|
345
|
+
title: zod_1.z.string(),
|
|
346
|
+
content: zod_1.z.string(),
|
|
347
|
+
creator: zod_1.z.number(),
|
|
348
|
+
creatorName: zod_1.z.string().nullable().optional(),
|
|
349
|
+
channelId: zod_1.z.number(),
|
|
350
|
+
workspaceId: zod_1.z.number(),
|
|
351
|
+
actions: zod_1.z.array(zod_1.z.unknown()).nullable().optional(),
|
|
352
|
+
attachments: zod_1.z.array(exports.AttachmentSchema).nullable().optional(),
|
|
353
|
+
commentCount: zod_1.z.number(),
|
|
354
|
+
directGroupMentions: zod_1.z.array(zod_1.z.number()).nullable().optional(),
|
|
355
|
+
directMentions: zod_1.z.array(zod_1.z.number()).nullable().optional(),
|
|
356
|
+
groups: zod_1.z.array(zod_1.z.number()).nullable().optional(),
|
|
357
|
+
lastEdited: zod_1.z.date().nullable().optional(),
|
|
358
|
+
lastObjIndex: zod_1.z.number().nullable().optional(),
|
|
359
|
+
lastUpdated: zod_1.z.date(),
|
|
360
|
+
mutedUntil: zod_1.z.date().nullable().optional(),
|
|
361
|
+
participants: zod_1.z.array(zod_1.z.number()).nullable().optional(),
|
|
362
|
+
pinned: zod_1.z.boolean(),
|
|
363
|
+
pinnedDate: zod_1.z.date().nullable().optional(),
|
|
364
|
+
posted: zod_1.z.date(),
|
|
365
|
+
reactions: zod_1.z.record(zod_1.z.string(), zod_1.z.array(zod_1.z.number())).nullable().optional(),
|
|
366
|
+
recipients: zod_1.z.array(zod_1.z.number()).nullable().optional(),
|
|
367
|
+
snippet: zod_1.z.string(),
|
|
368
|
+
snippetCreator: zod_1.z.number(),
|
|
369
|
+
snippetMaskAvatarUrl: zod_1.z.string().nullable().optional(),
|
|
370
|
+
snippetMaskPoster: zod_1.z.string().nullable().optional(),
|
|
371
|
+
starred: zod_1.z.boolean(),
|
|
372
|
+
systemMessage: exports.SystemMessageSchema,
|
|
373
|
+
isArchived: zod_1.z.boolean(),
|
|
374
|
+
inInbox: zod_1.z.boolean(),
|
|
375
|
+
isSaved: zod_1.z.boolean().nullable().optional(),
|
|
376
|
+
closed: zod_1.z.boolean(),
|
|
377
|
+
responders: zod_1.z.array(zod_1.z.number()).nullable().optional(),
|
|
378
|
+
lastComment: createCommentSchema(linkBaseUrl).nullable().optional(),
|
|
379
|
+
toEmails: zod_1.z.array(zod_1.z.string()).nullable().optional(),
|
|
380
|
+
version: zod_1.z.number().nullable().optional(),
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
function createInboxThreadSchema(linkBaseUrl) {
|
|
384
|
+
return createInboxThreadObjectSchema(linkBaseUrl).transform(function (data) { return (__assign(__assign({}, data), { url: (0, url_helpers_1.getFullTwistURL)({
|
|
385
|
+
workspaceId: data.workspaceId,
|
|
386
|
+
channelId: data.channelId,
|
|
387
|
+
threadId: data.id,
|
|
388
|
+
}, linkBaseUrl) })); });
|
|
389
|
+
}
|
|
390
|
+
exports.InboxThreadSchema = createInboxThreadSchema();
|
|
371
391
|
// UnreadThread entity from API - simplified thread reference for unread threads
|
|
372
392
|
exports.UnreadThreadSchema = zod_1.z.object({
|
|
373
393
|
threadId: zod_1.z.number(),
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
24
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
+
function step(op) {
|
|
27
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
29
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
30
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
+
switch (op[0]) {
|
|
32
|
+
case 0: case 1: t = op; break;
|
|
33
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
+
default:
|
|
37
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
+
if (t[2]) _.ops.pop();
|
|
42
|
+
_.trys.pop(); continue;
|
|
43
|
+
}
|
|
44
|
+
op = body.call(thisArg, _);
|
|
45
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.getContentTypeFromFileName = getContentTypeFromFileName;
|
|
51
|
+
exports.uploadMultipartFile = uploadMultipartFile;
|
|
52
|
+
var fetch_with_retry_1 = require("../transport/fetch-with-retry");
|
|
53
|
+
/**
|
|
54
|
+
* Determine a content-type from a filename extension. Falls back to
|
|
55
|
+
* `application/octet-stream` for unknown extensions.
|
|
56
|
+
*/
|
|
57
|
+
function getContentTypeFromFileName(fileName) {
|
|
58
|
+
var extension = fileName.toLowerCase().split('.').pop();
|
|
59
|
+
switch (extension) {
|
|
60
|
+
case 'png':
|
|
61
|
+
return 'image/png';
|
|
62
|
+
case 'jpg':
|
|
63
|
+
case 'jpeg':
|
|
64
|
+
return 'image/jpeg';
|
|
65
|
+
case 'gif':
|
|
66
|
+
return 'image/gif';
|
|
67
|
+
case 'webp':
|
|
68
|
+
return 'image/webp';
|
|
69
|
+
case 'svg':
|
|
70
|
+
return 'image/svg+xml';
|
|
71
|
+
case 'pdf':
|
|
72
|
+
return 'application/pdf';
|
|
73
|
+
default:
|
|
74
|
+
return 'application/octet-stream';
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Normalise a supported {@link UploadFile} into a `Blob` plus a resolved file name and
|
|
79
|
+
* content type, so uploads use the cross-platform global `FormData`/`Blob` body that
|
|
80
|
+
* `undici` and browsers both accept natively.
|
|
81
|
+
*/
|
|
82
|
+
function toBlob(file, fileName, contentType) {
|
|
83
|
+
if (file instanceof Blob) {
|
|
84
|
+
// `File` is not a global in Node 18, so guard the check before using it.
|
|
85
|
+
var name_1 = fileName ||
|
|
86
|
+
(typeof File !== 'undefined' && file instanceof File ? file.name : undefined) ||
|
|
87
|
+
'upload';
|
|
88
|
+
var type = contentType || file.type || getContentTypeFromFileName(name_1);
|
|
89
|
+
// Re-wrap only when stamping a type the Blob doesn't already carry.
|
|
90
|
+
var blob = file.type === type ? file : new Blob([file], { type: type });
|
|
91
|
+
return { blob: blob, fileName: name_1, contentType: type };
|
|
92
|
+
}
|
|
93
|
+
if (file instanceof Uint8Array) {
|
|
94
|
+
if (!fileName) {
|
|
95
|
+
throw new Error('fileName is required when uploading raw bytes');
|
|
96
|
+
}
|
|
97
|
+
var type = contentType || getContentTypeFromFileName(fileName);
|
|
98
|
+
// `Blob` accepts any `ArrayBufferView`; the cast satisfies the stricter lib
|
|
99
|
+
// `BlobPart` type (which pins the backing buffer to `ArrayBuffer`).
|
|
100
|
+
return { blob: new Blob([file], { type: type }), fileName: fileName, contentType: type };
|
|
101
|
+
}
|
|
102
|
+
throw new Error('Unsupported file type for upload: expected a Blob or Uint8Array');
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Upload a file using `multipart/form-data`.
|
|
106
|
+
*
|
|
107
|
+
* Builds the request body with the global `FormData`/`Blob` so it works unchanged in the
|
|
108
|
+
* browser and in Node.js (via `undici`). The `file` part is sent alongside `file_name`,
|
|
109
|
+
* `file_size`, and `underlying_type` fields (the canonical Twist upload shape); any
|
|
110
|
+
* `additionalFields` are merged in and override the derived values. Authentication uses
|
|
111
|
+
* `Authorization: Bearer`, matching every other Twist SDK client, and `Content-Type` is
|
|
112
|
+
* intentionally left unset so the runtime adds the correct multipart boundary.
|
|
113
|
+
*
|
|
114
|
+
* The response is JSON-parsed and camel-cased by {@link fetchWithRetry}; callers validate
|
|
115
|
+
* the returned shape with the appropriate schema.
|
|
116
|
+
*/
|
|
117
|
+
function uploadMultipartFile(args) {
|
|
118
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
119
|
+
var baseUrl, authToken, endpoint, file, fileName, contentType, additionalFields, requestId, customFetch, _a, blob, resolvedFileName, resolvedType, fields, form, _i, _b, _c, key, value, headers, url, response;
|
|
120
|
+
return __generator(this, function (_d) {
|
|
121
|
+
switch (_d.label) {
|
|
122
|
+
case 0:
|
|
123
|
+
baseUrl = args.baseUrl, authToken = args.authToken, endpoint = args.endpoint, file = args.file, fileName = args.fileName, contentType = args.contentType, additionalFields = args.additionalFields, requestId = args.requestId, customFetch = args.customFetch;
|
|
124
|
+
_a = toBlob(file, fileName, contentType), blob = _a.blob, resolvedFileName = _a.fileName, resolvedType = _a.contentType;
|
|
125
|
+
fields = __assign({ file_name: resolvedFileName, file_size: blob.size, underlying_type: resolvedType }, additionalFields);
|
|
126
|
+
form = new FormData();
|
|
127
|
+
form.append('file', blob, resolvedFileName);
|
|
128
|
+
for (_i = 0, _b = Object.entries(fields); _i < _b.length; _i++) {
|
|
129
|
+
_c = _b[_i], key = _c[0], value = _c[1];
|
|
130
|
+
if (value !== undefined && value !== null) {
|
|
131
|
+
form.append(key, String(value));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
headers = {
|
|
135
|
+
Authorization: "Bearer ".concat(authToken),
|
|
136
|
+
};
|
|
137
|
+
if (requestId) {
|
|
138
|
+
headers['X-Request-Id'] = requestId;
|
|
139
|
+
}
|
|
140
|
+
url = new URL(endpoint, baseUrl).toString();
|
|
141
|
+
return [4 /*yield*/, (0, fetch_with_retry_1.fetchWithRetry)(url, {
|
|
142
|
+
method: 'POST',
|
|
143
|
+
headers: headers,
|
|
144
|
+
body: form,
|
|
145
|
+
// Don't set Content-Type — the runtime adds the multipart boundary.
|
|
146
|
+
timeout: 30000,
|
|
147
|
+
}, 3, customFetch)];
|
|
148
|
+
case 1:
|
|
149
|
+
response = _d.sent();
|
|
150
|
+
return [2 /*return*/, response.data];
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
}
|
|
@@ -31,7 +31,6 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
31
31
|
};
|
|
32
32
|
import { ENDPOINT_COMMENTS } from '../consts/endpoints.js';
|
|
33
33
|
import { request } from '../transport/http-client.js';
|
|
34
|
-
import { CommentSchema } from '../types/entities.js';
|
|
35
34
|
import { NOTIFY_AUDIENCE_GROUP_IDS, NOTIFY_AUDIENCES } from '../types/enums.js';
|
|
36
35
|
var SENTINEL_GROUP_IDS = new Set(Object.values(NOTIFY_AUDIENCE_GROUP_IDS));
|
|
37
36
|
function isNotifyAudience(value) {
|
|
@@ -59,7 +58,7 @@ export function addCommentRequest(context, params, options) {
|
|
|
59
58
|
var normalized = applyNotifyAudience(params);
|
|
60
59
|
var payload = (options === null || options === void 0 ? void 0 : options.threadAction)
|
|
61
60
|
? __assign(__assign({}, normalized), { threadAction: options.threadAction }) : normalized;
|
|
62
|
-
var schema =
|
|
61
|
+
var schema = context.schema;
|
|
63
62
|
if (options === null || options === void 0 ? void 0 : options.batch) {
|
|
64
63
|
return { method: method, url: url, params: payload, schema: schema };
|
|
65
64
|
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
var __extends = (this && this.__extends) || (function () {
|
|
2
|
+
var extendStatics = function (d, b) {
|
|
3
|
+
extendStatics = Object.setPrototypeOf ||
|
|
4
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
5
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
6
|
+
return extendStatics(d, b);
|
|
7
|
+
};
|
|
8
|
+
return function (d, b) {
|
|
9
|
+
if (typeof b !== "function" && b !== null)
|
|
10
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
11
|
+
extendStatics(d, b);
|
|
12
|
+
function __() { this.constructor = d; }
|
|
13
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
14
|
+
};
|
|
15
|
+
})();
|
|
16
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
17
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
18
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
19
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
20
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
21
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
22
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
26
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
27
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
28
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
29
|
+
function step(op) {
|
|
30
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
31
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
32
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
33
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
34
|
+
switch (op[0]) {
|
|
35
|
+
case 0: case 1: t = op; break;
|
|
36
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
37
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
38
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
39
|
+
default:
|
|
40
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
41
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
42
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
43
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
44
|
+
if (t[2]) _.ops.pop();
|
|
45
|
+
_.trys.pop(); continue;
|
|
46
|
+
}
|
|
47
|
+
op = body.call(thisArg, _);
|
|
48
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
49
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
import { v4 as uuid } from 'uuid';
|
|
53
|
+
import { ENDPOINT_ATTACHMENTS } from '../consts/endpoints.js';
|
|
54
|
+
import { AttachmentSchema } from '../types/entities.js';
|
|
55
|
+
import { uploadMultipartFile } from '../utils/multipart-upload.js';
|
|
56
|
+
import { BaseClient } from './base-client.js';
|
|
57
|
+
/**
|
|
58
|
+
* Client for uploading file attachments to Twist.
|
|
59
|
+
*
|
|
60
|
+
* Attachments are uploaded independently, then referenced by passing the returned
|
|
61
|
+
* {@link Attachment} into the `attachments` array of `comments.createComment`,
|
|
62
|
+
* `conversationMessages.createMessage`, and similar calls.
|
|
63
|
+
*/
|
|
64
|
+
var AttachmentsClient = /** @class */ (function (_super) {
|
|
65
|
+
__extends(AttachmentsClient, _super);
|
|
66
|
+
function AttachmentsClient() {
|
|
67
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Uploads a file and returns the created {@link Attachment}.
|
|
71
|
+
*
|
|
72
|
+
* Mirrors the canonical multipart upload used by twist-web: `POST /attachments/upload`
|
|
73
|
+
* with the `file` binary plus `file_name`, `file_size`, `attachment_id`, and
|
|
74
|
+
* `underlying_type` form fields.
|
|
75
|
+
*
|
|
76
|
+
* @param args - The file to upload and optional metadata.
|
|
77
|
+
* @returns The created attachment, ready to attach to a comment or message.
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* import { readFile } from 'node:fs/promises'
|
|
82
|
+
*
|
|
83
|
+
* const attachment = await api.attachments.upload({
|
|
84
|
+
* file: await readFile('./diagram.png'),
|
|
85
|
+
* fileName: 'diagram.png',
|
|
86
|
+
* })
|
|
87
|
+
*
|
|
88
|
+
* await api.comments.createComment({
|
|
89
|
+
* threadId: 789,
|
|
90
|
+
* content: 'See attached',
|
|
91
|
+
* attachments: [attachment],
|
|
92
|
+
* })
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
AttachmentsClient.prototype.upload = function (args) {
|
|
96
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
97
|
+
var data;
|
|
98
|
+
return __generator(this, function (_a) {
|
|
99
|
+
switch (_a.label) {
|
|
100
|
+
case 0: return [4 /*yield*/, uploadMultipartFile({
|
|
101
|
+
baseUrl: this.getBaseUri(),
|
|
102
|
+
authToken: this.apiToken,
|
|
103
|
+
endpoint: "".concat(ENDPOINT_ATTACHMENTS, "/upload"),
|
|
104
|
+
file: args.file,
|
|
105
|
+
fileName: args.fileName,
|
|
106
|
+
contentType: args.contentType,
|
|
107
|
+
additionalFields: {
|
|
108
|
+
attachment_id: args.attachmentId || uuid(),
|
|
109
|
+
},
|
|
110
|
+
customFetch: this.customFetch,
|
|
111
|
+
})];
|
|
112
|
+
case 1:
|
|
113
|
+
data = _a.sent();
|
|
114
|
+
return [2 /*return*/, AttachmentSchema.parse(data)];
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
return AttachmentsClient;
|
|
120
|
+
}(BaseClient));
|
|
121
|
+
export { AttachmentsClient };
|
|
@@ -28,6 +28,16 @@ var BaseClient = /** @class */ (function () {
|
|
|
28
28
|
// Use centralized helper function for default Twist API URL
|
|
29
29
|
return getTwistBaseUri(apiVersion);
|
|
30
30
|
};
|
|
31
|
+
/**
|
|
32
|
+
* Base URL for entity web links, or `undefined` to use getFullTwistURL's default web app.
|
|
33
|
+
*/
|
|
34
|
+
BaseClient.prototype.getLinkBaseUrl = function () {
|
|
35
|
+
if (!this.baseUrl) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
// Strip a trailing slash so links don't double up, since entity paths start with '/'.
|
|
39
|
+
return this.baseUrl.endsWith('/') ? this.baseUrl.slice(0, -1) : this.baseUrl;
|
|
40
|
+
};
|
|
31
41
|
return BaseClient;
|
|
32
42
|
}());
|
|
33
43
|
export { BaseClient };
|
|
@@ -16,7 +16,7 @@ var __extends = (this && this.__extends) || (function () {
|
|
|
16
16
|
import { z } from 'zod';
|
|
17
17
|
import { ENDPOINT_CHANNELS } from '../consts/endpoints.js';
|
|
18
18
|
import { request } from '../transport/http-client.js';
|
|
19
|
-
import {
|
|
19
|
+
import { createChannelSchema } from '../types/entities.js';
|
|
20
20
|
import { BaseClient } from './base-client.js';
|
|
21
21
|
/**
|
|
22
22
|
* Client for interacting with Twist channel endpoints.
|
|
@@ -24,14 +24,17 @@ import { BaseClient } from './base-client.js';
|
|
|
24
24
|
var ChannelsClient = /** @class */ (function (_super) {
|
|
25
25
|
__extends(ChannelsClient, _super);
|
|
26
26
|
function ChannelsClient() {
|
|
27
|
-
|
|
27
|
+
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
28
|
+
_this.channelSchema = createChannelSchema(_this.getLinkBaseUrl());
|
|
29
|
+
return _this;
|
|
28
30
|
}
|
|
29
31
|
ChannelsClient.prototype.getChannels = function (args, options) {
|
|
32
|
+
var _this = this;
|
|
30
33
|
var method = 'GET';
|
|
31
34
|
var url = "".concat(ENDPOINT_CHANNELS, "/get");
|
|
32
35
|
var params = args;
|
|
33
36
|
if (options === null || options === void 0 ? void 0 : options.batch) {
|
|
34
|
-
return { method: method, url: url, params: params, schema: z.array(
|
|
37
|
+
return { method: method, url: url, params: params, schema: z.array(this.channelSchema) };
|
|
35
38
|
}
|
|
36
39
|
return request({
|
|
37
40
|
httpMethod: method,
|
|
@@ -40,13 +43,13 @@ var ChannelsClient = /** @class */ (function (_super) {
|
|
|
40
43
|
apiToken: this.apiToken,
|
|
41
44
|
payload: params,
|
|
42
45
|
customFetch: this.customFetch,
|
|
43
|
-
}).then(function (response) { return response.data.map(function (channel) { return
|
|
46
|
+
}).then(function (response) { return response.data.map(function (channel) { return _this.channelSchema.parse(channel); }); });
|
|
44
47
|
};
|
|
45
48
|
ChannelsClient.prototype.getChannel = function (id, options) {
|
|
46
49
|
var method = 'GET';
|
|
47
50
|
var url = "".concat(ENDPOINT_CHANNELS, "/getone");
|
|
48
51
|
var params = { id: id };
|
|
49
|
-
var schema =
|
|
52
|
+
var schema = this.channelSchema;
|
|
50
53
|
if (options === null || options === void 0 ? void 0 : options.batch) {
|
|
51
54
|
return { method: method, url: url, params: params, schema: schema };
|
|
52
55
|
}
|
|
@@ -63,7 +66,7 @@ var ChannelsClient = /** @class */ (function (_super) {
|
|
|
63
66
|
var method = 'POST';
|
|
64
67
|
var url = "".concat(ENDPOINT_CHANNELS, "/add");
|
|
65
68
|
var params = args;
|
|
66
|
-
var schema =
|
|
69
|
+
var schema = this.channelSchema;
|
|
67
70
|
if (options === null || options === void 0 ? void 0 : options.batch) {
|
|
68
71
|
return { method: method, url: url, params: params, schema: schema };
|
|
69
72
|
}
|
|
@@ -80,7 +83,7 @@ var ChannelsClient = /** @class */ (function (_super) {
|
|
|
80
83
|
var method = 'POST';
|
|
81
84
|
var url = "".concat(ENDPOINT_CHANNELS, "/update");
|
|
82
85
|
var params = args;
|
|
83
|
-
var schema =
|
|
86
|
+
var schema = this.channelSchema;
|
|
84
87
|
if (options === null || options === void 0 ? void 0 : options.batch) {
|
|
85
88
|
return { method: method, url: url, params: params, schema: schema };
|
|
86
89
|
}
|