@uipath/uipath-typescript 1.3.10 → 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 +192 -10
  17. package/dist/cases/index.d.ts +208 -7
  18. package/dist/cases/index.mjs +192 -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 +135 -70
  26. package/dist/entities/index.d.ts +146 -45
  27. package/dist/entities/index.mjs +135 -70
  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 +1050 -291
  35. package/dist/index.d.ts +1313 -134
  36. package/dist/index.mjs +1050 -292
  37. package/dist/index.umd.js +4546 -3770
  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 +224 -18
  42. package/dist/maestro-processes/index.d.ts +221 -9
  43. package/dist/maestro-processes/index.mjs +224 -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 +1933 -0
  54. package/dist/traces/index.d.ts +566 -0
  55. package/dist/traces/index.mjs +1931 -0
  56. package/package.json +42 -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
  /**
@@ -2789,10 +2857,6 @@ class EntityService extends BaseService {
2789
2857
  * @internal
2790
2858
  */
2791
2859
  async create(name, fields, options) {
2792
- this.validateName(name, 'entity');
2793
- for (const field of fields) {
2794
- this.validateName(field.fieldName, 'field');
2795
- }
2796
2860
  const opts = options ?? {};
2797
2861
  const payload = {
2798
2862
  ...(opts.description !== undefined && { description: opts.description }),
@@ -2806,23 +2870,27 @@ class EntityService extends BaseService {
2806
2870
  externalFields: opts.externalFields ?? [],
2807
2871
  },
2808
2872
  };
2809
- 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 }) });
2810
2874
  return response.data;
2811
2875
  }
2812
2876
  /**
2813
2877
  * Deletes a Data Fabric entity and all its records
2814
2878
  *
2815
2879
  * @param id - UUID of the entity to delete
2880
+ * @param options - Optional {@link EntityDeleteByIdOptions} (e.g. `folderKey` for folder-scoped entities)
2816
2881
  * @returns Promise resolving when the entity is deleted
2817
2882
  *
2818
2883
  * @example
2819
2884
  * ```typescript
2820
2885
  * await entities.deleteById("<entityId>");
2886
+ *
2887
+ * // Folder-scoped: pass the entity's folder key
2888
+ * await entities.deleteById("<entityId>", { folderKey: "<folderKey>" });
2821
2889
  * ```
2822
2890
  * @internal
2823
2891
  */
2824
- async deleteById(id) {
2825
- 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 }) });
2826
2894
  }
2827
2895
  /**
2828
2896
  * Updates an existing Data Fabric entity — schema and/or metadata.
@@ -2869,6 +2937,12 @@ class EntityService extends BaseService {
2869
2937
  * { id: "<fieldId>", lengthLimit: 1000 },
2870
2938
  * ],
2871
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
+ * });
2872
2946
  * ```
2873
2947
  * @internal
2874
2948
  */
@@ -2884,7 +2958,7 @@ class EntityService extends BaseService {
2884
2958
  ...(opts.displayName !== undefined && { displayName: opts.displayName }),
2885
2959
  ...(opts.description !== undefined && { description: opts.description }),
2886
2960
  ...(opts.isRbacEnabled !== undefined && { isRbacEnabled: opts.isRbacEnabled }),
2887
- });
2961
+ }, { headers: createHeaders({ [FOLDER_KEY]: opts.folderKey }) });
2888
2962
  }
2889
2963
  }
2890
2964
  /**
@@ -2895,7 +2969,8 @@ class EntityService extends BaseService {
2895
2969
  * @private
2896
2970
  */
2897
2971
  async applySchemaUpdate(entityId, options) {
2898
- 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 });
2899
2974
  const raw = entityResponse.data;
2900
2975
  // Carry forward existing non-system fields from GET response (skip system/primary-key fields)
2901
2976
  let fields = (raw.fields ?? [])
@@ -2935,6 +3010,7 @@ class EntityService extends BaseService {
2935
3010
  ...(update.isUnique !== undefined && { isUnique: update.isUnique }),
2936
3011
  ...(update.isRbacEnabled !== undefined && { isRbacEnabled: update.isRbacEnabled }),
2937
3012
  ...(update.isEncrypted !== undefined && { isEncrypted: update.isEncrypted }),
3013
+ ...(update.isHiddenField !== undefined && { isHiddenField: update.isHiddenField }),
2938
3014
  ...(update.defaultValue !== undefined && { defaultValue: update.defaultValue }),
2939
3015
  ...(hasConstraintUpdate && f.sqlType && { sqlType: { ...f.sqlType, ...constraintUpdate } }),
2940
3016
  };
