@unboundcx/sdk 4.0.6 → 4.0.7
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/base.js +0 -22
- package/index.js +0 -3
- package/package.json +1 -1
- package/services/googleCalendar.js +5 -24
- package/services/storage.js +2 -71
- package/services/video.js +9 -67
- package/test-backwards-compatibility.js +0 -1
- package/test-complete-coverage.js +0 -1
- package/test-constructor-patterns.js +0 -1
- package/services/developerApis.js +0 -222
package/base.js
CHANGED
|
@@ -297,17 +297,6 @@ export class BaseSDK {
|
|
|
297
297
|
return true;
|
|
298
298
|
}
|
|
299
299
|
|
|
300
|
-
// Streaming bodies (Node Readable or Web ReadableStream) — caller is
|
|
301
|
-
// expected to set an explicit content-type header alongside.
|
|
302
|
-
if (
|
|
303
|
-
typeof body === 'object' &&
|
|
304
|
-
body !== null &&
|
|
305
|
-
(typeof body.pipe === 'function' ||
|
|
306
|
-
typeof body.getReader === 'function')
|
|
307
|
-
) {
|
|
308
|
-
return true;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
300
|
return false;
|
|
312
301
|
}
|
|
313
302
|
|
|
@@ -364,20 +353,9 @@ export class BaseSDK {
|
|
|
364
353
|
typeof Buffer !== 'undefined' &&
|
|
365
354
|
Buffer.isBuffer &&
|
|
366
355
|
Buffer.isBuffer(body);
|
|
367
|
-
const isStream =
|
|
368
|
-
body &&
|
|
369
|
-
typeof body === 'object' &&
|
|
370
|
-
(typeof body.pipe === 'function' ||
|
|
371
|
-
typeof body.getReader === 'function');
|
|
372
356
|
|
|
373
357
|
if (isFormData || isBuffer) {
|
|
374
358
|
options.body = body;
|
|
375
|
-
} else if (isStream) {
|
|
376
|
-
// Node 18+ native fetch (undici) requires duplex: 'half' for
|
|
377
|
-
// streaming request bodies. Without this the fetch throws
|
|
378
|
-
// synchronously before the first byte is sent.
|
|
379
|
-
options.body = body;
|
|
380
|
-
options.duplex = 'half';
|
|
381
359
|
} else {
|
|
382
360
|
options.body = JSON.stringify(body);
|
|
383
361
|
}
|
package/index.js
CHANGED
|
@@ -27,7 +27,6 @@ import { EngagementMetricsService } from './services/engagementMetrics.js';
|
|
|
27
27
|
import { TaskRouterService } from './services/taskRouter.js';
|
|
28
28
|
import { KnowledgeBaseService } from './services/knowledgeBase.js';
|
|
29
29
|
import { FaxService } from './services/fax.js';
|
|
30
|
-
import { DeveloperApisService } from './services/developerApis.js';
|
|
31
30
|
|
|
32
31
|
class UnboundSDK extends BaseSDK {
|
|
33
32
|
constructor(options = {}) {
|
|
@@ -96,7 +95,6 @@ class UnboundSDK extends BaseSDK {
|
|
|
96
95
|
this.taskRouter = new TaskRouterService(this);
|
|
97
96
|
this.knowledgeBase = new KnowledgeBaseService(this);
|
|
98
97
|
this.fax = new FaxService(this);
|
|
99
|
-
this.developerApis = new DeveloperApisService(this);
|
|
100
98
|
|
|
101
99
|
// Add additional services that might be missing
|
|
102
100
|
this._initializeAdditionalServices();
|
|
@@ -276,5 +274,4 @@ export { TaskRouterService } from './services/taskRouter.js';
|
|
|
276
274
|
export { WorkerService } from './services/taskRouter/WorkerService.js';
|
|
277
275
|
export { KnowledgeBaseService } from './services/knowledgeBase.js';
|
|
278
276
|
export { FaxService } from './services/fax.js';
|
|
279
|
-
export { DeveloperApisService } from './services/developerApis.js';
|
|
280
277
|
export { BaseSDK } from './base.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unboundcx/sdk",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.7",
|
|
4
4
|
"description": "Official JavaScript SDK for the Unbound API - A comprehensive toolkit for integrating with Unbound's communication, AI, and data management services",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -3,38 +3,19 @@ export class GoogleCalendarService {
|
|
|
3
3
|
this.sdk = sdk;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
async setupWebhook({
|
|
7
|
-
calendarId,
|
|
8
|
-
eventTypes,
|
|
9
|
-
webhookUrl,
|
|
10
|
-
expirationTime,
|
|
11
|
-
recordTypeId,
|
|
12
|
-
} = {}) {
|
|
13
|
-
// Only calendarId is required. The server derives the webhook URL itself
|
|
14
|
-
// (per-environment: https://login.<API_BASE_URL>/webhooks/google/...) and
|
|
15
|
-
// watches all event types, so eventTypes/webhookUrl are optional. They
|
|
16
|
-
// were previously marked required, which broke the common
|
|
17
|
-
// setupWebhook({ calendarId }) call site (createRoom) with
|
|
18
|
-
// "Missing required parameter eventTypes".
|
|
19
|
-
// recordTypeId is optional: callers (e.g. createRoom) pass the meeting's
|
|
20
|
-
// already-resolved recordTypeId so the webhook row inherits it; if omitted
|
|
21
|
-
// the server resolves a fallback via findRecordTypeId.
|
|
6
|
+
async setupWebhook({ calendarId, eventTypes, webhookUrl, expirationTime }) {
|
|
22
7
|
this.sdk.validateParams(
|
|
23
|
-
{ calendarId, eventTypes, webhookUrl
|
|
8
|
+
{ calendarId, eventTypes, webhookUrl },
|
|
24
9
|
{
|
|
25
10
|
calendarId: { type: 'string', required: true },
|
|
26
|
-
eventTypes: { type: 'array', required:
|
|
27
|
-
webhookUrl: { type: 'string', required:
|
|
11
|
+
eventTypes: { type: 'array', required: true },
|
|
12
|
+
webhookUrl: { type: 'string', required: true },
|
|
28
13
|
expirationTime: { type: 'number', required: false },
|
|
29
|
-
recordTypeId: { type: 'string', required: false },
|
|
30
14
|
},
|
|
31
15
|
);
|
|
32
16
|
|
|
33
|
-
const webhookData = { calendarId };
|
|
34
|
-
if (eventTypes) webhookData.eventTypes = eventTypes;
|
|
35
|
-
if (webhookUrl) webhookData.webhookUrl = webhookUrl;
|
|
17
|
+
const webhookData = { calendarId, eventTypes, webhookUrl };
|
|
36
18
|
if (expirationTime) webhookData.expirationTime = expirationTime;
|
|
37
|
-
if (recordTypeId) webhookData.recordTypeId = recordTypeId;
|
|
38
19
|
|
|
39
20
|
const params = {
|
|
40
21
|
body: webhookData,
|
package/services/storage.js
CHANGED
|
@@ -87,69 +87,6 @@ export class StorageService {
|
|
|
87
87
|
return commonTypes[ext] || 'application/octet-stream';
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
// Private helper to detect if a value is a Node Readable or Web ReadableStream
|
|
91
|
-
_isStreamLike(value) {
|
|
92
|
-
if (!value || typeof value !== 'object') return false;
|
|
93
|
-
if (typeof value.pipe === 'function') return true; // Node Readable
|
|
94
|
-
if (typeof value.getReader === 'function') return true; // Web ReadableStream
|
|
95
|
-
if (typeof value[Symbol.asyncIterator] === 'function') return true;
|
|
96
|
-
return false;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Private helper to create a streaming multipart body for Node.js.
|
|
100
|
-
// Returns { body: ReadableStream, headers } for fetch() with duplex: 'half'.
|
|
101
|
-
// Byte-identical framing to _createNodeFormData — emitted in chunks so the full
|
|
102
|
-
// file never has to sit in memory.
|
|
103
|
-
_createNodeFormDataStream(fileStream, fileName, formFields) {
|
|
104
|
-
const boundary = `----formdata-${Date.now()}-${Math.random()
|
|
105
|
-
.toString(36)
|
|
106
|
-
.slice(2)}`;
|
|
107
|
-
const CRLF = '\r\n';
|
|
108
|
-
const contentType = this._getContentType(fileName);
|
|
109
|
-
|
|
110
|
-
const header =
|
|
111
|
-
`--${boundary}${CRLF}` +
|
|
112
|
-
`Content-Disposition: form-data; name="files"; filename="${
|
|
113
|
-
fileName || 'file'
|
|
114
|
-
}"${CRLF}` +
|
|
115
|
-
`Content-Type: ${contentType}${CRLF}${CRLF}`;
|
|
116
|
-
|
|
117
|
-
let tail = '';
|
|
118
|
-
for (const [name, value] of formFields) {
|
|
119
|
-
tail += `${CRLF}--${boundary}${CRLF}Content-Disposition: form-data; name="${name}"${CRLF}${CRLF}${value}`;
|
|
120
|
-
}
|
|
121
|
-
tail += `${CRLF}--${boundary}--${CRLF}`;
|
|
122
|
-
|
|
123
|
-
const body = new ReadableStream({
|
|
124
|
-
async start(controller) {
|
|
125
|
-
try {
|
|
126
|
-
controller.enqueue(Buffer.from(header, 'utf8'));
|
|
127
|
-
for await (const chunk of fileStream) {
|
|
128
|
-
controller.enqueue(
|
|
129
|
-
Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk),
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
controller.enqueue(Buffer.from(tail, 'utf8'));
|
|
133
|
-
controller.close();
|
|
134
|
-
} catch (err) {
|
|
135
|
-
controller.error(err);
|
|
136
|
-
}
|
|
137
|
-
},
|
|
138
|
-
cancel(reason) {
|
|
139
|
-
if (fileStream && typeof fileStream.destroy === 'function') {
|
|
140
|
-
fileStream.destroy(reason);
|
|
141
|
-
}
|
|
142
|
-
},
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
return {
|
|
146
|
-
body,
|
|
147
|
-
headers: {
|
|
148
|
-
'content-type': `multipart/form-data; boundary=${boundary}`,
|
|
149
|
-
},
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
90
|
// Private helper to create FormData for Node.js environment
|
|
154
91
|
_createNodeFormData(file, fileName, formFields) {
|
|
155
92
|
const boundary = `----formdata-${Date.now()}-${Math.random().toString(36)}`;
|
|
@@ -297,13 +234,7 @@ export class StorageService {
|
|
|
297
234
|
// Default behavior: Use fetch via sdk._fetch
|
|
298
235
|
let formData, headers;
|
|
299
236
|
|
|
300
|
-
if (isNode
|
|
301
|
-
// Streaming path — file is piped chunk-by-chunk, no full-buffer copy.
|
|
302
|
-
// Caller is responsible for creating a fresh stream per retry.
|
|
303
|
-
const result = this._createNodeFormDataStream(file, fileName, formFields);
|
|
304
|
-
formData = result.body;
|
|
305
|
-
headers = result.headers;
|
|
306
|
-
} else if (isNode) {
|
|
237
|
+
if (isNode) {
|
|
307
238
|
const result = this._createNodeFormData(file, fileName, formFields);
|
|
308
239
|
formData = result.formData;
|
|
309
240
|
headers = result.headers;
|
|
@@ -450,7 +381,7 @@ Response:
|
|
|
450
381
|
/**
|
|
451
382
|
* Upload a file to storage with optional format conversion
|
|
452
383
|
* @param {Object} config - Configuration object
|
|
453
|
-
* @param {Object} config.file - File content
|
|
384
|
+
* @param {Object} config.file - File content (Buffer or File) - REQUIRED
|
|
454
385
|
* @param {string} [config.classification='generic'] - File classification (e.g., 'fax', 'files', 'generic')
|
|
455
386
|
* @param {string} [config.folder] - Folder path for organizing files
|
|
456
387
|
* @param {string} [config.fileName] - Original file name
|
package/services/video.js
CHANGED
|
@@ -221,13 +221,6 @@ export class VideoService {
|
|
|
221
221
|
startMicrophoneMutedAfter,
|
|
222
222
|
enableChat,
|
|
223
223
|
engagementSessionId,
|
|
224
|
-
startRecordingOn,
|
|
225
|
-
startTranscribingOn,
|
|
226
|
-
syncToCalendar,
|
|
227
|
-
source,
|
|
228
|
-
calendarId,
|
|
229
|
-
eventId,
|
|
230
|
-
calendarProvider,
|
|
231
224
|
}) {
|
|
232
225
|
this.sdk.validateParams(
|
|
233
226
|
{
|
|
@@ -248,13 +241,6 @@ export class VideoService {
|
|
|
248
241
|
startMicrophoneMutedAfter,
|
|
249
242
|
enableChat,
|
|
250
243
|
engagementSessionId,
|
|
251
|
-
startRecordingOn,
|
|
252
|
-
startTranscribingOn,
|
|
253
|
-
syncToCalendar,
|
|
254
|
-
source,
|
|
255
|
-
calendarId,
|
|
256
|
-
eventId,
|
|
257
|
-
calendarProvider,
|
|
258
244
|
},
|
|
259
245
|
{
|
|
260
246
|
name: { type: 'string', required: false },
|
|
@@ -274,13 +260,6 @@ export class VideoService {
|
|
|
274
260
|
startMicrophoneMutedAfter: { type: 'number', required: false },
|
|
275
261
|
enableChat: { type: 'boolean', required: false },
|
|
276
262
|
engagementSessionId: { type: 'string', required: false },
|
|
277
|
-
startRecordingOn: { type: 'boolean', required: false },
|
|
278
|
-
startTranscribingOn: { type: 'boolean', required: false },
|
|
279
|
-
syncToCalendar: { type: 'boolean', required: false },
|
|
280
|
-
source: { type: 'string', required: false },
|
|
281
|
-
calendarId: { type: 'string', required: false },
|
|
282
|
-
eventId: { type: 'string', required: false },
|
|
283
|
-
calendarProvider: { type: 'string', required: false },
|
|
284
263
|
},
|
|
285
264
|
);
|
|
286
265
|
const params = {
|
|
@@ -302,13 +281,6 @@ export class VideoService {
|
|
|
302
281
|
startMicrophoneMutedAfter,
|
|
303
282
|
enableChat,
|
|
304
283
|
engagementSessionId,
|
|
305
|
-
startRecordingOn,
|
|
306
|
-
startTranscribingOn,
|
|
307
|
-
syncToCalendar,
|
|
308
|
-
source,
|
|
309
|
-
calendarId,
|
|
310
|
-
eventId,
|
|
311
|
-
calendarProvider,
|
|
312
284
|
},
|
|
313
285
|
};
|
|
314
286
|
const result = await this.sdk._fetch(`/video`, 'POST', params);
|
|
@@ -364,18 +336,24 @@ export class VideoService {
|
|
|
364
336
|
return result;
|
|
365
337
|
}
|
|
366
338
|
|
|
367
|
-
async updateRoomBot(
|
|
339
|
+
async updateRoomBot(
|
|
340
|
+
roomId,
|
|
341
|
+
{ isRecording, isTranscribing, recordingAssetStatus },
|
|
342
|
+
) {
|
|
368
343
|
this.sdk.validateParams(
|
|
369
|
-
{ roomId, isRecording, isTranscribing },
|
|
344
|
+
{ roomId, isRecording, isTranscribing, recordingAssetStatus },
|
|
370
345
|
{
|
|
371
346
|
roomId: { type: 'string', required: true },
|
|
372
347
|
isRecording: { type: 'boolean', required: false },
|
|
373
348
|
isTranscribing: { type: 'boolean', required: false },
|
|
349
|
+
// none|processing|ready_webm|ready_mp4|failed
|
|
350
|
+
recordingAssetStatus: { type: 'string', required: false },
|
|
374
351
|
},
|
|
375
352
|
);
|
|
376
353
|
const update = {
|
|
377
354
|
isRecording,
|
|
378
355
|
isTranscribing,
|
|
356
|
+
recordingAssetStatus,
|
|
379
357
|
};
|
|
380
358
|
const params = {
|
|
381
359
|
body: {
|
|
@@ -428,19 +406,6 @@ export class VideoService {
|
|
|
428
406
|
return await this.sdk._fetch(`/video/${roomId}`, 'GET', params);
|
|
429
407
|
}
|
|
430
408
|
|
|
431
|
-
// Live roster for a meeting card: { counts, inMeeting: [...], inWaiting: [...] }.
|
|
432
|
-
async getLivePresence(roomId) {
|
|
433
|
-
this.sdk.validateParams(
|
|
434
|
-
{ roomId },
|
|
435
|
-
{ roomId: { type: 'string', required: true } },
|
|
436
|
-
);
|
|
437
|
-
const result = await this.sdk._fetch(
|
|
438
|
-
`/video/${roomId}/livePresence`,
|
|
439
|
-
'GET',
|
|
440
|
-
);
|
|
441
|
-
return result;
|
|
442
|
-
}
|
|
443
|
-
|
|
444
409
|
async listMeetings(options = {}) {
|
|
445
410
|
// Validate optional parameters
|
|
446
411
|
const validationSchema = {};
|
|
@@ -494,7 +459,7 @@ export class VideoService {
|
|
|
494
459
|
return result;
|
|
495
460
|
}
|
|
496
461
|
|
|
497
|
-
async deleteRoom(roomId
|
|
462
|
+
async deleteRoom(roomId) {
|
|
498
463
|
this.sdk.validateParams(
|
|
499
464
|
{ roomId },
|
|
500
465
|
{
|
|
@@ -502,9 +467,6 @@ export class VideoService {
|
|
|
502
467
|
},
|
|
503
468
|
);
|
|
504
469
|
const params = {};
|
|
505
|
-
if (options && options.deleteCalendarEvent === true) {
|
|
506
|
-
params.body = { deleteCalendarEvent: true };
|
|
507
|
-
}
|
|
508
470
|
const result = await this.sdk._fetch(`/video/${roomId}`, 'DELETE', params);
|
|
509
471
|
return result;
|
|
510
472
|
}
|
|
@@ -656,26 +618,6 @@ export class VideoService {
|
|
|
656
618
|
return result;
|
|
657
619
|
}
|
|
658
620
|
|
|
659
|
-
// Persist a rolled-up quality summary to MySQL (one row per participant
|
|
660
|
-
// per meeting). Internal endpoint, called by app1-video-server on
|
|
661
|
-
// participant.leave. Long-term home for billing (bytes) and "was this
|
|
662
|
-
// meeting good?" support lookups, surviving ClickHouse TTL expiry.
|
|
663
|
-
async submitParticipantSummary(roomId, participantId, summary) {
|
|
664
|
-
this.sdk.validateParams(
|
|
665
|
-
{ roomId, participantId, summary },
|
|
666
|
-
{
|
|
667
|
-
roomId: { type: 'string', required: true },
|
|
668
|
-
participantId: { type: 'string', required: true },
|
|
669
|
-
summary: { type: 'object', required: true },
|
|
670
|
-
},
|
|
671
|
-
);
|
|
672
|
-
return this.sdk._fetch(
|
|
673
|
-
`/internal/video/${roomId}/participants/${participantId}/summary`,
|
|
674
|
-
'POST',
|
|
675
|
-
{ body: summary },
|
|
676
|
-
);
|
|
677
|
-
}
|
|
678
|
-
|
|
679
621
|
async submitSurvey({
|
|
680
622
|
videoRoomId,
|
|
681
623
|
participantId,
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Developer portal My APIs — account-scoped folders, requests, vars, sharing.
|
|
3
|
-
* API prefix: /developerApis
|
|
4
|
-
*/
|
|
5
|
-
export class DeveloperApisService {
|
|
6
|
-
constructor(sdk) {
|
|
7
|
-
this.sdk = sdk;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Full library for the current user (owned + shared folders/requests + personal vars).
|
|
12
|
-
* @returns {Promise<{ folders: object[], requests: object[], vars: object[], shares: object[] }>}
|
|
13
|
-
*/
|
|
14
|
-
async getLibrary() {
|
|
15
|
-
return this.sdk._fetch('/developerApis', 'GET');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// ——— Folders ———
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* @param {{ name?: string, parentId?: string|null, sort?: number }} [params]
|
|
22
|
-
*/
|
|
23
|
-
async createFolder(params = {}) {
|
|
24
|
-
const { name, parentId, sort } = params;
|
|
25
|
-
this.sdk.validateParams(
|
|
26
|
-
{ name, parentId, sort },
|
|
27
|
-
{
|
|
28
|
-
name: { type: 'string', required: false },
|
|
29
|
-
parentId: { type: 'string', required: false },
|
|
30
|
-
sort: { type: 'number', required: false },
|
|
31
|
-
},
|
|
32
|
-
);
|
|
33
|
-
return this.sdk._fetch('/developerApis/folders', 'POST', {
|
|
34
|
-
body: { name, parentId, sort },
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* @param {string} id
|
|
40
|
-
* @param {{ name?: string, parentId?: string|null, sort?: number }} updates
|
|
41
|
-
*/
|
|
42
|
-
async updateFolder(id, updates = {}) {
|
|
43
|
-
this.sdk.validateParams(
|
|
44
|
-
{ id, updates },
|
|
45
|
-
{
|
|
46
|
-
id: { type: 'string', required: true },
|
|
47
|
-
updates: { type: 'object', required: true },
|
|
48
|
-
},
|
|
49
|
-
);
|
|
50
|
-
return this.sdk._fetch(`/developerApis/folders/${id}`, 'PUT', {
|
|
51
|
-
body: updates,
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* @param {string} id
|
|
57
|
-
*/
|
|
58
|
-
async deleteFolder(id) {
|
|
59
|
-
this.sdk.validateParams({ id }, { id: { type: 'string', required: true } });
|
|
60
|
-
return this.sdk._fetch(`/developerApis/folders/${id}`, 'DELETE');
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// ——— Folder sharing ———
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* @param {string} folderId
|
|
67
|
-
*/
|
|
68
|
-
async listFolderShares(folderId) {
|
|
69
|
-
this.sdk.validateParams(
|
|
70
|
-
{ folderId },
|
|
71
|
-
{ folderId: { type: 'string', required: true } },
|
|
72
|
-
);
|
|
73
|
-
return this.sdk._fetch(`/developerApis/folders/${folderId}/shares`, 'GET');
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Share a folder with a user.
|
|
78
|
-
* @param {string} folderId
|
|
79
|
-
* @param {{ userId: string, access?: 'full'|'limited' }} params
|
|
80
|
-
*/
|
|
81
|
-
async shareFolder(folderId, params) {
|
|
82
|
-
const { userId, access } = params || {};
|
|
83
|
-
this.sdk.validateParams(
|
|
84
|
-
{ folderId, userId, access },
|
|
85
|
-
{
|
|
86
|
-
folderId: { type: 'string', required: true },
|
|
87
|
-
userId: { type: 'string', required: true },
|
|
88
|
-
access: { type: 'string', required: false },
|
|
89
|
-
},
|
|
90
|
-
);
|
|
91
|
-
return this.sdk._fetch(`/developerApis/folders/${folderId}/shares`, 'POST', {
|
|
92
|
-
body: { userId, access: access === 'full' ? 'full' : 'limited' },
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* @param {string} folderId
|
|
98
|
-
* @param {string} userId
|
|
99
|
-
*/
|
|
100
|
-
async unshareFolder(folderId, userId) {
|
|
101
|
-
this.sdk.validateParams(
|
|
102
|
-
{ folderId, userId },
|
|
103
|
-
{
|
|
104
|
-
folderId: { type: 'string', required: true },
|
|
105
|
-
userId: { type: 'string', required: true },
|
|
106
|
-
},
|
|
107
|
-
);
|
|
108
|
-
return this.sdk._fetch(
|
|
109
|
-
`/developerApis/folders/${folderId}/shares/${userId}`,
|
|
110
|
-
'DELETE',
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// ——— Requests ———
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* @param {object} [request] freeform request body
|
|
118
|
-
*/
|
|
119
|
-
async createRequest(request = {}) {
|
|
120
|
-
this.sdk.validateParams(
|
|
121
|
-
{ request },
|
|
122
|
-
{ request: { type: 'object', required: false } },
|
|
123
|
-
);
|
|
124
|
-
return this.sdk._fetch('/developerApis/requests', 'POST', {
|
|
125
|
-
body: request,
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* @param {string} id
|
|
131
|
-
*/
|
|
132
|
-
async getRequest(id) {
|
|
133
|
-
this.sdk.validateParams({ id }, { id: { type: 'string', required: true } });
|
|
134
|
-
return this.sdk._fetch(`/developerApis/requests/${id}`, 'GET');
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* @param {string} id
|
|
139
|
-
* @param {object} updates
|
|
140
|
-
*/
|
|
141
|
-
async updateRequest(id, updates = {}) {
|
|
142
|
-
this.sdk.validateParams(
|
|
143
|
-
{ id, updates },
|
|
144
|
-
{
|
|
145
|
-
id: { type: 'string', required: true },
|
|
146
|
-
updates: { type: 'object', required: true },
|
|
147
|
-
},
|
|
148
|
-
);
|
|
149
|
-
return this.sdk._fetch(`/developerApis/requests/${id}`, 'PUT', {
|
|
150
|
-
body: updates,
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* @param {string} id
|
|
156
|
-
*/
|
|
157
|
-
async deleteRequest(id) {
|
|
158
|
-
this.sdk.validateParams({ id }, { id: { type: 'string', required: true } });
|
|
159
|
-
return this.sdk._fetch(`/developerApis/requests/${id}`, 'DELETE');
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Clone a request (caller becomes owner of the copy).
|
|
164
|
-
* @param {string} id
|
|
165
|
-
*/
|
|
166
|
-
async cloneRequest(id) {
|
|
167
|
-
this.sdk.validateParams({ id }, { id: { type: 'string', required: true } });
|
|
168
|
-
return this.sdk._fetch(`/developerApis/requests/${id}/clone`, 'POST', {
|
|
169
|
-
body: {},
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// ——— Vars (personal) ———
|
|
174
|
-
|
|
175
|
-
async listVars() {
|
|
176
|
-
return this.sdk._fetch('/developerApis/vars', 'GET');
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* @param {{ key?: string, type?: 'default'|'secret', value?: string, enabled?: boolean }} [params]
|
|
181
|
-
*/
|
|
182
|
-
async createVar(params = {}) {
|
|
183
|
-
const { key, type, value, enabled } = params;
|
|
184
|
-
this.sdk.validateParams(
|
|
185
|
-
{ key, type, value, enabled },
|
|
186
|
-
{
|
|
187
|
-
key: { type: 'string', required: false },
|
|
188
|
-
type: { type: 'string', required: false },
|
|
189
|
-
value: { type: 'string', required: false },
|
|
190
|
-
enabled: { type: 'boolean', required: false },
|
|
191
|
-
},
|
|
192
|
-
);
|
|
193
|
-
return this.sdk._fetch('/developerApis/vars', 'POST', {
|
|
194
|
-
body: { key, type, value, enabled },
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* @param {string} id
|
|
200
|
-
* @param {{ key?: string, type?: string, value?: string, enabled?: boolean }} updates
|
|
201
|
-
*/
|
|
202
|
-
async updateVar(id, updates = {}) {
|
|
203
|
-
this.sdk.validateParams(
|
|
204
|
-
{ id, updates },
|
|
205
|
-
{
|
|
206
|
-
id: { type: 'string', required: true },
|
|
207
|
-
updates: { type: 'object', required: true },
|
|
208
|
-
},
|
|
209
|
-
);
|
|
210
|
-
return this.sdk._fetch(`/developerApis/vars/${id}`, 'PUT', {
|
|
211
|
-
body: updates,
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* @param {string} id
|
|
217
|
-
*/
|
|
218
|
-
async deleteVar(id) {
|
|
219
|
-
this.sdk.validateParams({ id }, { id: { type: 'string', required: true } });
|
|
220
|
-
return this.sdk._fetch(`/developerApis/vars/${id}`, 'DELETE');
|
|
221
|
-
}
|
|
222
|
-
}
|