@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.
- package/dist/agent-memory/index.cjs +1772 -0
- package/dist/agent-memory/index.d.ts +588 -0
- package/dist/agent-memory/index.mjs +1770 -0
- package/dist/agents/index.cjs +1995 -0
- package/dist/agents/index.d.ts +961 -0
- package/dist/agents/index.mjs +1993 -0
- package/dist/assets/index.cjs +171 -39
- package/dist/assets/index.d.ts +84 -5
- package/dist/assets/index.mjs +171 -39
- package/dist/attachments/index.cjs +53 -15
- package/dist/attachments/index.d.ts +1 -0
- package/dist/attachments/index.mjs +53 -15
- package/dist/buckets/index.cjs +151 -130
- package/dist/buckets/index.d.ts +198 -84
- package/dist/buckets/index.mjs +151 -130
- package/dist/cases/index.cjs +220 -23
- package/dist/cases/index.d.ts +148 -10
- package/dist/cases/index.mjs +220 -24
- package/dist/conversational-agent/index.cjs +140 -66
- package/dist/conversational-agent/index.d.ts +190 -122
- package/dist/conversational-agent/index.mjs +140 -66
- package/dist/core/index.cjs +445 -108
- package/dist/core/index.d.ts +15 -0
- package/dist/core/index.mjs +445 -108
- package/dist/entities/index.cjs +365 -102
- package/dist/entities/index.d.ts +446 -114
- package/dist/entities/index.mjs +365 -102
- package/dist/feedback/index.cjs +53 -15
- package/dist/feedback/index.d.ts +1 -0
- package/dist/feedback/index.mjs +53 -15
- package/dist/governance/index.cjs +1789 -0
- package/dist/governance/index.d.ts +598 -0
- package/dist/governance/index.mjs +1787 -0
- package/dist/index.cjs +1453 -444
- package/dist/index.d.ts +4150 -1742
- package/dist/index.mjs +1452 -445
- package/dist/index.umd.js +5035 -4009
- package/dist/jobs/index.cjs +53 -15
- package/dist/jobs/index.d.ts +1 -0
- package/dist/jobs/index.mjs +53 -15
- package/dist/maestro-processes/index.cjs +189 -27
- package/dist/maestro-processes/index.d.ts +131 -9
- package/dist/maestro-processes/index.mjs +189 -27
- package/dist/orchestrator-du-module/index.cjs +1788 -0
- package/dist/orchestrator-du-module/index.d.ts +757 -0
- package/dist/orchestrator-du-module/index.mjs +1785 -0
- package/dist/processes/index.cjs +53 -15
- package/dist/processes/index.d.ts +1 -0
- package/dist/processes/index.mjs +53 -15
- package/dist/queues/index.cjs +53 -15
- package/dist/queues/index.d.ts +1 -0
- package/dist/queues/index.mjs +53 -15
- package/dist/tasks/index.cjs +116 -19
- package/dist/tasks/index.d.ts +110 -4
- package/dist/tasks/index.mjs +117 -20
- package/dist/traces/index.cjs +340 -15
- package/dist/traces/index.d.ts +483 -2
- package/dist/traces/index.mjs +339 -16
- package/package.json +42 -2
package/dist/entities/index.mjs
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
},
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
* //
|
|
2515
|
-
* const
|
|
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
|
|
2627
|
+
* const records = await tenantEntities[0].getAllRecords();
|
|
2519
2628
|
* ```
|
|
2520
2629
|
*/
|
|
2521
|
-
async getAll() {
|
|
2522
|
-
|
|
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: ['
|
|
2602
|
-
},
|
|
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, {
|
|
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:
|
|
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
|
|
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(...
|
|
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
|
-
...(
|
|
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
|
|
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
|
-
* //
|
|
3245
|
-
* const
|
|
3461
|
+
* // Tenant-only (default)
|
|
3462
|
+
* const tenantChoiceSets = await choiceSets.getAll();
|
|
3246
3463
|
*
|
|
3247
|
-
* //
|
|
3248
|
-
*
|
|
3249
|
-
*
|
|
3250
|
-
*
|
|
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
|
-
|
|
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
|
-
},
|
|
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
|
-
|
|
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.` });
|