@uipath/uipath-typescript 1.3.9 → 1.3.10

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.
@@ -503,6 +503,45 @@ interface BlobItem {
503
503
  */
504
504
  lastModified: string | null;
505
505
  }
506
+ /**
507
+ * Represents a file or directory entry in a bucket
508
+ */
509
+ interface BucketFile {
510
+ /**
511
+ * Full path to the file or directory
512
+ */
513
+ path: string;
514
+ /**
515
+ * Content type of the file (empty for directories)
516
+ */
517
+ contentType: string;
518
+ /**
519
+ * Size of the file in bytes
520
+ */
521
+ size: number;
522
+ /**
523
+ * Whether the entry is a directory
524
+ */
525
+ isDirectory: boolean;
526
+ /**
527
+ * Identifier of the file, when available
528
+ */
529
+ id: string | null;
530
+ }
531
+ /**
532
+ * Options for listing files in a bucket directory
533
+ */
534
+ type BucketGetFilesOptions = RequestOptions & PaginationOptions & FolderScopedOptions & {
535
+ /**
536
+ * Regex pattern to filter file names (e.g., '.*\\.pdf$')
537
+ */
538
+ fileNameRegex?: string;
539
+ };
540
+ /**
541
+ * Options for deleting a file from a bucket
542
+ */
543
+ interface BucketDeleteFileOptions extends FolderScopedOptions {
544
+ }
506
545
  /**
507
546
  * Options for uploading files to a bucket
508
547
  */
