@nomad-media/full 1.1.19-alpha.3 → 1.1.20-alpha.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.
@@ -133,6 +133,9 @@
133
133
 
134
134
 
135
135
 
136
+
137
+
138
+
136
139
 
137
140
 
138
141
 
@@ -273,8 +276,6 @@
273
276
 
274
277
 
275
278
 
276
- import path from 'path';
277
-
278
279
  /**
279
280
  * @class NomadSDK
280
281
  * @classdesc This class is used to interact with the Nomad API.
@@ -325,7 +326,7 @@ class NomadMediaSDK {
325
326
  * @async
326
327
  * @description Logs in using the username and password from the config.
327
328
  * @returns {Promise<void>} - A promise that resolves when the login is successful.
328
- * Updates the token, refresh token, expiration seconds, and user session ID class varibles.
329
+ * Updates the token, refresh token, expiration seconds, and user session ID class variables.
329
330
  * @throws {Error} - An error is thrown if the login fails.
330
331
  */
331
332
  async login()
@@ -381,7 +382,7 @@ class NomadMediaSDK {
381
382
  }
382
383
  catch (error)
383
384
  {
384
- _printDatetime("Loggout failed");
385
+ _printDatetime("Logout failed");
385
386
  throw error;
386
387
  }
387
388
  }