@@ -2943,9 +3019,6 @@ class EntityService extends BaseService {
2943
3019
  // Build and append new fields
2944
3020
  const newFields = [];
2945
3021
  if (options.addFields?.length) {
2946
- for (const field of options.addFields) {
2947
- this.validateName(field.fieldName, 'field');
2948
- }
2949
3022
  newFields.push(...options.addFields.map(f => this.buildSchemaFieldPayload(f)));
2950
3023
  }
2951
3024
  await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPSERT, {
@@ -2960,7 +3033,7 @@ class EntityService extends BaseService {
2960
3033
  isInsightsEnabled: raw.isInsightsEnabled ?? false,
2961
3034
  externalFields: raw.externalFields ?? [],
2962
3035
  },
2963
- });
3036
+ }, { headers: folderHeaders });
2964
3037
  }
2965
3038
  /**
2966
3039
  * Orchestrates all field mapping transformations
@@ -3046,9 +3119,15 @@ class EntityService extends BaseService {
3046
3119
  }
3047
3120
  /** Converts a user-facing EntityCreateFieldOptions to the raw API field payload */
3048
3121
  buildSchemaFieldPayload(field) {
3049
- this.validateName(field.fieldName, 'field');
3050
3122
  const fieldType = field.type ?? EntityFieldDataType.STRING;
3051
3123
  this.validateFieldConstraints(fieldType, field, field.fieldName);
3124
+ const isRelationship = fieldType === EntityFieldDataType.RELATIONSHIP;
3125
+ const isFile = fieldType === EntityFieldDataType.FILE;
3126
+ if ((isRelationship || isFile) && (!field.referenceEntityId || !field.referenceFieldId)) {
3127
+ throw new ValidationError({
3128
+ message: `Field '${field.fieldName}' of type ${fieldType} requires both referenceEntityId and referenceFieldId (UUIDs of the target entity and field).`,
3129
+ });
3130
+ }
3052
3131
  const mapping = EntitySchemaFieldTypeMap[fieldType];
3053
3132
  return {
3054
3133
  name: field.fieldName,
@@ -3063,10 +3142,13 @@ class EntityService extends BaseService {
3063
3142
  isUnique: field.isUnique ?? false,
3064
3143
  isRbacEnabled: field.isRbacEnabled ?? false,
3065
3144
  isEncrypted: field.isEncrypted ?? false,
3145
+ isHiddenField: field.isHiddenField ?? false,
3066
3146
  ...(field.defaultValue !== undefined && { defaultValue: field.defaultValue }),
3067
3147
  ...(field.choiceSetId !== undefined && { choiceSetId: field.choiceSetId }),
3068
- ...(field.referenceEntityName !== undefined && { referenceEntityName: field.referenceEntityName }),
3069
- ...(field.referenceFieldName !== undefined && { referenceFieldName: field.referenceFieldName }),
3148
+ ...((isRelationship || isFile) && { isForeignKey: true }),
3149
+ ...(isRelationship && { referenceType: ReferenceType.ManyToOne }),
3150
+ ...(field.referenceEntityId !== undefined && { referenceEntity: { id: field.referenceEntityId } }),
3151
+ ...(field.referenceFieldId !== undefined && { referenceField: { id: field.referenceFieldId } }),
3070
3152
  };
3071
3153
  }
3072
3154
  /**
@@ -3170,24 +3252,7 @@ class EntityService extends BaseService {
3170
3252
  return {};
3171
3253
  }
3172
3254
  }
3173
- validateName(name, context) {
3174
- if (name.length < 3 || name.length > 100 || !/^[a-zA-Z]\w*$/.test(name)) {
3175
- const suggestion = name.replace(/\W/g, '').replace(/^[0-9_]+/, '');
3176
- const defaultName = `My${context.charAt(0).toUpperCase() + context.slice(1)}`;
3177
- throw new ValidationError({
3178
- message: `Invalid ${context} name '${name}'. Must start with a letter, contain only letters, numbers, and underscores, 3–100 characters (e.g., "${suggestion || defaultName}").`
3179
- });
3180
- }
3181
- if (context === 'field' && EntityService.RESERVED_FIELD_NAMES.has(name)) {
3182
- throw new ValidationError({
3183
- message: `Field name '${name}' is reserved. Reserved names: ${[...EntityService.RESERVED_FIELD_NAMES].join(', ')}.`
3184
- });
3185
- }
3186
- }
3187
3255
  }
3188
- EntityService.RESERVED_FIELD_NAMES = new Set([
3189
- 'Id', 'CreatedBy', 'CreateTime', 'UpdatedBy', 'UpdateTime'
3190
- ]);
3191
3256
  __decorate([
3192
3257
  track('Entities.GetById')
3193
3258
  ], EntityService.prototype, "getById", null);
@@ -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
  }