@nomad-media/public 1.1.12 → 1.1.13
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/nomad-media-sdk-debug.js +1437 -0
- package/dist/nomad-media-sdk.min.js +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,1437 @@
|
|
|
1
|
+
// account
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
// admin
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
// common
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
// portal
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
// helpers
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
import { promises as fs } from 'fs';
|
|
267
|
+
import path from 'path';
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* @class NomadSDK
|
|
271
|
+
* @classdesc This class is used to interact with the Nomad API.
|
|
272
|
+
*/
|
|
273
|
+
|
|
274
|
+
class NomadMediaSDK {
|
|
275
|
+
constructor(config = {}) {
|
|
276
|
+
if (NomadMediaSDK.instance)
|
|
277
|
+
{
|
|
278
|
+
return NomadMediaSDK.instance;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
this.config = config;
|
|
282
|
+
this.token = null;
|
|
283
|
+
this.refreshTokenVal = null;
|
|
284
|
+
this.expirationSeconds = null;
|
|
285
|
+
this.userSessionId = null;
|
|
286
|
+
this.id = null
|
|
287
|
+
this.debugMode = config.debugMode || false;
|
|
288
|
+
|
|
289
|
+
if (this.config.serviceApiUrl[this.config.serviceApiUrl.length - 1] === "/")
|
|
290
|
+
{
|
|
291
|
+
this.config.serviceApiUrl = this.config.serviceApiUrl.slice(0, -1);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
NomadMediaSDK.instance = this;
|
|
295
|
+
|
|
296
|
+
return this;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* @function init
|
|
301
|
+
* @async
|
|
302
|
+
* @private
|
|
303
|
+
* @description Initializes the SDK. Logs in using the username and password from the config.
|
|
304
|
+
* Then schedules a token refresh for the duration set by the value returned in the login.
|
|
305
|
+
* @returns {Promise<void>} - A promise that resolves when the SDK is initialized.
|
|
306
|
+
* @throws {Error} - An error is thrown if the SDK fails to initialize.
|
|
307
|
+
*/
|
|
308
|
+
async _init()
|
|
309
|
+
{
|
|
310
|
+
await this.login();
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// account functions
|
|
314
|
+
/**
|
|
315
|
+
* @function login
|
|
316
|
+
* @async
|
|
317
|
+
* @description Logs in using the username and password from the config.
|
|
318
|
+
* @returns {Promise<void>} - A promise that resolves when the login is successful.
|
|
319
|
+
* Updates the token, refresh token, expiration seconds, and user session ID class varibles.
|
|
320
|
+
* @throws {Error} - An error is thrown if the login fails.
|
|
321
|
+
*/
|
|
322
|
+
async login()
|
|
323
|
+
{
|
|
324
|
+
|
|
325
|
+
_printDatetime(`Logging in as ${this.config.username}`);
|
|
326
|
+
|
|
327
|
+
try
|
|
328
|
+
{
|
|
329
|
+
const LOGIN_INFO = await _login(this, this.config.username, this.config.password,
|
|
330
|
+
this.config.serviceApiUrl, this.debugMode);
|
|
331
|
+
this.token = LOGIN_INFO["token"];
|
|
332
|
+
this.refreshTokenVal = LOGIN_INFO["refreshToken"];
|
|
333
|
+
this.expirationSeconds = LOGIN_INFO["expirationSeconds"];
|
|
334
|
+
this.userSessionId = LOGIN_INFO["userSessionId"];
|
|
335
|
+
this.id = LOGIN_INFO["id"];
|
|
336
|
+
_printDatetime(`Login successful`);
|
|
337
|
+
}
|
|
338
|
+
catch (error)
|
|
339
|
+
{
|
|
340
|
+
_printDatetime(`Login failed`);
|
|
341
|
+
throw error;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* @function logout
|
|
347
|
+
* @async
|
|
348
|
+
* @description Logs out the current user.
|
|
349
|
+
* @returns {Promise<null>} - A promise that resolves when the logout is successful.
|
|
350
|
+
* @throws {Error} - An error is thrown if the logout fails.
|
|
351
|
+
*/
|
|
352
|
+
async logout()
|
|
353
|
+
{
|
|
354
|
+
if (this.token === null && this.config.username)
|
|
355
|
+
{
|
|
356
|
+
await this._init();
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
_printDatetime(`Logging out`);
|
|
360
|
+
|
|
361
|
+
try
|
|
362
|
+
{
|
|
363
|
+
await _logout(this, this.token, this.config.serviceApiUrl, this.debugMode);
|
|
364
|
+
this.token = null;
|
|
365
|
+
this.refreshTokenVal = null;
|
|
366
|
+
this.expirationSeconds = null;
|
|
367
|
+
this.userSessionId = null;
|
|
368
|
+
this.id = null;
|
|
369
|
+
|
|
370
|
+
_printDatetime(`Logout successful`);
|
|
371
|
+
}
|
|
372
|
+
catch (error)
|
|
373
|
+
{
|
|
374
|
+
_printDatetime("Loggout failed");
|
|
375
|
+
throw error;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* @function refreshToken
|
|
381
|
+
* @async
|
|
382
|
+
* @description Refreshes the current token.
|
|
383
|
+
* @returns {Promise<void>} - A promise that resolves when the token is refreshed.
|
|
384
|
+
* Updates the token class variable.
|
|
385
|
+
* @throws {Error} - An error is thrown if the token refresh fails.
|
|
386
|
+
*/
|
|
387
|
+
async refreshToken()
|
|
388
|
+
{
|
|
389
|
+
_printDatetime(`Refreshing token`);
|
|
390
|
+
|
|
391
|
+
try
|
|
392
|
+
{
|
|
393
|
+
const REFRESHED = await _refreshToken(this, this.token, this.config.serviceApiUrl,
|
|
394
|
+
this.refreshTokenVal, this.debugMode);
|
|
395
|
+
if (REFRESHED) _printDatetime(`Token refresh successful`);
|
|
396
|
+
}
|
|
397
|
+
catch (error)
|
|
398
|
+
{
|
|
399
|
+
_printDatetime(`Token refresh failed`);
|
|
400
|
+
throw error;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* @function forgotPassword
|
|
406
|
+
* @async
|
|
407
|
+
* @description Sends a code to the email to the user to be used
|
|
408
|
+
* be used to reset the password.
|
|
409
|
+
* @returns {Promise<void>}
|
|
410
|
+
* Sends email with code to reset password.
|
|
411
|
+
* @throws {Error} - An error is thrown if the code fails to send.
|
|
412
|
+
*/
|
|
413
|
+
async forgotPassword()
|
|
414
|
+
{
|
|
415
|
+
const USERNAME = this.config.username;
|
|
416
|
+
|
|
417
|
+
_printDatetime(`Sending code to ${USERNAME}`);
|
|
418
|
+
|
|
419
|
+
try
|
|
420
|
+
{
|
|
421
|
+
await _forgotPassword(this, this.config.serviceApiUrl, USERNAME, this.debugMode);
|
|
422
|
+
_printDatetime(`Code sent to ${USERNAME}`);
|
|
423
|
+
}
|
|
424
|
+
catch (error)
|
|
425
|
+
{
|
|
426
|
+
_printDatetime(`Code failed to send to ${USERNAME}`);
|
|
427
|
+
throw error;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* @function resetPassword
|
|
433
|
+
* @async
|
|
434
|
+
* @description Resets the password for the specified username.
|
|
435
|
+
* @param {string} CODE - The code to use to reset the password. Sent to the user's email
|
|
436
|
+
* by calling forgotPassword().
|
|
437
|
+
* @param {string} NEW_PASSWORD - The new password to set.
|
|
438
|
+
* @returns {Promise<void>}
|
|
439
|
+
* Resets the password for the specified username.
|
|
440
|
+
* @throws {Error} - An error is thrown if the password fails to reset.
|
|
441
|
+
*/
|
|
442
|
+
async resetPassword(CODE, NEW_PASSWORD)
|
|
443
|
+
{
|
|
444
|
+
const USERNAME = this.config.username;
|
|
445
|
+
|
|
446
|
+
_printDatetime(`Resetting password for ${USERNAME}`);
|
|
447
|
+
|
|
448
|
+
try
|
|
449
|
+
{
|
|
450
|
+
await _resetPassword(this, this.config.serviceApiUrl, USERNAME, CODE, NEW_PASSWORD,
|
|
451
|
+
this.debugMode);
|
|
452
|
+
_printDatetime(`Password reset for ${USERNAME}`);
|
|
453
|
+
}
|
|
454
|
+
catch (error)
|
|
455
|
+
{
|
|
456
|
+
_printDatetime(`Password failed to reset for ${USERNAME}`);
|
|
457
|
+
throw error;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// media functions
|
|
462
|
+
/**
|
|
463
|
+
* @function clearContinueWatching
|
|
464
|
+
* @async
|
|
465
|
+
* @description Delete continue watching markers.
|
|
466
|
+
* @param {string | null} USER_ID - The user ID of the user to clear the continue watching list.
|
|
467
|
+
* If not user Id is passed it clears the markers of the logged in user.
|
|
468
|
+
* @param {string | null} ASSET_ID - The asset ID of the asset to clear the continue watching
|
|
469
|
+
* list. If not asset Id is passed it clears the markers of all assets.
|
|
470
|
+
* @returns {Promise<void>} - A promise that resolves when the continue watching list is cleared.
|
|
471
|
+
* @throws {Error} - An error is thrown if the continue watching list fails to clear.
|
|
472
|
+
* @throws {Error} - An error is thrown if the API type is not portal.
|
|
473
|
+
*/
|
|
474
|
+
async clearContinueWatching(USER_ID, ASSET_ID)
|
|
475
|
+
{
|
|
476
|
+
if (this.token === null && this.config.username)
|
|
477
|
+
{
|
|
478
|
+
await this._init();
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
if (this.config.apiType !== "portal")
|
|
482
|
+
{
|
|
483
|
+
throw new Error("This function is only available for portal API type.");
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
_printDatetime(`Clearing continue watching`);
|
|
487
|
+
|
|
488
|
+
try
|
|
489
|
+
{
|
|
490
|
+
await _clearContinueWatching(this, this.token, this.config.serviceApiUrl, USER_ID, ASSET_ID,
|
|
491
|
+
this.debugMode);
|
|
492
|
+
_printDatetime(`Continue watching cleared`);
|
|
493
|
+
}
|
|
494
|
+
catch (error)
|
|
495
|
+
{
|
|
496
|
+
_printDatetime(`Continue watching failed to clear`);
|
|
497
|
+
throw error;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* @function clearWatchlist
|
|
503
|
+
* @async
|
|
504
|
+
* @description Clears the watchlist.
|
|
505
|
+
* @param {string | null} USER_ID - The user ID of the user to clear the watchlist.
|
|
506
|
+
* If not user Id is passed it clears the watchlist of the logged in user.
|
|
507
|
+
* @returns {Promise<void>} - A promise that resolves when the watchlist is cleared.
|
|
508
|
+
* @throws {Error} - An error is thrown if the watchlist fails to clear.
|
|
509
|
+
* @throws {Error} - An error is thrown if the API type is not portal.
|
|
510
|
+
*/
|
|
511
|
+
async clearWatchlist(USER_ID)
|
|
512
|
+
{
|
|
513
|
+
if (this.token === null && this.config.username)
|
|
514
|
+
{
|
|
515
|
+
await this._init();
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
if (this.config.apiType !== "portal")
|
|
519
|
+
{
|
|
520
|
+
throw new Error("This function is only available for portal API type.");
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
_printDatetime(`Clearing watchlist`);
|
|
524
|
+
|
|
525
|
+
try
|
|
526
|
+
{
|
|
527
|
+
USER_ID = USER_ID || this.id;
|
|
528
|
+
|
|
529
|
+
await _clearWatchlist(this, this.token, this.config.serviceApiUrl, USER_ID, this.debugMode);
|
|
530
|
+
_printDatetime(`Watchlist cleared`);
|
|
531
|
+
}
|
|
532
|
+
catch (error)
|
|
533
|
+
{
|
|
534
|
+
_printDatetime(`Watchlist failed to clear`);
|
|
535
|
+
throw error;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* @function createForm
|
|
541
|
+
* @async
|
|
542
|
+
* @description Gets media.
|
|
543
|
+
* @param {string} CONTENT_DEFINITION_ID - The ID of the content definition the form
|
|
544
|
+
* is going in.
|
|
545
|
+
* @param {JSON} FORM_INFO - The information of the form.
|
|
546
|
+
* JSON format: whatever key value pairs you want to add to the form.
|
|
547
|
+
* @returns {Promise<JSON>} - A promise that resolves when the from is created.
|
|
548
|
+
* Returns the id of the form.
|
|
549
|
+
* @throws {Error} - An error is thrown if the media fails to get.
|
|
550
|
+
* @throws {Error} - An error is thrown if the API type is not portal.
|
|
551
|
+
*/
|
|
552
|
+
async createForm(CONTENT_DEFINITION_ID, FORM_INFO)
|
|
553
|
+
{
|
|
554
|
+
if (this.token === null && this.config.username)
|
|
555
|
+
{
|
|
556
|
+
await this._init();
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
if (this.config.apiType !== "portal")
|
|
560
|
+
{
|
|
561
|
+
throw new Error("This function is only available for portal API type.");
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
_printDatetime(`Creating form`);
|
|
565
|
+
|
|
566
|
+
try
|
|
567
|
+
{
|
|
568
|
+
const GET_FORMS_INFO = await _createForm(this, this.token, this.config.serviceApiUrl,
|
|
569
|
+
CONTENT_DEFINITION_ID, FORM_INFO, this.debugMode);
|
|
570
|
+
if (GET_FORMS_INFO) _printDatetime(`Form created`);
|
|
571
|
+
return GET_FORMS_INFO;
|
|
572
|
+
}
|
|
573
|
+
catch (error)
|
|
574
|
+
{
|
|
575
|
+
_printDatetime(`Form failed to create`);
|
|
576
|
+
throw error;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* @function getContentCookies
|
|
582
|
+
* @async
|
|
583
|
+
* @description Gets content cookies.
|
|
584
|
+
* @param {string} CONTENT_ID - The Id of the content to retrieve the cookies for.
|
|
585
|
+
* This can be the ID for the content definition of the LiveChannel, or a folder asset
|
|
586
|
+
* ID or a specific Asset ID.
|
|
587
|
+
* @returns {Promise<JSON>} - A promise that resolves when the content cookies are gotten.
|
|
588
|
+
* Returns the information of the gotten content cookies.
|
|
589
|
+
* @throws {Error} - An error is thrown if the content cookies fail to get.
|
|
590
|
+
* @throws {Error} - An error is thrown if the API type is not portal.
|
|
591
|
+
*/
|
|
592
|
+
async getContentCookies(CONTENT_ID)
|
|
593
|
+
{
|
|
594
|
+
if (this.token === null && this.config.username)
|
|
595
|
+
{
|
|
596
|
+
await this._init();
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
if (this.config.apiType !== "portal")
|
|
600
|
+
{
|
|
601
|
+
throw new Error("This function is only available for portal API type.");
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
_printDatetime(`Getting content cookies`);
|
|
605
|
+
|
|
606
|
+
try
|
|
607
|
+
{
|
|
608
|
+
const GET_CONTENT_COOKIES_INFO = await _getContentCookies(this, this.token,
|
|
609
|
+
this.config.serviceApiUrl, CONTENT_ID, this.debugMode);
|
|
610
|
+
if (GET_CONTENT_COOKIES_INFO) _printDatetime(`Content cookies gotten`);
|
|
611
|
+
return GET_CONTENT_COOKIES_INFO;
|
|
612
|
+
}
|
|
613
|
+
catch (error)
|
|
614
|
+
{
|
|
615
|
+
_printDatetime(`Content cookies failed to get`);
|
|
616
|
+
throw error;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* @function getDefaultSiteConfig
|
|
622
|
+
* @async
|
|
623
|
+
* @description Gets default site config.
|
|
624
|
+
* @returns {Promise<Array<JSON>>} - A promise that resolves when the default site config is gotten.
|
|
625
|
+
* Returns the information of the gotten dynamic content.
|
|
626
|
+
* @throws {Error} - An error is thrown if the dynamic content fails to get.
|
|
627
|
+
* @throws {Error} - An error is thrown if the API type is not portal.
|
|
628
|
+
*/
|
|
629
|
+
async getDefaultSiteConfig()
|
|
630
|
+
{
|
|
631
|
+
if (this.token === null && this.config.username)
|
|
632
|
+
{
|
|
633
|
+
await this._init();
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
if (this.config.apiType !== "portal")
|
|
637
|
+
{
|
|
638
|
+
throw new Error("This function is only available for portal API type.");
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
_printDatetime(`Getting default site config`);
|
|
642
|
+
|
|
643
|
+
try
|
|
644
|
+
{
|
|
645
|
+
const GET_DYNAMIC_CONTENTS_INFO = await _getDefaultSiteConfig(this, this.token,
|
|
646
|
+
this.config.serviceApiUrl, this.debugMode);
|
|
647
|
+
if (GET_DYNAMIC_CONTENTS_INFO) _printDatetime(`Default site config gotten`);
|
|
648
|
+
return GET_DYNAMIC_CONTENTS_INFO;
|
|
649
|
+
}
|
|
650
|
+
catch (error)
|
|
651
|
+
{
|
|
652
|
+
_printDatetime(`Default site config failed to get`);
|
|
653
|
+
throw error;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* @function getDynamicContent
|
|
659
|
+
* @async
|
|
660
|
+
* @description Gets dynamic content.
|
|
661
|
+
* @param {string} DYNAMIC_CONTENT_RECORD_ID - The dynamic content record ID.
|
|
662
|
+
* @returns {Promise<JSON>} - A promise that resolves when the dynamic content is gotten.
|
|
663
|
+
* Returns the information of the gotten dynamic content.
|
|
664
|
+
* @throws {Error} - An error is thrown if the dynamic content fails to get.
|
|
665
|
+
* @throws {Error} - An error is thrown if the API type is not portal.
|
|
666
|
+
*/
|
|
667
|
+
async getDynamicContent(DYNAMIC_CONTENT_RECORD_ID)
|
|
668
|
+
{
|
|
669
|
+
if (this.token === null && this.config.username)
|
|
670
|
+
{
|
|
671
|
+
await this._init();
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
_printDatetime(`Getting dynamic content: ${DYNAMIC_CONTENT_RECORD_ID}`);
|
|
675
|
+
|
|
676
|
+
try
|
|
677
|
+
{
|
|
678
|
+
const GET_DYNAMIC_CONTENT_INFO = await _getDynamicContent(this, this.token,
|
|
679
|
+
this.config.serviceApiUrl, DYNAMIC_CONTENT_RECORD_ID, this.debugMode);
|
|
680
|
+
if (GET_DYNAMIC_CONTENT_INFO) _printDatetime(`Dynamic content gotten: ${DYNAMIC_CONTENT_RECORD_ID}`);
|
|
681
|
+
return GET_DYNAMIC_CONTENT_INFO;
|
|
682
|
+
}
|
|
683
|
+
catch (error)
|
|
684
|
+
{
|
|
685
|
+
_printDatetime(`Dynamic content failed to get: ${DYNAMIC_CONTENT_RECORD_ID}`);
|
|
686
|
+
throw error;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* @function getDynamicContents
|
|
692
|
+
* @async
|
|
693
|
+
* @description Gets dynamic contents.
|
|
694
|
+
* @returns {Promise<Array<JSON>>} - A promise that resolves when the dynamic contents is gotten.
|
|
695
|
+
* Returns the information of the gotten dynamic content.
|
|
696
|
+
* @throws {Error} - An error is thrown if the dynamic content fails to get.
|
|
697
|
+
* @throws {Error} - An error is thrown if the API type is not portal.
|
|
698
|
+
*/
|
|
699
|
+
async getDynamicContents()
|
|
700
|
+
{
|
|
701
|
+
if (this.token === null && this.config.username)
|
|
702
|
+
{
|
|
703
|
+
await this._init();
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
if (this.config.apiType !== "portal")
|
|
707
|
+
{
|
|
708
|
+
throw new Error("This function is only available for portal API type.");
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
_printDatetime(`Getting dynamic contents`);
|
|
712
|
+
|
|
713
|
+
try
|
|
714
|
+
{
|
|
715
|
+
const GET_DYNAMIC_CONTENTS_INFO = await _getDynamicContents(this, this.token,
|
|
716
|
+
this.config.serviceApiUrl, this.debugMode);
|
|
717
|
+
if (GET_DYNAMIC_CONTENTS_INFO) _printDatetime(`Dynamic contents gotten`);
|
|
718
|
+
return GET_DYNAMIC_CONTENTS_INFO;
|
|
719
|
+
}
|
|
720
|
+
catch (error)
|
|
721
|
+
{
|
|
722
|
+
_printDatetime(`Dynamic contents failed to get`);
|
|
723
|
+
throw error;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* @function getMediaGroup
|
|
729
|
+
* @async
|
|
730
|
+
* @description Gets media group.
|
|
731
|
+
* @param {string} MEDIA_GROUP_ID - The ID of the media group.
|
|
732
|
+
* @returns {Promise<JSON>} - A promise that resolves when the media group is gotten.
|
|
733
|
+
* Returns the information of the gotten media group.
|
|
734
|
+
* @throws {Error} - An error is thrown if the media group fails to get.
|
|
735
|
+
* @throws {Error} - An error is thrown if the API type is not portal.
|
|
736
|
+
*/
|
|
737
|
+
async getMediaGroup(MEDIA_GROUP_ID)
|
|
738
|
+
{
|
|
739
|
+
if (this.token === null && this.config.username)
|
|
740
|
+
{
|
|
741
|
+
await this._init();
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
if (this.config.apiType !== "portal")
|
|
745
|
+
{
|
|
746
|
+
throw new Error("This function is only available for portal API type.");
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
_printDatetime(`Getting media group: ${MEDIA_GROUP_ID}`);
|
|
750
|
+
|
|
751
|
+
try
|
|
752
|
+
{
|
|
753
|
+
const GET_MEDIA_GROUP_INFO = await _getMediaGroup(this, this.token, this.config.serviceApiUrl,
|
|
754
|
+
MEDIA_GROUP_ID, this.debugMode);
|
|
755
|
+
if (GET_MEDIA_GROUP_INFO) _printDatetime(`Media group gotten: ${MEDIA_GROUP_ID}`);
|
|
756
|
+
return GET_MEDIA_GROUP_INFO;
|
|
757
|
+
}
|
|
758
|
+
catch (error)
|
|
759
|
+
{
|
|
760
|
+
_printDatetime(`Media group failed to get: ${MEDIA_GROUP_ID}`);
|
|
761
|
+
throw error;
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
/**
|
|
766
|
+
* @function getMediaItem
|
|
767
|
+
* @async
|
|
768
|
+
* @description Gets media item.
|
|
769
|
+
* @param {string} MEDIA_ITEM_ID - The ID of the media item.
|
|
770
|
+
* @returns {Promise<JSON>} - A promise that resolves when the media item is gotten.
|
|
771
|
+
* Returns the information of the gotten media item.
|
|
772
|
+
* @throws {Error} - An error is thrown if the media item fails to get.
|
|
773
|
+
* @throws {Error} - An error is thrown if the API type is not portal.
|
|
774
|
+
*/
|
|
775
|
+
async getMediaItem(MEDIA_ITEM_ID)
|
|
776
|
+
{
|
|
777
|
+
if (this.token === null && this.config.username)
|
|
778
|
+
{
|
|
779
|
+
await this._init();
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
if (this.config.apiType !== "portal")
|
|
783
|
+
{
|
|
784
|
+
throw new Error("This function is only available for portal API type.");
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
_printDatetime(`Getting media item: ${MEDIA_ITEM_ID}`);
|
|
788
|
+
|
|
789
|
+
try
|
|
790
|
+
{
|
|
791
|
+
const GET_MEDIA_ITEM_INFO = await _getMediaItem(this, this.token, this.config.serviceApiUrl,
|
|
792
|
+
MEDIA_ITEM_ID, this.debugMode);
|
|
793
|
+
if (GET_MEDIA_ITEM_INFO) _printDatetime(`Media item gotten: ${MEDIA_ITEM_ID}`);
|
|
794
|
+
return GET_MEDIA_ITEM_INFO;
|
|
795
|
+
}
|
|
796
|
+
catch (error)
|
|
797
|
+
{
|
|
798
|
+
_printDatetime(`Media item failed to get: ${MEDIA_ITEM_ID}`);
|
|
799
|
+
throw error;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
/**
|
|
804
|
+
* @function getMyContent
|
|
805
|
+
* @async
|
|
806
|
+
* @description Gets favorites and continue watching lists of IDs for the logged in user.
|
|
807
|
+
* @returns {Promise<JSON>} - A promise that resolves when the favorites and continue watching
|
|
808
|
+
* lists of IDs are gotten.
|
|
809
|
+
* Returns the information of the gotten favorites and continue watching lists of IDs.
|
|
810
|
+
* @throws {Error} - An error is thrown if the favorites and continue watching lists of IDs fail
|
|
811
|
+
* to get.
|
|
812
|
+
* @throws {Error} - An error is thrown if the API type is not portal.
|
|
813
|
+
*/
|
|
814
|
+
async getMyContent()
|
|
815
|
+
{
|
|
816
|
+
if (this.token === null && this.config.username)
|
|
817
|
+
{
|
|
818
|
+
await this._init();
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
if (this.config.apiType !== "portal")
|
|
822
|
+
{
|
|
823
|
+
throw new Error("This function is not available for portal API type.");
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
_printDatetime(`Getting my content`);
|
|
827
|
+
|
|
828
|
+
try
|
|
829
|
+
{
|
|
830
|
+
const GET_MY_CONTENT_INFO = await _getMyContent(this, this.token, this.config.serviceApiUrl,
|
|
831
|
+
this.debugMode);
|
|
832
|
+
if (GET_MY_CONTENT_INFO) _printDatetime(`My content gotten`);
|
|
833
|
+
return GET_MY_CONTENT_INFO;
|
|
834
|
+
}
|
|
835
|
+
catch (error)
|
|
836
|
+
{
|
|
837
|
+
_printDatetime(`My content failed to get`);
|
|
838
|
+
throw error;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
/**
|
|
843
|
+
* @function getMyGroup
|
|
844
|
+
* @async
|
|
845
|
+
* @description Gets user's group.
|
|
846
|
+
* @param {string} GROUP_ID - The ID of the group.
|
|
847
|
+
* @returns {Promise<JSON>} - A promise that resolves when the user's group is gotten.
|
|
848
|
+
* Returns the information of the gotten user's group.
|
|
849
|
+
* @throws {Error} - An error is thrown if the user's group fails to get.
|
|
850
|
+
* @throws {Error} - An error is thrown if the API type is not portal.
|
|
851
|
+
*/
|
|
852
|
+
async getMyGroup(GROUP_ID)
|
|
853
|
+
{
|
|
854
|
+
if (this.token === null && this.config.username)
|
|
855
|
+
{
|
|
856
|
+
await this._init();
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
_printDatetime(`Getting my group: ${GROUP_ID}`);
|
|
860
|
+
|
|
861
|
+
try
|
|
862
|
+
{
|
|
863
|
+
const GET_MY_GROUP_INFO = await _getMyGroup(this, this.token, this.config.serviceApiUrl,
|
|
864
|
+
GROUP_ID, this.debugMode);
|
|
865
|
+
if (GET_MY_GROUP_INFO) _printDatetime(`My group gotten: ${GROUP_ID}`);
|
|
866
|
+
return GET_MY_GROUP_INFO;
|
|
867
|
+
}
|
|
868
|
+
catch (error)
|
|
869
|
+
{
|
|
870
|
+
_printDatetime(`My group failed to get: ${GROUP_ID}`);
|
|
871
|
+
throw error;
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
/**
|
|
876
|
+
* @function getSiteConfig
|
|
877
|
+
* @async
|
|
878
|
+
* @description Gets site config.
|
|
879
|
+
* @param {string} SITE_CONFIG_RECORD_ID - The site config record ID.
|
|
880
|
+
* @returns {Promise<JSON>} - A promise that resolves when the site config is gotten.
|
|
881
|
+
* Returns the information of the gotten site config.
|
|
882
|
+
* @throws {Error} - An error is thrown if the site config fails to get.
|
|
883
|
+
* @throws {Error} - An error is thrown if the API type is not portal.
|
|
884
|
+
*/
|
|
885
|
+
async getSiteConfig(SITE_CONFIG_RECORD_ID)
|
|
886
|
+
{
|
|
887
|
+
if (this.token === null && this.config.username)
|
|
888
|
+
{
|
|
889
|
+
await this._init();
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
_printDatetime(`Getting site config: ${SITE_CONFIG_RECORD_ID}`);
|
|
893
|
+
|
|
894
|
+
try
|
|
895
|
+
{
|
|
896
|
+
const GET_DYNAMIC_CONTENT_INFO = await _getSiteConfig(this, this.token,
|
|
897
|
+
this.config.serviceApiUrl, SITE_CONFIG_RECORD_ID, this.debugMode);
|
|
898
|
+
if (GET_DYNAMIC_CONTENT_INFO) _printDatetime(`Site config gotten: ${SITE_CONFIG_RECORD_ID}`);
|
|
899
|
+
return GET_DYNAMIC_CONTENT_INFO;
|
|
900
|
+
}
|
|
901
|
+
catch (error)
|
|
902
|
+
{
|
|
903
|
+
_printDatetime(`Site config failed to get: ${SITE_CONFIG_RECORD_ID}`);
|
|
904
|
+
throw error;
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
/**
|
|
909
|
+
* @function mediaSearch
|
|
910
|
+
* @async
|
|
911
|
+
* @description Searches for media.
|
|
912
|
+
* @param {string | null} QUERY - The query of the search.
|
|
913
|
+
* @param {Array<string> | null} IDS - The IDs of the media to be searched.
|
|
914
|
+
* @param {Array<JSON> | null} SORT_FIELDS - The sort fields of the search.
|
|
915
|
+
* JSON format: [{"fieldName": "string", "sortType": ("Ascending" | "Descending")} ...]
|
|
916
|
+
* @param {number | null} OFFSET - The page offset of the search.
|
|
917
|
+
* @param {number | null} SIZE - The page size of the search.
|
|
918
|
+
* @returns {Promise<JSON>} - A promise that resolves when the media are searched.
|
|
919
|
+
* Returns the information of the searched media.
|
|
920
|
+
* @throws {Error} - An error is thrown if the media fail to search.
|
|
921
|
+
* @throws {Error} - An error is thrown if the API type is not portal.
|
|
922
|
+
*/
|
|
923
|
+
async mediaSearch(QUERY, IDS, SORT_FIELDS, OFFSET, SIZE)
|
|
924
|
+
{
|
|
925
|
+
if (this.token === null && this.config.username)
|
|
926
|
+
{
|
|
927
|
+
await this._init();
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
if (this.config.apiType !== "portal")
|
|
931
|
+
{
|
|
932
|
+
throw new Error("This function is only available for portal API type.");
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
_printDatetime(`Searching media...`);
|
|
936
|
+
|
|
937
|
+
try
|
|
938
|
+
{
|
|
939
|
+
const MEDIA_SEARCH_INFO = await _mediaSearch(this, this.token, this.config.serviceApiUrl,
|
|
940
|
+
QUERY, IDS, SORT_FIELDS, OFFSET, SIZE, this.debugMode);
|
|
941
|
+
if (MEDIA_SEARCH_INFO) _printDatetime(`Media search complete`);
|
|
942
|
+
return MEDIA_SEARCH_INFO;
|
|
943
|
+
}
|
|
944
|
+
catch (error)
|
|
945
|
+
{
|
|
946
|
+
_printDatetime(`Media search failed`);
|
|
947
|
+
throw error;
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
// misc functions
|
|
952
|
+
/**
|
|
953
|
+
* @function miscFunctons
|
|
954
|
+
* @async
|
|
955
|
+
* @description Calls any nomad function given URL method and body.
|
|
956
|
+
* @param {string} URL_PATH - The URL path of the function.
|
|
957
|
+
* @param {string} METHOD - The method of the function.
|
|
958
|
+
* @param {JSON | null} BODY - The body of the api call.
|
|
959
|
+
* @param {boolean | null} NOT_API_PATH - If the path has /api.
|
|
960
|
+
* @returns {Promise<JSON>} - A promise that resolves when the function is called.
|
|
961
|
+
* Returns the information of the called function.
|
|
962
|
+
* @throws {Error} - An error is thrown if the function fails to call.
|
|
963
|
+
*/
|
|
964
|
+
|
|
965
|
+
async miscFunctions(URL_PATH, METHOD, BODY, NOT_API_PATH)
|
|
966
|
+
{
|
|
967
|
+
if (this.token === null && this.config.username)
|
|
968
|
+
{
|
|
969
|
+
await this._init();
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
_printDatetime(`Calling function: ${URL_PATH}`);
|
|
973
|
+
|
|
974
|
+
try
|
|
975
|
+
{
|
|
976
|
+
let API_URL = `${this.config.serviceApiUrl}/${URL_PATH}`;
|
|
977
|
+
if (NOT_API_PATH) {
|
|
978
|
+
API_URL = API_URL.replace('/api', '');
|
|
979
|
+
API_URL = API_URL.replace('app-api.', '');
|
|
980
|
+
API_URL = API_URL.replace('admin-app.', '');
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
const HEADERS = new Headers();
|
|
984
|
+
HEADERS.append("Content-Type", "application/json");
|
|
985
|
+
|
|
986
|
+
if (this.token !== null)
|
|
987
|
+
{
|
|
988
|
+
HEADERS.append("Authorization", `Bearer ${this.token}`);
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
if (this.debugMode)
|
|
992
|
+
{
|
|
993
|
+
console.log(`URL: ${API_URL}\nMETHOD: ${METHOD}`);
|
|
994
|
+
if (BODY) console.log(`BODY: ${JSON.stringify(BODY, null, 4 )}`);
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
const REQUEST = {
|
|
998
|
+
method: METHOD,
|
|
999
|
+
headers: HEADERS
|
|
1000
|
+
};
|
|
1001
|
+
if (BODY) {
|
|
1002
|
+
REQUEST.body = JSON.stringify(BODY);
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
const RESPONSE = await fetch(API_URL, REQUEST);
|
|
1006
|
+
|
|
1007
|
+
const RESPONSE_BODY = await RESPONSE.text();
|
|
1008
|
+
if (!RESPONSE.ok)
|
|
1009
|
+
{
|
|
1010
|
+
try
|
|
1011
|
+
{
|
|
1012
|
+
throw JSON.parse(RESPONSE_BODY);
|
|
1013
|
+
}
|
|
1014
|
+
catch (error)
|
|
1015
|
+
{
|
|
1016
|
+
throw RESPONSE_BODY;
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
try
|
|
1021
|
+
{
|
|
1022
|
+
return JSON.parse(RESPONSE_BODY);
|
|
1023
|
+
}
|
|
1024
|
+
catch (error)
|
|
1025
|
+
{
|
|
1026
|
+
return RESPONSE_BODY;
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
catch (error)
|
|
1030
|
+
{
|
|
1031
|
+
_apiExceptionHandler(error, "API call failed");
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
export default NomadMediaSDK;
|
|
1037
|
+
|
|
1038
|
+
|
|
1039
|
+
|
|
1040
|
+
async function _forgotPassword(instance, URL, USERNAME, DEBUG_MODE)
|
|
1041
|
+
{
|
|
1042
|
+
const API_URL = `${URL}/api/account/forgot-password`;
|
|
1043
|
+
|
|
1044
|
+
const BODY = {
|
|
1045
|
+
username: USERNAME
|
|
1046
|
+
};
|
|
1047
|
+
|
|
1048
|
+
return await _sendRequest(instance, null, "Forgot Password", API_URL, "POST", null, BODY, DEBUG_MODE);
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
|
|
1052
|
+
|
|
1053
|
+
|
|
1054
|
+
async function _login(instance, USERNAME, PASSWORD, URL, DEBUG_MODE)
|
|
1055
|
+
{
|
|
1056
|
+
const API_URL = `${URL}/api/account/login`;
|
|
1057
|
+
|
|
1058
|
+
const BODY = {
|
|
1059
|
+
"userName": USERNAME,
|
|
1060
|
+
"password": PASSWORD
|
|
1061
|
+
};
|
|
1062
|
+
|
|
1063
|
+
try
|
|
1064
|
+
{
|
|
1065
|
+
return await _sendRequest(instance, null, "Login", API_URL, "POST", null, BODY, DEBUG_MODE);
|
|
1066
|
+
}
|
|
1067
|
+
catch (error)
|
|
1068
|
+
{
|
|
1069
|
+
if (error.message.includes("409"))
|
|
1070
|
+
{
|
|
1071
|
+
throw new Error("Invalid username or password");
|
|
1072
|
+
}
|
|
1073
|
+
else
|
|
1074
|
+
{
|
|
1075
|
+
throw error;
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
|
|
1082
|
+
|
|
1083
|
+
|
|
1084
|
+
async function _logout(instance, AUTH_TOKEN, URL, DEBUG_MODE)
|
|
1085
|
+
{
|
|
1086
|
+
const API_URL = `${URL}/api/account/logout`;
|
|
1087
|
+
|
|
1088
|
+
return await _sendRequest(instance, AUTH_TOKEN, "Logout", API_URL, "POST", null, null, DEBUG_MODE);
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
|
|
1094
|
+
|
|
1095
|
+
|
|
1096
|
+
|
|
1097
|
+
async function _refreshToken(instance, AUTH_TOKEN, URL, REFRESH_TOKEN, DEBUG_MODE)
|
|
1098
|
+
{
|
|
1099
|
+
const API_URL = `${URL}/api/account/refresh-token`;
|
|
1100
|
+
|
|
1101
|
+
const BODY = {
|
|
1102
|
+
refreshToken: REFRESH_TOKEN
|
|
1103
|
+
};
|
|
1104
|
+
|
|
1105
|
+
const TOKEN_INFO = await _sendRequest(instance, AUTH_TOKEN, "Refreshing Token", API_URL, "POST", null, BODY, DEBUG_MODE);
|
|
1106
|
+
instance.token = TOKEN_INFO.token;
|
|
1107
|
+
|
|
1108
|
+
return true;
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
|
|
1112
|
+
|
|
1113
|
+
|
|
1114
|
+
|
|
1115
|
+
async function _resetPassword(instance, URL, USERNAME, TOKEN, NEW_PASSWORD, DEBUG_MODE)
|
|
1116
|
+
{
|
|
1117
|
+
const API_URL = `${URL}/api/account/reset-password`;
|
|
1118
|
+
|
|
1119
|
+
const BODY = {
|
|
1120
|
+
userName: USERNAME,
|
|
1121
|
+
TOKEN: TOKEN,
|
|
1122
|
+
newPassword: NEW_PASSWORD
|
|
1123
|
+
};
|
|
1124
|
+
|
|
1125
|
+
return await _sendRequest(instance, null, "Reset Password", API_URL, "POST", null, BODY, DEBUG_MODE);
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
|
|
1129
|
+
function _apiExceptionHandler(error, message) {
|
|
1130
|
+
// Check if we have a response object and error message
|
|
1131
|
+
if (!error) {
|
|
1132
|
+
console.error(message);
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
// Check if error is a string
|
|
1136
|
+
if (typeof error === "string") {
|
|
1137
|
+
console.error(`${message}: ${error}`);
|
|
1138
|
+
}
|
|
1139
|
+
else if (error.errors)
|
|
1140
|
+
{
|
|
1141
|
+
if (Array.isArray(error.errors)) {
|
|
1142
|
+
let errorString = "";
|
|
1143
|
+
for (let errorIdx = 0; errorIdx < error.errors.length; errorIdx++)
|
|
1144
|
+
{
|
|
1145
|
+
errorString += `${error.errors[errorIdx].code}: ${error.errors[errorIdx].field}: ${error.errors[errorIdx].message}\n`;
|
|
1146
|
+
}
|
|
1147
|
+
console.error(`${message}: ${errorString}`);
|
|
1148
|
+
}
|
|
1149
|
+
else if (typeof error.errors === "object") {
|
|
1150
|
+
let errorString = "";
|
|
1151
|
+
for (let key in error.errors) {
|
|
1152
|
+
if (Object.prototype.hasOwnProperty.call(error.errors, key)) {
|
|
1153
|
+
errorString += `${key}: ${error.errors[key]}\n`;
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
console.error(`${message}: ${errorString}`);
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
else
|
|
1160
|
+
{
|
|
1161
|
+
console.error(`${message}: ${error.message}`);
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
return null;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
|
|
1168
|
+
/**
|
|
1169
|
+
* New GUID
|
|
1170
|
+
*
|
|
1171
|
+
* @returns UUID v4 GUID
|
|
1172
|
+
*/
|
|
1173
|
+
|
|
1174
|
+
import { getRandomValues } from 'crypto';
|
|
1175
|
+
|
|
1176
|
+
function _newGuid() {
|
|
1177
|
+
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) =>
|
|
1178
|
+
(c ^ (getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)
|
|
1179
|
+
);
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
|
|
1183
|
+
|
|
1184
|
+
function _printDatetime(msg)
|
|
1185
|
+
{
|
|
1186
|
+
const NOW = new Date();
|
|
1187
|
+
const FORMATTED_TIME = NOW.toLocaleTimeString();
|
|
1188
|
+
console.log(`${FORMATTED_TIME}: ${msg}`);
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
|
|
1192
|
+
|
|
1193
|
+
|
|
1194
|
+
|
|
1195
|
+
|
|
1196
|
+
import axios from 'axios';
|
|
1197
|
+
|
|
1198
|
+
const MAX_RETRIES = 5;
|
|
1199
|
+
const TIMEOUT = 30000;
|
|
1200
|
+
const SLEEP_TIME = .5;
|
|
1201
|
+
|
|
1202
|
+
async function _sendRequest(instance, AUTH_TOKEN, FUNCTION_NAME, URL, METHOD_TYPE, PARAMS, BODY, DEBUG)
|
|
1203
|
+
{
|
|
1204
|
+
const HEADERS = {
|
|
1205
|
+
"Content-Type": "application/json"
|
|
1206
|
+
};
|
|
1207
|
+
|
|
1208
|
+
if (AUTH_TOKEN) HEADERS["Authorization"] = `Bearer ${AUTH_TOKEN}`;
|
|
1209
|
+
|
|
1210
|
+
if (DEBUG && FUNCTION_NAME !== "Login") console.log(`URL: ${URL}\nMETHOD: ${METHOD_TYPE}` + (PARAMS && PARAMS.size === 0 ? `\nPARAMS: ${JSON.stringify(PARAMS, null, 4)}` : "") + (BODY ? `\nBODY: ${JSON.stringify(BODY, null, 4)}` : ""));
|
|
1211
|
+
|
|
1212
|
+
let retries = 0;
|
|
1213
|
+
let RESPONSE = null;
|
|
1214
|
+
let refreshedToken = false;
|
|
1215
|
+
do
|
|
1216
|
+
{
|
|
1217
|
+
try
|
|
1218
|
+
{
|
|
1219
|
+
refreshedToken = true;
|
|
1220
|
+
RESPONSE = await axios({
|
|
1221
|
+
method: METHOD_TYPE,
|
|
1222
|
+
url: URL,
|
|
1223
|
+
headers: HEADERS,
|
|
1224
|
+
params: PARAMS,
|
|
1225
|
+
data: BODY,
|
|
1226
|
+
timeout: TIMEOUT
|
|
1227
|
+
});
|
|
1228
|
+
|
|
1229
|
+
if (RESPONSE.status >= 200 && RESPONSE.status < 300)
|
|
1230
|
+
{
|
|
1231
|
+
break;
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
throw new Error();
|
|
1235
|
+
}
|
|
1236
|
+
catch (error)
|
|
1237
|
+
{
|
|
1238
|
+
if (error?.response?.status === 403 && FUNCTION_NAME !== "Refresh Token" && !refreshedToken)
|
|
1239
|
+
{
|
|
1240
|
+
await instance.refreshToken();
|
|
1241
|
+
HEADERS["Authorization"] = `Bearer ${instance.token}`;
|
|
1242
|
+
refreshedToken = true;
|
|
1243
|
+
}
|
|
1244
|
+
else if (error.code === 'ECONNABORTED')
|
|
1245
|
+
{
|
|
1246
|
+
await _sleep(SLEEP_TIME * 2 ** (retries - 1));
|
|
1247
|
+
}
|
|
1248
|
+
else
|
|
1249
|
+
{
|
|
1250
|
+
return _apiExceptionHandler(error.response?.data.message ? error.response.data.message : error.message, `${FUNCTION_NAME} failed`);
|
|
1251
|
+
}
|
|
1252
|
+
++retries;
|
|
1253
|
+
}
|
|
1254
|
+
} while ((!RESPONSE || RESPONSE.status < 200 || RESPONSE.status >= 300) && retries < MAX_RETRIES);
|
|
1255
|
+
try { return RESPONSE.data; }
|
|
1256
|
+
catch (error) { return; }
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
|
|
1260
|
+
async function _sleep(duration) {
|
|
1261
|
+
// Check for valid duration
|
|
1262
|
+
if (!duration || duration === 0) {
|
|
1263
|
+
// Ignore
|
|
1264
|
+
return;
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
// Sleep
|
|
1268
|
+
return new Promise((resolve) => {
|
|
1269
|
+
setTimeout(() => {
|
|
1270
|
+
resolve();
|
|
1271
|
+
}, duration * 1000);
|
|
1272
|
+
});
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
|
|
1276
|
+
|
|
1277
|
+
function _slugify(text) {
|
|
1278
|
+
if (!text || text.trim().length === 0) return "";
|
|
1279
|
+
return text
|
|
1280
|
+
.toString()
|
|
1281
|
+
.normalize("NFD")
|
|
1282
|
+
.replace(/[\u0300-\u036f]/g, "")
|
|
1283
|
+
.toLowerCase()
|
|
1284
|
+
.trim()
|
|
1285
|
+
.replace(/\s+/g, "-")
|
|
1286
|
+
.replace(/[^\w-]+/g, "")
|
|
1287
|
+
.replace(/--+/g, "-");
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
|
|
1291
|
+
|
|
1292
|
+
|
|
1293
|
+
|
|
1294
|
+
async function _clearContinueWatching(instance, AUTH_TOKEN, URL, USER_ID, ASSET_ID, DEBUG_MODE)
|
|
1295
|
+
{
|
|
1296
|
+
const API_URL = `${URL}/api/media/clear-watching`;
|
|
1297
|
+
|
|
1298
|
+
const PARAMS = {
|
|
1299
|
+
userId: USER_ID,
|
|
1300
|
+
assetId: ASSET_ID
|
|
1301
|
+
};
|
|
1302
|
+
|
|
1303
|
+
return await _sendRequest(instance, AUTH_TOKEN, "Clear Continue Watching", API_URL, "POST", PARAMS, null, DEBUG_MODE);
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
|
|
1307
|
+
|
|
1308
|
+
|
|
1309
|
+
async function _clearWatchlist(instance, AUTH_TOKEN, URL, USER_ID, DEBUG_MODE)
|
|
1310
|
+
{
|
|
1311
|
+
const API_URL = `${URL}/api/media/clear-watchlist?userId=${USER_ID}`;
|
|
1312
|
+
|
|
1313
|
+
return await _sendRequest(instance, AUTH_TOKEN, "Clear Watchlist", API_URL, "POST", null, null, DEBUG_MODE);
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
async function _createForm(instance, AUTH_TOKEN, URL, CONTENT_DEFINITION_ID, FORM_INFO, DEBUG_MODE)
|
|
1320
|
+
{
|
|
1321
|
+
const API_URL = `${URL}/api/media/form/${CONTENT_DEFINITION_ID}`;
|
|
1322
|
+
|
|
1323
|
+
const BODY = FORM_INFO;
|
|
1324
|
+
|
|
1325
|
+
return await _sendRequest(instance, AUTH_TOKEN, "Creating Form", API_URL, "POST", null, BODY, DEBUG_MODE);
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
|
|
1329
|
+
|
|
1330
|
+
|
|
1331
|
+
async function _getContentCookies(instance, AUTH_TOKEN, URL, ID, DEBUG_MODE)
|
|
1332
|
+
{
|
|
1333
|
+
const API_URL = `${URL}/api/media/set-cookies/${ID}`;
|
|
1334
|
+
|
|
1335
|
+
return await _sendRequest(instance, AUTH_TOKEN, "Get Content Cookies", API_URL, "GET", undefined, undefined, DEBUG_MODE);
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
|
|
1339
|
+
|
|
1340
|
+
|
|
1341
|
+
async function _getDefaultSiteConfig(instance, AUTH_TOKEN, URL, DEBUG_MODE)
|
|
1342
|
+
{
|
|
1343
|
+
const API_URL = `${URL}/api/media/config`;
|
|
1344
|
+
|
|
1345
|
+
return await _sendRequest(instance, AUTH_TOKEN, "Get Default Site Config", API_URL, "GET", undefined, undefined, DEBUG_MODE);
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
|
|
1349
|
+
|
|
1350
|
+
|
|
1351
|
+
async function _getDynamicContent(instance, AUTH_TOKEN, URL, ID, DEBUG_MODE)
|
|
1352
|
+
{
|
|
1353
|
+
const API_URL = `${URL}/api/media/content/${ID}`;
|
|
1354
|
+
|
|
1355
|
+
return await _sendRequest(instance, AUTH_TOKEN, "Get Dynamic Content", API_URL, "GET", undefined, undefined, DEBUG_MODE);
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
|
|
1359
|
+
|
|
1360
|
+
|
|
1361
|
+
async function _getDynamicContents(instance, AUTH_TOKEN, URL, DEBUG_MODE)
|
|
1362
|
+
{
|
|
1363
|
+
const API_URL = `${URL}/api/media/content`;
|
|
1364
|
+
|
|
1365
|
+
return await _sendRequest(instance, AUTH_TOKEN, "Get Dynamic Contents", API_URL, "GET", undefined, undefined, DEBUG_MODE);
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
|
|
1369
|
+
|
|
1370
|
+
|
|
1371
|
+
async function _getMediaGroup(instance, AUTH_TOKEN, URL, ID, DEBUG_MODE)
|
|
1372
|
+
{
|
|
1373
|
+
const API_URL = `${URL}/api/media/group/${ID}`;
|
|
1374
|
+
|
|
1375
|
+
return await _sendRequest(instance, AUTH_TOKEN, "Get Media Group", API_URL, "GET", undefined, undefined, DEBUG_MODE);
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
|
|
1379
|
+
|
|
1380
|
+
|
|
1381
|
+
async function _getMediaItem(instance, AUTH_TOKEN, URL, ID, DEBUG_MODE)
|
|
1382
|
+
{
|
|
1383
|
+
const API_URL = `${URL}/api/media/item/${ID}`;
|
|
1384
|
+
|
|
1385
|
+
return await _sendRequest(instance, AUTH_TOKEN, "Get Media Item", API_URL, "GET", undefined, undefined, DEBUG_MODE);
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
|
|
1389
|
+
|
|
1390
|
+
|
|
1391
|
+
async function _getMyContent(instance, AUTH_TOKEN, URL, DEBUG_MODE)
|
|
1392
|
+
{
|
|
1393
|
+
const API_URL = `${URL}/api/media/my-content`;
|
|
1394
|
+
|
|
1395
|
+
return await _sendRequest(instance, AUTH_TOKEN, "Get My Content", API_URL, "GET", undefined, undefined, DEBUG_MODE);
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
|
|
1399
|
+
|
|
1400
|
+
|
|
1401
|
+
async function _getMyGroup(instance, AUTH_TOKEN, URL, ID, DEBUG_MODE)
|
|
1402
|
+
{
|
|
1403
|
+
const API_URL = `${URL}/api/media/my-group/${ID}`;
|
|
1404
|
+
|
|
1405
|
+
return await _sendRequest(instance, AUTH_TOKEN, "Get My Group", API_URL, "GET", undefined, undefined, DEBUG_MODE);
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
|
|
1409
|
+
|
|
1410
|
+
|
|
1411
|
+
async function _getSiteConfig(instance, AUTH_TOKEN, URL, ID, DEBUG_MODE)
|
|
1412
|
+
{
|
|
1413
|
+
const API_URL = `${URL}/api/media/config/${ID}`;
|
|
1414
|
+
|
|
1415
|
+
return await _sendRequest(instance, AUTH_TOKEN, "Get Site Config", API_URL, "GET", undefined, undefined, DEBUG_MODE);
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
|
|
1419
|
+
|
|
1420
|
+
|
|
1421
|
+
async function _mediaSearch(instance, AUTH_TOKEN, URL, SEARCH_QUERY, IDS, SORT_FIELDS,
|
|
1422
|
+
PAGE_OFFSET, PAGE_SIZE, DEBUG_MODE)
|
|
1423
|
+
{
|
|
1424
|
+
const API_URL = `${URL}/api/media/search`;
|
|
1425
|
+
|
|
1426
|
+
const BODY = {
|
|
1427
|
+
searchQuery: SEARCH_QUERY,
|
|
1428
|
+
ids: IDS,
|
|
1429
|
+
sortFields: SORT_FIELDS
|
|
1430
|
+
};
|
|
1431
|
+
|
|
1432
|
+
PAGE_OFFSET ? BODY["pageOffset"] = PAGE_OFFSET : BODY["pageOffset"] = 0;
|
|
1433
|
+
PAGE_SIZE ? BODY["pageSize"] = PAGE_SIZE : BODY["pageSize"] = 100;
|
|
1434
|
+
|
|
1435
|
+
return await _sendRequest(instance, AUTH_TOKEN, "Media Search", API_URL, "POST", null, BODY, DEBUG_MODE);
|
|
1436
|
+
}
|
|
1437
|
+
|