@@ -489,7 +490,7 @@ class NomadMediaSDK {
489
490
  * and cancel. Continue continues the upload from where it left off. Replace replaces an
490
491
  * existing asset. Replace is the one you want to use if you are starting a new upload.
491
492
  * Cancel cancels an uploading asset.
492
- * @param {File | string} FILE - The FILE object or full or relateive path of the file to upload.
493
+ * @param {File | string} FILE - The FILE object or full or relative path of the file to upload.
493
494
  * This is ignored if the ExistingAssetId or if the RelatedContentId has a value.
494
495
  * @param {string | null} PARENT_ID - The Parent AssetId (folder) to add the upload to.
495
496
  * Note that if there is a full relativePath, then it is appended to this parent path.
@@ -514,7 +515,12 @@ class NomadMediaSDK {
514
515
  let startUploadInfo = null
515
516
  try
516
517
  {
517
- const FILE_PROPS = (await _processFile(FILE))[0];
518
+ const FILE_PROPS = (await _processFile(FILE));
519
+ if (!FILE_PROPS)
520
+ {
521
+ _printDatetime("File not found");
522
+ return;
523
+ }
518
524
 
519
525
  _printDatetime("Starting upload");
520
526
  startUploadInfo = await _startUpload(this, NAME, EXISTING_ASSET_ID,
@@ -523,7 +529,9 @@ class NomadMediaSDK {
523
529
 
524
530
  if (!startUploadInfo) throw new Error("Failed to start upload");
525
531
 
526
- await _multiThreadUpload(this, FILE_PROPS, startUploadInfo);
532
+ const response = await _multiThreadUpload(this, FILE_PROPS, startUploadInfo);
533
+ if (!response) throw new Error("Failed to upload");
534
+
527
535
  await _completeUpload(this, startUploadInfo["id"]);
528
536
 
529
537
  const CONTENT_ID = startUploadInfo.assetId;
@@ -557,43 +565,69 @@ class NomadMediaSDK {
557
565
  * The option you want to use when uploading the asset. The options are continue, replace,
558
566
  * and cancel. Continue continues the upload from where it left off. Replace replaces an
559
567
  * existing asset. Replace is the one you want to use if you are starting a new upload.
560
- * @param {FILE | string} FILE - The FILE object or full or relative path of the file to upload.
568
+ * @param {FILE | string | null} FILE - The FILE object or full or relative path of the file to upload.
561
569
  * This is ignored if the ExistingAssetId or if the RelatedContentId has a value
562
570
  * @param {string | null} LANGUAGE_ID - The language of the asset to upload.
563
571
  * If this is left blank then the default system language is used.
572
+ * @param {bytes | null} FILE_CONTENTS - The contents of the file to upload.
573
+ * This is used to upload the file in memory instead of from a file.
564
574
  * @returns {Promise<string>} - A promise that resolves when the related asset is uploaded.
565
575
  * Returns the content ID of the uploaded related asset.
566
576
  * @throws {Error} - An error is thrown if the related asset fails to upload.
567
577
  */
568
578
  async uploadRelatedAsset(EXISTING_ASSET_ID, RELATED_ASSET_ID, NEW_RELATED_ASSET_METADATA_TYPE,
569
- UPLOAD_OVERWRITE_OPTION, FILE, LANGUAGE_ID)
579
+ UPLOAD_OVERWRITE_OPTION, FILE, LANGUAGE_ID, FILE_CONTENTS)
570
580
  {
571
581
  if (this.token === null)
572
582
  {
573
583
  await this._init();
574
584
  }
575
585
 
586
+ if (!FILE && !FILE_CONTENTS)
587
+ {
588
+ throw new Error("Either FILE or FILE_CONTENTS must be provided.");
589
+ }
590
+
576
591
  _printDatetime(`Uploading related asset`);
577
592
 
578
593
  let startUploadInfo = null;
579
594
  try
580
595
  {
581
- const [FILE_PROPS, FILE_PATH] = await _processFile(FILE);
596
+ let fileProps = null;
597
+ if (!FILE_CONTENTS)
598
+ {
599
+ const fileProps = await _processFile(FILE);
600
+ if (!fileProps)
601
+ {
602
+ _printDatetime("File not found");
603
+ return;
604
+ }
605
+ }
606
+ else
607
+ {
608
+ fileProps = {
609
+ originalname: FILE,
610
+ size: FILE_CONTENTS.byteLength
611
+ };
612
+ }
582
613
 
583
614
  startUploadInfo = await _startRelatedAssetUpload(this, EXISTING_ASSET_ID,
584
615
  RELATED_ASSET_ID, NEW_RELATED_ASSET_METADATA_TYPE, UPLOAD_OVERWRITE_OPTION,
585
- FILE_PROPS, LANGUAGE_ID);
616
+ fileProps, LANGUAGE_ID);
586
617
 
587
618
  if (!startUploadInfo) throw new Error("Failed to start related asset upload");
588
619
 
589
- await _multiThreadUpload(this, FILE_PROPS, startUploadInfo);
620
+ const response = await _multiThreadUpload(this, fileProps, startUploadInfo, FILE_CONTENTS);
621
+ if (!response) throw new Error("Failed to upload");
590
622
 
591
623
  await _completeUpload(this, startUploadInfo.id);
592
624
  _printDatetime("Related asset upload successful");
593
625
 
594
626
  const DETAILS = await _getAssetDetails(this, EXISTING_ASSET_ID);
595
627
 
596
- const ASSET_INFO = DETAILS.relatedAssets.find(asset => asset.url.includes(path.basename(FILE_PATH)));
628
+ const FILE_NAME = FILE_CONTENTS ? FILE : fileProps.originalName;
629
+
630
+ const ASSET_INFO = DETAILS.relatedAssets.find(asset => asset.url.includes(FILE_NAME));
597
631
  if (!ASSET_INFO) throw new Error("Asset ID not found");
598
632
  return ASSET_INFO.id;
599
633
  }
@@ -1505,7 +1539,7 @@ class NomadMediaSDK {
1505
1539
  * @param {string | null} CONTENT_DEFINITION_GROUP - The content definition group of the content definition to update.
1506
1540
  * enum: Custom Definitions, Forms, Layout, Navigation, Page Content, System Definitions
1507
1541
  * @param {string | null} CONTENT_DEFINITION_TYPE - The content definition type of the content definition to update.
1508
- * enum: Asset List Content Type, Basic Content, Dynamic Module Content Type, Form Content Type, Navigetion Content Type
1542
+ * enum: Asset List Content Type, Basic Content, Dynamic Module Content Type, Form Content Type, navigation Content Type
1509
1543
  * @param {string | null} DISPLAY_FIELD - The display field of the content definition to update. Must be a field in the content definition or the content field
1510
1544
  * @param {string | null} ROUTE_ITEM_NAME_FIELD - The route item name field of the content definition to update. Must be a field in the content definition or the content field
1511
1545
  * @param {Array<string> | null} SECURITY_GROUPS - The security groups of the content definition to update.
@@ -1643,7 +1677,7 @@ class NomadMediaSDK {
1643
1677
  /**
1644
1678
  * @function addLiveScheduleToEvent
1645
1679
  * @async
1646
- * @description Adds a live schedule to an event and updated live schedule attatched to event.
1680
+ * @description Adds a live schedule to an event and updated live schedule attached to event.
1647
1681
  * @param {string} EVENT_ID - The ID of the event to add the live schedule to.
1648
1682
  * @param {JSON | null} SLATE_VIDEO - The slate video ID of the event.
1649
1683
  * JSON format: {"id": string, "description": string }
@@ -1762,6 +1796,11 @@ class NomadMediaSDK {
1762
1796
  await this._init();
1763
1797
  }
1764
1798
 
1799
+ if (this.config.apiType !== "admin")
1800
+ {
1801
+ throw new Error ("This function is only available for admin API type.");
1802
+ }
1803
+
1765
1804
  _printDatetime(`Getting Live Schedule of Event: ${EVENT_ID}`);
1766
1805
 
1767
1806
  try
@@ -1793,6 +1832,11 @@ class NomadMediaSDK {
1793
1832
  await this._init();
1794
1833
  }
1795
1834
 
1835
+ if (this.config.apiType !== "admin")
1836
+ {
1837
+ throw new Error ("This function is only available for admin API type.");
1838
+ }
1839
+
1796
1840
  _printDatetime(`Starting Live Schedule of Event: ${EVENT_ID}`);
1797
1841
 
1798
1842
  try
@@ -1822,6 +1866,11 @@ class NomadMediaSDK {
1822
1866
  {
1823
1867
  await this._init();
1824
1868
  }
1869
+
1870
+ if (this.config.apiType !== "admin")
1871
+ {
1872
+ throw new Error ("This function is only available for admin API type.");
1873
+ }
1825
1874
 
1826
1875
  _printDatetime(`Stopping Live Schedule of Event: ${EVENT_ID}`);
1827
1876
 
@@ -1837,6 +1886,87 @@ class NomadMediaSDK {
1837
1886
  }
1838
1887
  }
1839
1888
 
1889
+ // job functions
1890
+ /**
1891
+ * @function createJob
1892
+ * @async
1893
+ * @description Creates a job.
1894
+ * @param {string} BUCKET_NAME - The name of the bucket to create the job in.
1895
+ * @param {string} OBJECT_KEY - The object key of the job.
1896
+ * @param {string} NOTIFICATION_CALLBACK_URL - The url to send the job notification to.
1897
+ * @param {string} EXTERNAL_ID - The external id of the job.
1898
+ * @param {boolean | null} REPLACE_EXISTING_JOB - Whether to replace an existing job.
1899
+ * @param {string | null} ASSET_URL - The asset url of the job.
1900
+ * @param {Array<string> | null} REQUESTED_TASKS - The tasks to request for the job.
1901
+ * @param {Array<string> | null} REQUESTED_TRANSCODE_PROFILES - The transcode profiles to request for the job.
1902
+ * @returns {Promise<JSON>} - A promise that resolves when the job is created.
1903
+ * Returns the id of the asset created.
1904
+ * @throws {Error} - An error is thrown if the job fails to create.
1905
+ * @throws {Error} - An error is thrown if the API type is not admin.
1906
+ */
1907
+ async createJob(
1908
+ BUCKET_NAME, OBJECT_KEY, NOTIFICATION_CALLBACK_URL, EXTERNAL_ID,
1909
+ REPLACE_EXISTING_JOB, ASSET_URL, REQUESTED_TASKS, REQUESTED_TRANSCODE_PROFILES)
1910
+ {
1911
+ if (this.token === null)
1912
+ {
1913
+ await this._init();
1914
+ }
1915
+
1916
+ if (this.config.apiType !== "admin")
1917
+ {
1918
+ throw new Error("This function is only available for admin API type.");
1919
+ }
1920
+
1921
+ _printDatetime(`Creating job: ${BUCKET_NAME}`);
1922
+
1923
+ try
1924
+ {
1925
+ const CREATE_JOB_RESULT = await _createJob(
1926
+ this, BUCKET_NAME, OBJECT_KEY, NOTIFICATION_CALLBACK_URL, EXTERNAL_ID,
1927
+ REPLACE_EXISTING_JOB, ASSET_URL, REQUESTED_TASKS, REQUESTED_TRANSCODE_PROFILES);
1928
+ if (CREATE_JOB_RESULT) _printDatetime(`Job created: ${BUCKET_NAME}`);
1929
+ return CREATE_JOB_RESULT;
1930
+ } catch (error) {
1931
+ _printDatetime(`Job failed: ${BUCKET_NAME}`);
1932
+ throw error;
1933
+ }
1934
+ }
1935
+
1936
+ /**
1937
+ * @function createJobId
1938
+ * @async
1939
+ * @description Creates a job.
1940
+ * @param {string} ASSET_ID - The asset id of the job.
1941
+ * @param {string} JOB_RESULTS_URL - The job results url of the job.
1942
+ * @param {string | null} EXTERNAL_ID - The external id of the job.
1943
+ * @throws {Error} - An error is thrown if the create job fails.
1944
+ * @throws {Error} - An error is thrown if the API type is not admin.
1945
+ */
1946
+ async createJobId(ASSET_ID, JOB_RESULTS_URL, EXTERNAL_ID)
1947
+ {
1948
+ if (this.token === null)
1949
+ {
1950
+ await this._init();
1951
+ }
1952
+
1953
+ if (this.config.apiType !== "admin")
1954
+ {
1955
+ throw new Error("This function is only available for admin API type.");
1956
+ }
1957
+
1958
+ _printDatetime(`Creating job: ${ASSET_ID}`);
1959
+
1960
+ try
1961
+ {
1962
+ await _createJob(
1963
+ this, ASSET_ID, JOB_RESULTS_URL, EXTERNAL_ID);
1964
+ _printDatetime(`Job created: ${ASSET_ID}`);
1965
+ } catch (error) {
1966
+ _printDatetime(`Job failed: ${ASSET_ID}`);
1967
+ throw error;
1968
+ }
1969
+ }
1840
1970
 
1841
1971
  // live channel functions
1842
1972
  /**
@@ -5843,7 +5973,7 @@ class NomadMediaSDK {
5843
5973
  /**
5844
5974
  * @function copyAsset
5845
5975
  * @async
5846
- * @description Copys an asset.
5976
+ * @description Copies an asset.
5847
5977
  * @param {Array<string>} ASSET_IDS - The IDs of the asset to copy.
5848
5978
  * @param {string} DESTINATION_FOLDER_ID - The destination folder ID of the asset.
5849
5979
  * @param {JSON | null} BATCH_ACTION - The actions to be performed.
@@ -5852,14 +5982,14 @@ class NomadMediaSDK {
5852
5982
  * @param {string | null} SCHEMA_NAME - The schema name of the asset.
5853
5983
  * Note that we convert all incoming keys to lower first char to help with serialization for JSON later
5854
5984
  * JSON format: {"key": "string", "value": "string"}
5855
- * @param {boolean | null} RESOLVER_EXCEMPT - The resolver excempt of the asset.
5985
+ * @param {boolean | null} RESOLVER_EXEMPT - The resolver exempt of the asset.
5856
5986
  * @returns {Promise<JSON>} - A promise that resolves when the assets are performed.
5857
5987
  * Returns the information of the performed assets.
5858
5988
  * @throws {Error} - An error is thrown if the assets fail to perform.
5859
5989
  * @throws {Error} - An error is thrown if the API type is not admin.
5860
5990
  */
5861
5991
  async copyAsset(ASSET_IDS, DESTINATION_FOLDER_ID, BATCH_ACTION,
5862
- CONTENT_DEFINITION_ID, SCHEMA_NAME, RESOLVER_EXCEMPT)
5992
+ CONTENT_DEFINITION_ID, SCHEMA_NAME, RESOLVER_EXEMPT)
5863
5993
  {
5864
5994
  if (this.token === null)
5865
5995
  {
@@ -5876,7 +6006,7 @@ class NomadMediaSDK {
5876
6006
  try
5877
6007
  {
5878
6008
  const COPY_INFO = await _copyAsset(this, ASSET_IDS, DESTINATION_FOLDER_ID, BATCH_ACTION,
5879
- CONTENT_DEFINITION_ID, SCHEMA_NAME, RESOLVER_EXCEMPT);
6009
+ CONTENT_DEFINITION_ID, SCHEMA_NAME, RESOLVER_EXEMPT);
5880
6010
  if (COPY_INFO) _printDatetime(`Asset(s) copied: ${ASSET_IDS}`);
5881
6011
  return COPY_INFO;
5882
6012
  }
@@ -6850,14 +6980,14 @@ class NomadMediaSDK {
6850
6980
  * @param {JSON | null} BATCH_ACTION - The batch action of the move.
6851
6981
  * @param {string | null} CONTENT_DEFINITION_ID - The content definition ID of the move.
6852
6982
  * @param {string | null} SCHEMA_NAME - The schema name of the move.
6853
- * @param {boolean | null} RESOLVER_EXCEMPT - The resolver excempt of the move.
6983
+ * @param {boolean | null} RESOLVER_EXEMPT - The resolver exempt of the move.
6854
6984
  * @returns {Promise<JSON>} - A promise that resolves when the asset is moved.
6855
6985
  * Returns the information of the moved asset.
6856
6986
  * @throws {Error} - An error is thrown if the asset fails to move.
6857
6987
  * @throws {Error} - An error is thrown if the API type is not admin.
6858
6988
  */
6859
6989
  async moveAsset(ASSET_ID, DESTINATION_FOLDER_ID, NAME, BATCH_ACTION,
6860
- CONTENT_DEFINITION_ID, SCHEMA_NAME, RESOLVER_EXCEMPT)
6990
+ CONTENT_DEFINITION_ID, SCHEMA_NAME, RESOLVER_EXEMPT)
6861
6991
  {
6862
6992
  if (this.token === null)
6863
6993
  {
@@ -6874,7 +7004,7 @@ class NomadMediaSDK {
6874
7004
  try
6875
7005
  {
6876
7006
  const MOVE_INFO = await _moveAsset(this, ASSET_ID, DESTINATION_FOLDER_ID, NAME,
6877
- BATCH_ACTION, CONTENT_DEFINITION_ID, SCHEMA_NAME, RESOLVER_EXCEMPT);
7007
+ BATCH_ACTION, CONTENT_DEFINITION_ID, SCHEMA_NAME, RESOLVER_EXEMPT);
6878
7008
  if (MOVE_INFO) _printDatetime(`Asset moved: ${ASSET_ID}`);
6879
7009
  return MOVE_INFO;
6880
7010
  }
@@ -6947,7 +7077,7 @@ class NomadMediaSDK {
6947
7077
  * "Moving", "SlugReplaced", "Updating", "Error", "Assembling", "Clipping", "Placeholder", "Creating"
6948
7078
  * @param {string | null} STORAGE_CLASS - The storage class of the register.
6949
7079
  * enum: "Standard", "ReducedRedundancy", "Glacier", "StandardInfrequentAccess",
6950
- * "OneZoneInfrequentAccess", "IntelligentTiering", "DeepArchive", "GlacierInstanctRetrival",
7080
+ * "OneZoneInfrequentAccess", "IntelligentTiering", "DeepArchive", "GlacierInstantRetrieval",
6951
7081
  * "Outposts"
6952
7082
  * @param {string | null} ASSET_TYPE - The asset type of the register.
6953
7083
  * enum: "Folder", "File", "Bucket"
@@ -7466,7 +7596,7 @@ class NomadMediaSDK {
7466
7596
  * @param {Array<string> | null} FULL_URL_FIELD_NAMES - Gets or sets the list of fields that should have
7467
7597
  * the FullURL calculated. The calculations are expensive and greatly slow down the query.
7468
7598
  * @param {string | null} DISTINCT_ON_FIELD_NAME - Gets or sets optional property that will be used to
7469
- * aggregate results records to distinct occurances of this field's values.
7599
+ * aggregate results records to distinct occurrences of this field's values.
7470
7600
  * @param {boolean | null} INCLUDE_VIDEO_CLIPS - Gets or sets a value indicating whether specify
7471
7601
  * if the video search results are grouped by include clips of the videos also.*
7472
7602
  * @param {bool | null} USE_LLM_SEARCH - Gets or sets a value indicating whether gets or
@@ -9900,7 +10030,7 @@ class NomadMediaSDK {
9900
10030
 
9901
10031
  // misc functions
9902
10032
  /**
9903
- * @function miscFunctons
10033
+ * @function miscFunctions
9904
10034
  * @async
9905
10035
  * @description Calls any nomad function given URL method and body.
9906
10036
  * @param {string} URL_PATH - The URL path of the function.
@@ -9995,44 +10125,49 @@ async function _cancelUpload(instance, ID)
9995
10125
 
9996
10126
 
9997
10127
 
9998
- const MAX_CONCURRENT_PROMISES = 8;
10128
+ const MAX_CONCURRENT_PROMISES = 3;
9999
10129
 
10000
- async function _multiThreadUpload(instance, FILE, UPLOAD_RESPONSE)
10130
+ async function _multiThreadUpload(instance, FILE, UPLOAD_RESPONSE, FILE_CONTENTS)
10001
10131
  {
10002
10132
  const PARTS = UPLOAD_RESPONSE.parts;
10003
10133
  const LENGTH = PARTS.length;
10004
- const NUM_TRIES = 5;
10134
+ const abortController = new AbortController();
10005
10135
 
10006
- for (let INDEX = 0; INDEX < LENGTH; INDEX += MAX_CONCURRENT_PROMISES)
10007
- {
10008
- const batch = PARTS.slice(INDEX, INDEX + MAX_CONCURRENT_PROMISES);
10009
- const batchPromises = batch.map(async (PART, INDEX) => {
10010
- for (let tryIdx = 0; tryIdx < NUM_TRIES; ++tryIdx)
10011
- {
10012
- try
10013
- {
10136
+ try {
10137
+ for (let INDEX = 0; INDEX < LENGTH; INDEX += MAX_CONCURRENT_PROMISES)
10138
+ {
10139
+ const batch = PARTS.slice(INDEX, INDEX + MAX_CONCURRENT_PROMISES);
10140
+ const batchPromises = batch.map(async (PART, INDEX) => {
10141
+ if (abortController.signal.aborted) return false;
10142
+
10143
+ try {
10014
10144
  console.log(`Uploading part ${INDEX + 1} of ${LENGTH}...`);
10015
- const ETAG = await _uploadPart(FILE, PART, instance.debug);
10145
+ const ETAG = await _uploadPart(FILE, PART, FILE_CONTENTS, instance.debug);
10146
+ if (!ETAG) {
10147
+ throw new Error("Connection error");
10148
+ }
10149
+
10016
10150
  await _uploadPartComplete(instance, PART.id, ETAG);
10017
10151
  console.log(`Uploaded part ${INDEX + 1} of ${LENGTH} successfully`);
10018
- break;
10019
- }
10020
- catch (error)
10021
- {
10022
- if (tryIdx === NUM_TRIES - 1)
10023
- {
10024
- throw error;
10025
- }
10026
- else
10027
- {
10028
- console.log(`Error uploading parts: ${error}. Retrying...`);
10029
- await new Promise((resolve) => setTimeout(resolve, 20000));
10030
- }
10152
+ } catch (error) {
10153
+ abortController.abort();
10154
+ console.error(`Upload failed at part ${INDEX + 1}: ${error}`);
10155
+ throw error;
10031
10156
  }
10157
+ });
10158
+
10159
+ await Promise.all(batchPromises).catch(error => {
10160
+ throw error;
10161
+ });
10162
+
10163
+ if (abortController.signal.aborted) {
10164
+ return false;
10032
10165
  }
10033
- });
10166
+ }
10034
10167
 
10035
- await Promise.all(batchPromises);
10168
+ return true;
10169
+ } catch (error) {
10170
+ return false;
10036
10171
  }
10037
10172
  }
10038
10173
 
@@ -10050,7 +10185,7 @@ async function _startUpload(instance, NAME, EXISTING_ASSET_ID, RELATED_CONTENT_I
10050
10185
  displayName: NAME || FILE.originalname,
10051
10186
  contentLength: FILE.size,
10052
10187
  uploadOverwriteOption: UPLOAD_OVERWRITE_OPTION,
10053
- relativePath: FILE.originalname,
10188
+ relativePath: FILE.originalName,
10054
10189
  parentId: PARENT_ID,
10055
10190
  chunkSize: CHUNK_SIZE,
10056
10191
  relatedContentId: RELATED_CONTENT_ID,
@@ -10113,16 +10248,23 @@ async function _uploadPartComplete(instance, PART_ID, ETAG)
10113
10248
 
10114
10249
  import { Buffer } from "buffer";
10115
10250
 
10116
- async function _uploadPart(FILE, PART, DEBUG_MODE, maxRetries = 3)
10251
+ async function _uploadPart(FILE, PART, FILE_CONTENTS, DEBUG_MODE, maxRetries = 3)
10117
10252
  {
10118
- for (let attempt = 0; attempt < maxRetries; attempt++)
10119
- {
10253
+ for (let attempt = 0; attempt < maxRetries; ++attempt)
10254
+ {
10120
10255
  try
10121
10256
  {
10122
- const BUFFER = Buffer.from(FILE.buffer, 'binary');
10123
- const BODY = BUFFER.slice(PART.startingPostion, PART.endingPosition + 1);
10257
+ let body;
10258
+ if (FILE_CONTENTS)
10259
+ {
10260
+ body = FILE_CONTENTS.slice(PART.startingPosition, PART.endingPosition + 1);
10261
+ }
10262
+ else
10263
+ {
10264
+ const BUFFER = Buffer.from(FILE.buffer, 'binary');
10265
+ body = BUFFER.slice(PART.startingPosition, PART.endingPosition + 1);
10266
+ }
10124
10267
 
10125
- // Create header for the request
10126
10268
  const HEADERS = new Headers();
10127
10269
  HEADERS.append("Accept", "application/json, text/plain, */*");
10128
10270
 
@@ -10131,7 +10273,7 @@ async function _uploadPart(FILE, PART, DEBUG_MODE, maxRetries = 3)
10131
10273
  const RESPONSE = await fetch(PART.url, {
10132
10274
  method: "PUT",
10133
10275
  headers: HEADERS,
10134
- body: BODY
10276
+ body: body
10135
10277
  });
10136
10278
 
10137
10279
  if (!RESPONSE.ok)
@@ -10145,13 +10287,11 @@ async function _uploadPart(FILE, PART, DEBUG_MODE, maxRetries = 3)
10145
10287
  catch (error)
10146
10288
  {
10147
10289
  if (attempt < maxRetries - 1)
10148
- {
10149
- // Retry if there are more attempts left
10290
+ {
10150
10291
  console.error(`Upload attempt ${attempt + 1} failed. Retrying...`);
10151
10292
  }
10152
10293
  else
10153
10294
  {
10154
- // No more retries left, handle the error
10155
10295
  _apiExceptionHandler(error, "Upload Part Failed");
10156
10296
  break;
10157
10297
  }
@@ -10435,65 +10575,65 @@ async function _getContent(instance, CONTENT_ID, CONTENT_DEFINITION_ID, IS_REVIS
10435
10575
  }
10436
10576
 
10437
10577
 
10438
-
10439
-
10440
- import deepEqual from "deep-equal";
10441
-
10442
- async function _updateContent(instance, CONTENT_ID, CONTENT_DEFINITION_ID, PROPERTIES, LANGUAGE_ID)
10443
- {
10444
- const API_URL = `${instance.config.serviceApiUrl}/api/content/${CONTENT_ID}`;
10445
-
10446
- let body = null;
10447
- try
10448
- {
10449
- body = await _getContent(instance, CONTENT_ID, CONTENT_DEFINITION_ID, null);
10450
-
10451
- if (body.contentDefinitionId !== CONTENT_DEFINITION_ID) body.contentDefinitionId = CONTENT_DEFINITION_ID;
10452
- if (body.contentId !== CONTENT_ID) body.contentId = CONTENT_ID;
10453
- if (body.language !== LANGUAGE_ID) body.language = LANGUAGE_ID;
10454
-
10455
- _updateProperties(body, PROPERTIES);
10456
- }
10457
- catch (error)
10458
- {
10459
- body = {
10460
- contentDefinitionId: CONTENT_DEFINITION_ID,
10461
- contentId: CONTENT_ID,
10462
- language: LANGUAGE_ID,
10463
- properties: PROPERTIES
10464
- }
10465
- }
10466
-
10467
- return await _sendRequest(instance, "Update Content", API_URL, "PUT", undefined, body);
10468
- }
10469
-
10470
- function _updateProperties(body, properties) {
10471
- for (const property in properties) {
10472
- if (Array.isArray(properties[property]))
10473
- {
10474
- for (let i = 0; i < properties[property].length; ++i)
10475
- {
10476
- if (!deepEqual(body.properties[property][i], properties[property][i]))
10477
- {
10478
- body.properties[property][i] = properties[property][i];
10479
- }
10480
- }
10481
- }
10482
- else if (typeof properties[property] === 'object')
10483
- {
10484
- if (!deepEqual(body.properties[property], properties[property]))
10485
- {
10486
- body.properties[property] = properties[property];
10487
- }
10488
- }
10489
- else if (body.properties[property] !== properties[property])
10490
- {
10491
- body.properties[property] = properties[property];
10492
- }
10493
- }
10494
- }
10495
-
10496
-
10578
+
10579
+
10580
+ import deepEqual from "deep-equal";
10581
+
10582
+ async function _updateContent(instance, CONTENT_ID, CONTENT_DEFINITION_ID, PROPERTIES, LANGUAGE_ID)
10583
+ {
10584
+ const API_URL = `${instance.config.serviceApiUrl}/api/content/${CONTENT_ID}`;
10585
+
10586
+ let body = null;
10587
+ try
10588
+ {
10589
+ body = await _getContent(instance, CONTENT_ID, CONTENT_DEFINITION_ID, null);
10590
+
10591
+ if (body.contentDefinitionId !== CONTENT_DEFINITION_ID) body.contentDefinitionId = CONTENT_DEFINITION_ID;
10592
+ if (body.contentId !== CONTENT_ID) body.contentId = CONTENT_ID;
10593
+ if (body.language !== LANGUAGE_ID) body.language = LANGUAGE_ID;
10594
+
10595
+ _updateProperties(body, PROPERTIES);
10596
+ }
10597
+ catch (error)
10598
+ {
10599
+ body = {
10600
+ contentDefinitionId: CONTENT_DEFINITION_ID,
10601
+ contentId: CONTENT_ID,
10602
+ language: LANGUAGE_ID,
10603
+ properties: PROPERTIES
10604
+ }
10605
+ }
10606
+
10607
+ return await _sendRequest(instance, "Update Content", API_URL, "PUT", undefined, body);
10608
+ }
10609
+
10610
+ function _updateProperties(body, properties) {
10611
+ for (const property in properties) {
10612
+ if (Array.isArray(properties[property]))
10613
+ {
10614
+ for (let i = 0; i < properties[property].length; ++i)
10615
+ {
10616
+ if (!deepEqual(body.properties[property][i], properties[property][i]))
10617
+ {
10618
+ body.properties[property][i] = properties[property][i];
10619
+ }
10620
+ }
10621
+ }
10622
+ else if (typeof properties[property] === 'object')
10623
+ {
10624
+ if (!deepEqual(body.properties[property], properties[property]))
10625
+ {
10626
+ body.properties[property] = properties[property];
10627
+ }
10628
+ }
10629
+ else if (body.properties[property] !== properties[property])
10630
+ {
10631
+ body.properties[property] = properties[property];
10632
+ }
10633
+ }
10634
+ }
10635
+
10636
+
10497
10637
 
10498
10638
 
10499
10639
 
@@ -10624,6 +10764,43 @@ async function _stopLiveSchedule(instance, EVENT_ID)
10624
10764
 
10625
10765
 
10626
10766
 
10767
+ async function _createJobId(instance, assetId, jobResultsUrl, externalId)
10768
+ {
10769
+ const API_URL = `${instance.config.serviceApiUrl}/api/admin/job/${assetId}`;
10770
+
10771
+ const body = {
10772
+ jobResultsUrl: jobResultsUrl,
10773
+ externalId: externalId
10774
+ };
10775
+
10776
+ return await _sendRequest(instance, "Create Job Id", API_URL, "POST", undefined, body);
10777
+ }
10778
+
10779
+
10780
+
10781
+
10782
+ async function _createJob(instance, bucketName, objectKey, notificationCallbackUrl, externalId,
10783
+ replaceExistingJob, assetUrl, requestedTasks, requestedTranscodeProfiles)
10784
+ {
10785
+ const API_URL = `${instance.config.serviceApiUrl}/api/admin/job`;
10786
+
10787
+ const body = {
10788
+ bucketName: bucketName,
10789
+ objectKey: objectKey,
10790
+ notificationCallbackUrl: notificationCallbackUrl,
10791
+ externalId: externalId,
10792
+ replaceExistingJob: replaceExistingJob,
10793
+ assetUrl: assetUrl,
10794
+ requestedTasks: requestedTasks,
10795
+ requestedTranscodeProfiles: requestedTranscodeProfiles
10796
+ };
10797
+
10798
+ return await _sendRequest(instance, "Create Job", API_URL, "POST", undefined, body);
10799
+ }
10800
+
10801
+
10802
+
10803
+
10627
10804
  async function _clipLiveChannel(instance, CHANNEL_ID, START_TIME_CODE, END_TIME_CODE,
10628
10805
  TITLE, OUTPUT_FOLDER_ID, TAGS, COLLECTIONS, RELATED_CONTENTS, VIDEO_BITRATE,
10629
10806
  AUDIO_TRACKS)
@@ -10646,64 +10823,64 @@ async function _clipLiveChannel(instance, CHANNEL_ID, START_TIME_CODE, END_TIME_
10646
10823
  }
10647
10824
 
10648
10825
 
10649
-
10650
-
10651
-
10652
-
10653
-
10654
-
10655
- async function _createLiveChannel(instance, NAME, THUMBNAIL_IMAGE_ID, ARCHIVE_FOLDER_ASSET_ID,
10656
- ENABLE_HIGH_AVAILABILITY, ENABLE_LIVE_CLIPPING, IS_SECURE_OUTPUT, IS_OUTPUT_SCREENSHOTS,
10657
- TYPE, EXTERNAL_URL, EXTERNAL_OUTPUT_PROFILES, SECURITY_GROUPS)
10658
- {
10659
- const API_URL = `${instance.config.serviceApiUrl}/api/liveChannel`;
10660
-
10661
- const BODY = {
10662
- name: NAME,
10663
- routeName: _slugify(NAME),
10664
- enableHighAvailability: ENABLE_HIGH_AVAILABILITY,
10665
- enableLiveClipping: ENABLE_LIVE_CLIPPING,
10666
- externalOutputProfiles: EXTERNAL_OUTPUT_PROFILES,
10667
- isSecureOutput: IS_SECURE_OUTPUT,
10668
- outputScreenshots: IS_OUTPUT_SCREENSHOTS,
10669
- type: {
10670
- id: _LIVE_CHANNEL_TYPES[TYPE],
10671
- descrption: TYPE
10672
- }
10673
- };
10674
-
10675
-
10676
- if (THUMBNAIL_IMAGE_ID)
10677
- {
10678
- BODY.thumbnailImage = { id: THUMBNAIL_IMAGE_ID };
10679
- }
10680
-
10681
- if (ARCHIVE_FOLDER_ASSET_ID)
10682
- {
10683
- BODY.archiveFolderAsset = { id: ARCHIVE_FOLDER_ASSET_ID };
10684
- }
10685
-
10686
- // Set the appropriate fields based on the channel type
10687
- if (TYPE === "External")
10688
- {
10689
- BODY.externalUrl = EXTERNAL_URL;
10690
- }
10691
-
10692
- if (SECURITY_GROUPS) {
10693
- const NOMAD_SECURITY_GROUPS = await _getSecurityGroups(instance);
10694
-
10695
- BODY.securityGroups = NOMAD_SECURITY_GROUPS.items
10696
- .filter(group => SECURITY_GROUPS.includes(group.description))
10697
- .map(group => ({
10698
- description: group.description,
10699
- id: group.id
10700
- }));
10701
- }
10702
-
10703
- return await _sendRequest(instance, "Create Live Channel", API_URL, "POST", undefined, BODY);
10704
- }
10705
-
10706
-
10826
+
10827
+
10828
+
10829
+
10830
+
10831
+
10832
+ async function _createLiveChannel(instance, NAME, THUMBNAIL_IMAGE_ID, ARCHIVE_FOLDER_ASSET_ID,
10833
+ ENABLE_HIGH_AVAILABILITY, ENABLE_LIVE_CLIPPING, IS_SECURE_OUTPUT, IS_OUTPUT_SCREENSHOTS,
10834
+ TYPE, EXTERNAL_URL, EXTERNAL_OUTPUT_PROFILES, SECURITY_GROUPS)
10835
+ {
10836
+ const API_URL = `${instance.config.serviceApiUrl}/api/liveChannel`;
10837
+
10838
+ const BODY = {
10839
+ name: NAME,
10840
+ routeName: _slugify(NAME),
10841
+ enableHighAvailability: ENABLE_HIGH_AVAILABILITY,
10842
+ enableLiveClipping: ENABLE_LIVE_CLIPPING,
10843
+ externalOutputProfiles: EXTERNAL_OUTPUT_PROFILES,
10844
+ isSecureOutput: IS_SECURE_OUTPUT,
10845
+ outputScreenshots: IS_OUTPUT_SCREENSHOTS,
10846
+ type: {
10847
+ id: _LIVE_CHANNEL_TYPES[TYPE],
10848
+ descrption: TYPE
10849
+ }
10850
+ };
10851
+
10852
+
10853
+ if (THUMBNAIL_IMAGE_ID)
10854
+ {
10855
+ BODY.thumbnailImage = { id: THUMBNAIL_IMAGE_ID };
10856
+ }
10857
+
10858
+ if (ARCHIVE_FOLDER_ASSET_ID)
10859
+ {
10860
+ BODY.archiveFolderAsset = { id: ARCHIVE_FOLDER_ASSET_ID };
10861
+ }
10862
+
10863
+ // Set the appropriate fields based on the channel type
10864
+ if (TYPE === "External")
10865
+ {
10866
+ BODY.externalUrl = EXTERNAL_URL;
10867
+ }
10868
+
10869
+ if (SECURITY_GROUPS) {
10870
+ const NOMAD_SECURITY_GROUPS = await _getSecurityGroups(instance);
10871
+
10872
+ BODY.securityGroups = NOMAD_SECURITY_GROUPS.items
10873
+ .filter(group => SECURITY_GROUPS.includes(group.description))
10874
+ .map(group => ({
10875
+ description: group.description,
10876
+ id: group.id
10877
+ }));
10878
+ }
10879
+
10880
+ return await _sendRequest(instance, "Create Live Channel", API_URL, "POST", undefined, BODY);
10881
+ }
10882
+
10883
+
10707
10884
 
10708
10885
 
10709
10886
 
@@ -10746,38 +10923,38 @@ async function _deleteLiveChannel(instance, CHANNEL_ID, DELETE_INPUTS)
10746
10923
  }
10747
10924
 
10748
10925
 
10749
-
10750
-
10751
- async function _getLiveChannelInputsIds(instance, CHANNEL_ID)
10752
- {
10753
- // Declare empty array for the IDs
10754
- const INPUT_IDS = [];
10755
-
10756
- // Get all the schedule events for the channel
10757
- if (instance.debug) console.log(`Getting Live Channel Schedule Events...`);
10758
-
10759
- const CHANNEL_EVENTS = await _getLiveChannelScheduleEvents(instance, CHANNEL_ID);
10760
-
10761
- // If there are schedule events
10762
- if (CHANNEL_EVENTS && CHANNEL_EVENTS.length > 0) {
10763
- // Loop schedule events
10764
- CHANNEL_EVENTS.forEach((SCHEDULE_EVENT) =>
10765
- {
10766
- // Check if schedule event is input type
10767
- if (SCHEDULE_EVENT && SCHEDULE_EVENT.liveInput && SCHEDULE_EVENT.liveInput != null) {
10768
- // If it has a valid lookupId add it to the array
10769
- if (SCHEDULE_EVENT.liveInput.lookupId) {
10770
- INPUT_IDS.push(SCHEDULE_EVENT.liveInput.lookupId);
10771
- }
10772
- }
10773
- });
10774
- }
10775
-
10776
- // Return the array of inputs IDs
10777
- return INPUT_IDS;
10778
- }
10779
-
10780
-
10926
+
10927
+
10928
+ async function _getLiveChannelInputsIds(instance, CHANNEL_ID)
10929
+ {
10930
+ // Declare empty array for the IDs
10931
+ const INPUT_IDS = [];
10932
+
10933
+ // Get all the schedule events for the channel
10934
+ if (instance.debug) console.log(`Getting Live Channel Schedule Events...`);
10935
+
10936
+ const CHANNEL_EVENTS = await _getLiveChannelScheduleEvents(instance, CHANNEL_ID);
10937
+
10938
+ // If there are schedule events
10939
+ if (CHANNEL_EVENTS && CHANNEL_EVENTS.length > 0) {
10940
+ // Loop schedule events
10941
+ CHANNEL_EVENTS.forEach((SCHEDULE_EVENT) =>
10942
+ {
10943
+ // Check if schedule event is input type
10944
+ if (SCHEDULE_EVENT && SCHEDULE_EVENT.liveInput && SCHEDULE_EVENT.liveInput != null) {
10945
+ // If it has a valid lookupId add it to the array
10946
+ if (SCHEDULE_EVENT.liveInput.lookupId) {
10947
+ INPUT_IDS.push(SCHEDULE_EVENT.liveInput.lookupId);
10948
+ }
10949
+ }
10950
+ });
10951
+ }
10952
+
10953
+ // Return the array of inputs IDs
10954
+ return INPUT_IDS;
10955
+ }
10956
+
10957
+
10781
10958
 
10782
10959
 
10783
10960
 
@@ -10789,52 +10966,52 @@ async function _getLiveChannelScheduleEvents(instance, CHANNEL_ID)
10789
10966
  }
10790
10967
 
10791
10968
 
10792
-
10793
-
10794
- async function _getLiveChannelStatusMessage(instance, CHANNEL_ID) {
10795
- // Get the live channel
10796
- if (instance.debug)
10797
- {
10798
- console.log(`Getting Live Channel...`);
10799
- }
10800
- const CHANNEL = await _getLiveChannel(instance, CHANNEL_ID);
10801
-
10802
- // Check if channel was found
10803
- if (CHANNEL) {
10804
- // Check if there are status messages
10805
- if (CHANNEL.statusMessages && CHANNEL.statusMessages.length > 0) {
10806
- // Return the first status message
10807
- return CHANNEL.statusMessages[0];
10808
- }
10809
- }
10810
-
10811
- // There are no status messages
10812
- return false;
10813
- }
10814
-
10815
-
10816
-
10817
-
10818
-
10819
- async function _getLiveChannelStatus(instance, CHANNEL_ID) {
10820
- // Get the live channel
10821
- if (instance.debug)
10822
- {
10823
- console.log(`Getting Live Channel...`);
10824
- }
10825
- const CHANNEL = await _getLiveChannel(instance, CHANNEL_ID);
10826
-
10827
- // Check if live channel was found
10828
- if (CHANNEL) {
10829
- // Return the status of the live channel
10830
- return CHANNEL.status.description;
10831
- }
10832
-
10833
- // Live channel was not found
10834
- return "Deleted";
10835
- }
10836
-
10837
-
10969
+
10970
+
10971
+ async function _getLiveChannelStatusMessage(instance, CHANNEL_ID) {
10972
+ // Get the live channel
10973
+ if (instance.debug)
10974
+ {
10975
+ console.log(`Getting Live Channel...`);
10976
+ }
10977
+ const CHANNEL = await _getLiveChannel(instance, CHANNEL_ID);
10978
+
10979
+ // Check if channel was found
10980
+ if (CHANNEL) {
10981
+ // Check if there are status messages
10982
+ if (CHANNEL.statusMessages && CHANNEL.statusMessages.length > 0) {
10983
+ // Return the first status message
10984
+ return CHANNEL.statusMessages[0];
10985
+ }
10986
+ }
10987
+
10988
+ // There are no status messages
10989
+ return false;
10990
+ }
10991
+
10992
+
10993
+
10994
+
10995
+
10996
+ async function _getLiveChannelStatus(instance, CHANNEL_ID) {
10997
+ // Get the live channel
10998
+ if (instance.debug)
10999
+ {
11000
+ console.log(`Getting Live Channel...`);
11001
+ }
11002
+ const CHANNEL = await _getLiveChannel(instance, CHANNEL_ID);
11003
+
11004
+ // Check if live channel was found
11005
+ if (CHANNEL) {
11006
+ // Return the status of the live channel
11007
+ return CHANNEL.status.description;
11008
+ }
11009
+
11010
+ // Live channel was not found
11011
+ return "Deleted";
11012
+ }
11013
+
11014
+
10838
11015
 
10839
11016
 
10840
11017
 
@@ -10885,33 +11062,33 @@ const _SECURITY_GROUPS = {
10885
11062
  }
10886
11063
 
10887
11064
 
10888
- const _LIVE_CHANNEL_STATUSES = {
10889
- CreateFailed: "Create Failed",
10890
- Creating: "Creating",
10891
- Deleted: "Deleted",
10892
- Deleting: "Deleting",
10893
- Error: "Error",
10894
- Idle: "Idle",
10895
- New: "New",
10896
- Pause: "Pause",
10897
- Recovering: "Recovering",
10898
- Running: "Running",
10899
- Starting: "Starting",
10900
- Stopping: "Stopping",
10901
- Unmanaged: "Unmanaged",
10902
- UpdateFailed: "Update Failed",
10903
- Updating: "Updating"
10904
- };
10905
-
10906
-
10907
-
10908
- const _LIVE_CHANNEL_TYPES = {
10909
- External: "2bf01dd4-0a9c-4168-a61b-27e135732103",
10910
- IVS: "2bf01dd4-0a9c-4168-a61b-27e135732102",
10911
- Normal: "2bf01dd4-0a9c-4168-a61b-27e135732100",
10912
- Realtime: "2bf01dd4-0a9c-4168-a61b-27e135732104"
10913
- };
10914
-
11065
+ const _LIVE_CHANNEL_STATUSES = {
11066
+ CreateFailed: "Create Failed",
11067
+ Creating: "Creating",
11068
+ Deleted: "Deleted",
11069
+ Deleting: "Deleting",
11070
+ Error: "Error",
11071
+ Idle: "Idle",
11072
+ New: "New",
11073
+ Pause: "Pause",
11074
+ Recovering: "Recovering",
11075
+ Running: "Running",
11076
+ Starting: "Starting",
11077
+ Stopping: "Stopping",
11078
+ Unmanaged: "Unmanaged",
11079
+ UpdateFailed: "Update Failed",
11080
+ Updating: "Updating"
11081
+ };
11082
+
11083
+
11084
+
11085
+ const _LIVE_CHANNEL_TYPES = {
11086
+ External: "2bf01dd4-0a9c-4168-a61b-27e135732103",
11087
+ IVS: "2bf01dd4-0a9c-4168-a61b-27e135732102",
11088
+ Normal: "2bf01dd4-0a9c-4168-a61b-27e135732100",
11089
+ Realtime: "2bf01dd4-0a9c-4168-a61b-27e135732104"
11090
+ };
11091
+
10915
11092
 
10916
11093
 
10917
11094
 
@@ -10923,317 +11100,47 @@ async function _nextEvent(instance, CHANNEL_ID)
10923
11100
  }
10924
11101
 
10925
11102
 
10926
-
10927
-
10928
-
10929
-
10930
- async function _startLiveChannel(instance, CHANNEL_ID, WAIT_FOR_START)
10931
- {
10932
- const API_URL = `${instance.config.serviceApiUrl}/api/liveChannel/${CHANNEL_ID}/start`
10933
-
10934
- await _sendRequest(instance, "Start Live Channel", API_URL, "POST", undefined, undefined);
10935
-
10936
- if (!WAIT_FOR_START) return;
10937
- await _waitForLiveChannelStatus(instance, CHANNEL_ID, _LIVE_CHANNEL_STATUSES.Running, 1200, 20);
10938
- }
10939
-
10940
11103
 
10941
11104
 
10942
11105
 
10943
- async function _startOutputTracking(instance, CHANNEL_ID)
11106
+
11107
+ async function _startLiveChannel(instance, CHANNEL_ID, WAIT_FOR_START)
10944
11108
  {
10945
- const API_URL = `${instance.config.serviceApiUrl}/api/liveChannel/${CHANNEL_ID}/startOutputTracking`;
11109
+ const API_URL = `${instance.config.serviceApiUrl}/api/liveChannel/${CHANNEL_ID}/start`
10946
11110
 
10947
- return await _sendRequest(instance, "Start Output Tracking", API_URL, "POST", undefined, undefined);
10948
- }
11111
+ await _sendRequest(instance, "Start Live Channel", API_URL, "POST", undefined, undefined);
10949
11112
 
11113
+ if (!WAIT_FOR_START) return;
11114
+ await _waitForLiveChannelStatus(instance, CHANNEL_ID, _LIVE_CHANNEL_STATUSES.Running, 1200, 20);
11115
+ }
10950
11116
 
10951
-
10952
-
10953
-
10954
-
10955
- async function _stopLiveChannel(instance, CHANNEL_ID, WAIT_FOR_STOP)
10956
- {
10957
- const API_URL = `${instance.config.serviceApiUrl}/api/liveChannel/${CHANNEL_ID}/stop`
10958
-
10959
- await _sendRequest(instance, "Stop Live Channel", API_URL, "POST", undefined, undefined);
10960
-
10961
- if (!WAIT_FOR_STOP) return;
10962
- await _waitForLiveChannelStatus(instance, CHANNEL_ID, _LIVE_CHANNEL_STATUSES.Idle, 1200, 20);
10963
- }
10964
-
10965
-
10966
-
10967
-
10968
-
10969
-
10970
-
10971
-
10972
-
10973
-
10974
-
10975
- async function _updateLiveChannel(instance, ID, NAME, THUMBNAIL_IMAGE_ID, ARCHIVE_FOLDER_ASSET_ID,
10976
- ENABLE_HIGH_AVAILABILITY, ENABLE_LIVE_CLIPPING, IS_SECURE_OUTPUT, OUTPUT_SCREENSHOTS, TYPE,
10977
- EXTERNAL_URL, EXTERNAL_OUTPUT_PROFILES, SECURITY_GROUPS)
10978
- {
10979
- const BODY = await _getLiveChannel(instance, ID);
10980
-
10981
- const API_URL = `${instance.config.serviceApiUrl}/api/liveChannel`;
10982
-
10983
- if (NAME && NAME !== BODY.name)
10984
- {
10985
- BODY.name = NAME;
10986
- BODY.routeName = _slugify(NAME);
10987
- }
10988
- if (THUMBNAIL_IMAGE_ID && THUMBNAIL_IMAGE_ID !== BODY.thumbnailImage) BODY.thumbnailImage = { id: THUMBNAIL_IMAGE_ID };
10989
- if (ARCHIVE_FOLDER_ASSET_ID && ARCHIVE_FOLDER_ASSET_ID !== BODY.archiveFolderAsset.id) BODY.archiveFolderAsset = { id: ARCHIVE_FOLDER_ASSET_ID };
10990
- if (ENABLE_HIGH_AVAILABILITY && ENABLE_HIGH_AVAILABILITY !== BODY.enableHighAvailability) BODY.enableHighAvailability = ENABLE_HIGH_AVAILABILITY;
10991
- if (ENABLE_LIVE_CLIPPING && ENABLE_LIVE_CLIPPING !== BODY.enableLiveClipping) BODY.enableLiveClipping = ENABLE_LIVE_CLIPPING;
10992
- if (IS_SECURE_OUTPUT && IS_SECURE_OUTPUT !== BODY.isSecureOutput) BODY.isSecureOutput = IS_SECURE_OUTPUT;
10993
- if (OUTPUT_SCREENSHOTS && OUTPUT_SCREENSHOTS !== BODY.outputScreenshots) BODY.outputScreenshots = OUTPUT_SCREENSHOTS;
10994
- if (TYPE && _LIVE_CHANNEL_STATUSES[TYPE] !== BODY.type.id) BODY.type = { id: _LIVE_CHANNEL_TYPES[TYPE] };
10995
- if (EXTERNAL_OUTPUT_PROFILES && EXTERNAL_OUTPUT_PROFILES !== BODY.externalOutputProfiles) BODY.externalOutputProfiles = EXTERNAL_OUTPUT_PROFILES;
10996
-
10997
-
10998
- // Set the appropriate fields based on the channel type
10999
- if (TYPE === "External") {
11000
- if (EXTERNAL_URL && EXTERNAL_URL !== BODY.externalUrl) BODY.externalUrl = EXTERNAL_URL;
11001
- }
11002
- else
11003
- {
11004
- if (EXTERNAL_URL && BODY.externalUrl) delete BODY.externalUrl;
11005
- }
11006
-
11007
- if (SECURITY_GROUPS) {
11008
- const NOMAD_SECURITY_GROUPS = await _getSecurityGroups(instance);
11009
-
11010
- const FILTERED_SECURITY_GROUPS = NOMAD_SECURITY_GROUPS
11011
- .filter(group => SECURITY_GROUPS.includes(group.description))
11012
- .map(group => ({
11013
- description: group.description,
11014
- id: group.id
11015
- }));
11016
-
11017
- if (FILTERED_SECURITY_GROUPS !== BODY.securityGroups) BODY.securityGroups = FILTERED_SECURITY_GROUPS;
11018
- }
11019
-
11020
- const INFO = await _sendRequest(instance, "Update Live Channel", API_URL, "PUT", undefined, BODY);
11021
-
11022
- await _waitForLiveChannelStatus(instance, INFO.id, _LIVE_CHANNEL_STATUSES.Idle, 120, 2);
11023
-
11024
- return INFO;
11025
- }
11026
-
11027
-
11028
-
11029
-
11030
-
11031
-
11032
-
11033
-
11034
- async function _waitForLiveChannelStatus(instance, CHANNEL_ID, STATUS_TO_WAIT_FOR, TIMEOUT = 30,
11035
- POLL_INTERVAL = 2)
11036
- {
11037
- const startingTime = new Date().getTime();
11038
-
11039
- // Elapsed time in seconds
11040
- let elapsedTime = 0;
11041
-
11042
- while (elapsedTime < TIMEOUT)
11043
- {
11044
- // Get the Live Channel status
11045
- const CHANNEL_STATUS = await _getLiveChannelStatus(instance, CHANNEL_ID);
11046
-
11047
- // If channel is in statusToWaitFor return
11048
- if (CHANNEL_STATUS === STATUS_TO_WAIT_FOR)
11049
- {
11050
- // Give feedback to the console
11051
- if (instance.debug)
11052
- {
11053
- console.log(`Live Channel [${CHANNEL_ID}] transitioned to status [${STATUS_TO_WAIT_FOR}]`);
11054
- }
11055
- return;
11056
- }
11057
-
11058
- // Give feedback to the console
11059
- console.log(`Live Channel [${CHANNEL_ID}] current status is [${CHANNEL_STATUS}]`);
11060
-
11061
- // Check for Error status
11062
- if (CHANNEL_STATUS === "Error")
11063
- {
11064
- // Get the error message
11065
- const CHANNEL_STATUS_MESSAGE = await _getLiveChannelStatusMessage(instance,
11066
- CHANNEL_ID);
11067
-
11068
- // Can't continue if Live Channel is in error status
11069
- throw new Error(`Live Channel [${CHANNEL_ID}] is in [Error] status: ${CHANNEL_STATUS_MESSAGE}`);
11070
- }
11071
-
11072
- // Calculate elapsed time in seconds
11073
- elapsedTime = (new Date().getTime() - startingTime) / 1000;
11074
-
11075
- // Give feedback to the console
11076
- if (instance.debug)
11077
- {
11078
- console.log(`Waiting for Live Channel [${CHANNEL_ID}] to transition to status [${STATUS_TO_WAIT_FOR}]... [${Math.round(elapsedTime)}/${TIMEOUT}]`);
11079
- }
11080
-
11081
- // Check for timeout
11082
- if (elapsedTime > TIMEOUT)
11083
- {
11084
- break;
11085
- }
11086
-
11087
- // Wait poll interval
11088
- await _sleep(POLL_INTERVAL);
11089
- }
11090
-
11091
- throw new Error(`Waiting for Live Channel [${CHANNEL_ID}] to transition to status [${STATUS_TO_WAIT_FOR}] timed out`);
11092
- }
11093
-
11094
-
11095
-
11096
-
11097
-
11098
-
11099
-
11100
-
11101
- async function _createLiveInput(instance, NAME, SOURCE, TYPE, IS_STANDARD, VIDEO_ASSET_ID,
11102
- DESTINATIONS, SOURCES)
11103
- {
11104
- const API_URL = `${instance.config.serviceApiUrl}/api/liveInput`;
11105
-
11106
- const BODY = {
11107
- name: NAME,
11108
- internalName: _slugify(NAME),
11109
- type: {
11110
- id: _LIVE_INPUT_TYPES[TYPE],
11111
- description: TYPE
11112
- }
11113
- };
11114
-
11115
- // Set the appropriate fields based on the type
11116
- if (TYPE == "RTMP_PUSH")
11117
- {
11118
- if (SOURCE) BODY["sourceCidr"] = SOURCE
11119
- }
11120
- else if (TYPE === "RTMP_PULL" || TYPE === "RTP_PUSH" || TYPE === "URL_PULL")
11121
- {
11122
- if (SOURCE) BODY["sources"] = [{ "url": SOURCE }]
11123
- }
11124
-
11125
- if (IS_STANDARD) BODY["isStandard"] = IS_STANDARD;
11126
- if (VIDEO_ASSET_ID) BODY["videoAsset"] = { id: VIDEO_ASSET_ID };
11127
- if (DESTINATIONS) BODY["destinations"] = DESTINATIONS;
11128
- if (SOURCES) BODY["sources"] = SOURCES;
11129
-
11130
- return await _sendRequest(instance, "Creating Live Input", API_URL, "POST", undefined, BODY);
11131
- }
11132
-
11133
-
11134
11117
 
11135
11118
 
11136
11119
 
11137
- async function _deleteLiveInput(instance, INPUT_ID)
11120
+ async function _startOutputTracking(instance, CHANNEL_ID)
11138
11121
  {
11139
- const API_URL = `${instance.config.serviceApiUrl}/api/liveInput/${INPUT_ID}`;
11122
+ const API_URL = `${instance.config.serviceApiUrl}/api/liveChannel/${CHANNEL_ID}/startOutputTracking`;
11140
11123
 
11141
- return await _sendRequest(instance, "Delete Live Input", API_URL, "DELETE", undefined, undefined);
11124
+ return await _sendRequest(instance, "Start Output Tracking", API_URL, "POST", undefined, undefined);
11142
11125
  }
11143
11126
 
11144
11127
 
11145
11128
 
11146
-
11147
-
11148
-
11149
- async function _getLiveInputStatusMessage(instance, INPUT_ID)
11150
- {
11151
- // Get the live input
11152
- if (instance.debug) console.log(`Getting Live Input...`);
11153
- const INPUT = await _getLiveInput(instance, INPUT_ID);
11154
-
11155
- // Check if input was found
11156
- if (INPUT)
11157
- {
11158
- // Check if there is status message
11159
- if (INPUT.statusMessage && INPUT.statusMessage)
11160
- {
11161
- // Return input status message
11162
- return INPUT.statusMessage;
11163
- }
11164
- }
11165
-
11166
- // There is no status message
11167
- return "";
11168
- }
11169
-
11170
-
11171
-
11172
-
11173
-
11174
- async function _getLiveInputStatus(instance, INPUT_ID)
11175
- {
11176
- // Get the live input
11177
- if (instance.debug) console.log(`Getting Live Input...`);
11178
- const INPUT = await _getLiveInput(instance, INPUT_ID);
11179
-
11180
- // Check if input was found
11181
- if (INPUT)
11182
- {
11183
- // Return the status of the input
11184
- return INPUT.status.description;
11185
- }
11186
-
11187
- // Input was not found
11188
- return "Deleted";
11189
- }
11190
-
11191
11129
 
11192
11130
 
11193
11131
 
11194
- async function _getLiveInput(instance, INPUT_ID)
11132
+ async function _stopLiveChannel(instance, CHANNEL_ID, WAIT_FOR_STOP)
11195
11133
  {
11196
- const API_URL = `${instance.config.serviceApiUrl}/api/liveInput/${INPUT_ID}`;
11134
+ const API_URL = `${instance.config.serviceApiUrl}/api/liveChannel/${CHANNEL_ID}/stop`
11197
11135
 
11198
- return await _sendRequest(instance, "Get Live Input", API_URL, "GET", undefined, undefined);
11199
- }
11200
-
11201
-
11202
-
11203
-
11204
- async function _getLiveInputs(instance)
11205
- {
11206
- const API_URL = `${instance.config.serviceApiUrl}/api/liveInput`;
11136
+ await _sendRequest(instance, "Stop Live Channel", API_URL, "POST", undefined, undefined);
11207
11137
 
11208
- return await _sendRequest(instance, "Get Live Inputs", API_URL, "GET", undefined, undefined);
11138
+ if (!WAIT_FOR_STOP) return;
11139
+ await _waitForLiveChannelStatus(instance, CHANNEL_ID, _LIVE_CHANNEL_STATUSES.Idle, 1200, 20);
11209
11140
  }
11210
11141
 
11211
11142
 
11212
- const _LIVE_INPUT_STATUSES = {
11213
- Attached: "Attached",
11214
- Attaching: "Attaching",
11215
- CreateFailed: "Create Failed",
11216
- Creating: "Creating",
11217
- Deleted: "Deleted",
11218
- Deleting: "Deleting",
11219
- Detached: "Detached",
11220
- Detaching: "Detaching",
11221
- Error: "Error",
11222
- Paused: "Paused",
11223
- Updating: "Updating"
11224
- };
11225
-
11226
-
11227
11143
 
11228
- const _LIVE_INPUT_TYPES = {
11229
- RTMP_PULL: "78acb07d-ba87-48fa-ad8f-c00e318a1254",
11230
- RTMP_PUSH: "78acb07d-ba87-48fa-ad8f-c00e318a1253",
11231
- RTP_PUSH: "78acb07d-ba87-48fa-ad8f-c00e318a1252",
11232
- UDP_PUSH: "78acb07d-ba87-48fa-ad8f-c00e318a1251",
11233
- URL_PULL: "78acb07d-ba87-48fa-ad8f-c00e318a1255"
11234
- };
11235
-
11236
-
11237
11144
 
11238
11145
 
11239
11146
 
@@ -11242,166 +11149,436 @@ const _LIVE_INPUT_TYPES = {
11242
11149
 
11243
11150
 
11244
11151
 
11245
- async function _updateLiveInput(instance, ID, NAME, SOURCE, TYPE, IS_STANDARD, VIDEO_ASSET_ID,
11246
- DESTINATIONS, SOURCES)
11152
+ async function _updateLiveChannel(instance, ID, NAME, THUMBNAIL_IMAGE_ID, ARCHIVE_FOLDER_ASSET_ID,
11153
+ ENABLE_HIGH_AVAILABILITY, ENABLE_LIVE_CLIPPING, IS_SECURE_OUTPUT, OUTPUT_SCREENSHOTS, TYPE,
11154
+ EXTERNAL_URL, EXTERNAL_OUTPUT_PROFILES, SECURITY_GROUPS)
11247
11155
  {
11248
- const INPUT_INFO = await _getLiveInput(instance, ID);
11249
-
11250
- const API_URL = `${instance.config.serviceApiUrl}/api/liveInput`;
11156
+ const BODY = await _getLiveChannel(instance, ID);
11251
11157
 
11252
- const BODY = INPUT_INFO
11158
+ const API_URL = `${instance.config.serviceApiUrl}/api/liveChannel`;
11253
11159
 
11254
11160
  if (NAME && NAME !== BODY.name)
11255
11161
  {
11256
11162
  BODY.name = NAME;
11257
- BODY.internalName = _slugify(NAME);
11163
+ BODY.routeName = _slugify(NAME);
11258
11164
  }
11259
- if (TYPE && _LIVE_INPUT_TYPES[TYPE] !== BODY.type.id) BODY.type = { id: _LIVE_INPUT_TYPES[TYPE] };
11165
+ if (THUMBNAIL_IMAGE_ID && THUMBNAIL_IMAGE_ID !== BODY.thumbnailImage) BODY.thumbnailImage = { id: THUMBNAIL_IMAGE_ID };
11166
+ if (ARCHIVE_FOLDER_ASSET_ID && ARCHIVE_FOLDER_ASSET_ID !== BODY.archiveFolderAsset.id) BODY.archiveFolderAsset = { id: ARCHIVE_FOLDER_ASSET_ID };
11167
+ if (ENABLE_HIGH_AVAILABILITY && ENABLE_HIGH_AVAILABILITY !== BODY.enableHighAvailability) BODY.enableHighAvailability = ENABLE_HIGH_AVAILABILITY;
11168
+ if (ENABLE_LIVE_CLIPPING && ENABLE_LIVE_CLIPPING !== BODY.enableLiveClipping) BODY.enableLiveClipping = ENABLE_LIVE_CLIPPING;
11169
+ if (IS_SECURE_OUTPUT && IS_SECURE_OUTPUT !== BODY.isSecureOutput) BODY.isSecureOutput = IS_SECURE_OUTPUT;
11170
+ if (OUTPUT_SCREENSHOTS && OUTPUT_SCREENSHOTS !== BODY.outputScreenshots) BODY.outputScreenshots = OUTPUT_SCREENSHOTS;
11171
+ if (TYPE && _LIVE_CHANNEL_STATUSES[TYPE] !== BODY.type.id) BODY.type = { id: _LIVE_CHANNEL_TYPES[TYPE] };
11172
+ if (EXTERNAL_OUTPUT_PROFILES && EXTERNAL_OUTPUT_PROFILES !== BODY.externalOutputProfiles) BODY.externalOutputProfiles = EXTERNAL_OUTPUT_PROFILES;
11260
11173
 
11261
- // Set the appropriate fields based on the type
11262
- if (TYPE == "RTMP_PUSH")
11263
- {
11264
- if (SOURCE && SOURCE !== BODY.sourceCidr) BODY["sourceCidr"] = SOURCE
11265
- if (BODY.sources) delete BODY.sources;
11266
- }
11267
- else if (TYPE === "RTMP_PULL" || TYPE === "RTP_PUSH" || TYPE === "URL_PULL")
11268
- {
11269
- if (SOURCE && SOURCE !== BODY.sources) BODY["sources"] = [{ "url": SOURCE }]
11270
- if (BODY.sourceCidr) delete BODY.sourceCidr;
11174
+
11175
+ // Set the appropriate fields based on the channel type
11176
+ if (TYPE === "External") {
11177
+ if (EXTERNAL_URL && EXTERNAL_URL !== BODY.externalUrl) BODY.externalUrl = EXTERNAL_URL;
11271
11178
  }
11272
- else
11179
+ else
11273
11180
  {
11274
- if (BODY.sourceCidr) delete BODY.sourceCidr;
11275
- if (BODY.sources) delete BODY.sources;
11181
+ if (EXTERNAL_URL && BODY.externalUrl) delete BODY.externalUrl;
11276
11182
  }
11277
11183
 
11278
- if (IS_STANDARD && IS_STANDARD !== BODY.isStandard) BODY.isStandard = IS_STANDARD;
11279
- if (VIDEO_ASSET_ID && VIDEO_ASSET_ID !== BODY.videoAsset.id) BODY.videoAsset = { id: VIDEO_ASSET_ID };
11280
- if (DESTINATIONS && DESTINATIONS !== BODY.destinations) BODY.destinations = DESTINATIONS;
11281
- if (SOURCES && SOURCES !== BODY.SOURCES) BODY.sources = SOURCES;
11184
+ if (SECURITY_GROUPS) {
11185
+ const NOMAD_SECURITY_GROUPS = await _getSecurityGroups(instance);
11282
11186
 
11283
- const INFO = await _sendRequest(instance, "Updating Live Input", API_URL, "PUT", undefined, BODY);
11284
- await _waitForLiveInputStatus(instance, INFO.id, _LIVE_INPUT_STATUSES.Detached, 15, 1);
11285
- }
11187
+ const FILTERED_SECURITY_GROUPS = NOMAD_SECURITY_GROUPS
11188
+ .filter(group => SECURITY_GROUPS.includes(group.description))
11189
+ .map(group => ({
11190
+ description: group.description,
11191
+ id: group.id
11192
+ }));
11286
11193
 
11194
+ if (FILTERED_SECURITY_GROUPS !== BODY.securityGroups) BODY.securityGroups = FILTERED_SECURITY_GROUPS;
11195
+ }
11287
11196
 
11197
+ const INFO = await _sendRequest(instance, "Update Live Channel", API_URL, "PUT", undefined, BODY);
11288
11198
 
11289
-
11290
-
11291
-
11292
-
11293
- async function _waitForLiveInputStatus(instance, INPUT_ID, STATUS_TO_WAIT_FOR, TIMEOUT = 30,
11294
- POLL_INTERVAL = 2)
11295
- {
11296
- // Set the starting time
11297
- const STARTING_TIME = new Date().getTime();
11298
-
11299
- // Elapsed time in seconds
11300
- let elapsedTime = 0;
11301
-
11302
- while (elapsedTime < TIMEOUT)
11303
- {
11304
- // Get the Live Input status
11305
- const INPUT_STATUS = await _getLiveInputStatus(instance, INPUT_ID);
11306
-
11307
- // If Live Input is in statusToWaitFor return
11308
- if (INPUT_STATUS === STATUS_TO_WAIT_FOR)
11309
- {
11310
- // Give feedback to the console
11311
- if (instance.debug)
11312
- {
11313
- console.log(`Live Input ${INPUT_ID} transitioned to status ${STATUS_TO_WAIT_FOR}`);
11314
- }
11315
- return;
11316
- }
11317
-
11318
- // Give feedback to the console
11319
- console.log(`Live Input [${INPUT_ID}] is in status [${INPUT_STATUS}]`);
11320
-
11321
- // Check for Error status
11322
- if (INPUT_STATUS === "Error")
11323
- {
11324
- // Get the error message
11325
- const INPUT_STATUS_MESSAGE = await _getLiveInputStatusMessage(instance, INPUT_ID);
11326
-
11327
- // Can't continue if Live Input is in error status
11328
- throw new Error(`Live Input ${INPUT_ID} is in Error status: ${INPUT_STATUS_MESSAGE}`);
11329
- }
11330
-
11331
- // Calculate elapsed time in seconds
11332
- elapsedTime = (new Date().getTime() - STARTING_TIME) / 1000;
11333
-
11334
- // Give feedback to the console
11335
- if (instance.debug)
11336
- {
11337
- console.log(`Waiting for Live Input [${INPUT_ID}] to transition to status [${STATUS_TO_WAIT_FOR}]... [${Math.round(elapsedTime)}/${TIMEOUT}]`);
11338
- }
11339
-
11340
- // Check for timeout
11341
- if (elapsedTime > TIMEOUT)
11342
- {
11343
- break;
11344
- }
11345
-
11346
- // Wait poll interval
11347
- await _sleep(POLL_INTERVAL);
11348
- }
11349
-
11350
- throw new Error(`Waiting for Live Input [${INPUT_ID}] to transition to status [${STATUS_TO_WAIT_FOR}] timed out`);
11351
- }
11352
-
11353
-
11354
-
11355
-
11356
-
11357
-
11358
- async function _cancelBroadcast(instance, ID)
11359
- {
11360
- const API_URL = `${instance.config.serviceApiUrl}/api/admin/liveOperator/${ID}/cancel`;
11361
-
11362
- return await _sendRequest(instance, "Cancel Broadcast", API_URL, "POST", undefined, undefined);
11363
- }
11364
-
11365
-
11366
-
11367
-
11368
- async function _cancelSegment(instance, ID)
11369
- {
11370
- const API_URL = `${instance.config.serviceApiUrl}/api/admin/liveOperator/${ID}/cancelSegment`;
11371
-
11372
- return await _sendRequest(instance, "Cancel Segment", API_URL, "POST", undefined, undefined);
11373
- }
11374
-
11375
-
11376
-
11377
-
11378
- async function _completeSegment(instance, ID, RELATED_CONTENT_IDS, TAG_IDS)
11379
- {
11380
- const API_URL = `${instance.config.serviceApiUrl}/api/admin/liveOperator/${ID}/completeSegment`;
11381
-
11382
- const BODY = {
11383
- liveOperatorId: ID
11384
- };
11385
-
11386
- if (RELATED_CONTENT_IDS && Array.isArray(RELATED_CONTENT_IDS) && RELATED_CONTENT_IDS.length > 0) {
11387
- BODY.relatedContent = RELATED_CONTENT_IDS.map(id => ({ id }));
11388
- }
11389
- if (TAG_IDS && Array.isArray(TAG_IDS) && TAG_IDS.length > 0) {
11390
- BODY.tags = TAG_IDS.map(id => ({ id }));
11391
- }
11392
-
11393
- return await _sendRequest(instance, "Complete Segment", API_URL, "POST", undefined, BODY);
11394
- }
11395
-
11199
+ await _waitForLiveChannelStatus(instance, INFO.id, _LIVE_CHANNEL_STATUSES.Idle, 120, 2);
11396
11200
 
11201
+ return INFO;
11202
+ }
11397
11203
 
11398
11204
 
11399
- async function _getCompletedSegments(instance, ID)
11400
- {
11401
- const API_URL = `${instance.config.serviceApiUrl}/api/admin/liveOperator/${ID}/segments`;
11402
-
11403
- return await _sendRequest(instance, "Get Completed Segments", API_URL, "GET", undefined, undefined);
11404
- }
11205
+
11206
+
11207
+
11208
+
11209
+
11210
+
11211
+ async function _waitForLiveChannelStatus(instance, CHANNEL_ID, STATUS_TO_WAIT_FOR, TIMEOUT = 30,
11212
+ POLL_INTERVAL = 2)
11213
+ {
11214
+ const startingTime = new Date().getTime();
11215
+
11216
+ // Elapsed time in seconds
11217
+ let elapsedTime = 0;
11218
+
11219
+ while (elapsedTime < TIMEOUT)
11220
+ {
11221
+ // Get the Live Channel status
11222
+ const CHANNEL_STATUS = await _getLiveChannelStatus(instance, CHANNEL_ID);
11223
+
11224
+ // If channel is in statusToWaitFor return
11225
+ if (CHANNEL_STATUS === STATUS_TO_WAIT_FOR)
11226
+ {
11227
+ // Give feedback to the console
11228
+ if (instance.debug)
11229
+ {
11230
+ console.log(`Live Channel [${CHANNEL_ID}] transitioned to status [${STATUS_TO_WAIT_FOR}]`);
11231
+ }
11232
+ return;
11233
+ }
11234
+
11235
+ // Give feedback to the console
11236
+ console.log(`Live Channel [${CHANNEL_ID}] current status is [${CHANNEL_STATUS}]`);
11237
+
11238
+ // Check for Error status
11239
+ if (CHANNEL_STATUS === "Error")
11240
+ {
11241
+ // Get the error message
11242
+ const CHANNEL_STATUS_MESSAGE = await _getLiveChannelStatusMessage(instance,
11243
+ CHANNEL_ID);
11244
+
11245
+ // Can't continue if Live Channel is in error status
11246
+ throw new Error(`Live Channel [${CHANNEL_ID}] is in [Error] status: ${CHANNEL_STATUS_MESSAGE}`);
11247
+ }
11248
+
11249
+ // Calculate elapsed time in seconds
11250
+ elapsedTime = (new Date().getTime() - startingTime) / 1000;
11251
+
11252
+ // Give feedback to the console
11253
+ if (instance.debug)
11254
+ {
11255
+ console.log(`Waiting for Live Channel [${CHANNEL_ID}] to transition to status [${STATUS_TO_WAIT_FOR}]... [${Math.round(elapsedTime)}/${TIMEOUT}]`);
11256
+ }
11257
+
11258
+ // Check for timeout
11259
+ if (elapsedTime > TIMEOUT)
11260
+ {
11261
+ break;
11262
+ }
11263
+
11264
+ // Wait poll interval
11265
+ await _sleep(POLL_INTERVAL);
11266
+ }
11267
+
11268
+ throw new Error(`Waiting for Live Channel [${CHANNEL_ID}] to transition to status [${STATUS_TO_WAIT_FOR}] timed out`);
11269
+ }
11270
+
11271
+
11272
+
11273
+
11274
+
11275
+
11276
+
11277
+
11278
+ async function _createLiveInput(instance, NAME, SOURCE, TYPE, IS_STANDARD, VIDEO_ASSET_ID,
11279
+ DESTINATIONS, SOURCES)
11280
+ {
11281
+ const API_URL = `${instance.config.serviceApiUrl}/api/liveInput`;
11282
+
11283
+ const BODY = {
11284
+ name: NAME,
11285
+ internalName: _slugify(NAME),
11286
+ type: {
11287
+ id: _LIVE_INPUT_TYPES[TYPE],
11288
+ description: TYPE
11289
+ }
11290
+ };
11291
+
11292
+ // Set the appropriate fields based on the type
11293
+ if (TYPE == "RTMP_PUSH")
11294
+ {
11295
+ if (SOURCE) BODY["sourceCidr"] = SOURCE
11296
+ }
11297
+ else if (TYPE === "RTMP_PULL" || TYPE === "RTP_PUSH" || TYPE === "URL_PULL")
11298
+ {
11299
+ if (SOURCE) BODY["sources"] = [{ "url": SOURCE }]
11300
+ }
11301
+
11302
+ if (IS_STANDARD) BODY["isStandard"] = IS_STANDARD;
11303
+ if (VIDEO_ASSET_ID) BODY["videoAsset"] = { id: VIDEO_ASSET_ID };
11304
+ if (DESTINATIONS) BODY["destinations"] = DESTINATIONS;
11305
+ if (SOURCES) BODY["sources"] = SOURCES;
11306
+
11307
+ return await _sendRequest(instance, "Creating Live Input", API_URL, "POST", undefined, BODY);
11308
+ }
11309
+
11310
+
11311
+
11312
+
11313
+
11314
+ async function _deleteLiveInput(instance, INPUT_ID)
11315
+ {
11316
+ const API_URL = `${instance.config.serviceApiUrl}/api/liveInput/${INPUT_ID}`;
11317
+
11318
+ return await _sendRequest(instance, "Delete Live Input", API_URL, "DELETE", undefined, undefined);
11319
+ }
11320
+
11321
+
11322
+
11323
+
11324
+
11325
+
11326
+ async function _getLiveInputStatusMessage(instance, INPUT_ID)
11327
+ {
11328
+ // Get the live input
11329
+ if (instance.debug) console.log(`Getting Live Input...`);
11330
+ const INPUT = await _getLiveInput(instance, INPUT_ID);
11331
+
11332
+ // Check if input was found
11333
+ if (INPUT)
11334
+ {
11335
+ // Check if there is status message
11336
+ if (INPUT.statusMessage && INPUT.statusMessage)
11337
+ {
11338
+ // Return input status message
11339
+ return INPUT.statusMessage;
11340
+ }
11341
+ }
11342
+
11343
+ // There is no status message
11344
+ return "";
11345
+ }
11346
+
11347
+
11348
+
11349
+
11350
+
11351
+ async function _getLiveInputStatus(instance, INPUT_ID)
11352
+ {
11353
+ // Get the live input
11354
+ if (instance.debug) console.log(`Getting Live Input...`);
11355
+ const INPUT = await _getLiveInput(instance, INPUT_ID);
11356
+
11357
+ // Check if input was found
11358
+ if (INPUT)
11359
+ {
11360
+ // Return the status of the input
11361
+ return INPUT.status.description;
11362
+ }
11363
+
11364
+ // Input was not found
11365
+ return "Deleted";
11366
+ }
11367
+
11368
+
11369
+
11370
+
11371
+ async function _getLiveInput(instance, INPUT_ID)
11372
+ {
11373
+ const API_URL = `${instance.config.serviceApiUrl}/api/liveInput/${INPUT_ID}`;
11374
+
11375
+ return await _sendRequest(instance, "Get Live Input", API_URL, "GET", undefined, undefined);
11376
+ }
11377
+
11378
+
11379
+
11380
+
11381
+ async function _getLiveInputs(instance)
11382
+ {
11383
+ const API_URL = `${instance.config.serviceApiUrl}/api/liveInput`;
11384
+
11385
+ return await _sendRequest(instance, "Get Live Inputs", API_URL, "GET", undefined, undefined);
11386
+ }
11387
+
11388
+
11389
+ const _LIVE_INPUT_STATUSES = {
11390
+ Attached: "Attached",
11391
+ Attaching: "Attaching",
11392
+ CreateFailed: "Create Failed",
11393
+ Creating: "Creating",
11394
+ Deleted: "Deleted",
11395
+ Deleting: "Deleting",
11396
+ Detached: "Detached",
11397
+ Detaching: "Detaching",
11398
+ Error: "Error",
11399
+ Paused: "Paused",
11400
+ Updating: "Updating"
11401
+ };
11402
+
11403
+
11404
+
11405
+ const _LIVE_INPUT_TYPES = {
11406
+ RTMP_PULL: "78acb07d-ba87-48fa-ad8f-c00e318a1254",
11407
+ RTMP_PUSH: "78acb07d-ba87-48fa-ad8f-c00e318a1253",
11408
+ RTP_PUSH: "78acb07d-ba87-48fa-ad8f-c00e318a1252",
11409
+ UDP_PUSH: "78acb07d-ba87-48fa-ad8f-c00e318a1251",
11410
+ URL_PULL: "78acb07d-ba87-48fa-ad8f-c00e318a1255"
11411
+ };
11412
+
11413
+
11414
+
11415
+
11416
+
11417
+
11418
+
11419
+
11420
+
11421
+
11422
+ async function _updateLiveInput(instance, ID, NAME, SOURCE, TYPE, IS_STANDARD, VIDEO_ASSET_ID,
11423
+ DESTINATIONS, SOURCES)
11424
+ {
11425
+ const INPUT_INFO = await _getLiveInput(instance, ID);
11426
+
11427
+ const API_URL = `${instance.config.serviceApiUrl}/api/liveInput`;
11428
+
11429
+ const BODY = INPUT_INFO
11430
+
11431
+ if (NAME && NAME !== BODY.name)
11432
+ {
11433
+ BODY.name = NAME;
11434
+ BODY.internalName = _slugify(NAME);
11435
+ }
11436
+ if (TYPE && _LIVE_INPUT_TYPES[TYPE] !== BODY.type.id) BODY.type = { id: _LIVE_INPUT_TYPES[TYPE] };
11437
+
11438
+ // Set the appropriate fields based on the type
11439
+ if (TYPE == "RTMP_PUSH")
11440
+ {
11441
+ if (SOURCE && SOURCE !== BODY.sourceCidr) BODY["sourceCidr"] = SOURCE
11442
+ if (BODY.sources) delete BODY.sources;
11443
+ }
11444
+ else if (TYPE === "RTMP_PULL" || TYPE === "RTP_PUSH" || TYPE === "URL_PULL")
11445
+ {
11446
+ if (SOURCE && SOURCE !== BODY.sources) BODY["sources"] = [{ "url": SOURCE }]
11447
+ if (BODY.sourceCidr) delete BODY.sourceCidr;
11448
+ }
11449
+ else
11450
+ {
11451
+ if (BODY.sourceCidr) delete BODY.sourceCidr;
11452
+ if (BODY.sources) delete BODY.sources;
11453
+ }
11454
+
11455
+ if (IS_STANDARD && IS_STANDARD !== BODY.isStandard) BODY.isStandard = IS_STANDARD;
11456
+ if (VIDEO_ASSET_ID && VIDEO_ASSET_ID !== BODY.videoAsset.id) BODY.videoAsset = { id: VIDEO_ASSET_ID };
11457
+ if (DESTINATIONS && DESTINATIONS !== BODY.destinations) BODY.destinations = DESTINATIONS;
11458
+ if (SOURCES && SOURCES !== BODY.SOURCES) BODY.sources = SOURCES;
11459
+
11460
+ const INFO = await _sendRequest(instance, "Updating Live Input", API_URL, "PUT", undefined, BODY);
11461
+ await _waitForLiveInputStatus(instance, INFO.id, _LIVE_INPUT_STATUSES.Detached, 15, 1);
11462
+ }
11463
+
11464
+
11465
+
11466
+
11467
+
11468
+
11469
+
11470
+ async function _waitForLiveInputStatus(instance, INPUT_ID, STATUS_TO_WAIT_FOR, TIMEOUT = 30,
11471
+ POLL_INTERVAL = 2)
11472
+ {
11473
+ // Set the starting time
11474
+ const STARTING_TIME = new Date().getTime();
11475
+
11476
+ // Elapsed time in seconds
11477
+ let elapsedTime = 0;
11478
+
11479
+ while (elapsedTime < TIMEOUT)
11480
+ {
11481
+ // Get the Live Input status
11482
+ const INPUT_STATUS = await _getLiveInputStatus(instance, INPUT_ID);
11483
+
11484
+ // If Live Input is in statusToWaitFor return
11485
+ if (INPUT_STATUS === STATUS_TO_WAIT_FOR)
11486
+ {
11487
+ // Give feedback to the console
11488
+ if (instance.debug)
11489
+ {
11490
+ console.log(`Live Input ${INPUT_ID} transitioned to status ${STATUS_TO_WAIT_FOR}`);
11491
+ }
11492
+ return;
11493
+ }
11494
+
11495
+ // Give feedback to the console
11496
+ console.log(`Live Input [${INPUT_ID}] is in status [${INPUT_STATUS}]`);
11497
+
11498
+ // Check for Error status
11499
+ if (INPUT_STATUS === "Error")
11500
+ {
11501
+ // Get the error message
11502
+ const INPUT_STATUS_MESSAGE = await _getLiveInputStatusMessage(instance, INPUT_ID);
11503
+
11504
+ // Can't continue if Live Input is in error status
11505
+ throw new Error(`Live Input ${INPUT_ID} is in Error status: ${INPUT_STATUS_MESSAGE}`);
11506
+ }
11507
+
11508
+ // Calculate elapsed time in seconds
11509
+ elapsedTime = (new Date().getTime() - STARTING_TIME) / 1000;
11510
+
11511
+ // Give feedback to the console
11512
+ if (instance.debug)
11513
+ {
11514
+ console.log(`Waiting for Live Input [${INPUT_ID}] to transition to status [${STATUS_TO_WAIT_FOR}]... [${Math.round(elapsedTime)}/${TIMEOUT}]`);
11515
+ }
11516
+
11517
+ // Check for timeout
11518
+ if (elapsedTime > TIMEOUT)
11519
+ {
11520
+ break;
11521
+ }
11522
+
11523
+ // Wait poll interval
11524
+ await _sleep(POLL_INTERVAL);
11525
+ }
11526
+
11527
+ throw new Error(`Waiting for Live Input [${INPUT_ID}] to transition to status [${STATUS_TO_WAIT_FOR}] timed out`);
11528
+ }
11529
+
11530
+
11531
+
11532
+
11533
+
11534
+
11535
+ async function _cancelBroadcast(instance, ID)
11536
+ {
11537
+ const API_URL = `${instance.config.serviceApiUrl}/api/admin/liveOperator/${ID}/cancel`;
11538
+
11539
+ return await _sendRequest(instance, "Cancel Broadcast", API_URL, "POST", undefined, undefined);
11540
+ }
11541
+
11542
+
11543
+
11544
+
11545
+ async function _cancelSegment(instance, ID)
11546
+ {
11547
+ const API_URL = `${instance.config.serviceApiUrl}/api/admin/liveOperator/${ID}/cancelSegment`;
11548
+
11549
+ return await _sendRequest(instance, "Cancel Segment", API_URL, "POST", undefined, undefined);
11550
+ }
11551
+
11552
+
11553
+
11554
+
11555
+ async function _completeSegment(instance, ID, RELATED_CONTENT_IDS, TAG_IDS)
11556
+ {
11557
+ const API_URL = `${instance.config.serviceApiUrl}/api/admin/liveOperator/${ID}/completeSegment`;
11558
+
11559
+ const BODY = {
11560
+ liveOperatorId: ID
11561
+ };
11562
+
11563
+ if (RELATED_CONTENT_IDS && Array.isArray(RELATED_CONTENT_IDS) && RELATED_CONTENT_IDS.length > 0) {
11564
+ BODY.relatedContent = RELATED_CONTENT_IDS.map(id => ({ id }));
11565
+ }
11566
+ if (TAG_IDS && Array.isArray(TAG_IDS) && TAG_IDS.length > 0) {
11567
+ BODY.tags = TAG_IDS.map(id => ({ id }));
11568
+ }
11569
+
11570
+ return await _sendRequest(instance, "Complete Segment", API_URL, "POST", undefined, BODY);
11571
+ }
11572
+
11573
+
11574
+
11575
+
11576
+ async function _getCompletedSegments(instance, ID)
11577
+ {
11578
+ const API_URL = `${instance.config.serviceApiUrl}/api/admin/liveOperator/${ID}/segments`;
11579
+
11580
+ return await _sendRequest(instance, "Get Completed Segments", API_URL, "GET", undefined, undefined);
11581
+ }
11405
11582
 
11406
11583
 
11407
11584
 
@@ -11424,53 +11601,53 @@ async function _getLiveOperators(instance)
11424
11601
  }
11425
11602
 
11426
11603
 
11427
-
11428
-
11429
-
11430
- async function _startBroadcast(instance, ID, PREROLL_ASSET_ID, POSTROLL_ASSET_ID, LIVE_INPUT_ID,
11431
- RELATED_CONTENT_IDS, TAG_IDS)
11432
- {
11433
- const API_URL = `${instance.config.serviceApiUrl}/api/admin/liveOperator/start`;
11434
-
11435
- const BODY = {
11436
- id: ID
11437
- };
11438
-
11439
- if (PREROLL_ASSET_ID) { BODY.prerollAsset = { id: PREROLL_ASSET_ID }; }
11440
- if (POSTROLL_ASSET_ID) { BODY.postrollAsset = { id: POSTROLL_ASSET_ID }; }
11441
- if (LIVE_INPUT_ID) { BODY.liveInput = { id: LIVE_INPUT_ID }; }
11442
-
11443
- if (RELATED_CONTENT_IDS && Array.isArray(RELATED_CONTENT_IDS) && RELATED_CONTENT_IDS.length > 0) {
11444
- BODY.relatedContent = RELATED_CONTENT_IDS.map(id => ({ id }));
11445
- }
11446
- if (TAG_IDS && Array.isArray(TAG_IDS) && TAG_IDS.length > 0) {
11447
- BODY.tags = TAG_IDS.map(id => ({ id }));
11448
- }
11449
-
11450
- return await _sendRequest(instance, "Start Broadcast", API_URL, "POST", undefined, BODY);
11451
- }
11452
-
11453
-
11454
-
11455
-
11456
- async function _startSegment(instance, ID)
11457
- {
11458
- const API_URL = `${instance.config.serviceApiUrl}/api/admin/liveOperator/${ID}/startSegment`;
11459
-
11460
- return await _sendRequest(instance, "Start Segment", API_URL, "POST", undefined, undefined);
11461
- }
11462
-
11463
-
11464
-
11465
-
11466
-
11467
- async function _stopBroadcast(instance, ID)
11468
- {
11469
- const API_URL = `${instance.config.serviceApiUrl}/api/admin/liveOperator/${ID}/stop`;
11470
-
11471
- return await _sendRequest(instance, "Stop Broadcast", API_URL, "POST", undefined, undefined);
11472
- }
11473
-
11604
+
11605
+
11606
+
11607
+ async function _startBroadcast(instance, ID, PREROLL_ASSET_ID, POSTROLL_ASSET_ID, LIVE_INPUT_ID,
11608
+ RELATED_CONTENT_IDS, TAG_IDS)
11609
+ {
11610
+ const API_URL = `${instance.config.serviceApiUrl}/api/admin/liveOperator/start`;
11611
+
11612
+ const BODY = {
11613
+ id: ID
11614
+ };
11615
+
11616
+ if (PREROLL_ASSET_ID) { BODY.prerollAsset = { id: PREROLL_ASSET_ID }; }
11617
+ if (POSTROLL_ASSET_ID) { BODY.postrollAsset = { id: POSTROLL_ASSET_ID }; }
11618
+ if (LIVE_INPUT_ID) { BODY.liveInput = { id: LIVE_INPUT_ID }; }
11619
+
11620
+ if (RELATED_CONTENT_IDS && Array.isArray(RELATED_CONTENT_IDS) && RELATED_CONTENT_IDS.length > 0) {
11621
+ BODY.relatedContent = RELATED_CONTENT_IDS.map(id => ({ id }));
11622
+ }
11623
+ if (TAG_IDS && Array.isArray(TAG_IDS) && TAG_IDS.length > 0) {
11624
+ BODY.tags = TAG_IDS.map(id => ({ id }));
11625
+ }
11626
+
11627
+ return await _sendRequest(instance, "Start Broadcast", API_URL, "POST", undefined, BODY);
11628
+ }
11629
+
11630
+
11631
+
11632
+
11633
+ async function _startSegment(instance, ID)
11634
+ {
11635
+ const API_URL = `${instance.config.serviceApiUrl}/api/admin/liveOperator/${ID}/startSegment`;
11636
+
11637
+ return await _sendRequest(instance, "Start Segment", API_URL, "POST", undefined, undefined);
11638
+ }
11639
+
11640
+
11641
+
11642
+
11643
+
11644
+ async function _stopBroadcast(instance, ID)
11645
+ {
11646
+ const API_URL = `${instance.config.serviceApiUrl}/api/admin/liveOperator/${ID}/stop`;
11647
+
11648
+ return await _sendRequest(instance, "Stop Broadcast", API_URL, "POST", undefined, undefined);
11649
+ }
11650
+
11474
11651
 
11475
11652
 
11476
11653
 
@@ -11721,59 +11898,59 @@ async function _updateLiveOutputProfile(instance, ID, NAME, OUTPUT_TYPE, ENABLED
11721
11898
 
11722
11899
 
11723
11900
 
11724
-
11725
-
11726
-
11727
- async function _addAssetScheduleEvent(instance, CHANNEL_ID, ASSET, IS_LOOP,
11728
- DURATION_TIME_CODE, PREVIOUS_ID)
11729
- {
11730
- const API_URL = `${instance.config.serviceApiUrl}/api/LiveChannel/${CHANNEL_ID}/liveScheduleEvent`;
11731
-
11732
- const BODY = {
11733
- isLoop: IS_LOOP,
11734
- channelId: CHANNEL_ID,
11735
- durationTimeCode: DURATION_TIME_CODE,
11736
- previousId: PREVIOUS_ID,
11737
- type: {
11738
- id: _eventType.videoAsset,
11739
- description: "Video Asset"
11740
- },
11741
- asset: ASSET
11742
- };
11743
-
11744
- return await _sendRequest(instance, "Adding Asset Schedule Event", API_URL, "POST", undefined, BODY);
11745
- }
11746
-
11747
-
11748
-
11749
-
11750
-
11751
-
11752
- async function _addInputScheduleEvent(instance, CHANNEL_ID, INPUT, BACKUP_INPUT,
11753
- FIXED_ON_AIR_TIME_UTC, PREVIOUS_ID)
11754
- {
11755
- const API_URL = `${instance.config.serviceApiUrl}/api/LiveChannel/${CHANNEL_ID}/liveScheduleEvent`;
11756
-
11757
- const BODY = {
11758
- channelId: CHANNEL_ID,
11759
- fixedOnAirTimeUtc: FIXED_ON_AIR_TIME_UTC,
11760
- type: {
11761
- id: _eventType.liveInput,
11762
- description: "Live Input"
11763
- },
11764
- liveInput: INPUT,
11765
- previousId: PREVIOUS_ID
11766
- };
11767
-
11768
- if (BACKUP_INPUT)
11769
- {
11770
- BODY["liveInput2"] = BACKUP_INPUT;
11771
- }
11772
-
11773
-
11774
- return await _sendRequest(instance, "Adding Input Schedule Event", API_URL, "POST", undefined, BODY);
11775
- }
11776
-
11901
+
11902
+
11903
+
11904
+ async function _addAssetScheduleEvent(instance, CHANNEL_ID, ASSET, IS_LOOP,
11905
+ DURATION_TIME_CODE, PREVIOUS_ID)
11906
+ {
11907
+ const API_URL = `${instance.config.serviceApiUrl}/api/LiveChannel/${CHANNEL_ID}/liveScheduleEvent`;
11908
+
11909
+ const BODY = {
11910
+ isLoop: IS_LOOP,
11911
+ channelId: CHANNEL_ID,
11912
+ durationTimeCode: DURATION_TIME_CODE,
11913
+ previousId: PREVIOUS_ID,
11914
+ type: {
11915
+ id: _eventType.videoAsset,
11916
+ description: "Video Asset"
11917
+ },
11918
+ asset: ASSET
11919
+ };
11920
+
11921
+ return await _sendRequest(instance, "Adding Asset Schedule Event", API_URL, "POST", undefined, BODY);
11922
+ }
11923
+
11924
+
11925
+
11926
+
11927
+
11928
+
11929
+ async function _addInputScheduleEvent(instance, CHANNEL_ID, INPUT, BACKUP_INPUT,
11930
+ FIXED_ON_AIR_TIME_UTC, PREVIOUS_ID)
11931
+ {
11932
+ const API_URL = `${instance.config.serviceApiUrl}/api/LiveChannel/${CHANNEL_ID}/liveScheduleEvent`;
11933
+
11934
+ const BODY = {
11935
+ channelId: CHANNEL_ID,
11936
+ fixedOnAirTimeUtc: FIXED_ON_AIR_TIME_UTC,
11937
+ type: {
11938
+ id: _eventType.liveInput,
11939
+ description: "Live Input"
11940
+ },
11941
+ liveInput: INPUT,
11942
+ previousId: PREVIOUS_ID
11943
+ };
11944
+
11945
+ if (BACKUP_INPUT)
11946
+ {
11947
+ BODY["liveInput2"] = BACKUP_INPUT;
11948
+ }
11949
+
11950
+
11951
+ return await _sendRequest(instance, "Adding Input Schedule Event", API_URL, "POST", undefined, BODY);
11952
+ }
11953
+
11777
11954
 
11778
11955
  const _eventType = {
11779
11956
  liveInput: "eef7ef23-56dc-4f48-8c0e-1f4d52990405",
@@ -11832,92 +12009,92 @@ async function _removeInputScheduleEvent(instance, CHANNEL_ID, INPUT_ID)
11832
12009
  {
11833
12010
  const API_URL = `${instance.config.serviceApiUrl}/api/liveChannel/${CHANNEL_ID}/liveScheduleEvent/${INPUT_ID}`
11834
12011
 
11835
- return await _sendRequest(instance, "Remove Input Schedule Event", API_URL, "DELETE", undefined, undefined);
12012
+ return await _sendRequest(instance, "Remove Input Schedule Event", API_URL, "DELETE", undefined, undefined);
12013
+ }
12014
+
12015
+
12016
+
12017
+
12018
+
12019
+
12020
+ async function _updateAssetScheduleEvent(instance, ID, CHANNEL_ID, ASSET, IS_LOOP,
12021
+ DURATION_TIME_CODE)
12022
+ {
12023
+ const SCHEDULE_EVENT_INFO = await _getAssetScheduleEvent(instance, CHANNEL_ID, ID);
12024
+
12025
+ const API_URL = `${instance.config.serviceApiUrl}/api/LiveChannel/${CHANNEL_ID}/liveScheduleEvent`;
12026
+
12027
+ const BODY = {
12028
+ type: {
12029
+ id: _eventType.videoAsset,
12030
+ description: "Video Asset"
12031
+ }
12032
+ };
12033
+
12034
+ BODY.id = ID && ID !== SCHEDULE_EVENT_INFO.id ? ID : SCHEDULE_EVENT_INFO.id;
12035
+ BODY.isLoop = IS_LOOP && IS_LOOP !== SCHEDULE_EVENT_INFO.isLoop ? IS_LOOP : SCHEDULE_EVENT_INFO.isLoop;
12036
+ BODY.channelId = CHANNEL_ID && CHANNEL_ID !== SCHEDULE_EVENT_INFO.channelId ? CHANNEL_ID : SCHEDULE_EVENT_INFO.channelId;
12037
+ BODY.durationTimeCode = DURATION_TIME_CODE && DURATION_TIME_CODE !== SCHEDULE_EVENT_INFO.durationTimeCode ? DURATION_TIME_CODE : SCHEDULE_EVENT_INFO.durationTimeCode;
12038
+ BODY.asset = ASSET && ASSET !== SCHEDULE_EVENT_INFO.asset ? ASSET : SCHEDULE_EVENT_INFO.asset;
12039
+
12040
+ return await _sendRequest(instance, "Updating Asset Schedule Event", API_URL, "PUT", undefined, BODY);
12041
+ }
12042
+
12043
+
12044
+
12045
+
12046
+
12047
+
12048
+
12049
+ async function _updateInputScheduleEvent(instance, ID, CHANNEL_ID, INPUT, BACKUP_INPUT,
12050
+ FIXED_ON_AIR_TIME_UTC)
12051
+ {
12052
+ const SCHEDULE_EVENT_INFO = await _getInputScheduleEvent(instance, CHANNEL_ID, ID);
12053
+
12054
+ const API_URL = `${instance.config.serviceApiUrl}/api/LiveChannel/${CHANNEL_ID}/liveScheduleEvent`;
12055
+
12056
+ const BODY = {
12057
+ type: {
12058
+ id: _eventType.liveInput,
12059
+ description: "Live Input"
12060
+ },
12061
+ };
12062
+
12063
+ BODY.id = ID && ID !== SCHEDULE_EVENT_INFO.id ? ID : SCHEDULE_EVENT_INFO.id;
12064
+ BODY.channelId = CHANNEL_ID && CHANNEL_ID !== SCHEDULE_EVENT_INFO.channelId ? CHANNEL_ID : SCHEDULE_EVENT_INFO.channelId;
12065
+ BODY.fixedOnAirTimeUtc = FIXED_ON_AIR_TIME_UTC && FIXED_ON_AIR_TIME_UTC !== SCHEDULE_EVENT_INFO.fixedOnAirTimeUtc ? FIXED_ON_AIR_TIME_UTC : SCHEDULE_EVENT_INFO.fixedOnAirTimeUtc;
12066
+
12067
+ if (INPUT && INPUT !== SCHEDULE_EVENT_INFO.liveInput)
12068
+ {
12069
+ BODY.liveInput = {
12070
+ id: INPUT.id,
12071
+ description: INPUT.name
12072
+ };
12073
+ }
12074
+ else
12075
+ {
12076
+ BODY.liveInput = {
12077
+ id: SCHEDULE_EVENT_INFO.liveInput.id,
12078
+ description: SCHEDULE_EVENT_INFO.liveInput.name
12079
+ };
12080
+ }
12081
+
12082
+ if (BACKUP_INPUT && BACKUP_INPUT !== SCHEDULE_EVENT_INFO.liveInput2) {
12083
+ BODY.liveInput2 = {
12084
+ id: BACKUP_INPUT.id,
12085
+ description: BACKUP_INPUT.name
12086
+ };
12087
+ } else if (SCHEDULE_EVENT_INFO.liveInput2) {
12088
+ BODY.liveInput2 = {
12089
+ id: SCHEDULE_EVENT_INFO.liveInput2.id,
12090
+ description: SCHEDULE_EVENT_INFO.liveInput2.name
12091
+ };
12092
+ }
12093
+
12094
+ return await _sendRequest(instance, "Updating Input Schedule Event", API_URL, "PUT", undefined, BODY);
11836
12095
  }
11837
12096
 
11838
12097
 
11839
-
11840
-
11841
-
11842
-
11843
- async function _updateAssetScheduleEvent(instance, ID, CHANNEL_ID, ASSET, IS_LOOP,
11844
- DURATION_TIME_CODE)
11845
- {
11846
- const SCHEDULE_EVENT_INFO = await _getAssetScheduleEvent(instance, CHANNEL_ID, ID);
11847
-
11848
- const API_URL = `${instance.config.serviceApiUrl}/api/LiveChannel/${CHANNEL_ID}/liveScheduleEvent`;
11849
-
11850
- const BODY = {
11851
- type: {
11852
- id: _eventType.videoAsset,
11853
- description: "Video Asset"
11854
- }
11855
- };
11856
-
11857
- BODY.id = ID && ID !== SCHEDULE_EVENT_INFO.id ? ID : SCHEDULE_EVENT_INFO.id;
11858
- BODY.isLoop = IS_LOOP && IS_LOOP !== SCHEDULE_EVENT_INFO.isLoop ? IS_LOOP : SCHEDULE_EVENT_INFO.isLoop;
11859
- BODY.channelId = CHANNEL_ID && CHANNEL_ID !== SCHEDULE_EVENT_INFO.channelId ? CHANNEL_ID : SCHEDULE_EVENT_INFO.channelId;
11860
- BODY.durationTimeCode = DURATION_TIME_CODE && DURATION_TIME_CODE !== SCHEDULE_EVENT_INFO.durationTimeCode ? DURATION_TIME_CODE : SCHEDULE_EVENT_INFO.durationTimeCode;
11861
- BODY.asset = ASSET && ASSET !== SCHEDULE_EVENT_INFO.asset ? ASSET : SCHEDULE_EVENT_INFO.asset;
11862
-
11863
- return await _sendRequest(instance, "Updating Asset Schedule Event", API_URL, "PUT", undefined, BODY);
11864
- }
11865
-
11866
-
11867
-
11868
-
11869
-
11870
-
11871
-
11872
- async function _updateInputScheduleEvent(instance, ID, CHANNEL_ID, INPUT, BACKUP_INPUT,
11873
- FIXED_ON_AIR_TIME_UTC)
11874
- {
11875
- const SCHEDULE_EVENT_INFO = await _getInputScheduleEvent(instance, CHANNEL_ID, ID);
11876
-
11877
- const API_URL = `${instance.config.serviceApiUrl}/api/LiveChannel/${CHANNEL_ID}/liveScheduleEvent`;
11878
-
11879
- const BODY = {
11880
- type: {
11881
- id: _eventType.liveInput,
11882
- description: "Live Input"
11883
- },
11884
- };
11885
-
11886
- BODY.id = ID && ID !== SCHEDULE_EVENT_INFO.id ? ID : SCHEDULE_EVENT_INFO.id;
11887
- BODY.channelId = CHANNEL_ID && CHANNEL_ID !== SCHEDULE_EVENT_INFO.channelId ? CHANNEL_ID : SCHEDULE_EVENT_INFO.channelId;
11888
- BODY.fixedOnAirTimeUtc = FIXED_ON_AIR_TIME_UTC && FIXED_ON_AIR_TIME_UTC !== SCHEDULE_EVENT_INFO.fixedOnAirTimeUtc ? FIXED_ON_AIR_TIME_UTC : SCHEDULE_EVENT_INFO.fixedOnAirTimeUtc;
11889
-
11890
- if (INPUT && INPUT !== SCHEDULE_EVENT_INFO.liveInput)
11891
- {
11892
- BODY.liveInput = {
11893
- id: INPUT.id,
11894
- description: INPUT.name
11895
- };
11896
- }
11897
- else
11898
- {
11899
- BODY.liveInput = {
11900
- id: SCHEDULE_EVENT_INFO.liveInput.id,
11901
- description: SCHEDULE_EVENT_INFO.liveInput.name
11902
- };
11903
- }
11904
-
11905
- if (BACKUP_INPUT && BACKUP_INPUT !== SCHEDULE_EVENT_INFO.liveInput2) {
11906
- BODY.liveInput2 = {
11907
- id: BACKUP_INPUT.id,
11908
- description: BACKUP_INPUT.name
11909
- };
11910
- } else if (SCHEDULE_EVENT_INFO.liveInput2) {
11911
- BODY.liveInput2 = {
11912
- id: SCHEDULE_EVENT_INFO.liveInput2.id,
11913
- description: SCHEDULE_EVENT_INFO.liveInput2.name
11914
- };
11915
- }
11916
-
11917
- return await _sendRequest(instance, "Updating Input Schedule Event", API_URL, "PUT", undefined, BODY);
11918
- }
11919
-
11920
-
11921
12098
 
11922
12099
 
11923
12100
 
@@ -12660,53 +12837,53 @@ async function _deleteUser(instance, USER_ID)
12660
12837
  }
12661
12838
 
12662
12839
 
12663
-
12664
-
12665
- async function _register(instance, EMAIL, FIRST_NAME, LAST_NAME, PASSWORD)
12666
- {
12667
- const API_URL = `${instance.config.serviceApiUrl}/api/account/register`
12668
-
12669
- const BODY = {
12670
- firstName: FIRST_NAME,
12671
- lastName: LAST_NAME,
12672
- email: EMAIL,
12673
- password: PASSWORD
12674
- };
12675
-
12676
- return await _sendRequest(instance, "Register", API_URL, "POST", undefined, BODY);
12677
- }
12678
-
12679
-
12680
-
12681
-
12682
-
12683
-
12684
- async function _resendCode(instance, EMAIL)
12685
- {
12686
- const API_URL = `${instance.config.serviceApiUrl}/api/account/resend-code`
12687
-
12688
- const BODY = {
12689
- userName: EMAIL
12690
- };
12691
-
12692
- return await _sendRequest(instance, "Resend Code", API_URL, "POST", undefined, BODY);
12693
- }
12694
-
12695
-
12696
-
12697
-
12698
- async function _verify(instance, EMAIL, CODE)
12699
- {
12700
- const API_URL = `${instance.config.serviceApiUrl}/api/account/verify`
12701
-
12702
- const BODY = {
12703
- userName: EMAIL,
12704
- token: CODE
12705
- };
12706
-
12707
- return await _sendRequest(instance, "Verify", API_URL, "POST", undefined, BODY);
12708
- }
12709
-
12840
+
12841
+
12842
+ async function _register(instance, EMAIL, FIRST_NAME, LAST_NAME, PASSWORD)
12843
+ {
12844
+ const API_URL = `${instance.config.serviceApiUrl}/api/account/register`
12845
+
12846
+ const BODY = {
12847
+ firstName: FIRST_NAME,
12848
+ lastName: LAST_NAME,
12849
+ email: EMAIL,
12850
+ password: PASSWORD
12851
+ };
12852
+
12853
+ return await _sendRequest(instance, "Register", API_URL, "POST", undefined, BODY);
12854
+ }
12855
+
12856
+
12857
+
12858
+
12859
+
12860
+
12861
+ async function _resendCode(instance, EMAIL)
12862
+ {
12863
+ const API_URL = `${instance.config.serviceApiUrl}/api/account/resend-code`
12864
+
12865
+ const BODY = {
12866
+ userName: EMAIL
12867
+ };
12868
+
12869
+ return await _sendRequest(instance, "Resend Code", API_URL, "POST", undefined, BODY);
12870
+ }
12871
+
12872
+
12873
+
12874
+
12875
+ async function _verify(instance, EMAIL, CODE)
12876
+ {
12877
+ const API_URL = `${instance.config.serviceApiUrl}/api/account/verify`
12878
+
12879
+ const BODY = {
12880
+ userName: EMAIL,
12881
+ token: CODE
12882
+ };
12883
+
12884
+ return await _sendRequest(instance, "Verify", API_URL, "POST", undefined, BODY);
12885
+ }
12886
+
12710
12887
 
12711
12888
 
12712
12889
 
@@ -13532,25 +13709,25 @@ async function _createTagOrCollection(instance, TYPE, TAG_NAME)
13532
13709
  }
13533
13710
 
13534
13711
 
13535
-
13536
-
13537
- async function _deleteRelatedContent(instance, CONTENT_ID, RELATED_CONTENT_ID, CONTENT_DEFINITION)
13538
- {
13539
- const API_URL = instance.config.apiType === "admin" ? `${instance.config.serviceApiUrl}/api/admin/related/delete` : `${instance.config.serviceApiUrl}/api/content/related/delete`;
13540
-
13541
- const BODY = {
13542
- items: [
13543
- {
13544
- contentDefinition: CONTENT_DEFINITION,
13545
- contentId: CONTENT_ID,
13546
- relatedContentId: RELATED_CONTENT_ID
13547
- }
13548
- ]
13549
- };
13550
-
13551
- return await _sendRequest(instance, "Deleting Related Content", API_URL, "POST", undefined, BODY);
13552
- }
13553
-
13712
+
13713
+
13714
+ async function _deleteRelatedContent(instance, CONTENT_ID, RELATED_CONTENT_ID, CONTENT_DEFINITION)
13715
+ {
13716
+ const API_URL = instance.config.apiType === "admin" ? `${instance.config.serviceApiUrl}/api/admin/related/delete` : `${instance.config.serviceApiUrl}/api/content/related/delete`;
13717
+
13718
+ const BODY = {
13719
+ items: [
13720
+ {
13721
+ contentDefinition: CONTENT_DEFINITION,
13722
+ contentId: CONTENT_ID,
13723
+ relatedContentId: RELATED_CONTENT_ID
13724
+ }
13725
+ ]
13726
+ };
13727
+
13728
+ return await _sendRequest(instance, "Deleting Related Content", API_URL, "POST", undefined, BODY);
13729
+ }
13730
+
13554
13731
 
13555
13732
 
13556
13733
 
@@ -13572,26 +13749,26 @@ async function _getTagOrCollection(instance, TYPE, ID)
13572
13749
  }
13573
13750
 
13574
13751
 
13575
-
13576
-
13577
- async function _removeTagOrCollection(instance, TYPE, CONTENT_ID, CONTENT_DEFINITION_ID, TAG_ID)
13578
- {
13579
- const API_URL = instance.config.apiType === "admin" ? `${instance.config.serviceApiUrl}/api/admin/${TYPE}/content/delete` : `${instance.config.serviceApiUrl}/api/content/${TYPE}/delete`;
13580
-
13581
- const BODY = {
13582
- items: [
13583
- {
13584
- contentDefinition: CONTENT_DEFINITION_ID,
13585
- contentId: CONTENT_ID
13586
- }
13587
- ]
13588
- };
13589
-
13590
- BODY.items[0][`${TYPE}Id`] = TAG_ID;
13591
-
13592
- return await _sendRequest(instance, "Removing Tag or Collection", API_URL, "POST", undefined, BODY);
13593
- }
13594
-
13752
+
13753
+
13754
+ async function _removeTagOrCollection(instance, TYPE, CONTENT_ID, CONTENT_DEFINITION_ID, TAG_ID)
13755
+ {
13756
+ const API_URL = instance.config.apiType === "admin" ? `${instance.config.serviceApiUrl}/api/admin/${TYPE}/content/delete` : `${instance.config.serviceApiUrl}/api/content/${TYPE}/delete`;
13757
+
13758
+ const BODY = {
13759
+ items: [
13760
+ {
13761
+ contentDefinition: CONTENT_DEFINITION_ID,
13762
+ contentId: CONTENT_ID
13763
+ }
13764
+ ]
13765
+ };
13766
+
13767
+ BODY.items[0][`${TYPE}Id`] = TAG_ID;
13768
+
13769
+ return await _sendRequest(instance, "Removing Tag or Collection", API_URL, "POST", undefined, BODY);
13770
+ }
13771
+
13595
13772
 
13596
13773
 
13597
13774
 
@@ -13660,62 +13837,62 @@ async function _search(instance, QUERY, OFFSET, SIZE, FILTERS, SORT_FIELDS, SEAR
13660
13837
  }
13661
13838
 
13662
13839
 
13663
- function _apiExceptionHandler(error, message)
13664
- {
13665
- // Check if we have a response object and error message
13666
- if (!error)
13667
- {
13668
- console.error(message);
13669
- }
13670
-
13671
- // Check if error is a string
13672
- if (typeof error === "string")
13673
- {
13674
- console.error(`${message}: ${error}`);
13675
- }
13676
- else if (error.errors)
13677
- {
13678
- if (Array.isArray(error.errors))
13679
- {
13680
- let errorString = "";
13681
- for (let errorIdx = 0; errorIdx < error.errors.length; errorIdx++)
13682
- {
13683
- errorString += `${error.errors[errorIdx].code}: ${error.errors[errorIdx].field}: ${error.errors[errorIdx].message}\n`;
13684
- }
13685
- console.error(`${message}: ${errorString}`);
13686
- }
13687
- else if (typeof error.errors === "object")
13688
- {
13689
- let errorString = "";
13690
- for (let key in error.errors)
13691
- {
13692
- if (Object.prototype.hasOwnProperty.call(error.errors, key))
13693
- {
13694
- errorString += `${key}: ${error.errors[key]}\n`;
13695
- }
13696
- }
13697
- console.error(`${message}: ${errorString}`);
13698
- }
13699
- }
13700
- else
13701
- {
13702
- console.error(`${message}: ${error.message}`);
13703
- }
13704
-
13705
- return null;
13706
- }
13707
-
13708
-
13709
- import { getRandomValues } from 'crypto';
13710
-
13711
- function _newGuid()
13712
- {
13713
- return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) =>
13714
- (c ^ (getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)
13715
- );
13716
- }
13717
-
13718
-
13840
+ function _apiExceptionHandler(error, message)
13841
+ {
13842
+ // Check if we have a response object and error message
13843
+ if (!error)
13844
+ {
13845
+ console.error(message);
13846
+ }
13847
+
13848
+ // Check if error is a string
13849
+ if (typeof error === "string")
13850
+ {
13851
+ console.error(`${message}: ${error}`);
13852
+ }
13853
+ else if (error.errors)
13854
+ {
13855
+ if (Array.isArray(error.errors))
13856
+ {
13857
+ let errorString = "";
13858
+ for (let errorIdx = 0; errorIdx < error.errors.length; errorIdx++)
13859
+ {
13860
+ errorString += `${error.errors[errorIdx].code}: ${error.errors[errorIdx].field}: ${error.errors[errorIdx].message}\n`;
13861
+ }
13862
+ console.error(`${message}: ${errorString}`);
13863
+ }
13864
+ else if (typeof error.errors === "object")
13865
+ {
13866
+ let errorString = "";
13867
+ for (let key in error.errors)
13868
+ {
13869
+ if (Object.prototype.hasOwnProperty.call(error.errors, key))
13870
+ {
13871
+ errorString += `${key}: ${error.errors[key]}\n`;
13872
+ }
13873
+ }
13874
+ console.error(`${message}: ${errorString}`);
13875
+ }
13876
+ }
13877
+ else
13878
+ {
13879
+ console.error(`${message}: ${error.message}`);
13880
+ }
13881
+
13882
+ return null;
13883
+ }
13884
+
13885
+
13886
+ import { getRandomValues } from 'crypto';
13887
+
13888
+ function _newGuid()
13889
+ {
13890
+ return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) =>
13891
+ (c ^ (getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)
13892
+ );
13893
+ }
13894
+
13895
+
13719
13896
 
13720
13897
  function _printDatetime(msg)
13721
13898
  {
@@ -13726,7 +13903,7 @@ function _printDatetime(msg)
13726
13903
 
13727
13904
 
13728
13905
  import { promises as fs } from 'fs';
13729
-
13906
+ import path from 'path';
13730
13907
 
13731
13908
  async function _processFile(FILE)
13732
13909
  {
@@ -13738,7 +13915,7 @@ async function _processFile(FILE)
13738
13915
  {
13739
13916
  FILE_PATH = FILE;
13740
13917
  FILE = await fs.stat(FILE);
13741
- FILE.originalname = path.basename(FILE_PATH);
13918
+ FILE.originalName = path.basename(FILE_PATH);
13742
13919
  if (!FILE.buffer)
13743
13920
  {
13744
13921
  FILE.buffer = await fs.readFile(FILE_PATH);
@@ -13751,7 +13928,7 @@ async function _processFile(FILE)
13751
13928
  }
13752
13929
  else
13753
13930
  {
13754
- FILE.originalname = FILE.name;
13931
+ FILE.originalName = FILE.name;
13755
13932
  // if running in browser
13756
13933
  if (!FILE.buffer)
13757
13934
  {
@@ -13759,7 +13936,7 @@ async function _processFile(FILE)
13759
13936
  }
13760
13937
  }
13761
13938
 
13762
- return [FILE, FILE_PATH];
13939
+ return FILE;
13763
13940
  }
13764
13941
 
13765
13942
  async function _readFileAsArrayBuffer(file)
@@ -13782,9 +13959,9 @@ async function _readFileAsArrayBuffer(file)
13782
13959
 
13783
13960
  import axios from 'axios';
13784
13961
 
13785
- const MAX_RETRIES = 5;
13786
- const TIMEOUT = 30000;
13787
- const SLEEP_TIME = .5;
13962
+ const MAX_RETRIES = 3;
13963
+ const TIMEOUT = 10000;
13964
+ const SLEEP_TIME = 2;
13788
13965
 
13789
13966
  async function _sendRequest(instance, FUNCTION_NAME, URL, METHOD_TYPE, PARAMS, BODY)
13790
13967
  {
@@ -13849,70 +14026,70 @@ async function _sendRequest(instance, FUNCTION_NAME, URL, METHOD_TYPE, PARAMS, B
13849
14026
  }
13850
14027
 
13851
14028
 
13852
- async function _sleep(duration)
13853
- {
13854
- // Check for valid duration
13855
- if (!duration || duration === 0)
13856
- {
13857
- // Ignore
13858
- return;
13859
- }
13860
-
13861
- // Sleep
13862
- return new Promise((resolve) => {
13863
- setTimeout(() => {
13864
- resolve();
13865
- }, duration * 1000);
13866
- });
13867
- }
13868
-
13869
-
13870
-
13871
- function _slugify(text)
13872
- {
13873
- if (!text || text.trim().length === 0) return "";
13874
- return text
13875
- .toString()
13876
- .normalize("NFD")
13877
- .replace(/[\u0300-\u036f]/g, "")
13878
- .toLowerCase()
13879
- .trim()
13880
- .replace(/\s+/g, "-")
13881
- .replace(/[^\w-]+/g, "")
13882
- .replace(/--+/g, "-");
13883
- }
13884
-
13885
-
13886
-
13887
-
13888
-
13889
- async function _changeEmail(instance, EMAIL)
13890
- {
13891
- const API_URL = `${instance.config.serviceApiUrl}/api/account/change-email`;
13892
-
13893
- const BODY = {
13894
- password: instance.config.password,
13895
- newEmail: EMAIL
13896
- };
13897
-
13898
- return await _sendRequest(instance, "Change email", API_URL, "POST", undefined, BODY);
13899
- }
13900
-
13901
-
13902
-
13903
-
13904
- async function _changePassword(instance, NEW_PASSWORD)
13905
- {
13906
- const API_URL = `${instance.config.serviceApiUrl}/api/account/change-password`;
13907
-
13908
- const BODY = {
13909
- password: instance.config.password,
13910
- newPassword: NEW_PASSWORD
13911
- };
13912
-
13913
- return await _sendRequest(instance, "Change password", API_URL, "POST", undefined, BODY);
13914
- }
13915
-
14029
+ async function _sleep(duration)
14030
+ {
14031
+ // Check for valid duration
14032
+ if (!duration || duration === 0)
14033
+ {
14034
+ // Ignore
14035
+ return;
14036
+ }
14037
+
14038
+ // Sleep
14039
+ return new Promise((resolve) => {
14040
+ setTimeout(() => {
14041
+ resolve();
14042
+ }, duration * 1000);
14043
+ });
14044
+ }
14045
+
14046
+
14047
+
14048
+ function _slugify(text)
14049
+ {
14050
+ if (!text || text.trim().length === 0) return "";
14051
+ return text
14052
+ .toString()
14053
+ .normalize("NFD")
14054
+ .replace(/[\u0300-\u036f]/g, "")
14055
+ .toLowerCase()
14056
+ .trim()
14057
+ .replace(/\s+/g, "-")
14058
+ .replace(/[^\w-]+/g, "")
14059
+ .replace(/--+/g, "-");
14060
+ }
14061
+
14062
+
14063
+
14064
+
14065
+
14066
+ async function _changeEmail(instance, EMAIL)
14067
+ {
14068
+ const API_URL = `${instance.config.serviceApiUrl}/api/account/change-email`;
14069
+
14070
+ const BODY = {
14071
+ password: instance.config.password,
14072
+ newEmail: EMAIL
14073
+ };
14074
+
14075
+ return await _sendRequest(instance, "Change email", API_URL, "POST", undefined, BODY);
14076
+ }
14077
+
14078
+
14079
+
14080
+
14081
+ async function _changePassword(instance, NEW_PASSWORD)
14082
+ {
14083
+ const API_URL = `${instance.config.serviceApiUrl}/api/account/change-password`;
14084
+
14085
+ const BODY = {
14086
+ password: instance.config.password,
14087
+ newPassword: NEW_PASSWORD
14088
+ };
14089
+
14090
+ return await _sendRequest(instance, "Change password", API_URL, "POST", undefined, BODY);
14091
+ }
14092
+
13916
14093
 
13917
14094
 
13918
14095
 
@@ -13935,74 +14112,74 @@ async function _getUser(instance)
13935
14112
  }
13936
14113
 
13937
14114
 
13938
-
13939
-
13940
-
13941
-
13942
-
13943
- async function _updateUser(instance, ADDRESS, ADDRESS2, CITY, COUNTRY,
13944
- FIRST_NAME, LAST_NAME, ORGANIZATION, PHONE_NUMBER, PHONE_EXT, POSTAL_CODE, STATE)
13945
- {
13946
- const USER_INFO = await _getUser(instance);
13947
-
13948
- const API_URL = `${instance.config.serviceApiUrl}/api/account/user`;
13949
-
13950
- const BODY = {};
13951
-
13952
- const LOOKUPS = await _getLookups(instance);
13953
-
13954
- const COUNTRIES_INFO = LOOKUPS.find(lookup => lookup["label"] === "Countries");
13955
- const COUNTRY_SELECTED = COUNTRIES_INFO.children.find(country => country["label"] === COUNTRY);
13956
-
13957
- const STATES_INFO = LOOKUPS.find(lookup => lookup["label"] === "States");
13958
- const STATE_SELECTED = STATES_INFO.children.find(state => state["label"] === STATE);
13959
-
13960
- const keyValues = {
13961
- address: ADDRESS,
13962
- address2: ADDRESS2,
13963
- city: CITY,
13964
- state: STATE_SELECTED,
13965
- country: COUNTRY_SELECTED,
13966
- firstName: FIRST_NAME,
13967
- lastName: LAST_NAME,
13968
- phone: PHONE_NUMBER,
13969
- phoneExt: PHONE_EXT,
13970
- postalCode: POSTAL_CODE,
13971
- organization: ORGANIZATION,
13972
- };
13973
-
13974
- Object.entries(keyValues).forEach(([key, value]) => {
13975
- BODY[key] = value !== null ? value: USER_INFO[key] ?? BODY[key];
13976
- });
13977
-
13978
- return await _sendRequest(instance, "Update user", API_URL, "PUT", undefined, BODY);
13979
- }
13980
-
13981
-
13982
-
13983
-
13984
- async function _addContentsToContentGroup(instance, CONTENT_GROUP_ID, CONTENTS)
13985
- {
13986
- const API_URL = `${instance.config.serviceApiUrl}/api/contentgroup/add/${CONTENT_GROUP_ID}`;
13987
-
13988
- const BODY = CONTENTS;
13989
-
13990
- return await _sendRequest(instance, "Adding Contents to Content Group", API_URL, "POST", undefined, BODY);
13991
- }
13992
-
13993
-
13994
-
13995
-
13996
- async function _createContentGroup(instance, NAME)
13997
- {
13998
- const API_URL = `${instance.config.serviceApiUrl}/api/contentGroup`;
13999
-
14000
- const BODY = {};
14001
- if (NAME) BODY.name = NAME;
14002
-
14003
- return await _sendRequest(instance, "Creating Content Group", API_URL, "POST", undefined, BODY);
14004
- }
14005
-
14115
+
14116
+
14117
+
14118
+
14119
+
14120
+ async function _updateUser(instance, ADDRESS, ADDRESS2, CITY, COUNTRY,
14121
+ FIRST_NAME, LAST_NAME, ORGANIZATION, PHONE_NUMBER, PHONE_EXT, POSTAL_CODE, STATE)
14122
+ {
14123
+ const USER_INFO = await _getUser(instance);
14124
+
14125
+ const API_URL = `${instance.config.serviceApiUrl}/api/account/user`;
14126
+
14127
+ const BODY = {};
14128
+
14129
+ const LOOKUPS = await _getLookups(instance);
14130
+
14131
+ const COUNTRIES_INFO = LOOKUPS.find(lookup => lookup["label"] === "Countries");
14132
+ const COUNTRY_SELECTED = COUNTRIES_INFO.children.find(country => country["label"] === COUNTRY);
14133
+
14134
+ const STATES_INFO = LOOKUPS.find(lookup => lookup["label"] === "States");
14135
+ const STATE_SELECTED = STATES_INFO.children.find(state => state["label"] === STATE);
14136
+
14137
+ const keyValues = {
14138
+ address: ADDRESS,
14139
+ address2: ADDRESS2,
14140
+ city: CITY,
14141
+ state: STATE_SELECTED,
14142
+ country: COUNTRY_SELECTED,
14143
+ firstName: FIRST_NAME,
14144
+ lastName: LAST_NAME,
14145
+ phone: PHONE_NUMBER,
14146
+ phoneExt: PHONE_EXT,
14147
+ postalCode: POSTAL_CODE,
14148
+ organization: ORGANIZATION,
14149
+ };
14150
+
14151
+ Object.entries(keyValues).forEach(([key, value]) => {
14152
+ BODY[key] = value !== null ? value: USER_INFO[key] ?? BODY[key];
14153
+ });
14154
+
14155
+ return await _sendRequest(instance, "Update user", API_URL, "PUT", undefined, BODY);
14156
+ }
14157
+
14158
+
14159
+
14160
+
14161
+ async function _addContentsToContentGroup(instance, CONTENT_GROUP_ID, CONTENTS)
14162
+ {
14163
+ const API_URL = `${instance.config.serviceApiUrl}/api/contentgroup/add/${CONTENT_GROUP_ID}`;
14164
+
14165
+ const BODY = CONTENTS;
14166
+
14167
+ return await _sendRequest(instance, "Adding Contents to Content Group", API_URL, "POST", undefined, BODY);
14168
+ }
14169
+
14170
+
14171
+
14172
+
14173
+ async function _createContentGroup(instance, NAME)
14174
+ {
14175
+ const API_URL = `${instance.config.serviceApiUrl}/api/contentGroup`;
14176
+
14177
+ const BODY = {};
14178
+ if (NAME) BODY.name = NAME;
14179
+
14180
+ return await _sendRequest(instance, "Creating Content Group", API_URL, "POST", undefined, BODY);
14181
+ }
14182
+
14006
14183
 
14007
14184
 
14008
14185
 
@@ -14034,57 +14211,57 @@ async function _getContentGroups(instance)
14034
14211
  }
14035
14212
 
14036
14213
 
14037
-
14038
-
14039
- async function _getPortalGroups(instance, PORTAL_GROUPS)
14040
- {
14041
- const API_URL = `${instance.config.serviceApiUrl}/api/portal/groups`;
14042
-
14043
- const BODY = {
14044
- "returnedGroupNames": PORTAL_GROUPS
14045
- }
14046
-
14047
- return await _sendRequest(instance, "Getting Portal Groups", API_URL, "POST", undefined, BODY);
14048
- }
14049
-
14050
-
14051
-
14052
-
14053
- async function _removeContentsFromContentGroup(instance, CONTENT_GROUP_ID, CONTENTS)
14054
- {
14055
- const API_URL = `${instance.config.serviceApiUrl}/api/contentgroup/remove/${CONTENT_GROUP_ID}`;
14056
-
14057
- const BODY = CONTENTS;
14058
-
14059
- return await _sendRequest(instance, "Removing Content From Content Group", API_URL, "POST", undefined, BODY);
14060
- }
14061
-
14062
-
14063
-
14064
-
14065
- async function _renameContentGroup(instance, CONTENT_GROUP_ID, NAME)
14066
- {
14067
- const API_URL = `${instance.config.serviceApiUrl}/api/contentgroup/${CONTENT_GROUP_ID}`;
14068
-
14069
- const BODY = {
14070
- Name: NAME
14071
- };
14072
-
14073
- return await _sendRequest(instance, "Renaming Content Group", API_URL, "PATCH", undefined, BODY);
14074
- }
14075
-
14076
-
14077
-
14078
-
14079
- async function _shareContentGroupWithUsers(instance, CONTENT_GROUP_ID, USER_IDS)
14080
- {
14081
- const API_URL = `${instance.config.serviceApiUrl}/api/contentgroup/share/${CONTENT_GROUP_ID}`;
14082
-
14083
- const BODY = USER_IDS;
14084
-
14085
- return await _sendRequest(instance, "Sharing Content Group With Users", API_URL, "POST", undefined, BODY);
14086
- }
14087
-
14214
+
14215
+
14216
+ async function _getPortalGroups(instance, PORTAL_GROUPS)
14217
+ {
14218
+ const API_URL = `${instance.config.serviceApiUrl}/api/portal/groups`;
14219
+
14220
+ const BODY = {
14221
+ "returnedGroupNames": PORTAL_GROUPS
14222
+ }
14223
+
14224
+ return await _sendRequest(instance, "Getting Portal Groups", API_URL, "POST", undefined, BODY);
14225
+ }
14226
+
14227
+
14228
+
14229
+
14230
+ async function _removeContentsFromContentGroup(instance, CONTENT_GROUP_ID, CONTENTS)
14231
+ {
14232
+ const API_URL = `${instance.config.serviceApiUrl}/api/contentgroup/remove/${CONTENT_GROUP_ID}`;
14233
+
14234
+ const BODY = CONTENTS;
14235
+
14236
+ return await _sendRequest(instance, "Removing Content From Content Group", API_URL, "POST", undefined, BODY);
14237
+ }
14238
+
14239
+
14240
+
14241
+
14242
+ async function _renameContentGroup(instance, CONTENT_GROUP_ID, NAME)
14243
+ {
14244
+ const API_URL = `${instance.config.serviceApiUrl}/api/contentgroup/${CONTENT_GROUP_ID}`;
14245
+
14246
+ const BODY = {
14247
+ Name: NAME
14248
+ };
14249
+
14250
+ return await _sendRequest(instance, "Renaming Content Group", API_URL, "PATCH", undefined, BODY);
14251
+ }
14252
+
14253
+
14254
+
14255
+
14256
+ async function _shareContentGroupWithUsers(instance, CONTENT_GROUP_ID, USER_IDS)
14257
+ {
14258
+ const API_URL = `${instance.config.serviceApiUrl}/api/contentgroup/share/${CONTENT_GROUP_ID}`;
14259
+
14260
+ const BODY = USER_IDS;
14261
+
14262
+ return await _sendRequest(instance, "Sharing Content Group With Users", API_URL, "POST", undefined, BODY);
14263
+ }
14264
+
14088
14265
 
14089
14266
 
14090
14267
 
@@ -14098,60 +14275,60 @@ async function _stopSharingContentGroupWithUsers(instance, CONTENT_GROUP_ID, USE
14098
14275
  }
14099
14276
 
14100
14277
 
14101
-
14102
-
14103
- async function _guestInvite(instance, CONTENT_ID, CONTENT_DEFINITION_ID, USER_ID,
14104
- EMAILS, CONTENT_SECURITY_ATTRIBUTE)
14105
- {
14106
- const API_URL = `${instance.config.serviceApiUrl}/api/account/invite-user`;
14107
-
14108
- const BODY = {
14109
- contentId: CONTENT_ID,
14110
- contentDefinitionId: CONTENT_DEFINITION_ID,
14111
- userId: USER_ID,
14112
- emails: EMAILS,
14113
- contentSecurityAttribute: CONTENT_SECURITY_ATTRIBUTE
14114
- };
14115
-
14116
- return await _sendRequest(instance, "Guest Invite", API_URL, "POST", undefined, BODY);
14117
- }
14118
-
14119
-
14120
-
14121
-
14122
- async function _registerGuest(instance, EMAIL, FIRST_NAME, LAST_NAME, PASSWORD)
14123
- {
14124
- const API_URL = `${instance.config.serviceApiUrl}/api/account/register-guest`;
14125
-
14126
- const BODY = {
14127
- email: EMAIL,
14128
- firstName: FIRST_NAME,
14129
- lastName: LAST_NAME,
14130
- password: PASSWORD
14131
- };
14132
-
14133
- return await _sendRequest(instance, "Register guest", API_URL, "POST", undefined, BODY);
14134
- }
14135
-
14136
-
14137
-
14138
-
14139
- async function _removeGuest(instance, CONTENT_ID, CONTENT_DEFINITION_ID, USER_ID,
14140
- EMAILS, CONTENT_SECURITY_ATTRIBUTE)
14141
- {
14142
- const API_URL = `${instance.config.serviceApiUrl}/api/account/remove-user`;
14143
-
14144
- const BODY = {
14145
- contentId: CONTENT_ID,
14146
- contentDefinitionId: CONTENT_DEFINITION_ID,
14147
- userId: USER_ID,
14148
- emails: EMAILS,
14149
- contentSecurityAttribute: CONTENT_SECURITY_ATTRIBUTE
14150
- };
14151
-
14152
- return await _sendRequest(instance, "Remove guest", API_URL, "POST", undefined, BODY);
14153
- }
14154
-
14278
+
14279
+
14280
+ async function _guestInvite(instance, CONTENT_ID, CONTENT_DEFINITION_ID, USER_ID,
14281
+ EMAILS, CONTENT_SECURITY_ATTRIBUTE)
14282
+ {
14283
+ const API_URL = `${instance.config.serviceApiUrl}/api/account/invite-user`;
14284
+
14285
+ const BODY = {
14286
+ contentId: CONTENT_ID,
14287
+ contentDefinitionId: CONTENT_DEFINITION_ID,
14288
+ userId: USER_ID,
14289
+ emails: EMAILS,
14290
+ contentSecurityAttribute: CONTENT_SECURITY_ATTRIBUTE
14291
+ };
14292
+
14293
+ return await _sendRequest(instance, "Guest Invite", API_URL, "POST", undefined, BODY);
14294
+ }
14295
+
14296
+
14297
+
14298
+
14299
+ async function _registerGuest(instance, EMAIL, FIRST_NAME, LAST_NAME, PASSWORD)
14300
+ {
14301
+ const API_URL = `${instance.config.serviceApiUrl}/api/account/register-guest`;
14302
+
14303
+ const BODY = {
14304
+ email: EMAIL,
14305
+ firstName: FIRST_NAME,
14306
+ lastName: LAST_NAME,
14307
+ password: PASSWORD
14308
+ };
14309
+
14310
+ return await _sendRequest(instance, "Register guest", API_URL, "POST", undefined, BODY);
14311
+ }
14312
+
14313
+
14314
+
14315
+
14316
+ async function _removeGuest(instance, CONTENT_ID, CONTENT_DEFINITION_ID, USER_ID,
14317
+ EMAILS, CONTENT_SECURITY_ATTRIBUTE)
14318
+ {
14319
+ const API_URL = `${instance.config.serviceApiUrl}/api/account/remove-user`;
14320
+
14321
+ const BODY = {
14322
+ contentId: CONTENT_ID,
14323
+ contentDefinitionId: CONTENT_DEFINITION_ID,
14324
+ userId: USER_ID,
14325
+ emails: EMAILS,
14326
+ contentSecurityAttribute: CONTENT_SECURITY_ATTRIBUTE
14327
+ };
14328
+
14329
+ return await _sendRequest(instance, "Remove guest", API_URL, "POST", undefined, BODY);
14330
+ }
14331
+
14155
14332
 
14156
14333
 
14157
14334
 
@@ -14366,17 +14543,17 @@ async function _clearWatchlist(instance, USER_ID)
14366
14543
  }
14367
14544
 
14368
14545
 
14369
-
14370
-
14371
- async function _createForm(instance, CONTENT_DEFINITION_ID, FORM_INFO)
14372
- {
14373
- const API_URL = `${instance.config.serviceApiUrl}/api/media/form/${CONTENT_DEFINITION_ID}`;
14374
-
14375
- const BODY = FORM_INFO;
14376
-
14377
- return await _sendRequest(instance, "Creating Form", API_URL, "POST", undefined, BODY);
14378
- }
14379
-
14546
+
14547
+
14548
+ async function _createForm(instance, CONTENT_DEFINITION_ID, FORM_INFO)
14549
+ {
14550
+ const API_URL = `${instance.config.serviceApiUrl}/api/media/form/${CONTENT_DEFINITION_ID}`;
14551
+
14552
+ const BODY = FORM_INFO;
14553
+
14554
+ return await _sendRequest(instance, "Creating Form", API_URL, "POST", undefined, BODY);
14555
+ }
14556
+
14380
14557
 
14381
14558
 
14382
14559
 
@@ -14468,25 +14645,25 @@ async function _getSiteConfig(instance, ID)
14468
14645
  }
14469
14646
 
14470
14647
 
14471
-
14472
-
14473
- async function _mediaSearch(instance, SEARCH_QUERY, IDS, SORT_FIELDS,
14474
- PAGE_OFFSET, PAGE_SIZE)
14475
- {
14476
- const API_URL = `${instance.config.serviceApiUrl}/api/media/search`;
14477
-
14478
- const BODY = {
14479
- searchQuery: SEARCH_QUERY,
14480
- ids: IDS,
14481
- sortFields: SORT_FIELDS
14482
- };
14483
-
14484
- PAGE_OFFSET ? BODY["pageOffset"] = PAGE_OFFSET : BODY["pageOffset"] = 0;
14485
- PAGE_SIZE ? BODY["pageSize"] = PAGE_SIZE : BODY["pageSize"] = 100;
14486
-
14487
- return await _sendRequest(instance, "Media Search", API_URL, "POST", undefined, BODY);
14488
- }
14489
-
14648
+
14649
+
14650
+ async function _mediaSearch(instance, SEARCH_QUERY, IDS, SORT_FIELDS,
14651
+ PAGE_OFFSET, PAGE_SIZE)
14652
+ {
14653
+ const API_URL = `${instance.config.serviceApiUrl}/api/media/search`;
14654
+
14655
+ const BODY = {
14656
+ searchQuery: SEARCH_QUERY,
14657
+ ids: IDS,
14658
+ sortFields: SORT_FIELDS
14659
+ };
14660
+
14661
+ PAGE_OFFSET ? BODY["pageOffset"] = PAGE_OFFSET : BODY["pageOffset"] = 0;
14662
+ PAGE_SIZE ? BODY["pageSize"] = PAGE_SIZE : BODY["pageSize"] = 100;
14663
+
14664
+ return await _sendRequest(instance, "Media Search", API_URL, "POST", undefined, BODY);
14665
+ }
14666
+
14490
14667
 
14491
14668
 
14492
14669