@uipath/uipath-typescript 1.3.11 → 1.4.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.
Files changed (56) hide show
  1. package/dist/agent-memory/index.cjs +1765 -0
  2. package/dist/agent-memory/index.d.ts +588 -0
  3. package/dist/agent-memory/index.mjs +1763 -0
  4. package/dist/agents/index.cjs +1726 -0
  5. package/dist/agents/index.d.ts +502 -0
  6. package/dist/agents/index.mjs +1724 -0
  7. package/dist/assets/index.cjs +155 -30
  8. package/dist/assets/index.d.ts +84 -5
  9. package/dist/assets/index.mjs +155 -30
  10. package/dist/attachments/index.cjs +37 -6
  11. package/dist/attachments/index.d.ts +1 -0
  12. package/dist/attachments/index.mjs +37 -6
  13. package/dist/buckets/index.cjs +37 -6
  14. package/dist/buckets/index.d.ts +1 -0
  15. package/dist/buckets/index.mjs +37 -6
  16. package/dist/cases/index.cjs +141 -10
  17. package/dist/cases/index.d.ts +118 -7
  18. package/dist/cases/index.mjs +141 -11
  19. package/dist/conversational-agent/index.cjs +124 -57
  20. package/dist/conversational-agent/index.d.ts +190 -122
  21. package/dist/conversational-agent/index.mjs +124 -57
  22. package/dist/core/index.cjs +413 -105
  23. package/dist/core/index.d.ts +15 -0
  24. package/dist/core/index.mjs +413 -105
  25. package/dist/entities/index.cjs +122 -43
  26. package/dist/entities/index.d.ts +140 -35
  27. package/dist/entities/index.mjs +122 -43
  28. package/dist/feedback/index.cjs +37 -6
  29. package/dist/feedback/index.d.ts +1 -0
  30. package/dist/feedback/index.mjs +37 -6
  31. package/dist/governance/index.cjs +1782 -0
  32. package/dist/governance/index.d.ts +598 -0
  33. package/dist/governance/index.mjs +1780 -0
  34. package/dist/index.cjs +956 -283
  35. package/dist/index.d.ts +1138 -121
  36. package/dist/index.mjs +956 -284
  37. package/dist/index.umd.js +3113 -2423
  38. package/dist/jobs/index.cjs +37 -6
  39. package/dist/jobs/index.d.ts +1 -0
  40. package/dist/jobs/index.mjs +37 -6
  41. package/dist/maestro-processes/index.cjs +173 -18
  42. package/dist/maestro-processes/index.d.ts +131 -9
  43. package/dist/maestro-processes/index.mjs +173 -18
  44. package/dist/processes/index.cjs +37 -6
  45. package/dist/processes/index.d.ts +1 -0
  46. package/dist/processes/index.mjs +37 -6
  47. package/dist/queues/index.cjs +37 -6
  48. package/dist/queues/index.d.ts +1 -0
  49. package/dist/queues/index.mjs +37 -6
  50. package/dist/tasks/index.cjs +37 -6
  51. package/dist/tasks/index.d.ts +1 -0
  52. package/dist/tasks/index.mjs +37 -6
  53. package/dist/traces/index.cjs +37 -6
  54. package/dist/traces/index.d.ts +1 -0
  55. package/dist/traces/index.mjs +37 -6
  56. package/package.json +32 -2
@@ -503,6 +503,7 @@ class ErrorFactory {
503
503
  }
504
504
  }
505
505
 
506
+ const FOLDER_KEY = 'X-UIPATH-FolderKey';
506
507
  const FOLDER_ID = 'X-UIPATH-OrganizationUnitId';
507
508
  const TRACEPARENT = 'traceparent';
508
509
  const UIPATH_TRACEPARENT_ID = 'x-uipath-traceparent-id';
