@nomad-media/full 1.1.19 → 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.
@@ -326,7 +326,7 @@ class NomadMediaSDK {
326
326
  * @async
327
327
  * @description Logs in using the username and password from the config.
328
328
  * @returns {Promise<void>} - A promise that resolves when the login is successful.
329
- * 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.
330
330
  * @throws {Error} - An error is thrown if the login fails.
331
331
  */
332
332
  async login()
@@ -382,7 +382,7 @@ class NomadMediaSDK {
382
382
  }
383
383
  catch (error)
384
384
  {
385
- _printDatetime("Loggout failed");
385
+ _printDatetime("Logout failed");
386
386
  throw error;
387
387
  }
388
388
  }
@@ -490,7 +490,7 @@ class NomadMediaSDK {
490
490
  * and cancel. Continue continues the upload from where it left off. Replace replaces an
491
491
  * existing asset. Replace is the one you want to use if you are starting a new upload.
492
492
  * Cancel cancels an uploading asset.
493
- * @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.
494
494
  * This is ignored if the ExistingAssetId or if the RelatedContentId has a value.
495
495
  * @param {string | null} PARENT_ID - The Parent AssetId (folder) to add the upload to.
496
496
  * Note that if there is a full relativePath, then it is appended to this parent path.
@@ -515,7 +515,12 @@ class NomadMediaSDK {
515
515
  let startUploadInfo = null
516
516
  try
517
517
  {
518
- 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
+ }
519
524
 
520
525
  _printDatetime("Starting upload");
521
526
  startUploadInfo = await _startUpload(this, NAME, EXISTING_ASSET_ID,
@@ -524,7 +529,9 @@ class NomadMediaSDK {
524
529
 
525
530
  if (!startUploadInfo) throw new Error("Failed to start upload");
526
531
 
527
- 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
+
528
535
  await _completeUpload(this, startUploadInfo["id"]);
529
536
 
530
537
  const CONTENT_ID = startUploadInfo.assetId;
@@ -558,43 +565,69 @@ class NomadMediaSDK {
558
565
  * The option you want to use when uploading the asset. The options are continue, replace,
559
566
  * and cancel. Continue continues the upload from where it left off. Replace replaces an
560
567
  * existing asset. Replace is the one you want to use if you are starting a new upload.
561
- * @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.
562
569
  * This is ignored if the ExistingAssetId or if the RelatedContentId has a value
563
570
  * @param {string | null} LANGUAGE_ID - The language of the asset to upload.
564
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.
565
574
  * @returns {Promise<string>} - A promise that resolves when the related asset is uploaded.
566
575
  * Returns the content ID of the uploaded related asset.
567
576
  * @throws {Error} - An error is thrown if the related asset fails to upload.
568
577
  */
569
578
  async uploadRelatedAsset(EXISTING_ASSET_ID, RELATED_ASSET_ID, NEW_RELATED_ASSET_METADATA_TYPE,
570
- UPLOAD_OVERWRITE_OPTION, FILE, LANGUAGE_ID)
579
+ UPLOAD_OVERWRITE_OPTION, FILE, LANGUAGE_ID, FILE_CONTENTS)
571
580
  {
572
581
  if (this.token === null)
573
582
  {
574
583
  await this._init();
575
584
  }
576
585
 
586
+ if (!FILE && !FILE_CONTENTS)
587
+ {
588
+ throw new Error("Either FILE or FILE_CONTENTS must be provided.");
589
+ }
590
+
577
591
  _printDatetime(`Uploading related asset`);
578
592
 
579
593
  let startUploadInfo = null;
580
594
  try
581
595
  {
582
- const FILE_PROPS = 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
+ }
583
613
 
584
614
  startUploadInfo = await _startRelatedAssetUpload(this, EXISTING_ASSET_ID,
585
615
  RELATED_ASSET_ID, NEW_RELATED_ASSET_METADATA_TYPE, UPLOAD_OVERWRITE_OPTION,
586
- FILE_PROPS, LANGUAGE_ID);
616
+ fileProps, LANGUAGE_ID);
587
617
 
588
618
  if (!startUploadInfo) throw new Error("Failed to start related asset upload");
589
619
 
590
- 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");
591
622
 
592
623
  await _completeUpload(this, startUploadInfo.id);
593
624
  _printDatetime("Related asset upload successful");
594
625
 
595
626
  const DETAILS = await _getAssetDetails(this, EXISTING_ASSET_ID);
596
627
 
597
- const ASSET_INFO = DETAILS.relatedAssets.find(asset => asset.url.includes(FILE_PROPS.originalName));
628
+ const FILE_NAME = FILE_CONTENTS ? FILE : fileProps.originalName;
629
+
630
+ const ASSET_INFO = DETAILS.relatedAssets.find(asset => asset.url.includes(FILE_NAME));
598
631
  if (!ASSET_INFO) throw new Error("Asset ID not found");
599
632
  return ASSET_INFO.id;
600
633
  }
@@ -1506,7 +1539,7 @@ class NomadMediaSDK {
1506
1539
  * @param {string | null} CONTENT_DEFINITION_GROUP - The content definition group of the content definition to update.
1507
1540
  * enum: Custom Definitions, Forms, Layout, Navigation, Page Content, System Definitions
1508
1541
  * @param {string | null} CONTENT_DEFINITION_TYPE - The content definition type of the content definition to update.
1509
- * 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
1510
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
1511
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
1512
1545
  * @param {Array<string> | null} SECURITY_GROUPS - The security groups of the content definition to update.
@@ -1644,7 +1677,7 @@ class NomadMediaSDK {
1644
1677
  /**
1645
1678
  * @function addLiveScheduleToEvent
1646
1679
  * @async
1647
- * @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.
1648
1681
  * @param {string} EVENT_ID - The ID of the event to add the live schedule to.
1649
1682
  * @param {JSON | null} SLATE_VIDEO - The slate video ID of the event.
1650
1683
  * JSON format: {"id": string, "description": string }
@@ -1861,7 +1894,7 @@ class NomadMediaSDK {
1861
1894
  * @param {string} BUCKET_NAME - The name of the bucket to create the job in.
1862
1895
  * @param {string} OBJECT_KEY - The object key of the job.
1863
1896
  * @param {string} NOTIFICATION_CALLBACK_URL - The url to send the job notification to.
1864
- * @param {string | null} EXTERNAL_ID - The external id of the job.
1897
+ * @param {string} EXTERNAL_ID - The external id of the job.
1865
1898
  * @param {boolean | null} REPLACE_EXISTING_JOB - Whether to replace an existing job.
1866
1899
  * @param {string | null} ASSET_URL - The asset url of the job.
1867
1900
  * @param {Array<string> | null} REQUESTED_TASKS - The tasks to request for the job.
@@ -1890,8 +1923,8 @@ class NomadMediaSDK {
1890
1923
  try
1891
1924
  {
1892
1925
  const CREATE_JOB_RESULT = await _createJob(
1893
- this, BUCKET_NAME, OBJECT_KEY, NOTIFICATION_CALLBACK_URL, REPLACE_EXISTING_JOB,
1894
- REQUESTED_TASKS, REQUESTED_TRANSCODE_PROFILES, EXTERNAL_ID, ASSET_URL);
1926
+ this, BUCKET_NAME, OBJECT_KEY, NOTIFICATION_CALLBACK_URL, EXTERNAL_ID,
1927
+ REPLACE_EXISTING_JOB, ASSET_URL, REQUESTED_TASKS, REQUESTED_TRANSCODE_PROFILES);
1895
1928
  if (CREATE_JOB_RESULT) _printDatetime(`Job created: ${BUCKET_NAME}`);
1896
1929
  return CREATE_JOB_RESULT;
1897
1930
  } catch (error) {
@@ -5940,7 +5973,7 @@ class NomadMediaSDK {
5940
5973
  /**
5941
5974
  * @function copyAsset
5942
5975
  * @async
5943
- * @description Copys an asset.
5976
+ * @description Copies an asset.
5944
5977
  * @param {Array<string>} ASSET_IDS - The IDs of the asset to copy.
5945
5978
  * @param {string} DESTINATION_FOLDER_ID - The destination folder ID of the asset.
5946
5979
  * @param {JSON | null} BATCH_ACTION - The actions to be performed.
@@ -5949,14 +5982,14 @@ class NomadMediaSDK {
5949
5982
  * @param {string | null} SCHEMA_NAME - The schema name of the asset.
5950
5983
  * Note that we convert all incoming keys to lower first char to help with serialization for JSON later
5951
5984
  * JSON format: {"key": "string", "value": "string"}
5952
- * @param {boolean | null} RESOLVER_EXCEMPT - The resolver excempt of the asset.
5985
+ * @param {boolean | null} RESOLVER_EXEMPT - The resolver exempt of the asset.
5953
5986
  * @returns {Promise<JSON>} - A promise that resolves when the assets are performed.
5954
5987
  * Returns the information of the performed assets.
5955
5988
  * @throws {Error} - An error is thrown if the assets fail to perform.
5956
5989
  * @throws {Error} - An error is thrown if the API type is not admin.
5957
5990
  */
5958
5991
  async copyAsset(ASSET_IDS, DESTINATION_FOLDER_ID, BATCH_ACTION,
5959
- CONTENT_DEFINITION_ID, SCHEMA_NAME, RESOLVER_EXCEMPT)
5992
+ CONTENT_DEFINITION_ID, SCHEMA_NAME, RESOLVER_EXEMPT)
5960
5993
  {
5961
5994
  if (this.token === null)
5962
5995
  {
@@ -5973,7 +6006,7 @@ class NomadMediaSDK {
5973
6006
  try
5974
6007
  {
5975
6008
  const COPY_INFO = await _copyAsset(this, ASSET_IDS, DESTINATION_FOLDER_ID, BATCH_ACTION,
5976
- CONTENT_DEFINITION_ID, SCHEMA_NAME, RESOLVER_EXCEMPT);
6009
+ CONTENT_DEFINITION_ID, SCHEMA_NAME, RESOLVER_EXEMPT);
5977
6010
  if (COPY_INFO) _printDatetime(`Asset(s) copied: ${ASSET_IDS}`);
5978
6011
  return COPY_INFO;
5979
6012
  }
@@ -6947,14 +6980,14 @@ class NomadMediaSDK {
6947
6980
  * @param {JSON | null} BATCH_ACTION - The batch action of the move.
6948
6981
  * @param {string | null} CONTENT_DEFINITION_ID - The content definition ID of the move.
6949
6982
  * @param {string | null} SCHEMA_NAME - The schema name of the move.
6950
- * @param {boolean | null} RESOLVER_EXCEMPT - The resolver excempt of the move.
6983
+ * @param {boolean | null} RESOLVER_EXEMPT - The resolver exempt of the move.
6951
6984
  * @returns {Promise<JSON>} - A promise that resolves when the asset is moved.
6952
6985
  * Returns the information of the moved asset.
6953
6986
  * @throws {Error} - An error is thrown if the asset fails to move.
6954
6987
  * @throws {Error} - An error is thrown if the API type is not admin.
6955
6988
  */
6956
6989
  async moveAsset(ASSET_ID, DESTINATION_FOLDER_ID, NAME, BATCH_ACTION,
6957
- CONTENT_DEFINITION_ID, SCHEMA_NAME, RESOLVER_EXCEMPT)
6990
+ CONTENT_DEFINITION_ID, SCHEMA_NAME, RESOLVER_EXEMPT)
6958
6991
  {
6959
6992
  if (this.token === null)
6960
6993
  {
@@ -6971,7 +7004,7 @@ class NomadMediaSDK {
6971
7004
  try
6972
7005
  {
6973
7006
  const MOVE_INFO = await _moveAsset(this, ASSET_ID, DESTINATION_FOLDER_ID, NAME,
6974
- BATCH_ACTION, CONTENT_DEFINITION_ID, SCHEMA_NAME, RESOLVER_EXCEMPT);
7007
+ BATCH_ACTION, CONTENT_DEFINITION_ID, SCHEMA_NAME, RESOLVER_EXEMPT);
6975
7008
  if (MOVE_INFO) _printDatetime(`Asset moved: ${ASSET_ID}`);
6976
7009
  return MOVE_INFO;
6977
7010
  }
@@ -7044,7 +7077,7 @@ class NomadMediaSDK {
7044
7077
  * "Moving", "SlugReplaced", "Updating", "Error", "Assembling", "Clipping", "Placeholder", "Creating"
7045
7078
  * @param {string | null} STORAGE_CLASS - The storage class of the register.
7046
7079
  * enum: "Standard", "ReducedRedundancy", "Glacier", "StandardInfrequentAccess",
7047
- * "OneZoneInfrequentAccess", "IntelligentTiering", "DeepArchive", "GlacierInstanctRetrival",
7080
+ * "OneZoneInfrequentAccess", "IntelligentTiering", "DeepArchive", "GlacierInstantRetrieval",
7048
7081
  * "Outposts"
7049
7082
  * @param {string | null} ASSET_TYPE - The asset type of the register.
7050
7083
  * enum: "Folder", "File", "Bucket"
@@ -7563,7 +7596,7 @@ class NomadMediaSDK {
7563
7596
  * @param {Array<string> | null} FULL_URL_FIELD_NAMES - Gets or sets the list of fields that should have
7564
7597
  * the FullURL calculated. The calculations are expensive and greatly slow down the query.
7565
7598
  * @param {string | null} DISTINCT_ON_FIELD_NAME - Gets or sets optional property that will be used to
7566
- * aggregate results records to distinct occurances of this field's values.
7599
+ * aggregate results records to distinct occurrences of this field's values.
7567
7600
  * @param {boolean | null} INCLUDE_VIDEO_CLIPS - Gets or sets a value indicating whether specify
7568
7601
  * if the video search results are grouped by include clips of the videos also.*
7569
7602
  * @param {bool | null} USE_LLM_SEARCH - Gets or sets a value indicating whether gets or
@@ -9997,7 +10030,7 @@ class NomadMediaSDK {
9997
10030
 
9998
10031
  // misc functions
9999
10032
  /**
10000
- * @function miscFunctons
10033
+ * @function miscFunctions
10001
10034
  * @async
10002
10035
  * @description Calls any nomad function given URL method and body.
10003
10036
  * @param {string} URL_PATH - The URL path of the function.
@@ -10092,44 +10125,49 @@ async function _cancelUpload(instance, ID)
10092
10125
 
10093
10126
 
10094
10127
 
10095
- const MAX_CONCURRENT_PROMISES = 8;
10128
+ const MAX_CONCURRENT_PROMISES = 3;
10096
10129
 
10097
- async function _multiThreadUpload(instance, FILE, UPLOAD_RESPONSE)
10130
+ async function _multiThreadUpload(instance, FILE, UPLOAD_RESPONSE, FILE_CONTENTS)
10098
10131
  {
10099
10132
  const PARTS = UPLOAD_RESPONSE.parts;
10100
10133
  const LENGTH = PARTS.length;
10101
- const NUM_TRIES = 5;
10134
+ const abortController = new AbortController();
10102
10135
 
10103
- for (let INDEX = 0; INDEX < LENGTH; INDEX += MAX_CONCURRENT_PROMISES)
10104
- {
10105
- const batch = PARTS.slice(INDEX, INDEX + MAX_CONCURRENT_PROMISES);
10106
- const batchPromises = batch.map(async (PART, INDEX) => {
10107
- for (let tryIdx = 0; tryIdx < NUM_TRIES; ++tryIdx)
10108
- {
10109
- try
10110
- {
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 {
10111
10144
  console.log(`Uploading part ${INDEX + 1} of ${LENGTH}...`);
10112
- 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
+
10113
10150
  await _uploadPartComplete(instance, PART.id, ETAG);
10114
10151
  console.log(`Uploaded part ${INDEX + 1} of ${LENGTH} successfully`);
10115
- break;
10116
- }
10117
- catch (error)
10118
- {
10119
- if (tryIdx === NUM_TRIES - 1)
10120
- {
10121
- throw error;
10122
- }
10123
- else
10124
- {
10125
- console.log(`Error uploading parts: ${error}. Retrying...`);
10126
- await new Promise((resolve) => setTimeout(resolve, 20000));
10127
- }
10152
+ } catch (error) {
10153
+ abortController.abort();
10154
+ console.error(`Upload failed at part ${INDEX + 1}: ${error}`);
10155
+ throw error;
10128
10156
  }
10157
+ });
10158
+
10159
+ await Promise.all(batchPromises).catch(error => {
10160
+ throw error;
10161
+ });
10162
+
10163
+ if (abortController.signal.aborted) {
10164
+ return false;
10129
10165
  }
10130
- });
10166
+ }
10131
10167
 
10132
- await Promise.all(batchPromises);
10168
+ return true;
10169
+ } catch (error) {
10170
+ return false;
10133
10171
  }
10134
10172
  }
10135
10173
 
@@ -10147,7 +10185,7 @@ async function _startUpload(instance, NAME, EXISTING_ASSET_ID, RELATED_CONTENT_I
10147
10185
  displayName: NAME || FILE.originalname,
10148
10186
  contentLength: FILE.size,
10149
10187
  uploadOverwriteOption: UPLOAD_OVERWRITE_OPTION,
10150
- relativePath: FILE.originalname,
10188
+ relativePath: FILE.originalName,
10151
10189
  parentId: PARENT_ID,
10152
10190
  chunkSize: CHUNK_SIZE,
10153
10191
  relatedContentId: RELATED_CONTENT_ID,
@@ -10210,16 +10248,23 @@ async function _uploadPartComplete(instance, PART_ID, ETAG)
10210
10248
 
10211
10249
  import { Buffer } from "buffer";
10212
10250
 
10213
- async function _uploadPart(FILE, PART, DEBUG_MODE, maxRetries = 3)
10251
+ async function _uploadPart(FILE, PART, FILE_CONTENTS, DEBUG_MODE, maxRetries = 3)
10214
10252
  {
10215
- for (let attempt = 0; attempt < maxRetries; attempt++)
10216
- {
10253
+ for (let attempt = 0; attempt < maxRetries; ++attempt)
10254
+ {
10217
10255
  try
10218
10256
  {
10219
- const BUFFER = Buffer.from(FILE.buffer, 'binary');
10220
- 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
+ }
10221
10267
 
10222
- // Create header for the request
10223
10268
  const HEADERS = new Headers();
10224
10269
  HEADERS.append("Accept", "application/json, text/plain, */*");
10225
10270
 
@@ -10228,7 +10273,7 @@ async function _uploadPart(FILE, PART, DEBUG_MODE, maxRetries = 3)
10228
10273
  const RESPONSE = await fetch(PART.url, {
10229
10274
  method: "PUT",
10230
10275
  headers: HEADERS,
10231
- body: BODY
10276
+ body: body
10232
10277
  });
10233
10278
 
10234
10279
  if (!RESPONSE.ok)
@@ -10242,13 +10287,11 @@ async function _uploadPart(FILE, PART, DEBUG_MODE, maxRetries = 3)
10242
10287
  catch (error)
10243
10288
  {
10244
10289
  if (attempt < maxRetries - 1)
10245
- {
10246
- // Retry if there are more attempts left
10290
+ {
10247
10291
  console.error(`Upload attempt ${attempt + 1} failed. Retrying...`);
10248
10292
  }
10249
10293
  else
10250
10294
  {
10251
- // No more retries left, handle the error
10252
10295
  _apiExceptionHandler(error, "Upload Part Failed");
10253
10296
  break;
10254
10297
  }
@@ -13916,9 +13959,9 @@ async function _readFileAsArrayBuffer(file)
13916
13959
 
13917
13960
  import axios from 'axios';
13918
13961
 
13919
- const MAX_RETRIES = 5;
13920
- const TIMEOUT = 30000;
13921
- const SLEEP_TIME = .5;
13962
+ const MAX_RETRIES = 3;
13963
+ const TIMEOUT = 10000;
13964
+ const SLEEP_TIME = 2;
13922
13965
 
13923
13966
  async function _sendRequest(instance, FUNCTION_NAME, URL, METHOD_TYPE, PARAMS, BODY)
13924
13967
  {