@@ -708,6 +747,64 @@ interface BucketServiceModel {
708
747
  * ```
709
748
  */
710
749
  uploadFile(options: BucketUploadFileOptions): Promise<BucketUploadResponse>;
750
+ /**
751
+ * Deletes a file from a bucket
752
+ *
753
+ * @param bucketId - The ID of the bucket
754
+ * @param path - The full path to the file to delete
755
+ * @param options - Folder scoping (`folderId` / `folderKey` / `folderPath`)
756
+ * @returns Promise resolving when the file is deleted
757
+ * @example
758
+ * ```typescript
759
+ * // Delete a file from a bucket
760
+ * await buckets.deleteFile(<bucketId>, '/folder/file.pdf', { folderId: <folderId> });
761
+ * ```
762
+ */
763
+ deleteFile(bucketId: number, path: string, options?: BucketDeleteFileOptions): Promise<void>;
764
+ /**
765
+ * Lists all files in a bucket.
766
+ *
767
+ * Returns a flat, recursive listing of all files in the bucket. Supports regex filtering
768
+ * and filter / orderby / select / expand. {@link BucketFile} entries include
769
+ * `isDirectory` so callers can distinguish folders from files.
770
+ *
771
+ * The method returns either:
772
+ * - A NonPaginatedResponse with items array (when no pagination parameters are provided)
773
+ * - A PaginatedResponse with navigation cursors (when any pagination parameter is provided)
774
+ *
775
+ * @param bucketId - The ID of the bucket
776
+ * @param options - Folder scoping (`folderId` / `folderKey` / `folderPath`) and optional parameters for regex filtering, query options, and pagination
777
+ * {@link BucketGetFilesOptions}
778
+ * @returns Promise resolving to either an array of files NonPaginatedResponse<BucketFile> or a PaginatedResponse<BucketFile> when pagination options are used.
779
+ * {@link BucketFile}
780
+ * @example
781
+ * ```typescript
782
+ * // List all files in the bucket
783
+ * const files = await buckets.getFiles(<bucketId>, { folderId: <folderId> });
784
+ *
785
+ * // Filter by regex pattern
786
+ * const pdfs = await buckets.getFiles(<bucketId>, {
787
+ * folderId: <folderId>,
788
+ * fileNameRegex: '.*\\.pdf$'
789
+ * });
790
+ *
791
+ * // First page with pagination
792
+ * const page1 = await buckets.getFiles(<bucketId>, { folderId: <folderId>, pageSize: 10 });
793
+ *
794
+ * // Navigate using cursor
795
+ * if (page1.hasNextPage) {
796
+ * const page2 = await buckets.getFiles(<bucketId>, { folderId: <folderId>, cursor: page1.nextCursor });
797
+ * }
798
+ *
799
+ * // Jump to specific page
800
+ * const page5 = await buckets.getFiles(<bucketId>, {
801
+ * folderId: <folderId>,
802
+ * jumpToPage: 5,
803
+ * pageSize: 10
804
+ * });
805
+ * ```
806
+ */
807
+ getFiles<T extends BucketGetFilesOptions = BucketGetFilesOptions>(bucketId: number, options?: T): Promise<T extends HasPaginationOptions<T> ? PaginatedResponse<BucketFile> : NonPaginatedResponse<BucketFile>>;
711
808
  }
712
809
 
713
810
  declare class BucketService extends FolderScopedService implements BucketServiceModel {
@@ -904,6 +1001,72 @@ declare class BucketService extends FolderScopedService implements BucketService
904
1001
  * @returns Promise resolving to blob file access information
905
1002
  */
906
1003
  private _getUri;
1004
+ /**
1005
+ * Lists all files in a bucket.
1006
+ *
1007
+ * Returns a flat, recursive listing of all files in the bucket. Supports regex filtering
1008
+ * and filter / orderby / select / expand. {@link BucketFile} entries include
1009
+ * `isDirectory` so callers can distinguish folders from files.
1010
+ *
1011
+ * The method returns either:
1012
+ * - A NonPaginatedResponse with items array (when no pagination parameters are provided)
1013
+ * - A PaginatedResponse with navigation cursors (when any pagination parameter is provided)
1014
+ *
1015
+ * @param bucketId - The ID of the bucket
1016
+ * @param options - Folder scoping (`folderId` / `folderKey` / `folderPath`) and optional parameters for regex filtering, query options, and pagination
1017
+ * @returns Promise resolving to either an array of files NonPaginatedResponse<BucketFile> or a PaginatedResponse<BucketFile> when pagination options are used.
1018
+ *
1019
+ * @example
1020
+ * ```typescript
1021
+ * import { Buckets } from '@uipath/uipath-typescript/buckets';
1022
+ *
1023
+ * const buckets = new Buckets(sdk);
1024
+ *
1025
+ * // List all files in the bucket
1026
+ * const files = await buckets.getFiles(<bucketId>, { folderId: <folderId> });
1027
+ *
1028
+ * // Filter by regex pattern
1029
+ * const pdfs = await buckets.getFiles(<bucketId>, {
1030
+ * folderId: <folderId>,
1031
+ * fileNameRegex: '.*\\.pdf$'
1032
+ * });
1033
+ *
1034
+ * // First page with pagination
1035
+ * const page1 = await buckets.getFiles(<bucketId>, { folderId: <folderId>, pageSize: 10 });
1036
+ *
1037
+ * // Navigate using cursor
1038
+ * if (page1.hasNextPage) {
1039
+ * const page2 = await buckets.getFiles(<bucketId>, { folderId: <folderId>, cursor: page1.nextCursor });
1040
+ * }
1041
+ *
1042
+ * // Jump to specific page
1043
+ * const page5 = await buckets.getFiles(<bucketId>, {
1044
+ * folderId: <folderId>,
1045
+ * jumpToPage: 5,
1046
+ * pageSize: 10
1047
+ * });
1048
+ * ```
1049
+ */
1050
+ getFiles<T extends BucketGetFilesOptions = BucketGetFilesOptions>(bucketId: number, options?: T): Promise<T extends HasPaginationOptions<T> ? PaginatedResponse<BucketFile> : NonPaginatedResponse<BucketFile>>;
1051
+ /**
1052
+ * Deletes a file from a bucket
1053
+ *
1054
+ * @param bucketId - The ID of the bucket
1055
+ * @param path - The full path to the file to delete
1056
+ * @param options - Folder scoping (`folderId` / `folderKey` / `folderPath`)
1057
+ * @returns Promise resolving when the file is deleted
1058
+ *
1059
+ * @example
1060
+ * ```typescript
1061
+ * import { Buckets } from '@uipath/uipath-typescript/buckets';
1062
+ *
1063
+ * const buckets = new Buckets(sdk);
1064
+ *
1065
+ * // Delete a file from a bucket
1066
+ * await buckets.deleteFile(<bucketId>, '/folder/file.pdf', { folderId: <folderId> });
1067
+ * ```
1068
+ */
1069
+ deleteFile(bucketId: number, path: string, options?: BucketDeleteFileOptions): Promise<void>;
907
1070
  /**
908
1071
  * Gets a direct upload URL for a file in the bucket
909
1072
  *
@@ -914,4 +1077,4 @@ declare class BucketService extends FolderScopedService implements BucketService
914
1077
  }
915
1078
 
916
1079
  export { BucketOptions, BucketService, BucketService as Buckets };
917
- export type { BlobItem, BucketGetAllOptions, BucketGetByIdOptions, BucketGetByNameOptions, BucketGetFileMetaDataOptions, BucketGetFileMetaDataResponse, BucketGetFileMetaDataWithPaginationOptions, BucketGetReadUriOptions, BucketGetResponse, BucketGetUriOptions, BucketGetUriResponse, BucketServiceModel, BucketUploadFileOptions, BucketUploadResponse, ResponseDictionary };
1080
+ export type { BlobItem, BucketDeleteFileOptions, BucketFile, BucketGetAllOptions, BucketGetByIdOptions, BucketGetByNameOptions, BucketGetFileMetaDataOptions, BucketGetFileMetaDataResponse, BucketGetFileMetaDataWithPaginationOptions, BucketGetFilesOptions, BucketGetReadUriOptions, BucketGetResponse, BucketGetUriOptions, BucketGetUriResponse, BucketServiceModel, BucketUploadFileOptions, BucketUploadResponse, ResponseDictionary };
@@ -611,14 +611,25 @@ class ApiClient {
611
611
  if (!text) {
612
612
  return undefined;
613
613
  }
614
- return JSON.parse(text);
614
+ try {
615
+ return JSON.parse(text);
616
+ }
617
+ catch (error) {
618
+ if (error instanceof SyntaxError) {
619
+ throw new ServerError({
620
+ message: `Server returned non-JSON response (${response.status} ${response.url}): ${error.message}`,
621
+ statusCode: response.status,
622
+ });
623
+ }
624
+ throw error;
625
+ }
615
626
  }
616
627
  catch (error) {
617
628
  // If it's already one of our errors, re-throw it
618
629
  if (error.type && error.type.includes('Error')) {
619
630
  throw error;
620
631
  }
621
- // Otherwise, it's likely a network error
632
+ // Otherwise, it's a genuine network/fetch failure
622
633
  throw ErrorFactory.createNetworkError(error);
623
634
  }
624
635
  }
@@ -1262,9 +1273,9 @@ class PaginationHelpers {
1262
1273
  * @returns Promise resolving to a paginated result
1263
1274
  */
1264
1275
  static async getAllPaginated(params) {
1265
- const { serviceAccess, getEndpoint, folderId, paginationParams, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1276
+ const { serviceAccess, getEndpoint, folderId, headers: providedHeaders, paginationParams, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1266
1277
  const endpoint = getEndpoint(folderId);
1267
- const headers = folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {};
1278
+ const headers = providedHeaders ?? (folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {});
1268
1279
  const paginatedResponse = await serviceAccess.requestWithPagination(method, endpoint, paginationParams, {
1269
1280
  headers,
1270
1281
  params: additionalParams,
@@ -1292,13 +1303,13 @@ class PaginationHelpers {
1292
1303
  * @returns Promise resolving to an object with data and totalCount
1293
1304
  */
1294
1305
  static async getAllNonPaginated(params) {
1295
- const { serviceAccess, getAllEndpoint, getByFolderEndpoint, folderId, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1306
+ const { serviceAccess, getAllEndpoint, getByFolderEndpoint, folderId, headers: providedHeaders, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1296
1307
  // Set default field names
1297
1308
  const itemsField = options.itemsField || DEFAULT_ITEMS_FIELD;
1298
1309
  const totalCountField = options.totalCountField || DEFAULT_TOTAL_COUNT_FIELD;
1299
1310
  // Determine endpoint and headers based on folderId
1300
1311
  const endpoint = folderId ? getByFolderEndpoint : getAllEndpoint;
1301
- const headers = folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {};
1312
+ const headers = providedHeaders ?? (folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {});
1302
1313
  // Make the API call based on method
1303
1314
  let response;
1304
1315
  if (method === HTTP_METHODS.POST) {
@@ -1357,6 +1368,7 @@ class PaginationHelpers {
1357
1368
  serviceAccess: config.serviceAccess,
1358
1369
  getEndpoint: config.getEndpoint,
1359
1370
  folderId,
1371
+ headers: config.headers,
1360
1372
  paginationParams: cursor ? { cursor, pageSize } : jumpToPage ? { jumpToPage, pageSize } : { pageSize },
1361
1373
  additionalParams: prefixedOptions,
1362
1374
  transformFn: config.transformFn,
@@ -1374,6 +1386,7 @@ class PaginationHelpers {
1374
1386
  getAllEndpoint: config.getEndpoint(),
1375
1387
  getByFolderEndpoint: byFolderEndpoint,
1376
1388
  folderId,
1389
+ headers: config.headers,
1377
1390
  additionalParams: prefixedOptions,
1378
1391
  transformFn: config.transformFn,
1379
1392
  method: config.method,
@@ -1918,6 +1931,8 @@ const BUCKET_ENDPOINTS = {
1918
1931
  GET_FILE_META_DATA: (id) => `${ORCHESTRATOR_BASE}/api/Buckets/${id}/ListFiles`,
1919
1932
  GET_READ_URI: (id) => `${ORCHESTRATOR_BASE}/odata/Buckets(${id})/UiPath.Server.Configuration.OData.GetReadUri`,
1920
1933
  GET_WRITE_URI: (id) => `${ORCHESTRATOR_BASE}/odata/Buckets(${id})/UiPath.Server.Configuration.OData.GetWriteUri`,
1934
+ DELETE_FILE: (id) => `${ORCHESTRATOR_BASE}/odata/Buckets(${id})/UiPath.Server.Configuration.OData.DeleteFile`,
1935
+ GET_FILES: (id) => `${ORCHESTRATOR_BASE}/odata/Buckets(${id})/UiPath.Server.Configuration.OData.GetFiles`,
1921
1936
  };
1922
1937
 
1923
1938
  /**
@@ -2291,6 +2306,120 @@ class BucketService extends FolderScopedService {
2291
2306
  }
2292
2307
  return transformedData;
2293
2308
  }
2309
+ /**
2310
+ * Lists all files in a bucket.
2311
+ *
2312
+ * Returns a flat, recursive listing of all files in the bucket. Supports regex filtering
2313
+ * and filter / orderby / select / expand. {@link BucketFile} entries include
2314
+ * `isDirectory` so callers can distinguish folders from files.
2315
+ *
2316
+ * The method returns either:
2317
+ * - A NonPaginatedResponse with items array (when no pagination parameters are provided)
2318
+ * - A PaginatedResponse with navigation cursors (when any pagination parameter is provided)
2319
+ *
2320
+ * @param bucketId - The ID of the bucket
2321
+ * @param options - Folder scoping (`folderId` / `folderKey` / `folderPath`) and optional parameters for regex filtering, query options, and pagination
2322
+ * @returns Promise resolving to either an array of files NonPaginatedResponse<BucketFile> or a PaginatedResponse<BucketFile> when pagination options are used.
2323
+ *
2324
+ * @example
2325
+ * ```typescript
2326
+ * import { Buckets } from '@uipath/uipath-typescript/buckets';
2327
+ *
2328
+ * const buckets = new Buckets(sdk);
2329
+ *
2330
+ * // List all files in the bucket
2331
+ * const files = await buckets.getFiles(<bucketId>, { folderId: <folderId> });
2332
+ *
2333
+ * // Filter by regex pattern
2334
+ * const pdfs = await buckets.getFiles(<bucketId>, {
2335
+ * folderId: <folderId>,
2336
+ * fileNameRegex: '.*\\.pdf$'
2337
+ * });
2338
+ *
2339
+ * // First page with pagination
2340
+ * const page1 = await buckets.getFiles(<bucketId>, { folderId: <folderId>, pageSize: 10 });
2341
+ *
2342
+ * // Navigate using cursor
2343
+ * if (page1.hasNextPage) {
2344
+ * const page2 = await buckets.getFiles(<bucketId>, { folderId: <folderId>, cursor: page1.nextCursor });
2345
+ * }
2346
+ *
2347
+ * // Jump to specific page
2348
+ * const page5 = await buckets.getFiles(<bucketId>, {
2349
+ * folderId: <folderId>,
2350
+ * jumpToPage: 5,
2351
+ * pageSize: 10
2352
+ * });
2353
+ * ```
2354
+ */
2355
+ async getFiles(bucketId, options) {
2356
+ if (!bucketId) {
2357
+ throw new ValidationError({ message: 'bucketId is required for getFiles' });
2358
+ }
2359
+ const { folderId, folderKey, folderPath, ...restOptions } = options ?? {};
2360
+ const headers = resolveFolderHeaders({
2361
+ folderId,
2362
+ folderKey,
2363
+ folderPath,
2364
+ resourceType: 'Buckets.getFiles',
2365
+ fallbackFolderKey: this.config.folderKey,
2366
+ });
2367
+ const transformBucketFile = (file) => transformData(pascalToCamelCaseKeys(file), BucketMap);
2368
+ return PaginationHelpers.getAll({
2369
+ serviceAccess: this.createPaginationServiceAccess(),
2370
+ getEndpoint: () => BUCKET_ENDPOINTS.GET_FILES(bucketId),
2371
+ transformFn: transformBucketFile,
2372
+ pagination: {
2373
+ paginationType: PaginationType.OFFSET,
2374
+ itemsField: ODATA_PAGINATION.ITEMS_FIELD,
2375
+ totalCountField: ODATA_PAGINATION.TOTAL_COUNT_FIELD,
2376
+ paginationParams: {
2377
+ pageSizeParam: ODATA_OFFSET_PARAMS.PAGE_SIZE_PARAM,
2378
+ offsetParam: ODATA_OFFSET_PARAMS.OFFSET_PARAM,
2379
+ countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM,
2380
+ },
2381
+ },
2382
+ excludeFromPrefix: ['directory', 'recursive', 'fileNameRegex'],
2383
+ headers,
2384
+ }, { ...restOptions, directory: '/', recursive: true });
2385
+ }
2386
+ /**
2387
+ * Deletes a file from a bucket
2388
+ *
2389
+ * @param bucketId - The ID of the bucket
2390
+ * @param path - The full path to the file to delete
2391
+ * @param options - Folder scoping (`folderId` / `folderKey` / `folderPath`)
2392
+ * @returns Promise resolving when the file is deleted
2393
+ *
2394
+ * @example
2395
+ * ```typescript
2396
+ * import { Buckets } from '@uipath/uipath-typescript/buckets';
2397
+ *
2398
+ * const buckets = new Buckets(sdk);
2399
+ *
2400
+ * // Delete a file from a bucket
2401
+ * await buckets.deleteFile(<bucketId>, '/folder/file.pdf', { folderId: <folderId> });
2402
+ * ```
2403
+ */
2404
+ async deleteFile(bucketId, path, options) {
2405
+ if (!bucketId) {
2406
+ throw new ValidationError({ message: 'bucketId is required for deleteFile' });
2407
+ }
2408
+ if (!path) {
2409
+ throw new ValidationError({ message: 'path is required for deleteFile' });
2410
+ }
2411
+ const headers = resolveFolderHeaders({
2412
+ folderId: options?.folderId,
2413
+ folderKey: options?.folderKey,
2414
+ folderPath: options?.folderPath,
2415
+ resourceType: 'Buckets.deleteFile',
2416
+ fallbackFolderKey: this.config.folderKey,
2417
+ });
2418
+ await this.delete(BUCKET_ENDPOINTS.DELETE_FILE(bucketId), {
2419
+ params: { path },
2420
+ headers,
2421
+ });
2422
+ }
2294
2423
  /**
2295
2424
  * Gets a direct upload URL for a file in the bucket
2296
2425
  *
@@ -2324,6 +2453,12 @@ __decorate([
2324
2453
  __decorate([
2325
2454
  track('Buckets.GetReadUri')
2326
2455
  ], BucketService.prototype, "getReadUri", null);
2456
+ __decorate([
2457
+ track('Buckets.GetFiles')
2458
+ ], BucketService.prototype, "getFiles", null);
2459
+ __decorate([
2460
+ track('Buckets.DeleteFile')
2461
+ ], BucketService.prototype, "deleteFile", null);
2327
2462
 
2328
2463
  var BucketOptions;
2329
2464
  (function (BucketOptions) {
@@ -748,14 +748,25 @@ class ApiClient {
748
748
  if (!text) {
749
749
  return undefined;
750
750
  }
751
- return JSON.parse(text);
751
+ try {
752
+ return JSON.parse(text);
753
+ }
754
+ catch (error) {
755
+ if (error instanceof SyntaxError) {
756
+ throw new ServerError({
757
+ message: `Server returned non-JSON response (${response.status} ${response.url}): ${error.message}`,
758
+ statusCode: response.status,
759
+ });
760
+ }
761
+ throw error;
762
+ }
752
763
  }
753
764
  catch (error) {
754
765
  // If it's already one of our errors, re-throw it
755
766
  if (error.type && error.type.includes('Error')) {
756
767
  throw error;
757
768
  }
758
- // Otherwise, it's likely a network error
769
+ // Otherwise, it's a genuine network/fetch failure
759
770
  throw ErrorFactory.createNetworkError(error);
760
771
  }
761
772
  }
@@ -1522,9 +1533,9 @@ class PaginationHelpers {
1522
1533
  * @returns Promise resolving to a paginated result
1523
1534
  */
1524
1535
  static async getAllPaginated(params) {
1525
- const { serviceAccess, getEndpoint, folderId, paginationParams, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1536
+ const { serviceAccess, getEndpoint, folderId, headers: providedHeaders, paginationParams, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1526
1537
  const endpoint = getEndpoint(folderId);
1527
- const headers = folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {};
1538
+ const headers = providedHeaders ?? (folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {});
1528
1539
  const paginatedResponse = await serviceAccess.requestWithPagination(method, endpoint, paginationParams, {
1529
1540
  headers,
1530
1541
  params: additionalParams,
@@ -1552,13 +1563,13 @@ class PaginationHelpers {
1552
1563
  * @returns Promise resolving to an object with data and totalCount
1553
1564
  */
1554
1565
  static async getAllNonPaginated(params) {
1555
- const { serviceAccess, getAllEndpoint, getByFolderEndpoint, folderId, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1566
+ const { serviceAccess, getAllEndpoint, getByFolderEndpoint, folderId, headers: providedHeaders, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1556
1567
  // Set default field names
1557
1568
  const itemsField = options.itemsField || DEFAULT_ITEMS_FIELD;
1558
1569
  const totalCountField = options.totalCountField || DEFAULT_TOTAL_COUNT_FIELD;
1559
1570
  // Determine endpoint and headers based on folderId
1560
1571
  const endpoint = folderId ? getByFolderEndpoint : getAllEndpoint;
1561
- const headers = folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {};
1572
+ const headers = providedHeaders ?? (folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {});
1562
1573
  // Make the API call based on method
1563
1574
  let response;
1564
1575
  if (method === HTTP_METHODS.POST) {
@@ -1617,6 +1628,7 @@ class PaginationHelpers {
1617
1628
  serviceAccess: config.serviceAccess,
1618
1629
  getEndpoint: config.getEndpoint,
1619
1630
  folderId,
1631
+ headers: config.headers,
1620
1632
  paginationParams: cursor ? { cursor, pageSize } : jumpToPage ? { jumpToPage, pageSize } : { pageSize },
1621
1633
  additionalParams: prefixedOptions,
1622
1634
  transformFn: config.transformFn,
@@ -1634,6 +1646,7 @@ class PaginationHelpers {
1634
1646
  getAllEndpoint: config.getEndpoint(),
1635
1647
  getByFolderEndpoint: byFolderEndpoint,
1636
1648
  folderId,
1649
+ headers: config.headers,
1637
1650
  additionalParams: prefixedOptions,
1638
1651
  transformFn: config.transformFn,
1639
1652
  method: config.method,
@@ -746,14 +746,25 @@ class ApiClient {
746
746
  if (!text) {
747
747
  return undefined;
748
748
  }
749
- return JSON.parse(text);
749
+ try {
750
+ return JSON.parse(text);
751
+ }
752
+ catch (error) {
753
+ if (error instanceof SyntaxError) {
754
+ throw new ServerError({
755
+ message: `Server returned non-JSON response (${response.status} ${response.url}): ${error.message}`,
756
+ statusCode: response.status,
757
+ });
758
+ }
759
+ throw error;
760
+ }
750
761
  }
751
762
  catch (error) {
752
763
  // If it's already one of our errors, re-throw it
753
764
  if (error.type && error.type.includes('Error')) {
754
765
  throw error;
755
766
  }
756
- // Otherwise, it's likely a network error
767
+ // Otherwise, it's a genuine network/fetch failure
757
768
  throw ErrorFactory.createNetworkError(error);
758
769
  }
759
770
  }
@@ -1520,9 +1531,9 @@ class PaginationHelpers {
1520
1531
  * @returns Promise resolving to a paginated result
1521
1532
  */
1522
1533
  static async getAllPaginated(params) {
1523
- const { serviceAccess, getEndpoint, folderId, paginationParams, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1534
+ const { serviceAccess, getEndpoint, folderId, headers: providedHeaders, paginationParams, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1524
1535
  const endpoint = getEndpoint(folderId);
1525
- const headers = folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {};
1536
+ const headers = providedHeaders ?? (folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {});
1526
1537
  const paginatedResponse = await serviceAccess.requestWithPagination(method, endpoint, paginationParams, {
1527
1538
  headers,
1528
1539
  params: additionalParams,
@@ -1550,13 +1561,13 @@ class PaginationHelpers {
1550
1561
  * @returns Promise resolving to an object with data and totalCount
1551
1562
  */
1552
1563
  static async getAllNonPaginated(params) {
1553
- const { serviceAccess, getAllEndpoint, getByFolderEndpoint, folderId, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1564
+ const { serviceAccess, getAllEndpoint, getByFolderEndpoint, folderId, headers: providedHeaders, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1554
1565
  // Set default field names
1555
1566
  const itemsField = options.itemsField || DEFAULT_ITEMS_FIELD;
1556
1567
  const totalCountField = options.totalCountField || DEFAULT_TOTAL_COUNT_FIELD;
1557
1568
  // Determine endpoint and headers based on folderId
1558
1569
  const endpoint = folderId ? getByFolderEndpoint : getAllEndpoint;
1559
- const headers = folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {};
1570
+ const headers = providedHeaders ?? (folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {});
1560
1571
  // Make the API call based on method
1561
1572
  let response;
1562
1573
  if (method === HTTP_METHODS.POST) {
@@ -1615,6 +1626,7 @@ class PaginationHelpers {
1615
1626
  serviceAccess: config.serviceAccess,
1616
1627
  getEndpoint: config.getEndpoint,
1617
1628
  folderId,
1629
+ headers: config.headers,
1618
1630
  paginationParams: cursor ? { cursor, pageSize } : jumpToPage ? { jumpToPage, pageSize } : { pageSize },
1619
1631
  additionalParams: prefixedOptions,
1620
1632
  transformFn: config.transformFn,
@@ -1632,6 +1644,7 @@ class PaginationHelpers {
1632
1644
  getAllEndpoint: config.getEndpoint(),
1633
1645
  getByFolderEndpoint: byFolderEndpoint,
1634
1646
  folderId,
1647
+ headers: config.headers,
1635
1648
  additionalParams: prefixedOptions,
1636
1649
  transformFn: config.transformFn,
1637
1650
  method: config.method,
@@ -671,14 +671,25 @@ class ApiClient {
671
671
  if (!text) {
672
672
  return undefined;
673
673
  }
674
- return JSON.parse(text);
674
+ try {
675
+ return JSON.parse(text);
676
+ }
677
+ catch (error) {
678
+ if (error instanceof SyntaxError) {
679
+ throw new ServerError({
680
+ message: `Server returned non-JSON response (${response.status} ${response.url}): ${error.message}`,
681
+ statusCode: response.status,
682
+ });
683
+ }
684
+ throw error;
685
+ }
675
686
  }
676
687
  catch (error) {
677
688
  // If it's already one of our errors, re-throw it
678
689
  if (error.type && error.type.includes('Error')) {
679
690
  throw error;
680
691
  }
681
- // Otherwise, it's likely a network error
692
+ // Otherwise, it's a genuine network/fetch failure
682
693
  throw ErrorFactory.createNetworkError(error);
683
694
  }
684
695
  }
@@ -1303,9 +1314,9 @@ class PaginationHelpers {
1303
1314
  * @returns Promise resolving to a paginated result
1304
1315
  */
1305
1316
  static async getAllPaginated(params) {
1306
- const { serviceAccess, getEndpoint, folderId, paginationParams, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1317
+ const { serviceAccess, getEndpoint, folderId, headers: providedHeaders, paginationParams, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1307
1318
  const endpoint = getEndpoint(folderId);
1308
- const headers = folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {};
1319
+ const headers = providedHeaders ?? (folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {});
1309
1320
  const paginatedResponse = await serviceAccess.requestWithPagination(method, endpoint, paginationParams, {
1310
1321
  headers,
1311
1322
  params: additionalParams,
@@ -1333,13 +1344,13 @@ class PaginationHelpers {
1333
1344
  * @returns Promise resolving to an object with data and totalCount
1334
1345
  */
1335
1346
  static async getAllNonPaginated(params) {
1336
- const { serviceAccess, getAllEndpoint, getByFolderEndpoint, folderId, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1347
+ const { serviceAccess, getAllEndpoint, getByFolderEndpoint, folderId, headers: providedHeaders, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1337
1348
  // Set default field names
1338
1349
  const itemsField = options.itemsField || DEFAULT_ITEMS_FIELD;
1339
1350
  const totalCountField = options.totalCountField || DEFAULT_TOTAL_COUNT_FIELD;
1340
1351
  // Determine endpoint and headers based on folderId
1341
1352
  const endpoint = folderId ? getByFolderEndpoint : getAllEndpoint;
1342
- const headers = folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {};
1353
+ const headers = providedHeaders ?? (folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {});
1343
1354
  // Make the API call based on method
1344
1355
  let response;
1345
1356
  if (method === HTTP_METHODS.POST) {
@@ -1398,6 +1409,7 @@ class PaginationHelpers {
1398
1409
  serviceAccess: config.serviceAccess,
1399
1410
  getEndpoint: config.getEndpoint,
1400
1411
  folderId,
1412
+ headers: config.headers,
1401
1413
  paginationParams: cursor ? { cursor, pageSize } : jumpToPage ? { jumpToPage, pageSize } : { pageSize },
1402
1414
  additionalParams: prefixedOptions,
1403
1415
  transformFn: config.transformFn,
@@ -1415,6 +1427,7 @@ class PaginationHelpers {
1415
1427
  getAllEndpoint: config.getEndpoint(),
1416
1428
  getByFolderEndpoint: byFolderEndpoint,
1417
1429
  folderId,
1430
+ headers: config.headers,
1418
1431
  additionalParams: prefixedOptions,
1419
1432
  transformFn: config.transformFn,
1420
1433
  method: config.method,