@@ -717,6 +718,32 @@ function filterUndefined(obj) {
717
718
  */
718
719
  const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
719
720
  isBrowser && window.self != window.top && window.location.href.includes('source=ActionCenter');
721
+ const _params = isBrowser ? new URLSearchParams(window.location.search) : null;
722
+ /**
723
+ * True when the coded app has been loaded inside a host frame that explicitly
724
+ * opted into token delegation by adding `?host=embed` to the iframe src URL.
725
+ */
726
+ const isHostEmbedded = isBrowser && window.self !== window.top && _params?.get('host') === 'embed';
727
+ /**
728
+ * The validated parent origin, read from the `?basedomain=` query param set
729
+ * by the embedding host in the iframe src URL.
730
+ * Mirrors the same mechanism used by ActionCenterTokenManager.
731
+ * Non-null only when `?host=embed` is present and `?basedomain=` is a valid URL.
732
+ */
733
+ (() => {
734
+ if (!isHostEmbedded)
735
+ return null;
736
+ const basedomain = _params?.get('basedomain');
737
+ if (!basedomain)
738
+ return null;
739
+ try {
740
+ return new URL(basedomain).origin;
741
+ }
742
+ catch {
743
+ console.warn('embeddingOrigin: basedomain query param is not a valid URL', basedomain);
744
+ return null;
745
+ }
746
+ })();
720
747
 
721
748
  /**
722
749
  * Base64 encoding/decoding
@@ -1298,8 +1325,9 @@ class PaginationHelpers {
1298
1325
  });
1299
1326
  }
1300
1327
  // Extract and transform items from response
1301
- // Handle both plain array responses and envelope responses ({ value: [...], totalRecordCount: N })
1302
- const rawItems = Array.isArray(response.data) ? response.data : response.data?.[itemsField];
1328
+ // Handle both plain array responses and envelope responses ({ value: [...], totalRecordCount: N }).
1329
+ // itemsField may be a dotted path (e.g. 'data.agents') for nested envelopes.
1330
+ const rawItems = Array.isArray(response.data) ? response.data : resolveNestedField(response.data, itemsField);
1303
1331
  const rawTotalCount = Array.isArray(response.data) ? undefined : resolveNestedField(response.data, totalCountField);
1304
1332
  const totalCount = typeof rawTotalCount === 'number' ? rawTotalCount : undefined;
1305
1333
  // Parse items - automatically handle JSON string responses
@@ -1345,7 +1373,7 @@ class PaginationHelpers {
1345
1373
  getEndpoint: config.getEndpoint,
1346
1374
  folderId,
1347
1375
  headers: config.headers,
1348
- paginationParams: cursor ? { cursor, pageSize } : jumpToPage ? { jumpToPage, pageSize } : { pageSize },
1376
+ paginationParams: cursor ? { cursor, pageSize } : jumpToPage !== undefined ? { jumpToPage, pageSize } : { pageSize },
1349
1377
  additionalParams: prefixedOptions,
1350
1378
  transformFn: config.transformFn,
1351
1379
  method: config.method,
@@ -1603,6 +1631,8 @@ class BaseService {
1603
1631
  // When true (default), converts pageNumber to a skip/offset value (e.g., page 3 with pageSize 10 → skip 20).
1604
1632
  // When false, passes pageNumber directly as the offset param — used by APIs that accept a page number instead of a record offset.
1605
1633
  const convertToSkip = paginationParams?.convertToSkip ?? true;
1634
+ // When true, sends pageNumber - 1 (for 0-based APIs). Default false (1-based).
1635
+ const zeroBased = paginationParams?.zeroBased ?? false;
1606
1636
  requestParams[pageSizeParam] = limitedPageSize;
1607
1637
  if (convertToSkip) {
1608
1638
  if (params.pageNumber && params.pageNumber > 1) {
@@ -1610,7 +1640,8 @@ class BaseService {
1610
1640
  }
1611
1641
  }
1612
1642
  else {
1613
- requestParams[offsetParam] = params.pageNumber || 1;
1643
+ const sdkPageNumber = params.pageNumber || 1;
1644
+ requestParams[offsetParam] = zeroBased ? sdkPageNumber - 1 : sdkPageNumber;
1614
1645
  }
1615
1646
  {
1616
1647
  requestParams[countParam] = true;
@@ -1639,8 +1670,9 @@ class BaseService {
1639
1670
  const totalCountField = fields.totalCountField || 'totalRecordCount';
1640
1671
  const continuationTokenField = fields.continuationTokenField || 'continuationToken';
1641
1672
  // Extract items and metadata
1642
- // Handle both plain array responses and envelope responses ({ value: [...], totalRecordCount: N })
1643
- const items = Array.isArray(response.data) ? response.data : (response.data[itemsField] || []);
1673
+ // Handle both plain array responses and envelope responses ({ value: [...], totalRecordCount: N }).
1674
+ // itemsField may be a dotted path (e.g. 'data.agents') for nested envelopes.
1675
+ const items = Array.isArray(response.data) ? response.data : (resolveNestedField(response.data, itemsField) || []);
1644
1676
  const rawTotalCount = Array.isArray(response.data) ? undefined : resolveNestedField(response.data, totalCountField);
1645
1677
  const totalCount = typeof rawTotalCount === 'number' ? rawTotalCount : undefined;
1646
1678
  const continuationToken = response.data[continuationTokenField];
@@ -1723,12 +1755,12 @@ function createEntityMethods(entityData, service) {
1723
1755
  throw new Error('Entity ID is undefined');
1724
1756
  return service.deleteRecordsById(entityData.id, recordIds, options);
1725
1757
  },
1726
- async deleteRecord(recordId) {
1758
+ async deleteRecord(recordId, options) {
1727
1759
  if (!entityData.id)
1728
1760
  throw new Error('Entity ID is undefined');
1729
1761
  if (!recordId)
1730
1762
  throw new Error('Record ID is undefined');
1731
- return service.deleteRecordById(entityData.id, recordId);
1763
+ return service.deleteRecordById(entityData.id, recordId, options);
1732
1764
  },
1733
1765
  async getAllRecords(options) {
1734
1766
  if (!entityData.id)
@@ -1742,30 +1774,30 @@ function createEntityMethods(entityData, service) {
1742
1774
  throw new Error('Record ID is undefined');
1743
1775
  return service.getRecordById(entityData.id, recordId, options);
1744
1776
  },
1745
- async downloadAttachment(recordId, fieldName) {
1777
+ async downloadAttachment(recordId, fieldName, options) {
1746
1778
  if (!entityData.id)
1747
1779
  throw new Error('Entity ID is undefined');
1748
- return service.downloadAttachment(entityData.id, recordId, fieldName);
1780
+ return service.downloadAttachment(entityData.id, recordId, fieldName, options);
1749
1781
  },
1750
1782
  async uploadAttachment(recordId, fieldName, file, options) {
1751
1783
  if (!entityData.id)
1752
1784
  throw new Error('Entity ID is undefined');
1753
1785
  return service.uploadAttachment(entityData.id, recordId, fieldName, file, options);
1754
1786
  },
1755
- async deleteAttachment(recordId, fieldName) {
1787
+ async deleteAttachment(recordId, fieldName, options) {
1756
1788
  if (!entityData.id)
1757
1789
  throw new Error('Entity ID is undefined');
1758
- return service.deleteAttachment(entityData.id, recordId, fieldName);
1790
+ return service.deleteAttachment(entityData.id, recordId, fieldName, options);
1759
1791
  },
1760
1792
  async queryRecords(options) {
1761
1793
  if (!entityData.id)
1762
1794
  throw new Error('Entity ID is undefined');
1763
1795
  return service.queryRecordsById(entityData.id, options);
1764
1796
  },
1765
- async importRecords(file) {
1797
+ async importRecords(file, options) {
1766
1798
  if (!entityData.id)
1767
1799
  throw new Error('Entity ID is undefined');
1768
- return service.importRecordsById(entityData.id, file);
1800
+ return service.importRecordsById(entityData.id, file, options);
1769
1801
  },
1770
1802
  async insert(data, options) {
1771
1803
  return this.insertRecord(data, options);
@@ -1776,10 +1808,10 @@ function createEntityMethods(entityData, service) {
1776
1808
  async getRecords(options) {
1777
1809
  return this.getAllRecords(options);
1778
1810
  },
1779
- async delete() {
1811
+ async delete(options) {
1780
1812
  if (!entityData.id)
1781
1813
  throw new Error('Entity ID is undefined');
1782
- return service.deleteById(entityData.id);
1814
+ return service.deleteById(entityData.id, options);
1783
1815
  },
1784
1816
  async update(options) {
1785
1817
  if (!entityData.id)
@@ -2188,6 +2220,7 @@ class EntityService extends BaseService {
2188
2220
  * Gets entity metadata by entity ID with attached operation methods
2189
2221
  *
2190
2222
  * @param id - UUID of the entity
2223
+ * @param options - Optional {@link EntityGetByIdOptions} (e.g. `folderKey` for folder-scoped entities)
2191
2224
  * @returns Promise resolving to entity metadata with schema information and operation methods
2192
2225
  *
2193
2226
  * @example
@@ -2197,6 +2230,9 @@ class EntityService extends BaseService {
2197
2230
  * const entities = new Entities(sdk);
2198
2231
  * const entity = await entities.getById("<entityId>");
2199
2232
  *
2233
+ * // Folder-scoped: pass the entity's folder key
2234
+ * const folderEntity = await entities.getById("<entityId>", { folderKey: "<folderKey>" });
2235
+ *
2200
2236
  * // Call operations directly on the entity
2201
2237
  * const records = await entity.getAllRecords();
2202
2238
  *
@@ -2210,9 +2246,9 @@ class EntityService extends BaseService {
2210
2246
  * ]);
2211
2247
  * ```
2212
2248
  */
2213
- async getById(id) {
2249
+ async getById(id, options) {
2214
2250
  // Get entity metadata
2215
- const response = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_BY_ID(id));
2251
+ const response = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_BY_ID(id), { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
2216
2252
  // Apply EntityMap transformations
2217
2253
  const metadata = transformData(response.data, EntityMap);
2218
2254
  // Transform metadata with field mappers
@@ -2255,9 +2291,14 @@ class EntityService extends BaseService {
2255
2291
  * ```
2256
2292
  */
2257
2293
  async getAllRecords(entityId, options) {
2294
+ // folderKey is header-only — destructure it out so PaginationHelpers doesn't serialise it
2295
+ // into the query string as $folderKey.
2296
+ const { folderKey, ...rest } = options ?? {};
2297
+ const downstreamOptions = options === undefined ? undefined : rest;
2258
2298
  return PaginationHelpers.getAll({
2259
2299
  serviceAccess: this.createPaginationServiceAccess(),
2260
2300
  getEndpoint: () => DATA_FABRIC_ENDPOINTS.ENTITY.GET_ENTITY_RECORDS(entityId),
2301
+ headers: createHeaders({ [FOLDER_KEY]: folderKey }),
2261
2302
  pagination: {
2262
2303
  paginationType: PaginationType.OFFSET,
2263
2304
  itemsField: ENTITY_PAGINATION.ITEMS_FIELD,
@@ -2269,7 +2310,7 @@ class EntityService extends BaseService {
2269
2310
  }
2270
2311
  },
2271
2312
  excludeFromPrefix: ['expansionLevel'] // Don't add ODATA prefix to expansionLevel
2272
- }, options);
2313
+ }, downstreamOptions);
2273
2314
  }
2274
2315
  /**
2275
2316
  * Gets a single entity record by entity ID and record ID
@@ -2294,7 +2335,7 @@ class EntityService extends BaseService {
2294
2335
  const params = createParams({
2295
2336
  expansionLevel: options.expansionLevel
2296
2337
  });
2297
- const response = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_RECORD_BY_ID(entityId, recordId), { params });
2338
+ const response = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_RECORD_BY_ID(entityId, recordId), { params, headers: createHeaders({ [FOLDER_KEY]: options.folderKey }) });
2298
2339
  return response.data;
2299
2340
  }
2300
2341
  /**
@@ -2326,7 +2367,7 @@ class EntityService extends BaseService {
2326
2367
  });
2327
2368
  const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.INSERT_BY_ID(id), data, {
2328
2369
  params,
2329
- ...options
2370
+ headers: createHeaders({ [FOLDER_KEY]: options.folderKey }),
2330
2371
  });
2331
2372
  return response.data;
2332
2373
  }
@@ -2367,7 +2408,7 @@ class EntityService extends BaseService {
2367
2408
  });
2368
2409
  const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.BATCH_INSERT_BY_ID(id), data, {
2369
2410
  params,
2370
- ...options
2411
+ headers: createHeaders({ [FOLDER_KEY]: options.folderKey }),
2371
2412
  });
2372
2413
  return response.data;
2373
2414
  }
@@ -2401,7 +2442,7 @@ class EntityService extends BaseService {
2401
2442
  });
2402
2443
  const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPDATE_RECORD_BY_ID(entityId, recordId), data, {
2403
2444
  params,
2404
- ...options
2445
+ headers: createHeaders({ [FOLDER_KEY]: options.folderKey }),
2405
2446
  });
2406
2447
  return response.data;
2407
2448
  }
@@ -2443,7 +2484,7 @@ class EntityService extends BaseService {
2443
2484
  });
2444
2485
  const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPDATE_BY_ID(id), data, {
2445
2486
  params,
2446
- ...options
2487
+ headers: createHeaders({ [FOLDER_KEY]: options.folderKey }),
2447
2488
  });
2448
2489
  return response.data;
2449
2490
  }
@@ -2475,7 +2516,7 @@ class EntityService extends BaseService {
2475
2516
  });
2476
2517
  const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE_BY_ID(id), recordIds, {
2477
2518
  params,
2478
- ...options
2519
+ headers: createHeaders({ [FOLDER_KEY]: options.folderKey }),
2479
2520
  });
2480
2521
  return response.data;
2481
2522
  }
@@ -2487,6 +2528,7 @@ class EntityService extends BaseService {
2487
2528
  *
2488
2529
  * @param entityId - UUID of the entity
2489
2530
  * @param recordId - UUID of the record to delete
2531
+ * @param options - Optional {@link EntityDeleteRecordByIdOptions} (e.g. `folderKey` for folder-scoped entities)
2490
2532
  * @returns Promise resolving to void on success
2491
2533
  * @example
2492
2534
  * ```typescript
@@ -2495,10 +2537,13 @@ class EntityService extends BaseService {
2495
2537
  * const entities = new Entities(sdk);
2496
2538
  *
2497
2539
  * await entities.deleteRecordById("<entityId>", "<recordId>");
2540
+ *
2541
+ * // Folder-scoped: pass the entity's folder key
2542
+ * await entities.deleteRecordById("<entityId>", "<recordId>", { folderKey: "<folderKey>" });
2498
2543
  * ```
2499
2544
  */
2500
- async deleteRecordById(entityId, recordId) {
2501
- await this.delete(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE_RECORD_BY_ID(entityId, recordId));
2545
+ async deleteRecordById(entityId, recordId, options) {
2546
+ await this.delete(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE_RECORD_BY_ID(entityId, recordId), { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
2502
2547
  }
2503
2548
  /**
2504
2549
  * Gets all entities in the system
@@ -2584,10 +2629,15 @@ class EntityService extends BaseService {
2584
2629
  * ```
2585
2630
  */
2586
2631
  async queryRecordsById(id, options) {
2632
+ // folderKey is header-only — destructure it out so PaginationHelpers doesn't include
2633
+ // it in the POST body alongside the query filters.
2634
+ const { folderKey, ...rest } = options ?? {};
2635
+ const downstreamOptions = options === undefined ? undefined : rest;
2587
2636
  return PaginationHelpers.getAll({
2588
2637
  serviceAccess: this.createPaginationServiceAccess(),
2589
2638
  getEndpoint: () => DATA_FABRIC_ENDPOINTS.ENTITY.QUERY_BY_ID(id),
2590
2639
  method: HTTP_METHODS.POST,
2640
+ headers: createHeaders({ [FOLDER_KEY]: folderKey }),
2591
2641
  pagination: {
2592
2642
  paginationType: PaginationType.OFFSET,
2593
2643
  itemsField: ENTITY_PAGINATION.ITEMS_FIELD,
@@ -2599,13 +2649,14 @@ class EntityService extends BaseService {
2599
2649
  }
2600
2650
  },
2601
2651
  excludeFromPrefix: ['expansionLevel', 'filterGroup', 'selectedFields', 'sortOptions', 'aggregates', 'groupBy']
2602
- }, options);
2652
+ }, downstreamOptions);
2603
2653
  }
2604
2654
  /**
2605
2655
  * Imports records from a CSV file into an entity
2606
2656
  *
2607
2657
  * @param id - UUID of the entity
2608
2658
  * @param file - CSV file to import (Blob, File, or Uint8Array)
2659
+ * @param options - Optional {@link EntityImportRecordsByIdOptions} (e.g. `folderKey` for folder-scoped entities)
2609
2660
  * @returns Promise resolving to import result with record counts
2610
2661
  *
2611
2662
  * @example
@@ -2626,10 +2677,12 @@ class EntityService extends BaseService {
2626
2677
  * if (result.errorFileLink) {
2627
2678
  * console.log(`Error file link: ${result.errorFileLink}`);
2628
2679
  * }
2680
+ *
2681
+ * // Folder-scoped entity: pass the entity's folder key
2682
+ * await entities.importRecordsById("<entityId>", fileInput.files[0], { folderKey: "<folderKey>" });
2629
2683
  * ```
2630
- * @internal
2631
2684
  */
2632
- async importRecordsById(id, file) {
2685
+ async importRecordsById(id, file, options) {
2633
2686
  const formData = new FormData();
2634
2687
  if (file instanceof Uint8Array) {
2635
2688
  formData.append('file', new Blob([file.buffer]));
@@ -2637,7 +2690,7 @@ class EntityService extends BaseService {
2637
2690
  else {
2638
2691
  formData.append('file', file);
2639
2692
  }
2640
- const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.BULK_UPLOAD_BY_ID(id), formData);
2693
+ const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.BULK_UPLOAD_BY_ID(id), formData, { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
2641
2694
  return response.data;
2642
2695
  }
2643
2696
  /**
@@ -2646,6 +2699,7 @@ class EntityService extends BaseService {
2646
2699
  * @param entityId - UUID of the entity
2647
2700
  * @param recordId - UUID of the record containing the attachment
2648
2701
  * @param fieldName - Name of the File-type field containing the attachment
2702
+ * @param options - Optional {@link EntityDownloadAttachmentOptions} (e.g. `folderKey` for folder-scoped entities)
2649
2703
  * @returns Promise resolving to Blob containing the file content
2650
2704
  *
2651
2705
  * @example
@@ -2664,11 +2718,15 @@ class EntityService extends BaseService {
2664
2718
  *
2665
2719
  * // Download attachment for a specific record and field
2666
2720
  * const blob = await entities.downloadAttachment(entityId, recordId, 'Documents');
2721
+ *
2722
+ * // Folder-scoped: pass the entity's folder key
2723
+ * const blob = await entities.downloadAttachment(entityId, recordId, 'Documents', { folderKey: "<folderKey>" });
2667
2724
  * ```
2668
2725
  */
2669
- async downloadAttachment(entityId, recordId, fieldName) {
2726
+ async downloadAttachment(entityId, recordId, fieldName, options) {
2670
2727
  const response = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.DOWNLOAD_ATTACHMENT(entityId, recordId, fieldName), {
2671
- responseType: RESPONSE_TYPES.BLOB
2728
+ responseType: RESPONSE_TYPES.BLOB,
2729
+ headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }),
2672
2730
  });
2673
2731
  return response.data;
2674
2732
  }
@@ -2679,7 +2737,7 @@ class EntityService extends BaseService {
2679
2737
  * @param recordId - UUID of the record to upload the attachment to
2680
2738
  * @param fieldName - Name of the File-type field
2681
2739
  * @param file - File to upload (Blob, File, or Uint8Array)
2682
- * @param options - Optional {@link EntityUploadAttachmentOptions} (e.g. expansionLevel)
2740
+ * @param options - Optional {@link EntityUploadAttachmentOptions} (e.g. `expansionLevel`, `folderKey` for folder-scoped entities)
2683
2741
  * @returns Promise resolving to {@link EntityUploadAttachmentResponse}
2684
2742
  *
2685
2743
  * @example
@@ -2698,6 +2756,9 @@ class EntityService extends BaseService {
2698
2756
  *
2699
2757
  * // Upload a file attachment
2700
2758
  * const response = await entities.uploadAttachment(entityId, recordId, 'Documents', file);
2759
+ *
2760
+ * // Folder-scoped entity: pass the entity's folder key
2761
+ * await entities.uploadAttachment(entityId, recordId, 'Documents', file, { folderKey: "<folderKey>" });
2701
2762
  * ```
2702
2763
  */
2703
2764
  async uploadAttachment(entityId, recordId, fieldName, file, options) {
@@ -2709,7 +2770,10 @@ class EntityService extends BaseService {
2709
2770
  formData.append('file', file);
2710
2771
  }
2711
2772
  const params = createParams({ expansionLevel: options?.expansionLevel });
2712
- const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPLOAD_ATTACHMENT(entityId, recordId, fieldName), formData, { params });
2773
+ const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPLOAD_ATTACHMENT(entityId, recordId, fieldName), formData, {
2774
+ params,
2775
+ headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }),
2776
+ });
2713
2777
  return response.data;
2714
2778
  }
2715
2779
  /**
@@ -2718,6 +2782,7 @@ class EntityService extends BaseService {
2718
2782
  * @param entityId - UUID of the entity
2719
2783
  * @param recordId - UUID of the record containing the attachment
2720
2784
  * @param fieldName - Name of the File-type field containing the attachment
2785
+ * @param options - Optional {@link EntityDeleteAttachmentOptions} (e.g. `folderKey` for folder-scoped entities)
2721
2786
  * @returns Promise resolving to {@link EntityDeleteAttachmentResponse}
2722
2787
  *
2723
2788
  * @example
@@ -2736,10 +2801,13 @@ class EntityService extends BaseService {
2736
2801
  *
2737
2802
  * // Delete attachment for a specific record and field
2738
2803
  * await entities.deleteAttachment(entityId, recordId, 'Documents');
2804
+ *
2805
+ * // Folder-scoped: pass the entity's folder key
2806
+ * await entities.deleteAttachment(entityId, recordId, 'Documents', { folderKey: "<folderKey>" });
2739
2807
  * ```
2740
2808
  */
2741
- async deleteAttachment(entityId, recordId, fieldName) {
2742
- const response = await this.delete(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE_ATTACHMENT(entityId, recordId, fieldName));
2809
+ async deleteAttachment(entityId, recordId, fieldName, options) {
2810
+ const response = await this.delete(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE_ATTACHMENT(entityId, recordId, fieldName), { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
2743
2811
  return response.data;
2744
2812
  }
2745
2813
  /**
@@ -2802,23 +2870,27 @@ class EntityService extends BaseService {
2802
2870
  externalFields: opts.externalFields ?? [],
2803
2871
  },
2804
2872
  };
2805
- const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPSERT, payload);
2873
+ const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPSERT, payload, { headers: createHeaders({ [FOLDER_KEY]: opts.folderKey }) });
2806
2874
  return response.data;
2807
2875
  }
2808
2876
  /**
2809
2877
  * Deletes a Data Fabric entity and all its records
2810
2878
  *
2811
2879
  * @param id - UUID of the entity to delete
2880
+ * @param options - Optional {@link EntityDeleteByIdOptions} (e.g. `folderKey` for folder-scoped entities)
2812
2881
  * @returns Promise resolving when the entity is deleted
2813
2882
  *
2814
2883
  * @example
2815
2884
  * ```typescript
2816
2885
  * await entities.deleteById("<entityId>");
2886
+ *
2887
+ * // Folder-scoped: pass the entity's folder key
2888
+ * await entities.deleteById("<entityId>", { folderKey: "<folderKey>" });
2817
2889
  * ```
2818
2890
  * @internal
2819
2891
  */
2820
- async deleteById(id) {
2821
- await this.delete(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE(id));
2892
+ async deleteById(id, options) {
2893
+ await this.delete(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE(id), { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
2822
2894
  }
2823
2895
  /**
2824
2896
  * Updates an existing Data Fabric entity — schema and/or metadata.
@@ -2865,6 +2937,12 @@ class EntityService extends BaseService {
2865
2937
  * { id: "<fieldId>", lengthLimit: 1000 },
2866
2938
  * ],
2867
2939
  * });
2940
+ *
2941
+ * // Folder-scoped entity: add a field to an entity that lives in a non-tenant folder
2942
+ * await entities.updateById("<entityId>", {
2943
+ * folderKey: "<folderKey>",
2944
+ * addFields: [{ fieldName: "notes", type: EntityFieldDataType.MULTILINE_TEXT }],
2945
+ * });
2868
2946
  * ```
2869
2947
  * @internal
2870
2948
  */
@@ -2880,7 +2958,7 @@ class EntityService extends BaseService {
2880
2958
  ...(opts.displayName !== undefined && { displayName: opts.displayName }),
2881
2959
  ...(opts.description !== undefined && { description: opts.description }),
2882
2960
  ...(opts.isRbacEnabled !== undefined && { isRbacEnabled: opts.isRbacEnabled }),
2883
- });
2961
+ }, { headers: createHeaders({ [FOLDER_KEY]: opts.folderKey }) });
2884
2962
  }
2885
2963
  }
2886
2964
  /**
@@ -2891,7 +2969,8 @@ class EntityService extends BaseService {
2891
2969
  * @private
2892
2970
  */
2893
2971
  async applySchemaUpdate(entityId, options) {
2894
- const entityResponse = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_BY_ID(entityId));
2972
+ const folderHeaders = createHeaders({ [FOLDER_KEY]: options.folderKey });
2973
+ const entityResponse = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_BY_ID(entityId), { headers: folderHeaders });
2895
2974
  const raw = entityResponse.data;
2896
2975
  // Carry forward existing non-system fields from GET response (skip system/primary-key fields)
2897
2976
  let fields = (raw.fields ?? [])
@@ -2954,7 +3033,7 @@ class EntityService extends BaseService {
2954
3033
  isInsightsEnabled: raw.isInsightsEnabled ?? false,
2955
3034
  externalFields: raw.externalFields ?? [],
2956
3035
  },
2957
- });
3036
+ }, { headers: folderHeaders });
2958
3037
  }
2959
3038
  /**
2960
3039
  * Orchestrates all field mapping transformations
@@ -720,6 +720,32 @@ function filterUndefined(obj) {
720
720
  */
721
721
  const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
722
722
  isBrowser && window.self != window.top && window.location.href.includes('source=ActionCenter');
723
+ const _params = isBrowser ? new URLSearchParams(window.location.search) : null;
724
+ /**
725
+ * True when the coded app has been loaded inside a host frame that explicitly
726
+ * opted into token delegation by adding `?host=embed` to the iframe src URL.
727
+ */
728
+ const isHostEmbedded = isBrowser && window.self !== window.top && _params?.get('host') === 'embed';
729
+ /**
730
+ * The validated parent origin, read from the `?basedomain=` query param set
731
+ * by the embedding host in the iframe src URL.
732
+ * Mirrors the same mechanism used by ActionCenterTokenManager.
733
+ * Non-null only when `?host=embed` is present and `?basedomain=` is a valid URL.
734
+ */
735
+ (() => {
736
+ if (!isHostEmbedded)
737
+ return null;
738
+ const basedomain = _params?.get('basedomain');
739
+ if (!basedomain)
740
+ return null;
741
+ try {
742
+ return new URL(basedomain).origin;
743
+ }
744
+ catch {
745
+ console.warn('embeddingOrigin: basedomain query param is not a valid URL', basedomain);
746
+ return null;
747
+ }
748
+ })();
723
749
 
724
750
  /**
725
751
  * Base64 encoding/decoding
@@ -1209,8 +1235,9 @@ class PaginationHelpers {
1209
1235
  });
1210
1236
  }
1211
1237
  // Extract and transform items from response
1212
- // Handle both plain array responses and envelope responses ({ value: [...], totalRecordCount: N })
1213
- const rawItems = Array.isArray(response.data) ? response.data : response.data?.[itemsField];
1238
+ // Handle both plain array responses and envelope responses ({ value: [...], totalRecordCount: N }).
1239
+ // itemsField may be a dotted path (e.g. 'data.agents') for nested envelopes.
1240
+ const rawItems = Array.isArray(response.data) ? response.data : resolveNestedField(response.data, itemsField);
1214
1241
  const rawTotalCount = Array.isArray(response.data) ? undefined : resolveNestedField(response.data, totalCountField);
1215
1242
  const totalCount = typeof rawTotalCount === 'number' ? rawTotalCount : undefined;
1216
1243
  // Parse items - automatically handle JSON string responses
@@ -1256,7 +1283,7 @@ class PaginationHelpers {
1256
1283
  getEndpoint: config.getEndpoint,
1257
1284
  folderId,
1258
1285
  headers: config.headers,
1259
- paginationParams: cursor ? { cursor, pageSize } : jumpToPage ? { jumpToPage, pageSize } : { pageSize },
1286
+ paginationParams: cursor ? { cursor, pageSize } : jumpToPage !== undefined ? { jumpToPage, pageSize } : { pageSize },
1260
1287
  additionalParams: prefixedOptions,
1261
1288
  transformFn: config.transformFn,
1262
1289
  method: config.method,
@@ -1514,6 +1541,8 @@ class BaseService {
1514
1541
  // When true (default), converts pageNumber to a skip/offset value (e.g., page 3 with pageSize 10 → skip 20).
1515
1542
  // When false, passes pageNumber directly as the offset param — used by APIs that accept a page number instead of a record offset.
1516
1543
  const convertToSkip = paginationParams?.convertToSkip ?? true;
1544
+ // When true, sends pageNumber - 1 (for 0-based APIs). Default false (1-based).
1545
+ const zeroBased = paginationParams?.zeroBased ?? false;
1517
1546
  requestParams[pageSizeParam] = limitedPageSize;
1518
1547
  if (convertToSkip) {
1519
1548
  if (params.pageNumber && params.pageNumber > 1) {
@@ -1521,7 +1550,8 @@ class BaseService {
1521
1550
  }
1522
1551
  }
1523
1552
  else {
1524
- requestParams[offsetParam] = params.pageNumber || 1;
1553
+ const sdkPageNumber = params.pageNumber || 1;
1554
+ requestParams[offsetParam] = zeroBased ? sdkPageNumber - 1 : sdkPageNumber;
1525
1555
  }
1526
1556
  {
1527
1557
  requestParams[countParam] = true;
@@ -1550,8 +1580,9 @@ class BaseService {
1550
1580
  const totalCountField = fields.totalCountField || 'totalRecordCount';
1551
1581
  const continuationTokenField = fields.continuationTokenField || 'continuationToken';
1552
1582
  // Extract items and metadata
1553
- // Handle both plain array responses and envelope responses ({ value: [...], totalRecordCount: N })
1554
- const items = Array.isArray(response.data) ? response.data : (response.data[itemsField] || []);
1583
+ // Handle both plain array responses and envelope responses ({ value: [...], totalRecordCount: N }).
1584
+ // itemsField may be a dotted path (e.g. 'data.agents') for nested envelopes.
1585
+ const items = Array.isArray(response.data) ? response.data : (resolveNestedField(response.data, itemsField) || []);
1555
1586
  const rawTotalCount = Array.isArray(response.data) ? undefined : resolveNestedField(response.data, totalCountField);
1556
1587
  const totalCount = typeof rawTotalCount === 'number' ? rawTotalCount : undefined;
1557
1588
  const continuationToken = response.data[continuationTokenField];
@@ -107,6 +107,7 @@ interface RequestWithPaginationOptions extends RequestSpec {
107
107
  tokenParam?: string;
108
108
  countParam?: string;
109
109
  convertToSkip?: boolean;
110
+ zeroBased?: boolean;
110
111
  };
111
112
  };
112
113
  }
@@ -718,6 +718,32 @@ function filterUndefined(obj) {
718
718
  */
719
719
  const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
720
720
  isBrowser && window.self != window.top && window.location.href.includes('source=ActionCenter');
721
+ const _params = isBrowser ? new URLSearchParams(window.location.search) : null;
722
+ /**
723
+ * True when the coded app has been loaded inside a host frame that explicitly
724
+ * opted into token delegation by adding `?host=embed` to the iframe src URL.
725
+ */
726
+ const isHostEmbedded = isBrowser && window.self !== window.top && _params?.get('host') === 'embed';
727
+ /**
728
+ * The validated parent origin, read from the `?basedomain=` query param set
729
+ * by the embedding host in the iframe src URL.
730
+ * Mirrors the same mechanism used by ActionCenterTokenManager.
731
+ * Non-null only when `?host=embed` is present and `?basedomain=` is a valid URL.
732
+ */
733
+ (() => {
734
+ if (!isHostEmbedded)
735
+ return null;
736
+ const basedomain = _params?.get('basedomain');
737
+ if (!basedomain)
738
+ return null;
739
+ try {
740
+ return new URL(basedomain).origin;
741
+ }
742
+ catch {
743
+ console.warn('embeddingOrigin: basedomain query param is not a valid URL', basedomain);
744
+ return null;
745
+ }
746
+ })();
721
747
 
722
748
  /**
723
749
  * Base64 encoding/decoding
@@ -1207,8 +1233,9 @@ class PaginationHelpers {
1207
1233
  });
1208
1234
  }
1209
1235
  // Extract and transform items from response
1210
- // Handle both plain array responses and envelope responses ({ value: [...], totalRecordCount: N })
1211
- const rawItems = Array.isArray(response.data) ? response.data : response.data?.[itemsField];
1236
+ // Handle both plain array responses and envelope responses ({ value: [...], totalRecordCount: N }).
1237
+ // itemsField may be a dotted path (e.g. 'data.agents') for nested envelopes.
1238
+ const rawItems = Array.isArray(response.data) ? response.data : resolveNestedField(response.data, itemsField);
1212
1239
  const rawTotalCount = Array.isArray(response.data) ? undefined : resolveNestedField(response.data, totalCountField);
1213
1240
  const totalCount = typeof rawTotalCount === 'number' ? rawTotalCount : undefined;
1214
1241
  // Parse items - automatically handle JSON string responses
@@ -1254,7 +1281,7 @@ class PaginationHelpers {
1254
1281
  getEndpoint: config.getEndpoint,
1255
1282
  folderId,
1256
1283
  headers: config.headers,
1257
- paginationParams: cursor ? { cursor, pageSize } : jumpToPage ? { jumpToPage, pageSize } : { pageSize },
1284
+ paginationParams: cursor ? { cursor, pageSize } : jumpToPage !== undefined ? { jumpToPage, pageSize } : { pageSize },
1258
1285
  additionalParams: prefixedOptions,
1259
1286
  transformFn: config.transformFn,
1260
1287
  method: config.method,
@@ -1512,6 +1539,8 @@ class BaseService {
1512
1539
  // When true (default), converts pageNumber to a skip/offset value (e.g., page 3 with pageSize 10 → skip 20).
1513
1540
  // When false, passes pageNumber directly as the offset param — used by APIs that accept a page number instead of a record offset.
1514
1541
  const convertToSkip = paginationParams?.convertToSkip ?? true;
1542
+ // When true, sends pageNumber - 1 (for 0-based APIs). Default false (1-based).
1543
+ const zeroBased = paginationParams?.zeroBased ?? false;
1515
1544
  requestParams[pageSizeParam] = limitedPageSize;
1516
1545
  if (convertToSkip) {
1517
1546
  if (params.pageNumber && params.pageNumber > 1) {
@@ -1519,7 +1548,8 @@ class BaseService {
1519
1548
  }
1520
1549
  }
1521
1550
  else {
1522
- requestParams[offsetParam] = params.pageNumber || 1;
1551
+ const sdkPageNumber = params.pageNumber || 1;
1552
+ requestParams[offsetParam] = zeroBased ? sdkPageNumber - 1 : sdkPageNumber;
1523
1553
  }
1524
1554
  {
1525
1555
  requestParams[countParam] = true;
@@ -1548,8 +1578,9 @@ class BaseService {
1548
1578
  const totalCountField = fields.totalCountField || 'totalRecordCount';
1549
1579
  const continuationTokenField = fields.continuationTokenField || 'continuationToken';
1550
1580
  // Extract items and metadata
1551
- // Handle both plain array responses and envelope responses ({ value: [...], totalRecordCount: N })
1552
- const items = Array.isArray(response.data) ? response.data : (response.data[itemsField] || []);
1581
+ // Handle both plain array responses and envelope responses ({ value: [...], totalRecordCount: N }).
1582
+ // itemsField may be a dotted path (e.g. 'data.agents') for nested envelopes.
1583
+ const items = Array.isArray(response.data) ? response.data : (resolveNestedField(response.data, itemsField) || []);
1553
1584
  const rawTotalCount = Array.isArray(response.data) ? undefined : resolveNestedField(response.data, totalCountField);
1554
1585
  const totalCount = typeof rawTotalCount === 'number' ? rawTotalCount : undefined;
1555
1586
  const continuationToken = response.data[continuationTokenField];