@uipath/uipath-typescript 1.3.11 → 1.4.1

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 (59) hide show
  1. package/dist/agent-memory/index.cjs +1772 -0
  2. package/dist/agent-memory/index.d.ts +588 -0
  3. package/dist/agent-memory/index.mjs +1770 -0
  4. package/dist/agents/index.cjs +1995 -0
  5. package/dist/agents/index.d.ts +961 -0
  6. package/dist/agents/index.mjs +1993 -0
  7. package/dist/assets/index.cjs +171 -39
  8. package/dist/assets/index.d.ts +84 -5
  9. package/dist/assets/index.mjs +171 -39
  10. package/dist/attachments/index.cjs +53 -15
  11. package/dist/attachments/index.d.ts +1 -0
  12. package/dist/attachments/index.mjs +53 -15
  13. package/dist/buckets/index.cjs +151 -130
  14. package/dist/buckets/index.d.ts +198 -84
  15. package/dist/buckets/index.mjs +151 -130
  16. package/dist/cases/index.cjs +220 -23
  17. package/dist/cases/index.d.ts +148 -10
  18. package/dist/cases/index.mjs +220 -24
  19. package/dist/conversational-agent/index.cjs +140 -66
  20. package/dist/conversational-agent/index.d.ts +190 -122
  21. package/dist/conversational-agent/index.mjs +140 -66
  22. package/dist/core/index.cjs +445 -108
  23. package/dist/core/index.d.ts +15 -0
  24. package/dist/core/index.mjs +445 -108
  25. package/dist/entities/index.cjs +365 -102
  26. package/dist/entities/index.d.ts +446 -114
  27. package/dist/entities/index.mjs +365 -102
  28. package/dist/feedback/index.cjs +53 -15
  29. package/dist/feedback/index.d.ts +1 -0
  30. package/dist/feedback/index.mjs +53 -15
  31. package/dist/governance/index.cjs +1789 -0
  32. package/dist/governance/index.d.ts +598 -0
  33. package/dist/governance/index.mjs +1787 -0
  34. package/dist/index.cjs +1453 -444
  35. package/dist/index.d.ts +4150 -1742
  36. package/dist/index.mjs +1452 -445
  37. package/dist/index.umd.js +5035 -4009
  38. package/dist/jobs/index.cjs +53 -15
  39. package/dist/jobs/index.d.ts +1 -0
  40. package/dist/jobs/index.mjs +53 -15
  41. package/dist/maestro-processes/index.cjs +189 -27
  42. package/dist/maestro-processes/index.d.ts +131 -9
  43. package/dist/maestro-processes/index.mjs +189 -27
  44. package/dist/orchestrator-du-module/index.cjs +1788 -0
  45. package/dist/orchestrator-du-module/index.d.ts +757 -0
  46. package/dist/orchestrator-du-module/index.mjs +1785 -0
  47. package/dist/processes/index.cjs +53 -15
  48. package/dist/processes/index.d.ts +1 -0
  49. package/dist/processes/index.mjs +53 -15
  50. package/dist/queues/index.cjs +53 -15
  51. package/dist/queues/index.d.ts +1 -0
  52. package/dist/queues/index.mjs +53 -15
  53. package/dist/tasks/index.cjs +116 -19
  54. package/dist/tasks/index.d.ts +110 -4
  55. package/dist/tasks/index.mjs +117 -20
  56. package/dist/traces/index.cjs +340 -15
  57. package/dist/traces/index.d.ts +483 -2
  58. package/dist/traces/index.mjs +339 -16
  59. 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
@@ -1249,12 +1276,18 @@ class PaginationHelpers {
1249
1276
  * @returns Promise resolving to a paginated result
1250
1277
  */
1251
1278
  static async getAllPaginated(params) {
1252
- const { serviceAccess, getEndpoint, folderId, headers: providedHeaders, paginationParams, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1279
+ const { serviceAccess, getEndpoint, folderId, headers: providedHeaders, paginationParams, additionalParams, queryParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1253
1280
  const endpoint = getEndpoint(folderId);
1254
1281
  const headers = providedHeaders ?? (folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {});
1282
+ // On POST, the caller's options go in the body; queryParams stays in the URL.
1283
+ // On GET, everything is URL — queryParams merges with additionalParams.
1284
+ const isPost = method === HTTP_METHODS.POST;
1285
+ const requestSpec = isPost
1286
+ ? { body: additionalParams, params: queryParams }
1287
+ : { params: { ...additionalParams, ...queryParams } };
1255
1288
  const paginatedResponse = await serviceAccess.requestWithPagination(method, endpoint, paginationParams, {
1256
1289
  headers,
1257
- params: additionalParams,
1290
+ ...requestSpec,
1258
1291
  pagination: {
1259
1292
  paginationType: options.paginationType || PaginationType.OFFSET,
1260
1293
  itemsField: options.itemsField || DEFAULT_ITEMS_FIELD,
@@ -1279,7 +1312,7 @@ class PaginationHelpers {
1279
1312
  * @returns Promise resolving to an object with data and totalCount
1280
1313
  */
1281
1314
  static async getAllNonPaginated(params) {
1282
- const { serviceAccess, getAllEndpoint, getByFolderEndpoint, folderId, headers: providedHeaders, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1315
+ const { serviceAccess, getAllEndpoint, getByFolderEndpoint, folderId, headers: providedHeaders, additionalParams, queryParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1283
1316
  // Set default field names
1284
1317
  const itemsField = options.itemsField || DEFAULT_ITEMS_FIELD;
1285
1318
  const totalCountField = options.totalCountField || DEFAULT_TOTAL_COUNT_FIELD;
@@ -1289,17 +1322,18 @@ class PaginationHelpers {
1289
1322
  // Make the API call based on method
1290
1323
  let response;
1291
1324
  if (method === HTTP_METHODS.POST) {
1292
- response = await serviceAccess.post(endpoint, additionalParams, { headers });
1325
+ response = await serviceAccess.post(endpoint, additionalParams, { headers, params: queryParams });
1293
1326
  }
1294
1327
  else {
1295
1328
  response = await serviceAccess.get(endpoint, {
1296
- params: additionalParams,
1329
+ params: { ...additionalParams, ...queryParams },
1297
1330
  headers
1298
1331
  });
1299
1332
  }
1300
1333
  // 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];
1334
+ // Handle both plain array responses and envelope responses ({ value: [...], totalRecordCount: N }).
1335
+ // itemsField may be a dotted path (e.g. 'data.agents') for nested envelopes.
1336
+ const rawItems = Array.isArray(response.data) ? response.data : resolveNestedField(response.data, itemsField);
1303
1337
  const rawTotalCount = Array.isArray(response.data) ? undefined : resolveNestedField(response.data, totalCountField);
1304
1338
  const totalCount = typeof rawTotalCount === 'number' ? rawTotalCount : undefined;
1305
1339
  // Parse items - automatically handle JSON string responses
@@ -1345,8 +1379,9 @@ class PaginationHelpers {
1345
1379
  getEndpoint: config.getEndpoint,
1346
1380
  folderId,
1347
1381
  headers: config.headers,
1348
- paginationParams: cursor ? { cursor, pageSize } : jumpToPage ? { jumpToPage, pageSize } : { pageSize },
1382
+ paginationParams: cursor ? { cursor, pageSize } : jumpToPage !== undefined ? { jumpToPage, pageSize } : { pageSize },
1349
1383
  additionalParams: prefixedOptions,
1384
+ queryParams: config.queryParams,
1350
1385
  transformFn: config.transformFn,
1351
1386
  method: config.method,
1352
1387
  options: {
@@ -1364,6 +1399,7 @@ class PaginationHelpers {
1364
1399
  folderId,
1365
1400
  headers: config.headers,
1366
1401
  additionalParams: prefixedOptions,
1402
+ queryParams: config.queryParams,
1367
1403
  transformFn: config.transformFn,
1368
1404
  method: config.method,
1369
1405
  options: {
@@ -1555,18 +1591,17 @@ class BaseService {
1555
1591
  const params = this.validateAndPreparePaginationParams(paginationType, paginationOptions);
1556
1592
  // Prepare request parameters based on pagination type
1557
1593
  const requestParams = this.preparePaginationRequestParams(paginationType, params, options.pagination);
1558
- // For POST requests, merge pagination params into body and set params to undefined; for GET, use query params
1594
+ // Route pagination state to wherever the API expects it (body for POST, URL for GET).
1595
+ // Caller-supplied options.body / options.params are respected as-is — the api-client
1596
+ // already handles params (URL) and body (request body) independently for every method.
1559
1597
  if (method.toUpperCase() === 'POST') {
1560
1598
  const existingBody = (options.body && typeof options.body === 'object') ? options.body : {};
1561
1599
  options.body = {
1562
1600
  ...existingBody,
1563
- ...options.params,
1564
1601
  ...requestParams
1565
1602
  };
1566
- options.params = undefined;
1567
1603
  }
1568
1604
  else {
1569
- // Merge pagination parameters with existing parameters
1570
1605
  options.params = {
1571
1606
  ...options.params,
1572
1607
  ...requestParams
@@ -1603,6 +1638,8 @@ class BaseService {
1603
1638
  // When true (default), converts pageNumber to a skip/offset value (e.g., page 3 with pageSize 10 → skip 20).
1604
1639
  // When false, passes pageNumber directly as the offset param — used by APIs that accept a page number instead of a record offset.
1605
1640
  const convertToSkip = paginationParams?.convertToSkip ?? true;
1641
+ // When true, sends pageNumber - 1 (for 0-based APIs). Default false (1-based).
1642
+ const zeroBased = paginationParams?.zeroBased ?? false;
1606
1643
  requestParams[pageSizeParam] = limitedPageSize;
1607
1644
  if (convertToSkip) {
1608
1645
  if (params.pageNumber && params.pageNumber > 1) {
@@ -1610,7 +1647,8 @@ class BaseService {
1610
1647
  }
1611
1648
  }
1612
1649
  else {
1613
- requestParams[offsetParam] = params.pageNumber || 1;
1650
+ const sdkPageNumber = params.pageNumber || 1;
1651
+ requestParams[offsetParam] = zeroBased ? sdkPageNumber - 1 : sdkPageNumber;
1614
1652
  }
1615
1653
  {
1616
1654
  requestParams[countParam] = true;
@@ -1639,8 +1677,9 @@ class BaseService {
1639
1677
  const totalCountField = fields.totalCountField || 'totalRecordCount';
1640
1678
  const continuationTokenField = fields.continuationTokenField || 'continuationToken';
1641
1679
  // 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] || []);
1680
+ // Handle both plain array responses and envelope responses ({ value: [...], totalRecordCount: N }).
1681
+ // itemsField may be a dotted path (e.g. 'data.agents') for nested envelopes.
1682
+ const items = Array.isArray(response.data) ? response.data : (resolveNestedField(response.data, itemsField) || []);
1644
1683
  const rawTotalCount = Array.isArray(response.data) ? undefined : resolveNestedField(response.data, totalCountField);
1645
1684
  const totalCount = typeof rawTotalCount === 'number' ? rawTotalCount : undefined;
1646
1685
  const continuationToken = response.data[continuationTokenField];
@@ -1723,12 +1762,12 @@ function createEntityMethods(entityData, service) {
1723
1762
  throw new Error('Entity ID is undefined');
1724
1763
  return service.deleteRecordsById(entityData.id, recordIds, options);
1725
1764
  },
1726
- async deleteRecord(recordId) {
1765
+ async deleteRecord(recordId, options) {
1727
1766
  if (!entityData.id)
1728
1767
  throw new Error('Entity ID is undefined');
1729
1768
  if (!recordId)
1730
1769
  throw new Error('Record ID is undefined');
1731
- return service.deleteRecordById(entityData.id, recordId);
1770
+ return service.deleteRecordById(entityData.id, recordId, options);
1732
1771
  },
1733
1772
  async getAllRecords(options) {
1734
1773
  if (!entityData.id)
@@ -1742,30 +1781,30 @@ function createEntityMethods(entityData, service) {
1742
1781
  throw new Error('Record ID is undefined');
1743
1782
  return service.getRecordById(entityData.id, recordId, options);
1744
1783
  },
1745
- async downloadAttachment(recordId, fieldName) {
1784
+ async downloadAttachment(recordId, fieldName, options) {
1746
1785
  if (!entityData.id)
1747
1786
  throw new Error('Entity ID is undefined');
1748
- return service.downloadAttachment(entityData.id, recordId, fieldName);
1787
+ return service.downloadAttachment(entityData.id, recordId, fieldName, options);
1749
1788
  },
1750
1789
  async uploadAttachment(recordId, fieldName, file, options) {
1751
1790
  if (!entityData.id)
1752
1791
  throw new Error('Entity ID is undefined');
1753
1792
  return service.uploadAttachment(entityData.id, recordId, fieldName, file, options);
1754
1793
  },
1755
- async deleteAttachment(recordId, fieldName) {
1794
+ async deleteAttachment(recordId, fieldName, options) {
1756
1795
  if (!entityData.id)
1757
1796
  throw new Error('Entity ID is undefined');
1758
- return service.deleteAttachment(entityData.id, recordId, fieldName);
1797
+ return service.deleteAttachment(entityData.id, recordId, fieldName, options);
1759
1798
  },
1760
1799
  async queryRecords(options) {
1761
1800
  if (!entityData.id)
1762
1801
  throw new Error('Entity ID is undefined');
1763
1802
  return service.queryRecordsById(entityData.id, options);
1764
1803
  },
1765
- async importRecords(file) {
1804
+ async importRecords(file, options) {
1766
1805
  if (!entityData.id)
1767
1806
  throw new Error('Entity ID is undefined');
1768
- return service.importRecordsById(entityData.id, file);
1807
+ return service.importRecordsById(entityData.id, file, options);
1769
1808
  },
1770
1809
  async insert(data, options) {
1771
1810
  return this.insertRecord(data, options);
@@ -1776,10 +1815,10 @@ function createEntityMethods(entityData, service) {
1776
1815
  async getRecords(options) {
1777
1816
  return this.getAllRecords(options);
1778
1817
  },
1779
- async delete() {
1818
+ async delete(options) {
1780
1819
  if (!entityData.id)
1781
1820
  throw new Error('Entity ID is undefined');
1782
- return service.deleteById(entityData.id);
1821
+ return service.deleteById(entityData.id, options);
1783
1822
  },
1784
1823
  async update(options) {
1785
1824
  if (!entityData.id)
@@ -1928,6 +1967,9 @@ const DATA_FABRIC_TENANT_FOLDER_ID = '00000000-0000-0000-0000-000000000000';
1928
1967
  const DATA_FABRIC_ENDPOINTS = {
1929
1968
  ENTITY: {
1930
1969
  GET_ALL: `${DATAFABRIC_BASE}/api/Entity`,
1970
+ // Lists tenant-level and folder-level entities together.
1971
+ // Used by getAll when includeFolderEntities is true.
1972
+ GET_ALL_V2: `${DATAFABRIC_BASE}/api/v2/Entity`,
1931
1973
  GET_ENTITY_RECORDS: (entityId) => `${DATAFABRIC_BASE}/api/EntityService/entity/${entityId}/read`,
1932
1974
  GET_BY_ID: (entityId) => `${DATAFABRIC_BASE}/api/Entity/${entityId}`,
1933
1975
  GET_RECORD_BY_ID: (entityId, recordId) => `${DATAFABRIC_BASE}/api/EntityService/entity/${entityId}/read/${recordId}`,
@@ -2026,6 +2068,14 @@ var SqlFieldType;
2026
2068
  SqlFieldType["MULTILINE"] = "MULTILINE";
2027
2069
  })(SqlFieldType || (SqlFieldType = {}));
2028
2070
 
2071
+ /**
2072
+ * Numeric type IDs that pair with {@link EntityType} on reference payloads
2073
+ * (entityType + entityTypeId travel together in `referenceEntity` /
2074
+ * `referenceChoiceSet` bodies on cross-folder schema upserts).
2075
+ */
2076
+ const ENTITY_TYPE_IDS = {
2077
+ [EntityType.ChoiceSet]: 1,
2078
+ };
2029
2079
  /**
2030
2080
  * Maps fields for Entities
2031
2081
  */
@@ -2188,6 +2238,7 @@ class EntityService extends BaseService {
2188
2238
  * Gets entity metadata by entity ID with attached operation methods
2189
2239
  *
2190
2240
  * @param id - UUID of the entity
2241
+ * @param options - Optional {@link EntityGetByIdOptions} (e.g. `folderKey` for folder-scoped entities) The `folderKey` property is **experimental**.
2191
2242
  * @returns Promise resolving to entity metadata with schema information and operation methods
2192
2243
  *
2193
2244
  * @example
@@ -2197,6 +2248,9 @@ class EntityService extends BaseService {
2197
2248
  * const entities = new Entities(sdk);
2198
2249
  * const entity = await entities.getById("<entityId>");
2199
2250
  *
2251
+ * // Folder-scoped: pass the entity's folder key
2252
+ * const folderEntity = await entities.getById("<entityId>", { folderKey: "<folderKey>" });
2253
+ *
2200
2254
  * // Call operations directly on the entity
2201
2255
  * const records = await entity.getAllRecords();
2202
2256
  *
@@ -2210,9 +2264,9 @@ class EntityService extends BaseService {
2210
2264
  * ]);
2211
2265
  * ```
2212
2266
  */
2213
- async getById(id) {
2267
+ async getById(id, options) {
2214
2268
  // Get entity metadata
2215
- const response = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_BY_ID(id));
2269
+ const response = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_BY_ID(id), { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
2216
2270
  // Apply EntityMap transformations
2217
2271
  const metadata = transformData(response.data, EntityMap);
2218
2272
  // Transform metadata with field mappers
@@ -2224,7 +2278,7 @@ class EntityService extends BaseService {
2224
2278
  * Gets entity records by entity ID
2225
2279
  *
2226
2280
  * @param entityId - UUID of the entity
2227
- * @param options - Query options including expansionLevel and pagination options
2281
+ * @param options - Query options including expansionLevel and pagination options The `folderKey` property is **experimental**.
2228
2282
  * @returns Promise resolving to an array of entity records or paginated response
2229
2283
  *
2230
2284
  * @example
@@ -2252,12 +2306,20 @@ class EntityService extends BaseService {
2252
2306
  * cursor: paginatedResponse.nextCursor,
2253
2307
  * expansionLevel: 1
2254
2308
  * });
2309
+ *
2310
+ * // Folder-scoped entity: pass the entity's folder key
2311
+ * const records = await entities.getAllRecords("<entityId>", { folderKey: "<folderKey>" });
2255
2312
  * ```
2256
2313
  */
2257
2314
  async getAllRecords(entityId, options) {
2315
+ // folderKey is header-only — destructure it out so PaginationHelpers doesn't serialise it
2316
+ // into the query string as $folderKey.
2317
+ const { folderKey, ...rest } = options ?? {};
2318
+ const downstreamOptions = options === undefined ? undefined : rest;
2258
2319
  return PaginationHelpers.getAll({
2259
2320
  serviceAccess: this.createPaginationServiceAccess(),
2260
2321
  getEndpoint: () => DATA_FABRIC_ENDPOINTS.ENTITY.GET_ENTITY_RECORDS(entityId),
2322
+ headers: createHeaders({ [FOLDER_KEY]: folderKey }),
2261
2323
  pagination: {
2262
2324
  paginationType: PaginationType.OFFSET,
2263
2325
  itemsField: ENTITY_PAGINATION.ITEMS_FIELD,
@@ -2269,14 +2331,14 @@ class EntityService extends BaseService {
2269
2331
  }
2270
2332
  },
2271
2333
  excludeFromPrefix: ['expansionLevel'] // Don't add ODATA prefix to expansionLevel
2272
- }, options);
2334
+ }, downstreamOptions);
2273
2335
  }
2274
2336
  /**
2275
2337
  * Gets a single entity record by entity ID and record ID
2276
2338
  *
2277
2339
  * @param entityId - UUID of the entity
2278
2340
  * @param recordId - UUID of the record
2279
- * @param options - Query options including expansionLevel
2341
+ * @param options - Query options including `expansionLevel` and `folderKey` The `folderKey` property is **experimental**.
2280
2342
  * @returns Promise resolving to the entity record
2281
2343
  *
2282
2344
  * @example
@@ -2288,13 +2350,18 @@ class EntityService extends BaseService {
2288
2350
  * const record = await sdk.entities.getRecordById(<entityId>, <recordId>, {
2289
2351
  * expansionLevel: 1
2290
2352
  * });
2353
+ *
2354
+ * // Folder-scoped entity: pass the entity's folder key
2355
+ * const record = await sdk.entities.getRecordById(<entityId>, <recordId>, {
2356
+ * folderKey: "<folderKey>"
2357
+ * });
2291
2358
  * ```
2292
2359
  */
2293
2360
  async getRecordById(entityId, recordId, options = {}) {
2294
2361
  const params = createParams({
2295
2362
  expansionLevel: options.expansionLevel
2296
2363
  });
2297
- const response = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_RECORD_BY_ID(entityId, recordId), { params });
2364
+ const response = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_RECORD_BY_ID(entityId, recordId), { params, headers: createHeaders({ [FOLDER_KEY]: options.folderKey }) });
2298
2365
  return response.data;
2299
2366
  }
2300
2367
  /**
@@ -2302,7 +2369,7 @@ class EntityService extends BaseService {
2302
2369
  *
2303
2370
  * @param entityId - UUID of the entity
2304
2371
  * @param data - Record to insert
2305
- * @param options - Insert options
2372
+ * @param options - Insert options The `folderKey` property is **experimental**.
2306
2373
  * @returns Promise resolving to the inserted record with generated record ID
2307
2374
  *
2308
2375
  * @example
@@ -2318,6 +2385,11 @@ class EntityService extends BaseService {
2318
2385
  * const result = await entities.insertRecordById("<entityId>", { name: "John", age: 30 }, {
2319
2386
  * expansionLevel: 1
2320
2387
  * });
2388
+ *
2389
+ * // Folder-scoped entity: pass the entity's folder key
2390
+ * await entities.insertRecordById("<entityId>", { name: "John", age: 30 }, {
2391
+ * folderKey: "<folderKey>"
2392
+ * });
2321
2393
  * ```
2322
2394
  */
2323
2395
  async insertRecordById(id, data, options = {}) {
@@ -2326,7 +2398,7 @@ class EntityService extends BaseService {
2326
2398
  });
2327
2399
  const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.INSERT_BY_ID(id), data, {
2328
2400
  params,
2329
- ...options
2401
+ headers: createHeaders({ [FOLDER_KEY]: options.folderKey }),
2330
2402
  });
2331
2403
  return response.data;
2332
2404
  }
@@ -2335,7 +2407,7 @@ class EntityService extends BaseService {
2335
2407
  *
2336
2408
  * @param entityId - UUID of the entity
2337
2409
  * @param data - Array of records to insert
2338
- * @param options - Insert options
2410
+ * @param options - Insert options The `folderKey` property is **experimental**.
2339
2411
  * @returns Promise resolving to insert response
2340
2412
  *
2341
2413
  * @example
@@ -2358,6 +2430,12 @@ class EntityService extends BaseService {
2358
2430
  * expansionLevel: 1,
2359
2431
  * failOnFirst: true
2360
2432
  * });
2433
+ *
2434
+ * // Folder-scoped entity: pass the entity's folder key
2435
+ * await entities.insertRecordsById("<entityId>", [
2436
+ * { name: "John", age: 30 },
2437
+ * { name: "Jane", age: 25 }
2438
+ * ], { folderKey: "<folderKey>" });
2361
2439
  * ```
2362
2440
  */
2363
2441
  async insertRecordsById(id, data, options = {}) {
@@ -2367,7 +2445,7 @@ class EntityService extends BaseService {
2367
2445
  });
2368
2446
  const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.BATCH_INSERT_BY_ID(id), data, {
2369
2447
  params,
2370
- ...options
2448
+ headers: createHeaders({ [FOLDER_KEY]: options.folderKey }),
2371
2449
  });
2372
2450
  return response.data;
2373
2451
  }
@@ -2377,7 +2455,7 @@ class EntityService extends BaseService {
2377
2455
  * @param entityId - UUID of the entity
2378
2456
  * @param recordId - UUID of the record to update
2379
2457
  * @param data - Key-value pairs of fields to update
2380
- * @param options - Update options
2458
+ * @param options - Update options The `folderKey` property is **experimental**.
2381
2459
  * @returns Promise resolving to the updated record
2382
2460
  *
2383
2461
  * @example
@@ -2393,6 +2471,11 @@ class EntityService extends BaseService {
2393
2471
  * const result = await entities.updateRecordById("<entityId>", "<recordId>", { name: "John Updated", age: 31 }, {
2394
2472
  * expansionLevel: 1
2395
2473
  * });
2474
+ *
2475
+ * // Folder-scoped entity: pass the entity's folder key
2476
+ * await entities.updateRecordById("<entityId>", "<recordId>", { name: "John Updated" }, {
2477
+ * folderKey: "<folderKey>"
2478
+ * });
2396
2479
  * ```
2397
2480
  */
2398
2481
  async updateRecordById(entityId, recordId, data, options = {}) {
@@ -2401,7 +2484,7 @@ class EntityService extends BaseService {
2401
2484
  });
2402
2485
  const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPDATE_RECORD_BY_ID(entityId, recordId), data, {
2403
2486
  params,
2404
- ...options
2487
+ headers: createHeaders({ [FOLDER_KEY]: options.folderKey }),
2405
2488
  });
2406
2489
  return response.data;
2407
2490
  }
@@ -2411,7 +2494,7 @@ class EntityService extends BaseService {
2411
2494
  * @param entityId - UUID of the entity
2412
2495
  * @param data - Array of records to update. Each record MUST contain the record Id,
2413
2496
  * otherwise the update will fail.
2414
- * @param options - Update options
2497
+ * @param options - Update options The `folderKey` property is **experimental**.
2415
2498
  * @returns Promise resolving to update response
2416
2499
  *
2417
2500
  * @example
@@ -2434,6 +2517,11 @@ class EntityService extends BaseService {
2434
2517
  * expansionLevel: 1,
2435
2518
  * failOnFirst: true
2436
2519
  * });
2520
+ *
2521
+ * // Folder-scoped entity: pass the entity's folder key
2522
+ * await entities.updateRecordsById("<entityId>", [
2523
+ * { Id: "123", name: "John Updated" }
2524
+ * ], { folderKey: "<folderKey>" });
2437
2525
  * ```
2438
2526
  */
2439
2527
  async updateRecordsById(id, data, options = {}) {
@@ -2443,7 +2531,7 @@ class EntityService extends BaseService {
2443
2531
  });
2444
2532
  const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPDATE_BY_ID(id), data, {
2445
2533
  params,
2446
- ...options
2534
+ headers: createHeaders({ [FOLDER_KEY]: options.folderKey }),
2447
2535
  });
2448
2536
  return response.data;
2449
2537
  }
@@ -2454,7 +2542,7 @@ class EntityService extends BaseService {
2454
2542
  *
2455
2543
  * @param entityId - UUID of the entity
2456
2544
  * @param recordIds - Array of record UUIDs to delete
2457
- * @param options - Delete options
2545
+ * @param options - Delete options The `folderKey` property is **experimental**.
2458
2546
  * @returns Promise resolving to delete response
2459
2547
  *
2460
2548
  * @example
@@ -2467,6 +2555,11 @@ class EntityService extends BaseService {
2467
2555
  * const result = await entities.deleteRecordsById("<entityId>", [
2468
2556
  * "<recordId-1>", "<recordId-2>"
2469
2557
  * ]);
2558
+ *
2559
+ * // Folder-scoped entity: pass the entity's folder key
2560
+ * await entities.deleteRecordsById("<entityId>", [
2561
+ * "<recordId-1>", "<recordId-2>"
2562
+ * ], { folderKey: "<folderKey>" });
2470
2563
  * ```
2471
2564
  */
2472
2565
  async deleteRecordsById(id, recordIds, options = {}) {
@@ -2475,7 +2568,7 @@ class EntityService extends BaseService {
2475
2568
  });
2476
2569
  const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE_BY_ID(id), recordIds, {
2477
2570
  params,
2478
- ...options
2571
+ headers: createHeaders({ [FOLDER_KEY]: options.folderKey }),
2479
2572
  });
2480
2573
  return response.data;
2481
2574
  }
@@ -2487,6 +2580,7 @@ class EntityService extends BaseService {
2487
2580
  *
2488
2581
  * @param entityId - UUID of the entity
2489
2582
  * @param recordId - UUID of the record to delete
2583
+ * @param options - Optional {@link EntityDeleteRecordByIdOptions} (e.g. `folderKey` for folder-scoped entities) The `folderKey` property is **experimental**.
2490
2584
  * @returns Promise resolving to void on success
2491
2585
  * @example
2492
2586
  * ```typescript
@@ -2495,14 +2589,23 @@ class EntityService extends BaseService {
2495
2589
  * const entities = new Entities(sdk);
2496
2590
  *
2497
2591
  * await entities.deleteRecordById("<entityId>", "<recordId>");
2592
+ *
2593
+ * // Folder-scoped: pass the entity's folder key
2594
+ * await entities.deleteRecordById("<entityId>", "<recordId>", { folderKey: "<folderKey>" });
2498
2595
  * ```
2499
2596
  */
2500
- async deleteRecordById(entityId, recordId) {
2501
- await this.delete(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE_RECORD_BY_ID(entityId, recordId));
2597
+ async deleteRecordById(entityId, recordId, options) {
2598
+ await this.delete(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE_RECORD_BY_ID(entityId, recordId), { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
2502
2599
  }
2503
2600
  /**
2504
- * Gets all entities in the system
2601
+ * Gets entities in the tenant.
2505
2602
  *
2603
+ * Three call modes:
2604
+ * - `getAll()` — default. Returns only tenant-level entities.
2605
+ * - `getAll({ folderKey: "<uuid>" })` — preferred for folder-scoped data. Returns only entities in that folder.
2606
+ * - `getAll({ includeFolderEntities: true })` — returns tenant-level **and** folder-level entities together. `folderKey` is preferred over `includeFolderEntities` when both are set.
2607
+ *
2608
+ * @param options - Optional {@link EntityGetAllOptions} (`folderKey` to list a single folder's entities — preferred when scoping to a folder; `includeFolderEntities: true` to list tenant + folder entities together) The `folderKey` property is **experimental**.
2506
2609
  * @returns Promise resolving to an array of entity metadata
2507
2610
  *
2508
2611
  * @example
@@ -2511,15 +2614,29 @@ class EntityService extends BaseService {
2511
2614
  *
2512
2615
  * const entities = new Entities(sdk);
2513
2616
  *
2514
- * // Get all entities
2515
- * const allEntities = await entities.getAll();
2617
+ * // Tenant-only (default)
2618
+ * const tenantEntities = await entities.getAll();
2619
+ *
2620
+ * // A single folder's entities (preferred when targeting a specific folder)
2621
+ * const folderEntities = await entities.getAll({ folderKey: "<folderKey>" });
2622
+ *
2623
+ * // Tenant + folder entities together
2624
+ * const allEntities = await entities.getAll({ includeFolderEntities: true });
2516
2625
  *
2517
2626
  * // Call operations on an entity
2518
- * const records = await allEntities[0].getAllRecords();
2627
+ * const records = await tenantEntities[0].getAllRecords();
2519
2628
  * ```
2520
2629
  */
2521
- async getAll() {
2522
- const response = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_ALL);
2630
+ async getAll(options) {
2631
+ // folderKey is preferred over includeFolderEntities: when present, scope to that folder
2632
+ // via the v1 endpoint + header. Only when no folderKey is given AND includeFolderEntities
2633
+ // is explicitly true does the SDK switch to the v2 endpoint (returns tenant + folder
2634
+ // entities together). Default (no options or includeFolderEntities omitted) stays on
2635
+ // the v1 endpoint = tenant only.
2636
+ const endpoint = !options?.folderKey && options?.includeFolderEntities
2637
+ ? DATA_FABRIC_ENDPOINTS.ENTITY.GET_ALL_V2
2638
+ : DATA_FABRIC_ENDPOINTS.ENTITY.GET_ALL;
2639
+ const response = await this.get(endpoint, { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
2523
2640
  // Apply transformations
2524
2641
  const entities = response.data.map(entity => {
2525
2642
  // Transform each entity
@@ -2534,7 +2651,7 @@ class EntityService extends BaseService {
2534
2651
  * Queries entity records with filters, sorting, aggregates, and pagination
2535
2652
  *
2536
2653
  * @param id - UUID of the entity
2537
- * @param options - Query options including filterGroup, selectedFields, sortOptions, aggregates, groupBy, and pagination
2654
+ * @param options - Query options including filterGroup, selectedFields, sortOptions, aggregates, groupBy, and pagination The `folderKey` property is **experimental**.
2538
2655
  * @returns Promise resolving to {@link NonPaginatedResponse} without pagination options,
2539
2656
  * or {@link PaginatedResponse} when `pageSize`, `cursor`, or `jumpToPage` are provided
2540
2657
  *
@@ -2581,13 +2698,24 @@ class EntityService extends BaseService {
2581
2698
  * { function: EntityAggregateFunction.Avg, field: "amount", alias: "avgAmount" },
2582
2699
  * ],
2583
2700
  * });
2701
+ *
2702
+ * // Folder-scoped entity: pass the entity's folder key
2703
+ * await entities.queryRecordsById("<entityId>", {
2704
+ * filterGroup: { queryFilters: [{ fieldName: "status", operator: QueryFilterOperator.Equals, value: "active" }] },
2705
+ * folderKey: "<folderKey>",
2706
+ * });
2584
2707
  * ```
2585
2708
  */
2586
2709
  async queryRecordsById(id, options) {
2710
+ // folderKey is header-only; expansionLevel must be sent as a query param by PaginationHelpers.
2711
+ const { folderKey, expansionLevel, ...rest } = options ?? {};
2712
+ const downstreamOptions = options === undefined ? undefined : rest;
2587
2713
  return PaginationHelpers.getAll({
2588
2714
  serviceAccess: this.createPaginationServiceAccess(),
2589
2715
  getEndpoint: () => DATA_FABRIC_ENDPOINTS.ENTITY.QUERY_BY_ID(id),
2590
2716
  method: HTTP_METHODS.POST,
2717
+ headers: createHeaders({ [FOLDER_KEY]: folderKey }),
2718
+ queryParams: createParams({ expansionLevel }),
2591
2719
  pagination: {
2592
2720
  paginationType: PaginationType.OFFSET,
2593
2721
  itemsField: ENTITY_PAGINATION.ITEMS_FIELD,
@@ -2598,14 +2726,15 @@ class EntityService extends BaseService {
2598
2726
  countParam: ENTITY_OFFSET_PARAMS.COUNT_PARAM
2599
2727
  }
2600
2728
  },
2601
- excludeFromPrefix: ['expansionLevel', 'filterGroup', 'selectedFields', 'sortOptions', 'aggregates', 'groupBy']
2602
- }, options);
2729
+ excludeFromPrefix: ['filterGroup', 'selectedFields', 'sortOptions', 'aggregates', 'groupBy']
2730
+ }, downstreamOptions);
2603
2731
  }
2604
2732
  /**
2605
2733
  * Imports records from a CSV file into an entity
2606
2734
  *
2607
2735
  * @param id - UUID of the entity
2608
2736
  * @param file - CSV file to import (Blob, File, or Uint8Array)
2737
+ * @param options - Optional {@link EntityImportRecordsByIdOptions} (e.g. `folderKey` for folder-scoped entities) The `folderKey` property is **experimental**.
2609
2738
  * @returns Promise resolving to import result with record counts
2610
2739
  *
2611
2740
  * @example
@@ -2626,10 +2755,12 @@ class EntityService extends BaseService {
2626
2755
  * if (result.errorFileLink) {
2627
2756
  * console.log(`Error file link: ${result.errorFileLink}`);
2628
2757
  * }
2758
+ *
2759
+ * // Folder-scoped entity: pass the entity's folder key
2760
+ * await entities.importRecordsById("<entityId>", fileInput.files[0], { folderKey: "<folderKey>" });
2629
2761
  * ```
2630
- * @internal
2631
2762
  */
2632
- async importRecordsById(id, file) {
2763
+ async importRecordsById(id, file, options) {
2633
2764
  const formData = new FormData();
2634
2765
  if (file instanceof Uint8Array) {
2635
2766
  formData.append('file', new Blob([file.buffer]));
@@ -2637,7 +2768,7 @@ class EntityService extends BaseService {
2637
2768
  else {
2638
2769
  formData.append('file', file);
2639
2770
  }
2640
- const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.BULK_UPLOAD_BY_ID(id), formData);
2771
+ const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.BULK_UPLOAD_BY_ID(id), formData, { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
2641
2772
  return response.data;
2642
2773
  }
2643
2774
  /**
@@ -2646,6 +2777,7 @@ class EntityService extends BaseService {
2646
2777
  * @param entityId - UUID of the entity
2647
2778
  * @param recordId - UUID of the record containing the attachment
2648
2779
  * @param fieldName - Name of the File-type field containing the attachment
2780
+ * @param options - Optional {@link EntityDownloadAttachmentOptions} (e.g. `folderKey` for folder-scoped entities) The `folderKey` property is **experimental**.
2649
2781
  * @returns Promise resolving to Blob containing the file content
2650
2782
  *
2651
2783
  * @example
@@ -2664,11 +2796,15 @@ class EntityService extends BaseService {
2664
2796
  *
2665
2797
  * // Download attachment for a specific record and field
2666
2798
  * const blob = await entities.downloadAttachment(entityId, recordId, 'Documents');
2799
+ *
2800
+ * // Folder-scoped: pass the entity's folder key
2801
+ * const blob = await entities.downloadAttachment(entityId, recordId, 'Documents', { folderKey: "<folderKey>" });
2667
2802
  * ```
2668
2803
  */
2669
- async downloadAttachment(entityId, recordId, fieldName) {
2804
+ async downloadAttachment(entityId, recordId, fieldName, options) {
2670
2805
  const response = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.DOWNLOAD_ATTACHMENT(entityId, recordId, fieldName), {
2671
- responseType: RESPONSE_TYPES.BLOB
2806
+ responseType: RESPONSE_TYPES.BLOB,
2807
+ headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }),
2672
2808
  });
2673
2809
  return response.data;
2674
2810
  }
@@ -2679,7 +2815,7 @@ class EntityService extends BaseService {
2679
2815
  * @param recordId - UUID of the record to upload the attachment to
2680
2816
  * @param fieldName - Name of the File-type field
2681
2817
  * @param file - File to upload (Blob, File, or Uint8Array)
2682
- * @param options - Optional {@link EntityUploadAttachmentOptions} (e.g. expansionLevel)
2818
+ * @param options - Optional {@link EntityUploadAttachmentOptions} (e.g. `expansionLevel`, `folderKey` for folder-scoped entities) The `folderKey` property is **experimental**.
2683
2819
  * @returns Promise resolving to {@link EntityUploadAttachmentResponse}
2684
2820
  *
2685
2821
  * @example
@@ -2698,6 +2834,9 @@ class EntityService extends BaseService {
2698
2834
  *
2699
2835
  * // Upload a file attachment
2700
2836
  * const response = await entities.uploadAttachment(entityId, recordId, 'Documents', file);
2837
+ *
2838
+ * // Folder-scoped entity: pass the entity's folder key
2839
+ * await entities.uploadAttachment(entityId, recordId, 'Documents', file, { folderKey: "<folderKey>" });
2701
2840
  * ```
2702
2841
  */
2703
2842
  async uploadAttachment(entityId, recordId, fieldName, file, options) {
@@ -2709,7 +2848,10 @@ class EntityService extends BaseService {
2709
2848
  formData.append('file', file);
2710
2849
  }
2711
2850
  const params = createParams({ expansionLevel: options?.expansionLevel });
2712
- const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPLOAD_ATTACHMENT(entityId, recordId, fieldName), formData, { params });
2851
+ const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPLOAD_ATTACHMENT(entityId, recordId, fieldName), formData, {
2852
+ params,
2853
+ headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }),
2854
+ });
2713
2855
  return response.data;
2714
2856
  }
2715
2857
  /**
@@ -2718,6 +2860,7 @@ class EntityService extends BaseService {
2718
2860
  * @param entityId - UUID of the entity
2719
2861
  * @param recordId - UUID of the record containing the attachment
2720
2862
  * @param fieldName - Name of the File-type field containing the attachment
2863
+ * @param options - Optional {@link EntityDeleteAttachmentOptions} (e.g. `folderKey` for folder-scoped entities) The `folderKey` property is **experimental**.
2721
2864
  * @returns Promise resolving to {@link EntityDeleteAttachmentResponse}
2722
2865
  *
2723
2866
  * @example
@@ -2736,10 +2879,13 @@ class EntityService extends BaseService {
2736
2879
  *
2737
2880
  * // Delete attachment for a specific record and field
2738
2881
  * await entities.deleteAttachment(entityId, recordId, 'Documents');
2882
+ *
2883
+ * // Folder-scoped: pass the entity's folder key
2884
+ * await entities.deleteAttachment(entityId, recordId, 'Documents', { folderKey: "<folderKey>" });
2739
2885
  * ```
2740
2886
  */
2741
- async deleteAttachment(entityId, recordId, fieldName) {
2742
- const response = await this.delete(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE_ATTACHMENT(entityId, recordId, fieldName));
2887
+ async deleteAttachment(entityId, recordId, fieldName, options) {
2888
+ const response = await this.delete(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE_ATTACHMENT(entityId, recordId, fieldName), { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
2743
2889
  return response.data;
2744
2890
  }
2745
2891
  /**
@@ -2769,7 +2915,7 @@ class EntityService extends BaseService {
2769
2915
  * @param name - Entity name — must start with a letter and contain
2770
2916
  * only letters, numbers, and underscores (e.g., `"productCatalog"`).
2771
2917
  * @param fields - Array of field definitions
2772
- * @param options - Optional entity-level settings ({@link EntityCreateOptions})
2918
+ * @param options - Optional entity-level settings ({@link EntityCreateOptions}) The `folderKey` property is **experimental**.
2773
2919
  * @returns Promise resolving to the ID of the created entity
2774
2920
  *
2775
2921
  * @example
@@ -2785,40 +2931,63 @@ class EntityService extends BaseService {
2785
2931
  * { fieldName: "price", type: EntityFieldDataType.DECIMAL, decimalPrecision: 4, maxValue: 999999, minValue: 0 },
2786
2932
  * { fieldName: "quantity", type: EntityFieldDataType.INTEGER, maxValue: 10000, minValue: 1, defaultValue: "0" },
2787
2933
  * ]);
2934
+ *
2935
+ * // Cross-folder references — link a folder-scoped entity to entities and
2936
+ * // system choice sets that live in another folder or at the tenant level.
2937
+ * await entities.create("orderLine", [
2938
+ * {
2939
+ * fieldName: "order",
2940
+ * type: EntityFieldDataType.RELATIONSHIP,
2941
+ * referenceEntityId: "<orderEntityId>",
2942
+ * referenceFieldId: "<orderEntityPkId>",
2943
+ * referenceFolderKey: "<otherFolderKey>", // target lives in a different folder
2944
+ * },
2945
+ * {
2946
+ * fieldName: "userType",
2947
+ * type: EntityFieldDataType.CHOICE_SET_SINGLE,
2948
+ * choiceSetId: "<systemUserTypeChoiceSetId>", // tenant-level system choice set
2949
+ * // referenceFolderKey omitted → SDK looks up the target at tenant scope
2950
+ * },
2951
+ * ], { folderKey: "<sourceFolderKey>" });
2788
2952
  * ```
2789
2953
  * @internal
2790
2954
  */
2791
2955
  async create(name, fields, options) {
2792
2956
  const opts = options ?? {};
2957
+ const fieldPayloads = await this.buildFieldsWithReferenceMeta(fields);
2793
2958
  const payload = {
2794
2959
  ...(opts.description !== undefined && { description: opts.description }),
2795
2960
  displayName: opts.displayName ?? name,
2796
2961
  entityDefinition: {
2797
2962
  name,
2798
- fields: fields.map(f => this.buildSchemaFieldPayload(f)),
2963
+ fields: fieldPayloads,
2799
2964
  folderId: opts.folderKey ?? DATA_FABRIC_TENANT_FOLDER_ID,
2800
2965
  isRbacEnabled: opts.isRbacEnabled ?? false,
2801
2966
  isInsightsEnabled: opts.isAnalyticsEnabled ?? false,
2802
2967
  externalFields: opts.externalFields ?? [],
2803
2968
  },
2804
2969
  };
2805
- const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPSERT, payload);
2970
+ const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPSERT, payload, { headers: createHeaders({ [FOLDER_KEY]: opts.folderKey }) });
2806
2971
  return response.data;
2807
2972
  }
2808
2973
  /**
2809
2974
  * Deletes a Data Fabric entity and all its records
2810
2975
  *
2811
2976
  * @param id - UUID of the entity to delete
2977
+ * @param options - Optional {@link EntityDeleteByIdOptions} (e.g. `folderKey` for folder-scoped entities) The `folderKey` property is **experimental**.
2812
2978
  * @returns Promise resolving when the entity is deleted
2813
2979
  *
2814
2980
  * @example
2815
2981
  * ```typescript
2816
2982
  * await entities.deleteById("<entityId>");
2983
+ *
2984
+ * // Folder-scoped: pass the entity's folder key
2985
+ * await entities.deleteById("<entityId>", { folderKey: "<folderKey>" });
2817
2986
  * ```
2818
2987
  * @internal
2819
2988
  */
2820
- async deleteById(id) {
2821
- await this.delete(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE(id));
2989
+ async deleteById(id, options) {
2990
+ await this.delete(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE(id), { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
2822
2991
  }
2823
2992
  /**
2824
2993
  * Updates an existing Data Fabric entity — schema and/or metadata.
@@ -2832,7 +3001,7 @@ class EntityService extends BaseService {
2832
3001
  * overwrite each other's changes.
2833
3002
  *
2834
3003
  * @param id - UUID of the entity to update
2835
- * @param options - Changes to apply ({@link EntityUpdateByIdOptions})
3004
+ * @param options - Changes to apply ({@link EntityUpdateByIdOptions}) The `folderKey` property is **experimental**.
2836
3005
  * @returns Promise resolving when the update is complete
2837
3006
  *
2838
3007
  * @example
@@ -2865,6 +3034,12 @@ class EntityService extends BaseService {
2865
3034
  * { id: "<fieldId>", lengthLimit: 1000 },
2866
3035
  * ],
2867
3036
  * });
3037
+ *
3038
+ * // Folder-scoped entity: add a field to an entity that lives in a non-tenant folder
3039
+ * await entities.updateById("<entityId>", {
3040
+ * folderKey: "<folderKey>",
3041
+ * addFields: [{ fieldName: "notes", type: EntityFieldDataType.MULTILINE_TEXT }],
3042
+ * });
2868
3043
  * ```
2869
3044
  * @internal
2870
3045
  */
@@ -2880,7 +3055,7 @@ class EntityService extends BaseService {
2880
3055
  ...(opts.displayName !== undefined && { displayName: opts.displayName }),
2881
3056
  ...(opts.description !== undefined && { description: opts.description }),
2882
3057
  ...(opts.isRbacEnabled !== undefined && { isRbacEnabled: opts.isRbacEnabled }),
2883
- });
3058
+ }, { headers: createHeaders({ [FOLDER_KEY]: opts.folderKey }) });
2884
3059
  }
2885
3060
  }
2886
3061
  /**
@@ -2891,7 +3066,8 @@ class EntityService extends BaseService {
2891
3066
  * @private
2892
3067
  */
2893
3068
  async applySchemaUpdate(entityId, options) {
2894
- const entityResponse = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_BY_ID(entityId));
3069
+ const folderHeaders = createHeaders({ [FOLDER_KEY]: options.folderKey });
3070
+ const entityResponse = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_BY_ID(entityId), { headers: folderHeaders });
2895
3071
  const raw = entityResponse.data;
2896
3072
  // Carry forward existing non-system fields from GET response (skip system/primary-key fields)
2897
3073
  let fields = (raw.fields ?? [])
@@ -2937,10 +3113,9 @@ class EntityService extends BaseService {
2937
3113
  };
2938
3114
  });
2939
3115
  }
2940
- // Build and append new fields
2941
3116
  const newFields = [];
2942
3117
  if (options.addFields?.length) {
2943
- newFields.push(...options.addFields.map(f => this.buildSchemaFieldPayload(f)));
3118
+ newFields.push(...await this.buildFieldsWithReferenceMeta(options.addFields));
2944
3119
  }
2945
3120
  await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPSERT, {
2946
3121
  displayName: raw.displayName,
@@ -2954,7 +3129,7 @@ class EntityService extends BaseService {
2954
3129
  isInsightsEnabled: raw.isInsightsEnabled ?? false,
2955
3130
  externalFields: raw.externalFields ?? [],
2956
3131
  },
2957
- });
3132
+ }, { headers: folderHeaders });
2958
3133
  }
2959
3134
  /**
2960
3135
  * Orchestrates all field mapping transformations
@@ -3038,8 +3213,39 @@ class EntityService extends BaseService {
3038
3213
  return externalSource;
3039
3214
  });
3040
3215
  }
3216
+ async buildFieldsWithReferenceMeta(fields) {
3217
+ const metas = await Promise.all(fields.map(f => this.buildReferenceMeta(f)));
3218
+ return fields.map((f, i) => this.buildSchemaFieldPayload(f, metas[i]));
3219
+ }
3220
+ // Choice-set targets resolve server-side by NAME (the API rejects cross-folder
3221
+ // refs with empty target name even when folderId is supplied), so the SDK
3222
+ // fetches the name once for each cross-folder choice-set field. Relationship
3223
+ // targets resolve by folderId — no lookup needed.
3224
+ async buildReferenceMeta(field) {
3225
+ if (field.referenceFolderKey === undefined)
3226
+ return undefined;
3227
+ if (field.referenceEntityId === undefined && field.choiceSetId === undefined)
3228
+ return undefined;
3229
+ const folderId = field.referenceFolderKey;
3230
+ const meta = {};
3231
+ if (field.referenceEntityId !== undefined) {
3232
+ meta.referenceEntity = { id: field.referenceEntityId, folderId };
3233
+ }
3234
+ if (field.choiceSetId !== undefined) {
3235
+ const lookupFolderKey = folderId === DATA_FABRIC_TENANT_FOLDER_ID ? undefined : folderId;
3236
+ const target = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_BY_ID(field.choiceSetId), { headers: createHeaders({ [FOLDER_KEY]: lookupFolderKey }) });
3237
+ meta.referenceChoiceSet = {
3238
+ id: field.choiceSetId,
3239
+ name: target.data.name,
3240
+ folderId,
3241
+ entityType: EntityType.ChoiceSet,
3242
+ entityTypeId: ENTITY_TYPE_IDS[EntityType.ChoiceSet],
3243
+ };
3244
+ }
3245
+ return meta;
3246
+ }
3041
3247
  /** Converts a user-facing EntityCreateFieldOptions to the raw API field payload */
3042
- buildSchemaFieldPayload(field) {
3248
+ buildSchemaFieldPayload(field, refMeta) {
3043
3249
  const fieldType = field.type ?? EntityFieldDataType.STRING;
3044
3250
  this.validateFieldConstraints(fieldType, field, field.fieldName);
3045
3251
  const isRelationship = fieldType === EntityFieldDataType.RELATIONSHIP;
@@ -3050,6 +3256,10 @@ class EntityService extends BaseService {
3050
3256
  });
3051
3257
  }
3052
3258
  const mapping = EntitySchemaFieldTypeMap[fieldType];
3259
+ // Prefer the resolved {id, name, folderId} body so cross-folder targets resolve
3260
+ // server-side; fall back to a bare {id} when no meta was fetched.
3261
+ const referenceEntityBody = refMeta?.referenceEntity ?? (field.referenceEntityId === undefined ? undefined : { id: field.referenceEntityId });
3262
+ const referenceChoiceSetBody = refMeta?.referenceChoiceSet;
3053
3263
  return {
3054
3264
  name: field.fieldName,
3055
3265
  displayName: field.displayName ?? field.fieldName,
@@ -3068,7 +3278,8 @@ class EntityService extends BaseService {
3068
3278
  ...(field.choiceSetId !== undefined && { choiceSetId: field.choiceSetId }),
3069
3279
  ...((isRelationship || isFile) && { isForeignKey: true }),
3070
3280
  ...(isRelationship && { referenceType: ReferenceType.ManyToOne }),
3071
- ...(field.referenceEntityId !== undefined && { referenceEntity: { id: field.referenceEntityId } }),
3281
+ ...(referenceEntityBody !== undefined && { referenceEntity: referenceEntityBody }),
3282
+ ...(referenceChoiceSetBody !== undefined && { referenceChoiceSet: referenceChoiceSetBody }),
3072
3283
  ...(field.referenceFieldId !== undefined && { referenceField: { id: field.referenceFieldId } }),
3073
3284
  };
3074
3285
  }
@@ -3231,8 +3442,14 @@ __decorate([
3231
3442
 
3232
3443
  class ChoiceSetService extends BaseService {
3233
3444
  /**
3234
- * Gets all choice sets in the system
3445
+ * Gets choice sets in the tenant.
3446
+ *
3447
+ * Three call modes:
3448
+ * - `getAll()` — default. Returns only tenant-level choice sets.
3449
+ * - `getAll({ folderKey: "<uuid>" })` — preferred for folder-scoped data. Returns only choice sets in that folder.
3450
+ * - `getAll({ includeFolderChoiceSets: true })` — returns tenant-level **and** folder-level choice sets together. `folderKey` is preferred over `includeFolderChoiceSets` when both are set.
3235
3451
  *
3452
+ * @param options - Optional {@link ChoiceSetGetAllOptions} (`folderKey` to list a single folder's choice sets — preferred when scoping to a folder; `includeFolderChoiceSets: true` to list tenant + folder choice sets together) The `folderKey` property is **experimental**.
3236
3453
  * @returns Promise resolving to an array of choice set metadata
3237
3454
  *
3238
3455
  * @example
@@ -3241,18 +3458,33 @@ class ChoiceSetService extends BaseService {
3241
3458
  *
3242
3459
  * const choiceSets = new ChoiceSets(sdk);
3243
3460
  *
3244
- * // Get all choice sets
3245
- * const allChoiceSets = await choiceSets.getAll();
3461
+ * // Tenant-only (default)
3462
+ * const tenantChoiceSets = await choiceSets.getAll();
3246
3463
  *
3247
- * // Iterate through choice sets
3248
- * allChoiceSets.forEach(choiceSet => {
3249
- * console.log(`ChoiceSet: ${choiceSet.displayName} (${choiceSet.name})`);
3250
- * console.log(`Description: ${choiceSet.description}`);
3251
- * });
3464
+ * // A single folder's choice sets (preferred when targeting a specific folder)
3465
+ * const folderChoiceSets = await choiceSets.getAll({ folderKey: "<folderKey>" });
3466
+ *
3467
+ * // Tenant + folder choice sets together
3468
+ * const allChoiceSets = await choiceSets.getAll({ includeFolderChoiceSets: true });
3252
3469
  * ```
3253
3470
  */
3254
- async getAll() {
3255
- const rawResponse = await this.get(DATA_FABRIC_ENDPOINTS.CHOICESETS.GET_ALL);
3471
+ async getAll(options) {
3472
+ return this.fetchAllChoiceSets(options);
3473
+ }
3474
+ /**
3475
+ * Internal helper that performs the choice-set fetch. Kept separate from the
3476
+ * public `getAll()` so that internal callers (e.g. `resolveChoiceSetName`)
3477
+ * can reuse it without triggering double `@track` telemetry.
3478
+ */
3479
+ async fetchAllChoiceSets(options) {
3480
+ // The choice-set endpoint returns cross-scope results when called without
3481
+ // a folder header. To stay tenant-only by default, send the tenant-marker
3482
+ // UUID as the folder key unless the caller explicitly opts into cross-scope
3483
+ // via includeFolderChoiceSets: true. folderKey is preferred over
3484
+ // includeFolderChoiceSets when both are set.
3485
+ const folderKey = options?.folderKey
3486
+ ?? (options?.includeFolderChoiceSets ? undefined : DATA_FABRIC_TENANT_FOLDER_ID);
3487
+ const rawResponse = await this.get(DATA_FABRIC_ENDPOINTS.CHOICESETS.GET_ALL, { headers: createHeaders({ [FOLDER_KEY]: folderKey }) });
3256
3488
  // Transform field names
3257
3489
  const data = rawResponse.data || [];
3258
3490
  return data.map(choiceSet => transformData(choiceSet, EntityMap));
@@ -3265,7 +3497,7 @@ class ChoiceSetService extends BaseService {
3265
3497
  * - A PaginatedResponse with navigation cursors (when any pagination parameter is provided)
3266
3498
  *
3267
3499
  * @param choiceSetId - UUID of the choice set
3268
- * @param options - Pagination options
3500
+ * @param options - Pagination options and optional `folderKey` for folder-scoped choice sets The `folderKey` property is **experimental**.
3269
3501
  * @returns Promise resolving to choice set values or paginated result
3270
3502
  *
3271
3503
  * @example
@@ -3294,6 +3526,9 @@ class ChoiceSetService extends BaseService {
3294
3526
  * if (page1.hasNextPage) {
3295
3527
  * const page2 = await choiceSets.getById(choiceSetId, { cursor: page1.nextCursor });
3296
3528
  * }
3529
+ *
3530
+ * // Folder-scoped choice set
3531
+ * const folderValues = await choiceSets.getById(choiceSetId, { folderKey: "<folderKey>" });
3297
3532
  * ```
3298
3533
  */
3299
3534
  async getById(choiceSetId, options) {
@@ -3302,11 +3537,16 @@ class ChoiceSetService extends BaseService {
3302
3537
  const camelCased = pascalToCamelCaseKeys(item);
3303
3538
  return transformData(camelCased, EntityMap);
3304
3539
  };
3540
+ // folderKey is header-only — destructure it out so PaginationHelpers doesn't
3541
+ // include it in the POST body alongside pagination params.
3542
+ const { folderKey, ...rest } = options ?? {};
3543
+ const downstreamOptions = options === undefined ? undefined : rest;
3305
3544
  return PaginationHelpers.getAll({
3306
3545
  serviceAccess: this.createPaginationServiceAccess(),
3307
3546
  getEndpoint: () => DATA_FABRIC_ENDPOINTS.CHOICESETS.GET_BY_ID(choiceSetId),
3308
3547
  transformFn,
3309
3548
  method: HTTP_METHODS.POST,
3549
+ headers: createHeaders({ [FOLDER_KEY]: folderKey }),
3310
3550
  pagination: {
3311
3551
  paginationType: PaginationType.OFFSET,
3312
3552
  itemsField: CHOICESET_VALUES_PAGINATION.ITEMS_FIELD,
@@ -3317,7 +3557,7 @@ class ChoiceSetService extends BaseService {
3317
3557
  countParam: ENTITY_OFFSET_PARAMS.COUNT_PARAM
3318
3558
  }
3319
3559
  }
3320
- }, options);
3560
+ }, downstreamOptions);
3321
3561
  }
3322
3562
  /**
3323
3563
  * Creates a new Data Fabric choice set
@@ -3325,7 +3565,7 @@ class ChoiceSetService extends BaseService {
3325
3565
  * @param name - Choice set name. Must start with a
3326
3566
  * letter, may contain only letters, numbers, and underscores, length
3327
3567
  * 3–100 characters (e.g., `"expenseTypes"`).
3328
- * @param options - Optional choice-set-level settings ({@link ChoiceSetCreateOptions})
3568
+ * @param options - Optional choice-set-level settings ({@link ChoiceSetCreateOptions}) The `folderKey` property is **experimental**.
3329
3569
  * @returns Promise resolving to the UUID of the created choice set
3330
3570
  *
3331
3571
  * @example
@@ -3356,7 +3596,7 @@ class ChoiceSetService extends BaseService {
3356
3596
  folderId: opts.folderKey ?? DATA_FABRIC_TENANT_FOLDER_ID,
3357
3597
  },
3358
3598
  };
3359
- const response = await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.CREATE, payload);
3599
+ const response = await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.CREATE, payload, { headers: createHeaders({ [FOLDER_KEY]: opts.folderKey }) });
3360
3600
  return response.data;
3361
3601
  }
3362
3602
  /**
@@ -3366,7 +3606,7 @@ class ChoiceSetService extends BaseService {
3366
3606
  * the call throws `ValidationError` if both are omitted.
3367
3607
  *
3368
3608
  * @param choiceSetId - UUID of the choice set to update
3369
- * @param options - Metadata fields to change ({@link ChoiceSetUpdateOptions})
3609
+ * @param options - Metadata fields to change ({@link ChoiceSetUpdateOptions}) The `folderKey` property is **experimental**.
3370
3610
  * @returns Promise resolving when the update is complete
3371
3611
  *
3372
3612
  * @example
@@ -3391,12 +3631,13 @@ class ChoiceSetService extends BaseService {
3391
3631
  await this.patch(DATA_FABRIC_ENDPOINTS.CHOICESETS.UPDATE(choiceSetId), {
3392
3632
  ...(options.displayName !== undefined && { displayName: options.displayName }),
3393
3633
  ...(options.description !== undefined && { description: options.description }),
3394
- });
3634
+ }, { headers: createHeaders({ [FOLDER_KEY]: options.folderKey }) });
3395
3635
  }
3396
3636
  /**
3397
3637
  * Deletes a Data Fabric choice set and all its values.
3398
3638
  *
3399
3639
  * @param choiceSetId - UUID of the choice set to delete
3640
+ * @param options - Optional {@link ChoiceSetDeleteByIdOptions} (e.g. `folderKey` for folder-scoped choice sets) The `folderKey` property is **experimental**.
3400
3641
  * @returns Promise resolving when the choice set is deleted
3401
3642
  *
3402
3643
  * @example
@@ -3406,18 +3647,21 @@ class ChoiceSetService extends BaseService {
3406
3647
  * const expenseTypes = allChoiceSets.find(cs => cs.name === 'expense_types');
3407
3648
  *
3408
3649
  * await choicesets.deleteById(expenseTypes.id);
3650
+ *
3651
+ * // Folder-scoped choice set
3652
+ * await choicesets.deleteById(expenseTypes.id, { folderKey: "<folderKey>" });
3409
3653
  * ```
3410
3654
  * @internal
3411
3655
  */
3412
- async deleteById(choiceSetId) {
3413
- await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.DELETE(choiceSetId), {});
3656
+ async deleteById(choiceSetId, options) {
3657
+ await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.DELETE(choiceSetId), {}, { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
3414
3658
  }
3415
3659
  /**
3416
3660
  * Inserts a single value into a choice set.
3417
3661
  *
3418
3662
  * @param choiceSetId - UUID of the parent choice set
3419
3663
  * @param name - Identifier name of the new value (e.g., `"TRAVEL"`)
3420
- * @param options - Optional fields ({@link ChoiceSetValueInsertOptions})
3664
+ * @param options - Optional fields ({@link ChoiceSetValueInsertOptions}) The `folderKey` property is **experimental**.
3421
3665
  * @returns Promise resolving to the inserted value ({@link ChoiceSetValueInsertResponse})
3422
3666
  *
3423
3667
  * @example
@@ -3430,16 +3674,22 @@ class ChoiceSetService extends BaseService {
3430
3674
  * displayName: 'Travel',
3431
3675
  * });
3432
3676
  * console.log(inserted.id);
3677
+ *
3678
+ * // Folder-scoped choice set: folderKey is required on the wire
3679
+ * await choicesets.insertValueById(expenseTypes.id, 'TRAVEL', {
3680
+ * displayName: 'Travel',
3681
+ * folderKey: "<folderKey>",
3682
+ * });
3433
3683
  * ```
3434
3684
  * @internal
3435
3685
  */
3436
3686
  async insertValueById(choiceSetId, name, options) {
3437
- const choiceSetName = await this.resolveChoiceSetName(choiceSetId);
3687
+ const choiceSetName = await this.resolveChoiceSetName(choiceSetId, options?.folderKey);
3438
3688
  const payload = {
3439
3689
  Name: name,
3440
3690
  ...(options?.displayName !== undefined && { DisplayName: options.displayName }),
3441
3691
  };
3442
- const response = await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.INSERT_BY_NAME(choiceSetName), payload);
3692
+ const response = await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.INSERT_BY_NAME(choiceSetName), payload, { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
3443
3693
  const camelCased = pascalToCamelCaseKeys(response.data);
3444
3694
  return transformData(camelCased, EntityMap);
3445
3695
  }
@@ -3452,6 +3702,7 @@ class ChoiceSetService extends BaseService {
3452
3702
  * @param choiceSetId - UUID of the parent choice set
3453
3703
  * @param valueId - UUID of the value to update
3454
3704
  * @param displayName - New human-readable display name for the value
3705
+ * @param options - Optional {@link ChoiceSetValueUpdateOptions} — pass `folderKey` for folder-scoped choice sets; omit for tenant-level. The `folderKey` property is **experimental**.
3455
3706
  * @returns Promise resolving to the updated value ({@link ChoiceSetValueUpdateResponse})
3456
3707
  *
3457
3708
  * @example
@@ -3463,13 +3714,18 @@ class ChoiceSetService extends BaseService {
3463
3714
  * const travel = values.items.find(v => v.name === 'TRAVEL');
3464
3715
  *
3465
3716
  * await choicesets.updateValueById(expenseTypes.id, travel.id, 'Business Travel');
3717
+ *
3718
+ * // Folder-scoped choice set: folderKey is required on the wire
3719
+ * await choicesets.updateValueById(expenseTypes.id, travel.id, 'Business Travel', {
3720
+ * folderKey: "<folderKey>",
3721
+ * });
3466
3722
  * ```
3467
3723
  * @internal
3468
3724
  */
3469
- async updateValueById(choiceSetId, valueId, displayName) {
3470
- const choiceSetName = await this.resolveChoiceSetName(choiceSetId);
3725
+ async updateValueById(choiceSetId, valueId, displayName, options) {
3726
+ const choiceSetName = await this.resolveChoiceSetName(choiceSetId, options?.folderKey);
3471
3727
  const payload = { DisplayName: displayName };
3472
- const response = await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.UPDATE_BY_NAME(choiceSetName, valueId), payload);
3728
+ const response = await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.UPDATE_BY_NAME(choiceSetName, valueId), payload, { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
3473
3729
  const camelCased = pascalToCamelCaseKeys(response.data);
3474
3730
  return transformData(camelCased, EntityMap);
3475
3731
  }
@@ -3478,6 +3734,7 @@ class ChoiceSetService extends BaseService {
3478
3734
  *
3479
3735
  * @param choiceSetId - UUID of the parent choice set
3480
3736
  * @param valueIds - Array of value UUIDs to delete
3737
+ * @param options - Optional {@link ChoiceSetValueDeleteOptions} (e.g. `folderKey` for folder-scoped choice sets) The `folderKey` property is **experimental**.
3481
3738
  * @returns Promise resolving when the values are deleted
3482
3739
  *
3483
3740
  * @example
@@ -3487,14 +3744,20 @@ class ChoiceSetService extends BaseService {
3487
3744
  * const idsToDelete = values.items.slice(0, 2).map(v => v.id);
3488
3745
  *
3489
3746
  * await choicesets.deleteValuesById('<choiceSetId>', idsToDelete);
3747
+ *
3748
+ * // Folder-scoped choice set
3749
+ * await choicesets.deleteValuesById('<choiceSetId>', idsToDelete, { folderKey: "<folderKey>" });
3490
3750
  * ```
3491
3751
  * @internal
3492
3752
  */
3493
- async deleteValuesById(choiceSetId, valueIds) {
3494
- await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.DELETE_BY_ID(choiceSetId), valueIds);
3753
+ async deleteValuesById(choiceSetId, valueIds, options) {
3754
+ await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.DELETE_BY_ID(choiceSetId), valueIds, { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
3495
3755
  }
3496
- async resolveChoiceSetName(choiceSetId) {
3497
- const all = await this.getAll();
3756
+ async resolveChoiceSetName(choiceSetId, folderKey) {
3757
+ // Use the un-tracked helper directly so we don't fire a duplicate
3758
+ // `Choicesets.GetAll` telemetry event for every insertValueById /
3759
+ // updateValueById call.
3760
+ const all = await this.fetchAllChoiceSets(folderKey === undefined ? undefined : { folderKey });
3498
3761
  const match = all.find(cs => cs.id === choiceSetId);
3499
3762
  if (!match) {
3500
3763
  throw new NotFoundError({ message: `Choice set with id '${choiceSetId}' not found.` });