@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.cjs
CHANGED
|
@@ -505,6 +505,7 @@ class ErrorFactory {
|
|
|
505
505
|
}
|
|
506
506
|
}
|
|
507
507
|
|
|
508
|
+
const FOLDER_KEY = 'X-UIPATH-FolderKey';
|
|
508
509
|
const FOLDER_ID = 'X-UIPATH-OrganizationUnitId';
|
|
509
510
|
const TRACEPARENT = 'traceparent';
|
|
510
511
|
const UIPATH_TRACEPARENT_ID = 'x-uipath-traceparent-id';
|
|
@@ -719,6 +720,32 @@ function filterUndefined(obj) {
|
|
|
719
720
|
*/
|
|
720
721
|
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
721
722
|
isBrowser && window.self != window.top && window.location.href.includes('source=ActionCenter');
|
|
723
|
+
const _params = isBrowser ? new URLSearchParams(window.location.search) : null;
|
|
724
|
+
/**
|
|
725
|
+
* True when the coded app has been loaded inside a host frame that explicitly
|
|
726
|
+
* opted into token delegation by adding `?host=embed` to the iframe src URL.
|
|
727
|
+
*/
|
|
728
|
+
const isHostEmbedded = isBrowser && window.self !== window.top && _params?.get('host') === 'embed';
|
|
729
|
+
/**
|
|
730
|
+
* The validated parent origin, read from the `?basedomain=` query param set
|
|
731
|
+
* by the embedding host in the iframe src URL.
|
|
732
|
+
* Mirrors the same mechanism used by ActionCenterTokenManager.
|
|
733
|
+
* Non-null only when `?host=embed` is present and `?basedomain=` is a valid URL.
|
|
734
|
+
*/
|
|
735
|
+
(() => {
|
|
736
|
+
if (!isHostEmbedded)
|
|
737
|
+
return null;
|
|
738
|
+
const basedomain = _params?.get('basedomain');
|
|
739
|
+
if (!basedomain)
|
|
740
|
+
return null;
|
|
741
|
+
try {
|
|
742
|
+
return new URL(basedomain).origin;
|
|
743
|
+
}
|
|
744
|
+
catch {
|
|
745
|
+
console.warn('embeddingOrigin: basedomain query param is not a valid URL', basedomain);
|
|
746
|
+
return null;
|
|
747
|
+
}
|
|
748
|
+
})();
|
|
722
749
|
|
|
723
750
|
/**
|
|
724
751
|
* Base64 encoding/decoding
|
|
@@ -1251,12 +1278,18 @@ class PaginationHelpers {
|
|
|
1251
1278
|
* @returns Promise resolving to a paginated result
|
|
1252
1279
|
*/
|
|
1253
1280
|
static async getAllPaginated(params) {
|
|
1254
|
-
const { serviceAccess, getEndpoint, folderId, headers: providedHeaders, paginationParams, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
|
|
1281
|
+
const { serviceAccess, getEndpoint, folderId, headers: providedHeaders, paginationParams, additionalParams, queryParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
|
|
1255
1282
|
const endpoint = getEndpoint(folderId);
|
|
1256
1283
|
const headers = providedHeaders ?? (folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {});
|
|
1284
|
+
// On POST, the caller's options go in the body; queryParams stays in the URL.
|
|
1285
|
+
// On GET, everything is URL — queryParams merges with additionalParams.
|
|
1286
|
+
const isPost = method === HTTP_METHODS.POST;
|
|
1287
|
+
const requestSpec = isPost
|
|
1288
|
+
? { body: additionalParams, params: queryParams }
|
|
1289
|
+
: { params: { ...additionalParams, ...queryParams } };
|
|
1257
1290
|
const paginatedResponse = await serviceAccess.requestWithPagination(method, endpoint, paginationParams, {
|
|
1258
1291
|
headers,
|
|
1259
|
-
|
|
1292
|
+
...requestSpec,
|
|
1260
1293
|
pagination: {
|
|
1261
1294
|
paginationType: options.paginationType || PaginationType.OFFSET,
|
|
1262
1295
|
itemsField: options.itemsField || DEFAULT_ITEMS_FIELD,
|
|
@@ -1281,7 +1314,7 @@ class PaginationHelpers {
|
|
|
1281
1314
|
* @returns Promise resolving to an object with data and totalCount
|
|
1282
1315
|
*/
|
|
1283
1316
|
static async getAllNonPaginated(params) {
|
|
1284
|
-
const { serviceAccess, getAllEndpoint, getByFolderEndpoint, folderId, headers: providedHeaders, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
|
|
1317
|
+
const { serviceAccess, getAllEndpoint, getByFolderEndpoint, folderId, headers: providedHeaders, additionalParams, queryParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
|
|
1285
1318
|
// Set default field names
|
|
1286
1319
|
const itemsField = options.itemsField || DEFAULT_ITEMS_FIELD;
|
|
1287
1320
|
const totalCountField = options.totalCountField || DEFAULT_TOTAL_COUNT_FIELD;
|
|
@@ -1291,17 +1324,18 @@ class PaginationHelpers {
|
|
|
1291
1324
|
// Make the API call based on method
|
|
1292
1325
|
let response;
|
|
1293
1326
|
if (method === HTTP_METHODS.POST) {
|
|
1294
|
-
response = await serviceAccess.post(endpoint, additionalParams, { headers });
|
|
1327
|
+
response = await serviceAccess.post(endpoint, additionalParams, { headers, params: queryParams });
|
|
1295
1328
|
}
|
|
1296
1329
|
else {
|
|
1297
1330
|
response = await serviceAccess.get(endpoint, {
|
|
1298
|
-
params: additionalParams,
|
|
1331
|
+
params: { ...additionalParams, ...queryParams },
|
|
1299
1332
|
headers
|
|
1300
1333
|
});
|
|
1301
1334
|
}
|
|
1302
1335
|
// Extract and transform items from response
|
|
1303
|
-
// Handle both plain array responses and envelope responses ({ value: [...], totalRecordCount: N })
|
|
1304
|
-
|
|
1336
|
+
// Handle both plain array responses and envelope responses ({ value: [...], totalRecordCount: N }).
|
|
1337
|
+
// itemsField may be a dotted path (e.g. 'data.agents') for nested envelopes.
|
|
1338
|
+
const rawItems = Array.isArray(response.data) ? response.data : resolveNestedField(response.data, itemsField);
|
|
1305
1339
|
const rawTotalCount = Array.isArray(response.data) ? undefined : resolveNestedField(response.data, totalCountField);
|
|
1306
1340
|
const totalCount = typeof rawTotalCount === 'number' ? rawTotalCount : undefined;
|
|
1307
1341
|
// Parse items - automatically handle JSON string responses
|
|
@@ -1347,8 +1381,9 @@ class PaginationHelpers {
|
|
|
1347
1381
|
getEndpoint: config.getEndpoint,
|
|
1348
1382
|
folderId,
|
|
1349
1383
|
headers: config.headers,
|
|
1350
|
-
paginationParams: cursor ? { cursor, pageSize } : jumpToPage ? { jumpToPage, pageSize } : { pageSize },
|
|
1384
|
+
paginationParams: cursor ? { cursor, pageSize } : jumpToPage !== undefined ? { jumpToPage, pageSize } : { pageSize },
|
|
1351
1385
|
additionalParams: prefixedOptions,
|
|
1386
|
+
queryParams: config.queryParams,
|
|
1352
1387
|
transformFn: config.transformFn,
|
|
1353
1388
|
method: config.method,
|
|
1354
1389
|
options: {
|
|
@@ -1366,6 +1401,7 @@ class PaginationHelpers {
|
|
|
1366
1401
|
folderId,
|
|
1367
1402
|
headers: config.headers,
|
|
1368
1403
|
additionalParams: prefixedOptions,
|
|
1404
|
+
queryParams: config.queryParams,
|
|
1369
1405
|
transformFn: config.transformFn,
|
|
1370
1406
|
method: config.method,
|
|
1371
1407
|
options: {
|
|
@@ -1557,18 +1593,17 @@ class BaseService {
|
|
|
1557
1593
|
const params = this.validateAndPreparePaginationParams(paginationType, paginationOptions);
|
|
1558
1594
|
// Prepare request parameters based on pagination type
|
|
1559
1595
|
const requestParams = this.preparePaginationRequestParams(paginationType, params, options.pagination);
|
|
1560
|
-
//
|
|
1596
|
+
// Route pagination state to wherever the API expects it (body for POST, URL for GET).
|
|
1597
|
+
// Caller-supplied options.body / options.params are respected as-is — the api-client
|
|
1598
|
+
// already handles params (URL) and body (request body) independently for every method.
|
|
1561
1599
|
if (method.toUpperCase() === 'POST') {
|
|
1562
1600
|
const existingBody = (options.body && typeof options.body === 'object') ? options.body : {};
|
|
1563
1601
|
options.body = {
|
|
1564
1602
|
...existingBody,
|
|
1565
|
-
...options.params,
|
|
1566
1603
|
...requestParams
|
|
1567
1604
|
};
|
|
1568
|
-
options.params = undefined;
|
|
1569
1605
|
}
|
|
1570
1606
|
else {
|
|
1571
|
-
// Merge pagination parameters with existing parameters
|
|
1572
1607
|
options.params = {
|
|
1573
1608
|
...options.params,
|
|
1574
1609
|
...requestParams
|
|
@@ -1605,6 +1640,8 @@ class BaseService {
|
|
|
1605
1640
|
// When true (default), converts pageNumber to a skip/offset value (e.g., page 3 with pageSize 10 → skip 20).
|
|
1606
1641
|
// When false, passes pageNumber directly as the offset param — used by APIs that accept a page number instead of a record offset.
|
|
1607
1642
|
const convertToSkip = paginationParams?.convertToSkip ?? true;
|
|
1643
|
+
// When true, sends pageNumber - 1 (for 0-based APIs). Default false (1-based).
|
|
1644
|
+
const zeroBased = paginationParams?.zeroBased ?? false;
|
|
1608
1645
|
requestParams[pageSizeParam] = limitedPageSize;
|
|
1609
1646
|
if (convertToSkip) {
|
|
1610
1647
|
if (params.pageNumber && params.pageNumber > 1) {
|
|
@@ -1612,7 +1649,8 @@ class BaseService {
|
|
|
1612
1649
|
}
|
|
1613
1650
|
}
|
|
1614
1651
|
else {
|
|
1615
|
-
|
|
1652
|
+
const sdkPageNumber = params.pageNumber || 1;
|
|
1653
|
+
requestParams[offsetParam] = zeroBased ? sdkPageNumber - 1 : sdkPageNumber;
|
|
1616
1654
|
}
|
|
1617
1655
|
{
|
|
1618
1656
|
requestParams[countParam] = true;
|
|
@@ -1641,8 +1679,9 @@ class BaseService {
|
|
|
1641
1679
|
const totalCountField = fields.totalCountField || 'totalRecordCount';
|
|
1642
1680
|
const continuationTokenField = fields.continuationTokenField || 'continuationToken';
|
|
1643
1681
|
// Extract items and metadata
|
|
1644
|
-
// Handle both plain array responses and envelope responses ({ value: [...], totalRecordCount: N })
|
|
1645
|
-
|
|
1682
|
+
// Handle both plain array responses and envelope responses ({ value: [...], totalRecordCount: N }).
|
|
1683
|
+
// itemsField may be a dotted path (e.g. 'data.agents') for nested envelopes.
|
|
1684
|
+
const items = Array.isArray(response.data) ? response.data : (resolveNestedField(response.data, itemsField) || []);
|
|
1646
1685
|
const rawTotalCount = Array.isArray(response.data) ? undefined : resolveNestedField(response.data, totalCountField);
|
|
1647
1686
|
const totalCount = typeof rawTotalCount === 'number' ? rawTotalCount : undefined;
|
|
1648
1687
|
const continuationToken = response.data[continuationTokenField];
|
|
@@ -1725,12 +1764,12 @@ function createEntityMethods(entityData, service) {
|
|
|
1725
1764
|
throw new Error('Entity ID is undefined');
|
|
1726
1765
|
return service.deleteRecordsById(entityData.id, recordIds, options);
|
|
1727
1766
|
},
|
|
1728
|
-
async deleteRecord(recordId) {
|
|
1767
|
+
async deleteRecord(recordId, options) {
|
|
1729
1768
|
if (!entityData.id)
|
|
1730
1769
|
throw new Error('Entity ID is undefined');
|
|
1731
1770
|
if (!recordId)
|
|
1732
1771
|
throw new Error('Record ID is undefined');
|
|
1733
|
-
return service.deleteRecordById(entityData.id, recordId);
|
|
1772
|
+
return service.deleteRecordById(entityData.id, recordId, options);
|
|
1734
1773
|
},
|
|
1735
1774
|
async getAllRecords(options) {
|
|
1736
1775
|
if (!entityData.id)
|
|
@@ -1744,30 +1783,30 @@ function createEntityMethods(entityData, service) {
|
|
|
1744
1783
|
throw new Error('Record ID is undefined');
|
|
1745
1784
|
return service.getRecordById(entityData.id, recordId, options);
|
|
1746
1785
|
},
|
|
1747
|
-
async downloadAttachment(recordId, fieldName) {
|
|
1786
|
+
async downloadAttachment(recordId, fieldName, options) {
|
|
1748
1787
|
if (!entityData.id)
|
|
1749
1788
|
throw new Error('Entity ID is undefined');
|
|
1750
|
-
return service.downloadAttachment(entityData.id, recordId, fieldName);
|
|
1789
|
+
return service.downloadAttachment(entityData.id, recordId, fieldName, options);
|
|
1751
1790
|
},
|
|
1752
1791
|
async uploadAttachment(recordId, fieldName, file, options) {
|
|
1753
1792
|
if (!entityData.id)
|
|
1754
1793
|
throw new Error('Entity ID is undefined');
|
|
1755
1794
|
return service.uploadAttachment(entityData.id, recordId, fieldName, file, options);
|
|
1756
1795
|
},
|
|
1757
|
-
async deleteAttachment(recordId, fieldName) {
|
|
1796
|
+
async deleteAttachment(recordId, fieldName, options) {
|
|
1758
1797
|
if (!entityData.id)
|
|
1759
1798
|
throw new Error('Entity ID is undefined');
|
|
1760
|
-
return service.deleteAttachment(entityData.id, recordId, fieldName);
|
|
1799
|
+
return service.deleteAttachment(entityData.id, recordId, fieldName, options);
|
|
1761
1800
|
},
|
|
1762
1801
|
async queryRecords(options) {
|
|
1763
1802
|
if (!entityData.id)
|
|
1764
1803
|
throw new Error('Entity ID is undefined');
|
|
1765
1804
|
return service.queryRecordsById(entityData.id, options);
|
|
1766
1805
|
},
|
|
1767
|
-
async importRecords(file) {
|
|
1806
|
+
async importRecords(file, options) {
|
|
1768
1807
|
if (!entityData.id)
|
|
1769
1808
|
throw new Error('Entity ID is undefined');
|
|
1770
|
-
return service.importRecordsById(entityData.id, file);
|
|
1809
|
+
return service.importRecordsById(entityData.id, file, options);
|
|
1771
1810
|
},
|
|
1772
1811
|
async insert(data, options) {
|
|
1773
1812
|
return this.insertRecord(data, options);
|
|
@@ -1778,10 +1817,10 @@ function createEntityMethods(entityData, service) {
|
|
|
1778
1817
|
async getRecords(options) {
|
|
1779
1818
|
return this.getAllRecords(options);
|
|
1780
1819
|
},
|
|
1781
|
-
async delete() {
|
|
1820
|
+
async delete(options) {
|
|
1782
1821
|
if (!entityData.id)
|
|
1783
1822
|
throw new Error('Entity ID is undefined');
|
|
1784
|
-
return service.deleteById(entityData.id);
|
|
1823
|
+
return service.deleteById(entityData.id, options);
|
|
1785
1824
|
},
|
|
1786
1825
|
async update(options) {
|
|
1787
1826
|
if (!entityData.id)
|
|
@@ -1930,6 +1969,9 @@ const DATA_FABRIC_TENANT_FOLDER_ID = '00000000-0000-0000-0000-000000000000';
|
|
|
1930
1969
|
const DATA_FABRIC_ENDPOINTS = {
|
|
1931
1970
|
ENTITY: {
|
|
1932
1971
|
GET_ALL: `${DATAFABRIC_BASE}/api/Entity`,
|
|
1972
|
+
// Lists tenant-level and folder-level entities together.
|
|
1973
|
+
// Used by getAll when includeFolderEntities is true.
|
|
1974
|
+
GET_ALL_V2: `${DATAFABRIC_BASE}/api/v2/Entity`,
|
|
1933
1975
|
GET_ENTITY_RECORDS: (entityId) => `${DATAFABRIC_BASE}/api/EntityService/entity/${entityId}/read`,
|
|
1934
1976
|
GET_BY_ID: (entityId) => `${DATAFABRIC_BASE}/api/Entity/${entityId}`,
|
|
1935
1977
|
GET_RECORD_BY_ID: (entityId, recordId) => `${DATAFABRIC_BASE}/api/EntityService/entity/${entityId}/read/${recordId}`,
|
|
@@ -2028,6 +2070,14 @@ var SqlFieldType;
|
|
|
2028
2070
|
SqlFieldType["MULTILINE"] = "MULTILINE";
|
|
2029
2071
|
})(SqlFieldType || (SqlFieldType = {}));
|
|
2030
2072
|
|
|
2073
|
+
/**
|
|
2074
|
+
* Numeric type IDs that pair with {@link EntityType} on reference payloads
|
|
2075
|
+
* (entityType + entityTypeId travel together in `referenceEntity` /
|
|
2076
|
+
* `referenceChoiceSet` bodies on cross-folder schema upserts).
|
|
2077
|
+
*/
|
|
2078
|
+
const ENTITY_TYPE_IDS = {
|
|
2079
|
+
[exports.EntityType.ChoiceSet]: 1,
|
|
2080
|
+
};
|
|
2031
2081
|
/**
|
|
2032
2082
|
* Maps fields for Entities
|
|
2033
2083
|
*/
|
|
@@ -2190,6 +2240,7 @@ class EntityService extends BaseService {
|
|
|
2190
2240
|
* Gets entity metadata by entity ID with attached operation methods
|
|
2191
2241
|
*
|
|
2192
2242
|
* @param id - UUID of the entity
|
|
2243
|
+
* @param options - Optional {@link EntityGetByIdOptions} (e.g. `folderKey` for folder-scoped entities) The `folderKey` property is **experimental**.
|
|
2193
2244
|
* @returns Promise resolving to entity metadata with schema information and operation methods
|
|
2194
2245
|
*
|
|
2195
2246
|
* @example
|
|
@@ -2199,6 +2250,9 @@ class EntityService extends BaseService {
|
|
|
2199
2250
|
* const entities = new Entities(sdk);
|
|
2200
2251
|
* const entity = await entities.getById("<entityId>");
|
|
2201
2252
|
*
|
|
2253
|
+
* // Folder-scoped: pass the entity's folder key
|
|
2254
|
+
* const folderEntity = await entities.getById("<entityId>", { folderKey: "<folderKey>" });
|
|
2255
|
+
*
|
|
2202
2256
|
* // Call operations directly on the entity
|
|
2203
2257
|
* const records = await entity.getAllRecords();
|
|
2204
2258
|
*
|
|
@@ -2212,9 +2266,9 @@ class EntityService extends BaseService {
|
|
|
2212
2266
|
* ]);
|
|
2213
2267
|
* ```
|
|
2214
2268
|
*/
|
|
2215
|
-
async getById(id) {
|
|
2269
|
+
async getById(id, options) {
|
|
2216
2270
|
// Get entity metadata
|
|
2217
|
-
const response = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_BY_ID(id));
|
|
2271
|
+
const response = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_BY_ID(id), { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
|
|
2218
2272
|
// Apply EntityMap transformations
|
|
2219
2273
|
const metadata = transformData(response.data, EntityMap);
|
|
2220
2274
|
// Transform metadata with field mappers
|
|
@@ -2226,7 +2280,7 @@ class EntityService extends BaseService {
|
|
|
2226
2280
|
* Gets entity records by entity ID
|
|
2227
2281
|
*
|
|
2228
2282
|
* @param entityId - UUID of the entity
|
|
2229
|
-
* @param options - Query options including expansionLevel and pagination options
|
|
2283
|
+
* @param options - Query options including expansionLevel and pagination options The `folderKey` property is **experimental**.
|
|
2230
2284
|
* @returns Promise resolving to an array of entity records or paginated response
|
|
2231
2285
|
*
|
|
2232
2286
|
* @example
|
|
@@ -2254,12 +2308,20 @@ class EntityService extends BaseService {
|
|
|
2254
2308
|
* cursor: paginatedResponse.nextCursor,
|
|
2255
2309
|
* expansionLevel: 1
|
|
2256
2310
|
* });
|
|
2311
|
+
*
|
|
2312
|
+
* // Folder-scoped entity: pass the entity's folder key
|
|
2313
|
+
* const records = await entities.getAllRecords("<entityId>", { folderKey: "<folderKey>" });
|
|
2257
2314
|
* ```
|
|
2258
2315
|
*/
|
|
2259
2316
|
async getAllRecords(entityId, options) {
|
|
2317
|
+
// folderKey is header-only — destructure it out so PaginationHelpers doesn't serialise it
|
|
2318
|
+
// into the query string as $folderKey.
|
|
2319
|
+
const { folderKey, ...rest } = options ?? {};
|
|
2320
|
+
const downstreamOptions = options === undefined ? undefined : rest;
|
|
2260
2321
|
return PaginationHelpers.getAll({
|
|
2261
2322
|
serviceAccess: this.createPaginationServiceAccess(),
|
|
2262
2323
|
getEndpoint: () => DATA_FABRIC_ENDPOINTS.ENTITY.GET_ENTITY_RECORDS(entityId),
|
|
2324
|
+
headers: createHeaders({ [FOLDER_KEY]: folderKey }),
|
|
2263
2325
|
pagination: {
|
|
2264
2326
|
paginationType: PaginationType.OFFSET,
|
|
2265
2327
|
itemsField: ENTITY_PAGINATION.ITEMS_FIELD,
|
|
@@ -2271,14 +2333,14 @@ class EntityService extends BaseService {
|
|
|
2271
2333
|
}
|
|
2272
2334
|
},
|
|
2273
2335
|
excludeFromPrefix: ['expansionLevel'] // Don't add ODATA prefix to expansionLevel
|
|
2274
|
-
},
|
|
2336
|
+
}, downstreamOptions);
|
|
2275
2337
|
}
|
|
2276
2338
|
/**
|
|
2277
2339
|
* Gets a single entity record by entity ID and record ID
|
|
2278
2340
|
*
|
|
2279
2341
|
* @param entityId - UUID of the entity
|
|
2280
2342
|
* @param recordId - UUID of the record
|
|
2281
|
-
* @param options - Query options including expansionLevel
|
|
2343
|
+
* @param options - Query options including `expansionLevel` and `folderKey` The `folderKey` property is **experimental**.
|
|
2282
2344
|
* @returns Promise resolving to the entity record
|
|
2283
2345
|
*
|
|
2284
2346
|
* @example
|
|
@@ -2290,13 +2352,18 @@ class EntityService extends BaseService {
|
|
|
2290
2352
|
* const record = await sdk.entities.getRecordById(<entityId>, <recordId>, {
|
|
2291
2353
|
* expansionLevel: 1
|
|
2292
2354
|
* });
|
|
2355
|
+
*
|
|
2356
|
+
* // Folder-scoped entity: pass the entity's folder key
|
|
2357
|
+
* const record = await sdk.entities.getRecordById(<entityId>, <recordId>, {
|
|
2358
|
+
* folderKey: "<folderKey>"
|
|
2359
|
+
* });
|
|
2293
2360
|
* ```
|
|
2294
2361
|
*/
|
|
2295
2362
|
async getRecordById(entityId, recordId, options = {}) {
|
|
2296
2363
|
const params = createParams({
|
|
2297
2364
|
expansionLevel: options.expansionLevel
|
|
2298
2365
|
});
|
|
2299
|
-
const response = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_RECORD_BY_ID(entityId, recordId), { params });
|
|
2366
|
+
const response = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_RECORD_BY_ID(entityId, recordId), { params, headers: createHeaders({ [FOLDER_KEY]: options.folderKey }) });
|
|
2300
2367
|
return response.data;
|
|
2301
2368
|
}
|
|
2302
2369
|
/**
|
|
@@ -2304,7 +2371,7 @@ class EntityService extends BaseService {
|
|
|
2304
2371
|
*
|
|
2305
2372
|
* @param entityId - UUID of the entity
|
|
2306
2373
|
* @param data - Record to insert
|
|
2307
|
-
* @param options - Insert options
|
|
2374
|
+
* @param options - Insert options The `folderKey` property is **experimental**.
|
|
2308
2375
|
* @returns Promise resolving to the inserted record with generated record ID
|
|
2309
2376
|
*
|
|
2310
2377
|
* @example
|
|
@@ -2320,6 +2387,11 @@ class EntityService extends BaseService {
|
|
|
2320
2387
|
* const result = await entities.insertRecordById("<entityId>", { name: "John", age: 30 }, {
|
|
2321
2388
|
* expansionLevel: 1
|
|
2322
2389
|
* });
|
|
2390
|
+
*
|
|
2391
|
+
* // Folder-scoped entity: pass the entity's folder key
|
|
2392
|
+
* await entities.insertRecordById("<entityId>", { name: "John", age: 30 }, {
|
|
2393
|
+
* folderKey: "<folderKey>"
|
|
2394
|
+
* });
|
|
2323
2395
|
* ```
|
|
2324
2396
|
*/
|
|
2325
2397
|
async insertRecordById(id, data, options = {}) {
|
|
@@ -2328,7 +2400,7 @@ class EntityService extends BaseService {
|
|
|
2328
2400
|
});
|
|
2329
2401
|
const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.INSERT_BY_ID(id), data, {
|
|
2330
2402
|
params,
|
|
2331
|
-
|
|
2403
|
+
headers: createHeaders({ [FOLDER_KEY]: options.folderKey }),
|
|
2332
2404
|
});
|
|
2333
2405
|
return response.data;
|
|
2334
2406
|
}
|
|
@@ -2337,7 +2409,7 @@ class EntityService extends BaseService {
|
|
|
2337
2409
|
*
|
|
2338
2410
|
* @param entityId - UUID of the entity
|
|
2339
2411
|
* @param data - Array of records to insert
|
|
2340
|
-
* @param options - Insert options
|
|
2412
|
+
* @param options - Insert options The `folderKey` property is **experimental**.
|
|
2341
2413
|
* @returns Promise resolving to insert response
|
|
2342
2414
|
*
|
|
2343
2415
|
* @example
|
|
@@ -2360,6 +2432,12 @@ class EntityService extends BaseService {
|
|
|
2360
2432
|
* expansionLevel: 1,
|
|
2361
2433
|
* failOnFirst: true
|
|
2362
2434
|
* });
|
|
2435
|
+
*
|
|
2436
|
+
* // Folder-scoped entity: pass the entity's folder key
|
|
2437
|
+
* await entities.insertRecordsById("<entityId>", [
|
|
2438
|
+
* { name: "John", age: 30 },
|
|
2439
|
+
* { name: "Jane", age: 25 }
|
|
2440
|
+
* ], { folderKey: "<folderKey>" });
|
|
2363
2441
|
* ```
|
|
2364
2442
|
*/
|
|
2365
2443
|
async insertRecordsById(id, data, options = {}) {
|
|
@@ -2369,7 +2447,7 @@ class EntityService extends BaseService {
|
|
|
2369
2447
|
});
|
|
2370
2448
|
const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.BATCH_INSERT_BY_ID(id), data, {
|
|
2371
2449
|
params,
|
|
2372
|
-
|
|
2450
|
+
headers: createHeaders({ [FOLDER_KEY]: options.folderKey }),
|
|
2373
2451
|
});
|
|
2374
2452
|
return response.data;
|
|
2375
2453
|
}
|
|
@@ -2379,7 +2457,7 @@ class EntityService extends BaseService {
|
|
|
2379
2457
|
* @param entityId - UUID of the entity
|
|
2380
2458
|
* @param recordId - UUID of the record to update
|
|
2381
2459
|
* @param data - Key-value pairs of fields to update
|
|
2382
|
-
* @param options - Update options
|
|
2460
|
+
* @param options - Update options The `folderKey` property is **experimental**.
|
|
2383
2461
|
* @returns Promise resolving to the updated record
|
|
2384
2462
|
*
|
|
2385
2463
|
* @example
|
|
@@ -2395,6 +2473,11 @@ class EntityService extends BaseService {
|
|
|
2395
2473
|
* const result = await entities.updateRecordById("<entityId>", "<recordId>", { name: "John Updated", age: 31 }, {
|
|
2396
2474
|
* expansionLevel: 1
|
|
2397
2475
|
* });
|
|
2476
|
+
*
|
|
2477
|
+
* // Folder-scoped entity: pass the entity's folder key
|
|
2478
|
+
* await entities.updateRecordById("<entityId>", "<recordId>", { name: "John Updated" }, {
|
|
2479
|
+
* folderKey: "<folderKey>"
|
|
2480
|
+
* });
|
|
2398
2481
|
* ```
|
|
2399
2482
|
*/
|
|
2400
2483
|
async updateRecordById(entityId, recordId, data, options = {}) {
|
|
@@ -2403,7 +2486,7 @@ class EntityService extends BaseService {
|
|
|
2403
2486
|
});
|
|
2404
2487
|
const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPDATE_RECORD_BY_ID(entityId, recordId), data, {
|
|
2405
2488
|
params,
|
|
2406
|
-
|
|
2489
|
+
headers: createHeaders({ [FOLDER_KEY]: options.folderKey }),
|
|
2407
2490
|
});
|
|
2408
2491
|
return response.data;
|
|
2409
2492
|
}
|
|
@@ -2413,7 +2496,7 @@ class EntityService extends BaseService {
|
|
|
2413
2496
|
* @param entityId - UUID of the entity
|
|
2414
2497
|
* @param data - Array of records to update. Each record MUST contain the record Id,
|
|
2415
2498
|
* otherwise the update will fail.
|
|
2416
|
-
* @param options - Update options
|
|
2499
|
+
* @param options - Update options The `folderKey` property is **experimental**.
|
|
2417
2500
|
* @returns Promise resolving to update response
|
|
2418
2501
|
*
|
|
2419
2502
|
* @example
|
|
@@ -2436,6 +2519,11 @@ class EntityService extends BaseService {
|
|
|
2436
2519
|
* expansionLevel: 1,
|
|
2437
2520
|
* failOnFirst: true
|
|
2438
2521
|
* });
|
|
2522
|
+
*
|
|
2523
|
+
* // Folder-scoped entity: pass the entity's folder key
|
|
2524
|
+
* await entities.updateRecordsById("<entityId>", [
|
|
2525
|
+
* { Id: "123", name: "John Updated" }
|
|
2526
|
+
* ], { folderKey: "<folderKey>" });
|
|
2439
2527
|
* ```
|
|
2440
2528
|
*/
|
|
2441
2529
|
async updateRecordsById(id, data, options = {}) {
|
|
@@ -2445,7 +2533,7 @@ class EntityService extends BaseService {
|
|
|
2445
2533
|
});
|
|
2446
2534
|
const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPDATE_BY_ID(id), data, {
|
|
2447
2535
|
params,
|
|
2448
|
-
|
|
2536
|
+
headers: createHeaders({ [FOLDER_KEY]: options.folderKey }),
|
|
2449
2537
|
});
|
|
2450
2538
|
return response.data;
|
|
2451
2539
|
}
|
|
@@ -2456,7 +2544,7 @@ class EntityService extends BaseService {
|
|
|
2456
2544
|
*
|
|
2457
2545
|
* @param entityId - UUID of the entity
|
|
2458
2546
|
* @param recordIds - Array of record UUIDs to delete
|
|
2459
|
-
* @param options - Delete options
|
|
2547
|
+
* @param options - Delete options The `folderKey` property is **experimental**.
|
|
2460
2548
|
* @returns Promise resolving to delete response
|
|
2461
2549
|
*
|
|
2462
2550
|
* @example
|
|
@@ -2469,6 +2557,11 @@ class EntityService extends BaseService {
|
|
|
2469
2557
|
* const result = await entities.deleteRecordsById("<entityId>", [
|
|
2470
2558
|
* "<recordId-1>", "<recordId-2>"
|
|
2471
2559
|
* ]);
|
|
2560
|
+
*
|
|
2561
|
+
* // Folder-scoped entity: pass the entity's folder key
|
|
2562
|
+
* await entities.deleteRecordsById("<entityId>", [
|
|
2563
|
+
* "<recordId-1>", "<recordId-2>"
|
|
2564
|
+
* ], { folderKey: "<folderKey>" });
|
|
2472
2565
|
* ```
|
|
2473
2566
|
*/
|
|
2474
2567
|
async deleteRecordsById(id, recordIds, options = {}) {
|
|
@@ -2477,7 +2570,7 @@ class EntityService extends BaseService {
|
|
|
2477
2570
|
});
|
|
2478
2571
|
const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE_BY_ID(id), recordIds, {
|
|
2479
2572
|
params,
|
|
2480
|
-
|
|
2573
|
+
headers: createHeaders({ [FOLDER_KEY]: options.folderKey }),
|
|
2481
2574
|
});
|
|
2482
2575
|
return response.data;
|
|
2483
2576
|
}
|
|
@@ -2489,6 +2582,7 @@ class EntityService extends BaseService {
|
|
|
2489
2582
|
*
|
|
2490
2583
|
* @param entityId - UUID of the entity
|
|
2491
2584
|
* @param recordId - UUID of the record to delete
|
|
2585
|
+
* @param options - Optional {@link EntityDeleteRecordByIdOptions} (e.g. `folderKey` for folder-scoped entities) The `folderKey` property is **experimental**.
|
|
2492
2586
|
* @returns Promise resolving to void on success
|
|
2493
2587
|
* @example
|
|
2494
2588
|
* ```typescript
|
|
@@ -2497,14 +2591,23 @@ class EntityService extends BaseService {
|
|
|
2497
2591
|
* const entities = new Entities(sdk);
|
|
2498
2592
|
*
|
|
2499
2593
|
* await entities.deleteRecordById("<entityId>", "<recordId>");
|
|
2594
|
+
*
|
|
2595
|
+
* // Folder-scoped: pass the entity's folder key
|
|
2596
|
+
* await entities.deleteRecordById("<entityId>", "<recordId>", { folderKey: "<folderKey>" });
|
|
2500
2597
|
* ```
|
|
2501
2598
|
*/
|
|
2502
|
-
async deleteRecordById(entityId, recordId) {
|
|
2503
|
-
await this.delete(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE_RECORD_BY_ID(entityId, recordId));
|
|
2599
|
+
async deleteRecordById(entityId, recordId, options) {
|
|
2600
|
+
await this.delete(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE_RECORD_BY_ID(entityId, recordId), { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
|
|
2504
2601
|
}
|
|
2505
2602
|
/**
|
|
2506
|
-
* Gets
|
|
2603
|
+
* Gets entities in the tenant.
|
|
2507
2604
|
*
|
|
2605
|
+
* Three call modes:
|
|
2606
|
+
* - `getAll()` — default. Returns only tenant-level entities.
|
|
2607
|
+
* - `getAll({ folderKey: "<uuid>" })` — preferred for folder-scoped data. Returns only entities in that folder.
|
|
2608
|
+
* - `getAll({ includeFolderEntities: true })` — returns tenant-level **and** folder-level entities together. `folderKey` is preferred over `includeFolderEntities` when both are set.
|
|
2609
|
+
*
|
|
2610
|
+
* @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**.
|
|
2508
2611
|
* @returns Promise resolving to an array of entity metadata
|
|
2509
2612
|
*
|
|
2510
2613
|
* @example
|
|
@@ -2513,15 +2616,29 @@ class EntityService extends BaseService {
|
|
|
2513
2616
|
*
|
|
2514
2617
|
* const entities = new Entities(sdk);
|
|
2515
2618
|
*
|
|
2516
|
-
* //
|
|
2517
|
-
* const
|
|
2619
|
+
* // Tenant-only (default)
|
|
2620
|
+
* const tenantEntities = await entities.getAll();
|
|
2621
|
+
*
|
|
2622
|
+
* // A single folder's entities (preferred when targeting a specific folder)
|
|
2623
|
+
* const folderEntities = await entities.getAll({ folderKey: "<folderKey>" });
|
|
2624
|
+
*
|
|
2625
|
+
* // Tenant + folder entities together
|
|
2626
|
+
* const allEntities = await entities.getAll({ includeFolderEntities: true });
|
|
2518
2627
|
*
|
|
2519
2628
|
* // Call operations on an entity
|
|
2520
|
-
* const records = await
|
|
2629
|
+
* const records = await tenantEntities[0].getAllRecords();
|
|
2521
2630
|
* ```
|
|
2522
2631
|
*/
|
|
2523
|
-
async getAll() {
|
|
2524
|
-
|
|
2632
|
+
async getAll(options) {
|
|
2633
|
+
// folderKey is preferred over includeFolderEntities: when present, scope to that folder
|
|
2634
|
+
// via the v1 endpoint + header. Only when no folderKey is given AND includeFolderEntities
|
|
2635
|
+
// is explicitly true does the SDK switch to the v2 endpoint (returns tenant + folder
|
|
2636
|
+
// entities together). Default (no options or includeFolderEntities omitted) stays on
|
|
2637
|
+
// the v1 endpoint = tenant only.
|
|
2638
|
+
const endpoint = !options?.folderKey && options?.includeFolderEntities
|
|
2639
|
+
? DATA_FABRIC_ENDPOINTS.ENTITY.GET_ALL_V2
|
|
2640
|
+
: DATA_FABRIC_ENDPOINTS.ENTITY.GET_ALL;
|
|
2641
|
+
const response = await this.get(endpoint, { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
|
|
2525
2642
|
// Apply transformations
|
|
2526
2643
|
const entities = response.data.map(entity => {
|
|
2527
2644
|
// Transform each entity
|
|
@@ -2536,7 +2653,7 @@ class EntityService extends BaseService {
|
|
|
2536
2653
|
* Queries entity records with filters, sorting, aggregates, and pagination
|
|
2537
2654
|
*
|
|
2538
2655
|
* @param id - UUID of the entity
|
|
2539
|
-
* @param options - Query options including filterGroup, selectedFields, sortOptions, aggregates, groupBy, and pagination
|
|
2656
|
+
* @param options - Query options including filterGroup, selectedFields, sortOptions, aggregates, groupBy, and pagination The `folderKey` property is **experimental**.
|
|
2540
2657
|
* @returns Promise resolving to {@link NonPaginatedResponse} without pagination options,
|
|
2541
2658
|
* or {@link PaginatedResponse} when `pageSize`, `cursor`, or `jumpToPage` are provided
|
|
2542
2659
|
*
|
|
@@ -2583,13 +2700,24 @@ class EntityService extends BaseService {
|
|
|
2583
2700
|
* { function: EntityAggregateFunction.Avg, field: "amount", alias: "avgAmount" },
|
|
2584
2701
|
* ],
|
|
2585
2702
|
* });
|
|
2703
|
+
*
|
|
2704
|
+
* // Folder-scoped entity: pass the entity's folder key
|
|
2705
|
+
* await entities.queryRecordsById("<entityId>", {
|
|
2706
|
+
* filterGroup: { queryFilters: [{ fieldName: "status", operator: QueryFilterOperator.Equals, value: "active" }] },
|
|
2707
|
+
* folderKey: "<folderKey>",
|
|
2708
|
+
* });
|
|
2586
2709
|
* ```
|
|
2587
2710
|
*/
|
|
2588
2711
|
async queryRecordsById(id, options) {
|
|
2712
|
+
// folderKey is header-only; expansionLevel must be sent as a query param by PaginationHelpers.
|
|
2713
|
+
const { folderKey, expansionLevel, ...rest } = options ?? {};
|
|
2714
|
+
const downstreamOptions = options === undefined ? undefined : rest;
|
|
2589
2715
|
return PaginationHelpers.getAll({
|
|
2590
2716
|
serviceAccess: this.createPaginationServiceAccess(),
|
|
2591
2717
|
getEndpoint: () => DATA_FABRIC_ENDPOINTS.ENTITY.QUERY_BY_ID(id),
|
|
2592
2718
|
method: HTTP_METHODS.POST,
|
|
2719
|
+
headers: createHeaders({ [FOLDER_KEY]: folderKey }),
|
|
2720
|
+
queryParams: createParams({ expansionLevel }),
|
|
2593
2721
|
pagination: {
|
|
2594
2722
|
paginationType: PaginationType.OFFSET,
|
|
2595
2723
|
itemsField: ENTITY_PAGINATION.ITEMS_FIELD,
|
|
@@ -2600,14 +2728,15 @@ class EntityService extends BaseService {
|
|
|
2600
2728
|
countParam: ENTITY_OFFSET_PARAMS.COUNT_PARAM
|
|
2601
2729
|
}
|
|
2602
2730
|
},
|
|
2603
|
-
excludeFromPrefix: ['
|
|
2604
|
-
},
|
|
2731
|
+
excludeFromPrefix: ['filterGroup', 'selectedFields', 'sortOptions', 'aggregates', 'groupBy']
|
|
2732
|
+
}, downstreamOptions);
|
|
2605
2733
|
}
|
|
2606
2734
|
/**
|
|
2607
2735
|
* Imports records from a CSV file into an entity
|
|
2608
2736
|
*
|
|
2609
2737
|
* @param id - UUID of the entity
|
|
2610
2738
|
* @param file - CSV file to import (Blob, File, or Uint8Array)
|
|
2739
|
+
* @param options - Optional {@link EntityImportRecordsByIdOptions} (e.g. `folderKey` for folder-scoped entities) The `folderKey` property is **experimental**.
|
|
2611
2740
|
* @returns Promise resolving to import result with record counts
|
|
2612
2741
|
*
|
|
2613
2742
|
* @example
|
|
@@ -2628,10 +2757,12 @@ class EntityService extends BaseService {
|
|
|
2628
2757
|
* if (result.errorFileLink) {
|
|
2629
2758
|
* console.log(`Error file link: ${result.errorFileLink}`);
|
|
2630
2759
|
* }
|
|
2760
|
+
*
|
|
2761
|
+
* // Folder-scoped entity: pass the entity's folder key
|
|
2762
|
+
* await entities.importRecordsById("<entityId>", fileInput.files[0], { folderKey: "<folderKey>" });
|
|
2631
2763
|
* ```
|
|
2632
|
-
* @internal
|
|
2633
2764
|
*/
|
|
2634
|
-
async importRecordsById(id, file) {
|
|
2765
|
+
async importRecordsById(id, file, options) {
|
|
2635
2766
|
const formData = new FormData();
|
|
2636
2767
|
if (file instanceof Uint8Array) {
|
|
2637
2768
|
formData.append('file', new Blob([file.buffer]));
|
|
@@ -2639,7 +2770,7 @@ class EntityService extends BaseService {
|
|
|
2639
2770
|
else {
|
|
2640
2771
|
formData.append('file', file);
|
|
2641
2772
|
}
|
|
2642
|
-
const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.BULK_UPLOAD_BY_ID(id), formData);
|
|
2773
|
+
const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.BULK_UPLOAD_BY_ID(id), formData, { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
|
|
2643
2774
|
return response.data;
|
|
2644
2775
|
}
|
|
2645
2776
|
/**
|
|
@@ -2648,6 +2779,7 @@ class EntityService extends BaseService {
|
|
|
2648
2779
|
* @param entityId - UUID of the entity
|
|
2649
2780
|
* @param recordId - UUID of the record containing the attachment
|
|
2650
2781
|
* @param fieldName - Name of the File-type field containing the attachment
|
|
2782
|
+
* @param options - Optional {@link EntityDownloadAttachmentOptions} (e.g. `folderKey` for folder-scoped entities) The `folderKey` property is **experimental**.
|
|
2651
2783
|
* @returns Promise resolving to Blob containing the file content
|
|
2652
2784
|
*
|
|
2653
2785
|
* @example
|
|
@@ -2666,11 +2798,15 @@ class EntityService extends BaseService {
|
|
|
2666
2798
|
*
|
|
2667
2799
|
* // Download attachment for a specific record and field
|
|
2668
2800
|
* const blob = await entities.downloadAttachment(entityId, recordId, 'Documents');
|
|
2801
|
+
*
|
|
2802
|
+
* // Folder-scoped: pass the entity's folder key
|
|
2803
|
+
* const blob = await entities.downloadAttachment(entityId, recordId, 'Documents', { folderKey: "<folderKey>" });
|
|
2669
2804
|
* ```
|
|
2670
2805
|
*/
|
|
2671
|
-
async downloadAttachment(entityId, recordId, fieldName) {
|
|
2806
|
+
async downloadAttachment(entityId, recordId, fieldName, options) {
|
|
2672
2807
|
const response = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.DOWNLOAD_ATTACHMENT(entityId, recordId, fieldName), {
|
|
2673
|
-
responseType: RESPONSE_TYPES.BLOB
|
|
2808
|
+
responseType: RESPONSE_TYPES.BLOB,
|
|
2809
|
+
headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }),
|
|
2674
2810
|
});
|
|
2675
2811
|
return response.data;
|
|
2676
2812
|
}
|
|
@@ -2681,7 +2817,7 @@ class EntityService extends BaseService {
|
|
|
2681
2817
|
* @param recordId - UUID of the record to upload the attachment to
|
|
2682
2818
|
* @param fieldName - Name of the File-type field
|
|
2683
2819
|
* @param file - File to upload (Blob, File, or Uint8Array)
|
|
2684
|
-
* @param options - Optional {@link EntityUploadAttachmentOptions} (e.g. expansionLevel)
|
|
2820
|
+
* @param options - Optional {@link EntityUploadAttachmentOptions} (e.g. `expansionLevel`, `folderKey` for folder-scoped entities) The `folderKey` property is **experimental**.
|
|
2685
2821
|
* @returns Promise resolving to {@link EntityUploadAttachmentResponse}
|
|
2686
2822
|
*
|
|
2687
2823
|
* @example
|
|
@@ -2700,6 +2836,9 @@ class EntityService extends BaseService {
|
|
|
2700
2836
|
*
|
|
2701
2837
|
* // Upload a file attachment
|
|
2702
2838
|
* const response = await entities.uploadAttachment(entityId, recordId, 'Documents', file);
|
|
2839
|
+
*
|
|
2840
|
+
* // Folder-scoped entity: pass the entity's folder key
|
|
2841
|
+
* await entities.uploadAttachment(entityId, recordId, 'Documents', file, { folderKey: "<folderKey>" });
|
|
2703
2842
|
* ```
|
|
2704
2843
|
*/
|
|
2705
2844
|
async uploadAttachment(entityId, recordId, fieldName, file, options) {
|
|
@@ -2711,7 +2850,10 @@ class EntityService extends BaseService {
|
|
|
2711
2850
|
formData.append('file', file);
|
|
2712
2851
|
}
|
|
2713
2852
|
const params = createParams({ expansionLevel: options?.expansionLevel });
|
|
2714
|
-
const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPLOAD_ATTACHMENT(entityId, recordId, fieldName), formData, {
|
|
2853
|
+
const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPLOAD_ATTACHMENT(entityId, recordId, fieldName), formData, {
|
|
2854
|
+
params,
|
|
2855
|
+
headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }),
|
|
2856
|
+
});
|
|
2715
2857
|
return response.data;
|
|
2716
2858
|
}
|
|
2717
2859
|
/**
|
|
@@ -2720,6 +2862,7 @@ class EntityService extends BaseService {
|
|
|
2720
2862
|
* @param entityId - UUID of the entity
|
|
2721
2863
|
* @param recordId - UUID of the record containing the attachment
|
|
2722
2864
|
* @param fieldName - Name of the File-type field containing the attachment
|
|
2865
|
+
* @param options - Optional {@link EntityDeleteAttachmentOptions} (e.g. `folderKey` for folder-scoped entities) The `folderKey` property is **experimental**.
|
|
2723
2866
|
* @returns Promise resolving to {@link EntityDeleteAttachmentResponse}
|
|
2724
2867
|
*
|
|
2725
2868
|
* @example
|
|
@@ -2738,10 +2881,13 @@ class EntityService extends BaseService {
|
|
|
2738
2881
|
*
|
|
2739
2882
|
* // Delete attachment for a specific record and field
|
|
2740
2883
|
* await entities.deleteAttachment(entityId, recordId, 'Documents');
|
|
2884
|
+
*
|
|
2885
|
+
* // Folder-scoped: pass the entity's folder key
|
|
2886
|
+
* await entities.deleteAttachment(entityId, recordId, 'Documents', { folderKey: "<folderKey>" });
|
|
2741
2887
|
* ```
|
|
2742
2888
|
*/
|
|
2743
|
-
async deleteAttachment(entityId, recordId, fieldName) {
|
|
2744
|
-
const response = await this.delete(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE_ATTACHMENT(entityId, recordId, fieldName));
|
|
2889
|
+
async deleteAttachment(entityId, recordId, fieldName, options) {
|
|
2890
|
+
const response = await this.delete(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE_ATTACHMENT(entityId, recordId, fieldName), { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
|
|
2745
2891
|
return response.data;
|
|
2746
2892
|
}
|
|
2747
2893
|
/**
|
|
@@ -2771,7 +2917,7 @@ class EntityService extends BaseService {
|
|
|
2771
2917
|
* @param name - Entity name — must start with a letter and contain
|
|
2772
2918
|
* only letters, numbers, and underscores (e.g., `"productCatalog"`).
|
|
2773
2919
|
* @param fields - Array of field definitions
|
|
2774
|
-
* @param options - Optional entity-level settings ({@link EntityCreateOptions})
|
|
2920
|
+
* @param options - Optional entity-level settings ({@link EntityCreateOptions}) The `folderKey` property is **experimental**.
|
|
2775
2921
|
* @returns Promise resolving to the ID of the created entity
|
|
2776
2922
|
*
|
|
2777
2923
|
* @example
|
|
@@ -2787,40 +2933,63 @@ class EntityService extends BaseService {
|
|
|
2787
2933
|
* { fieldName: "price", type: EntityFieldDataType.DECIMAL, decimalPrecision: 4, maxValue: 999999, minValue: 0 },
|
|
2788
2934
|
* { fieldName: "quantity", type: EntityFieldDataType.INTEGER, maxValue: 10000, minValue: 1, defaultValue: "0" },
|
|
2789
2935
|
* ]);
|
|
2936
|
+
*
|
|
2937
|
+
* // Cross-folder references — link a folder-scoped entity to entities and
|
|
2938
|
+
* // system choice sets that live in another folder or at the tenant level.
|
|
2939
|
+
* await entities.create("orderLine", [
|
|
2940
|
+
* {
|
|
2941
|
+
* fieldName: "order",
|
|
2942
|
+
* type: EntityFieldDataType.RELATIONSHIP,
|
|
2943
|
+
* referenceEntityId: "<orderEntityId>",
|
|
2944
|
+
* referenceFieldId: "<orderEntityPkId>",
|
|
2945
|
+
* referenceFolderKey: "<otherFolderKey>", // target lives in a different folder
|
|
2946
|
+
* },
|
|
2947
|
+
* {
|
|
2948
|
+
* fieldName: "userType",
|
|
2949
|
+
* type: EntityFieldDataType.CHOICE_SET_SINGLE,
|
|
2950
|
+
* choiceSetId: "<systemUserTypeChoiceSetId>", // tenant-level system choice set
|
|
2951
|
+
* // referenceFolderKey omitted → SDK looks up the target at tenant scope
|
|
2952
|
+
* },
|
|
2953
|
+
* ], { folderKey: "<sourceFolderKey>" });
|
|
2790
2954
|
* ```
|
|
2791
2955
|
* @internal
|
|
2792
2956
|
*/
|
|
2793
2957
|
async create(name, fields, options) {
|
|
2794
2958
|
const opts = options ?? {};
|
|
2959
|
+
const fieldPayloads = await this.buildFieldsWithReferenceMeta(fields);
|
|
2795
2960
|
const payload = {
|
|
2796
2961
|
...(opts.description !== undefined && { description: opts.description }),
|
|
2797
2962
|
displayName: opts.displayName ?? name,
|
|
2798
2963
|
entityDefinition: {
|
|
2799
2964
|
name,
|
|
2800
|
-
fields:
|
|
2965
|
+
fields: fieldPayloads,
|
|
2801
2966
|
folderId: opts.folderKey ?? DATA_FABRIC_TENANT_FOLDER_ID,
|
|
2802
2967
|
isRbacEnabled: opts.isRbacEnabled ?? false,
|
|
2803
2968
|
isInsightsEnabled: opts.isAnalyticsEnabled ?? false,
|
|
2804
2969
|
externalFields: opts.externalFields ?? [],
|
|
2805
2970
|
},
|
|
2806
2971
|
};
|
|
2807
|
-
const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPSERT, payload);
|
|
2972
|
+
const response = await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPSERT, payload, { headers: createHeaders({ [FOLDER_KEY]: opts.folderKey }) });
|
|
2808
2973
|
return response.data;
|
|
2809
2974
|
}
|
|
2810
2975
|
/**
|
|
2811
2976
|
* Deletes a Data Fabric entity and all its records
|
|
2812
2977
|
*
|
|
2813
2978
|
* @param id - UUID of the entity to delete
|
|
2979
|
+
* @param options - Optional {@link EntityDeleteByIdOptions} (e.g. `folderKey` for folder-scoped entities) The `folderKey` property is **experimental**.
|
|
2814
2980
|
* @returns Promise resolving when the entity is deleted
|
|
2815
2981
|
*
|
|
2816
2982
|
* @example
|
|
2817
2983
|
* ```typescript
|
|
2818
2984
|
* await entities.deleteById("<entityId>");
|
|
2985
|
+
*
|
|
2986
|
+
* // Folder-scoped: pass the entity's folder key
|
|
2987
|
+
* await entities.deleteById("<entityId>", { folderKey: "<folderKey>" });
|
|
2819
2988
|
* ```
|
|
2820
2989
|
* @internal
|
|
2821
2990
|
*/
|
|
2822
|
-
async deleteById(id) {
|
|
2823
|
-
await this.delete(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE(id));
|
|
2991
|
+
async deleteById(id, options) {
|
|
2992
|
+
await this.delete(DATA_FABRIC_ENDPOINTS.ENTITY.DELETE(id), { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
|
|
2824
2993
|
}
|
|
2825
2994
|
/**
|
|
2826
2995
|
* Updates an existing Data Fabric entity — schema and/or metadata.
|
|
@@ -2834,7 +3003,7 @@ class EntityService extends BaseService {
|
|
|
2834
3003
|
* overwrite each other's changes.
|
|
2835
3004
|
*
|
|
2836
3005
|
* @param id - UUID of the entity to update
|
|
2837
|
-
* @param options - Changes to apply ({@link EntityUpdateByIdOptions})
|
|
3006
|
+
* @param options - Changes to apply ({@link EntityUpdateByIdOptions}) The `folderKey` property is **experimental**.
|
|
2838
3007
|
* @returns Promise resolving when the update is complete
|
|
2839
3008
|
*
|
|
2840
3009
|
* @example
|
|
@@ -2867,6 +3036,12 @@ class EntityService extends BaseService {
|
|
|
2867
3036
|
* { id: "<fieldId>", lengthLimit: 1000 },
|
|
2868
3037
|
* ],
|
|
2869
3038
|
* });
|
|
3039
|
+
*
|
|
3040
|
+
* // Folder-scoped entity: add a field to an entity that lives in a non-tenant folder
|
|
3041
|
+
* await entities.updateById("<entityId>", {
|
|
3042
|
+
* folderKey: "<folderKey>",
|
|
3043
|
+
* addFields: [{ fieldName: "notes", type: EntityFieldDataType.MULTILINE_TEXT }],
|
|
3044
|
+
* });
|
|
2870
3045
|
* ```
|
|
2871
3046
|
* @internal
|
|
2872
3047
|
*/
|
|
@@ -2882,7 +3057,7 @@ class EntityService extends BaseService {
|
|
|
2882
3057
|
...(opts.displayName !== undefined && { displayName: opts.displayName }),
|
|
2883
3058
|
...(opts.description !== undefined && { description: opts.description }),
|
|
2884
3059
|
...(opts.isRbacEnabled !== undefined && { isRbacEnabled: opts.isRbacEnabled }),
|
|
2885
|
-
});
|
|
3060
|
+
}, { headers: createHeaders({ [FOLDER_KEY]: opts.folderKey }) });
|
|
2886
3061
|
}
|
|
2887
3062
|
}
|
|
2888
3063
|
/**
|
|
@@ -2893,7 +3068,8 @@ class EntityService extends BaseService {
|
|
|
2893
3068
|
* @private
|
|
2894
3069
|
*/
|
|
2895
3070
|
async applySchemaUpdate(entityId, options) {
|
|
2896
|
-
const
|
|
3071
|
+
const folderHeaders = createHeaders({ [FOLDER_KEY]: options.folderKey });
|
|
3072
|
+
const entityResponse = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_BY_ID(entityId), { headers: folderHeaders });
|
|
2897
3073
|
const raw = entityResponse.data;
|
|
2898
3074
|
// Carry forward existing non-system fields from GET response (skip system/primary-key fields)
|
|
2899
3075
|
let fields = (raw.fields ?? [])
|
|
@@ -2939,10 +3115,9 @@ class EntityService extends BaseService {
|
|
|
2939
3115
|
};
|
|
2940
3116
|
});
|
|
2941
3117
|
}
|
|
2942
|
-
// Build and append new fields
|
|
2943
3118
|
const newFields = [];
|
|
2944
3119
|
if (options.addFields?.length) {
|
|
2945
|
-
newFields.push(...
|
|
3120
|
+
newFields.push(...await this.buildFieldsWithReferenceMeta(options.addFields));
|
|
2946
3121
|
}
|
|
2947
3122
|
await this.post(DATA_FABRIC_ENDPOINTS.ENTITY.UPSERT, {
|
|
2948
3123
|
displayName: raw.displayName,
|
|
@@ -2956,7 +3131,7 @@ class EntityService extends BaseService {
|
|
|
2956
3131
|
isInsightsEnabled: raw.isInsightsEnabled ?? false,
|
|
2957
3132
|
externalFields: raw.externalFields ?? [],
|
|
2958
3133
|
},
|
|
2959
|
-
});
|
|
3134
|
+
}, { headers: folderHeaders });
|
|
2960
3135
|
}
|
|
2961
3136
|
/**
|
|
2962
3137
|
* Orchestrates all field mapping transformations
|
|
@@ -3040,8 +3215,39 @@ class EntityService extends BaseService {
|
|
|
3040
3215
|
return externalSource;
|
|
3041
3216
|
});
|
|
3042
3217
|
}
|
|
3218
|
+
async buildFieldsWithReferenceMeta(fields) {
|
|
3219
|
+
const metas = await Promise.all(fields.map(f => this.buildReferenceMeta(f)));
|
|
3220
|
+
return fields.map((f, i) => this.buildSchemaFieldPayload(f, metas[i]));
|
|
3221
|
+
}
|
|
3222
|
+
// Choice-set targets resolve server-side by NAME (the API rejects cross-folder
|
|
3223
|
+
// refs with empty target name even when folderId is supplied), so the SDK
|
|
3224
|
+
// fetches the name once for each cross-folder choice-set field. Relationship
|
|
3225
|
+
// targets resolve by folderId — no lookup needed.
|
|
3226
|
+
async buildReferenceMeta(field) {
|
|
3227
|
+
if (field.referenceFolderKey === undefined)
|
|
3228
|
+
return undefined;
|
|
3229
|
+
if (field.referenceEntityId === undefined && field.choiceSetId === undefined)
|
|
3230
|
+
return undefined;
|
|
3231
|
+
const folderId = field.referenceFolderKey;
|
|
3232
|
+
const meta = {};
|
|
3233
|
+
if (field.referenceEntityId !== undefined) {
|
|
3234
|
+
meta.referenceEntity = { id: field.referenceEntityId, folderId };
|
|
3235
|
+
}
|
|
3236
|
+
if (field.choiceSetId !== undefined) {
|
|
3237
|
+
const lookupFolderKey = folderId === DATA_FABRIC_TENANT_FOLDER_ID ? undefined : folderId;
|
|
3238
|
+
const target = await this.get(DATA_FABRIC_ENDPOINTS.ENTITY.GET_BY_ID(field.choiceSetId), { headers: createHeaders({ [FOLDER_KEY]: lookupFolderKey }) });
|
|
3239
|
+
meta.referenceChoiceSet = {
|
|
3240
|
+
id: field.choiceSetId,
|
|
3241
|
+
name: target.data.name,
|
|
3242
|
+
folderId,
|
|
3243
|
+
entityType: exports.EntityType.ChoiceSet,
|
|
3244
|
+
entityTypeId: ENTITY_TYPE_IDS[exports.EntityType.ChoiceSet],
|
|
3245
|
+
};
|
|
3246
|
+
}
|
|
3247
|
+
return meta;
|
|
3248
|
+
}
|
|
3043
3249
|
/** Converts a user-facing EntityCreateFieldOptions to the raw API field payload */
|
|
3044
|
-
buildSchemaFieldPayload(field) {
|
|
3250
|
+
buildSchemaFieldPayload(field, refMeta) {
|
|
3045
3251
|
const fieldType = field.type ?? exports.EntityFieldDataType.STRING;
|
|
3046
3252
|
this.validateFieldConstraints(fieldType, field, field.fieldName);
|
|
3047
3253
|
const isRelationship = fieldType === exports.EntityFieldDataType.RELATIONSHIP;
|
|
@@ -3052,6 +3258,10 @@ class EntityService extends BaseService {
|
|
|
3052
3258
|
});
|
|
3053
3259
|
}
|
|
3054
3260
|
const mapping = EntitySchemaFieldTypeMap[fieldType];
|
|
3261
|
+
// Prefer the resolved {id, name, folderId} body so cross-folder targets resolve
|
|
3262
|
+
// server-side; fall back to a bare {id} when no meta was fetched.
|
|
3263
|
+
const referenceEntityBody = refMeta?.referenceEntity ?? (field.referenceEntityId === undefined ? undefined : { id: field.referenceEntityId });
|
|
3264
|
+
const referenceChoiceSetBody = refMeta?.referenceChoiceSet;
|
|
3055
3265
|
return {
|
|
3056
3266
|
name: field.fieldName,
|
|
3057
3267
|
displayName: field.displayName ?? field.fieldName,
|
|
@@ -3070,7 +3280,8 @@ class EntityService extends BaseService {
|
|
|
3070
3280
|
...(field.choiceSetId !== undefined && { choiceSetId: field.choiceSetId }),
|
|
3071
3281
|
...((isRelationship || isFile) && { isForeignKey: true }),
|
|
3072
3282
|
...(isRelationship && { referenceType: exports.ReferenceType.ManyToOne }),
|
|
3073
|
-
...(
|
|
3283
|
+
...(referenceEntityBody !== undefined && { referenceEntity: referenceEntityBody }),
|
|
3284
|
+
...(referenceChoiceSetBody !== undefined && { referenceChoiceSet: referenceChoiceSetBody }),
|
|
3074
3285
|
...(field.referenceFieldId !== undefined && { referenceField: { id: field.referenceFieldId } }),
|
|
3075
3286
|
};
|
|
3076
3287
|
}
|
|
@@ -3233,8 +3444,14 @@ __decorate([
|
|
|
3233
3444
|
|
|
3234
3445
|
class ChoiceSetService extends BaseService {
|
|
3235
3446
|
/**
|
|
3236
|
-
* Gets
|
|
3447
|
+
* Gets choice sets in the tenant.
|
|
3448
|
+
*
|
|
3449
|
+
* Three call modes:
|
|
3450
|
+
* - `getAll()` — default. Returns only tenant-level choice sets.
|
|
3451
|
+
* - `getAll({ folderKey: "<uuid>" })` — preferred for folder-scoped data. Returns only choice sets in that folder.
|
|
3452
|
+
* - `getAll({ includeFolderChoiceSets: true })` — returns tenant-level **and** folder-level choice sets together. `folderKey` is preferred over `includeFolderChoiceSets` when both are set.
|
|
3237
3453
|
*
|
|
3454
|
+
* @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**.
|
|
3238
3455
|
* @returns Promise resolving to an array of choice set metadata
|
|
3239
3456
|
*
|
|
3240
3457
|
* @example
|
|
@@ -3243,18 +3460,33 @@ class ChoiceSetService extends BaseService {
|
|
|
3243
3460
|
*
|
|
3244
3461
|
* const choiceSets = new ChoiceSets(sdk);
|
|
3245
3462
|
*
|
|
3246
|
-
* //
|
|
3247
|
-
* const
|
|
3463
|
+
* // Tenant-only (default)
|
|
3464
|
+
* const tenantChoiceSets = await choiceSets.getAll();
|
|
3248
3465
|
*
|
|
3249
|
-
* //
|
|
3250
|
-
*
|
|
3251
|
-
*
|
|
3252
|
-
*
|
|
3253
|
-
* });
|
|
3466
|
+
* // A single folder's choice sets (preferred when targeting a specific folder)
|
|
3467
|
+
* const folderChoiceSets = await choiceSets.getAll({ folderKey: "<folderKey>" });
|
|
3468
|
+
*
|
|
3469
|
+
* // Tenant + folder choice sets together
|
|
3470
|
+
* const allChoiceSets = await choiceSets.getAll({ includeFolderChoiceSets: true });
|
|
3254
3471
|
* ```
|
|
3255
3472
|
*/
|
|
3256
|
-
async getAll() {
|
|
3257
|
-
|
|
3473
|
+
async getAll(options) {
|
|
3474
|
+
return this.fetchAllChoiceSets(options);
|
|
3475
|
+
}
|
|
3476
|
+
/**
|
|
3477
|
+
* Internal helper that performs the choice-set fetch. Kept separate from the
|
|
3478
|
+
* public `getAll()` so that internal callers (e.g. `resolveChoiceSetName`)
|
|
3479
|
+
* can reuse it without triggering double `@track` telemetry.
|
|
3480
|
+
*/
|
|
3481
|
+
async fetchAllChoiceSets(options) {
|
|
3482
|
+
// The choice-set endpoint returns cross-scope results when called without
|
|
3483
|
+
// a folder header. To stay tenant-only by default, send the tenant-marker
|
|
3484
|
+
// UUID as the folder key unless the caller explicitly opts into cross-scope
|
|
3485
|
+
// via includeFolderChoiceSets: true. folderKey is preferred over
|
|
3486
|
+
// includeFolderChoiceSets when both are set.
|
|
3487
|
+
const folderKey = options?.folderKey
|
|
3488
|
+
?? (options?.includeFolderChoiceSets ? undefined : DATA_FABRIC_TENANT_FOLDER_ID);
|
|
3489
|
+
const rawResponse = await this.get(DATA_FABRIC_ENDPOINTS.CHOICESETS.GET_ALL, { headers: createHeaders({ [FOLDER_KEY]: folderKey }) });
|
|
3258
3490
|
// Transform field names
|
|
3259
3491
|
const data = rawResponse.data || [];
|
|
3260
3492
|
return data.map(choiceSet => transformData(choiceSet, EntityMap));
|
|
@@ -3267,7 +3499,7 @@ class ChoiceSetService extends BaseService {
|
|
|
3267
3499
|
* - A PaginatedResponse with navigation cursors (when any pagination parameter is provided)
|
|
3268
3500
|
*
|
|
3269
3501
|
* @param choiceSetId - UUID of the choice set
|
|
3270
|
-
* @param options - Pagination options
|
|
3502
|
+
* @param options - Pagination options and optional `folderKey` for folder-scoped choice sets The `folderKey` property is **experimental**.
|
|
3271
3503
|
* @returns Promise resolving to choice set values or paginated result
|
|
3272
3504
|
*
|
|
3273
3505
|
* @example
|
|
@@ -3296,6 +3528,9 @@ class ChoiceSetService extends BaseService {
|
|
|
3296
3528
|
* if (page1.hasNextPage) {
|
|
3297
3529
|
* const page2 = await choiceSets.getById(choiceSetId, { cursor: page1.nextCursor });
|
|
3298
3530
|
* }
|
|
3531
|
+
*
|
|
3532
|
+
* // Folder-scoped choice set
|
|
3533
|
+
* const folderValues = await choiceSets.getById(choiceSetId, { folderKey: "<folderKey>" });
|
|
3299
3534
|
* ```
|
|
3300
3535
|
*/
|
|
3301
3536
|
async getById(choiceSetId, options) {
|
|
@@ -3304,11 +3539,16 @@ class ChoiceSetService extends BaseService {
|
|
|
3304
3539
|
const camelCased = pascalToCamelCaseKeys(item);
|
|
3305
3540
|
return transformData(camelCased, EntityMap);
|
|
3306
3541
|
};
|
|
3542
|
+
// folderKey is header-only — destructure it out so PaginationHelpers doesn't
|
|
3543
|
+
// include it in the POST body alongside pagination params.
|
|
3544
|
+
const { folderKey, ...rest } = options ?? {};
|
|
3545
|
+
const downstreamOptions = options === undefined ? undefined : rest;
|
|
3307
3546
|
return PaginationHelpers.getAll({
|
|
3308
3547
|
serviceAccess: this.createPaginationServiceAccess(),
|
|
3309
3548
|
getEndpoint: () => DATA_FABRIC_ENDPOINTS.CHOICESETS.GET_BY_ID(choiceSetId),
|
|
3310
3549
|
transformFn,
|
|
3311
3550
|
method: HTTP_METHODS.POST,
|
|
3551
|
+
headers: createHeaders({ [FOLDER_KEY]: folderKey }),
|
|
3312
3552
|
pagination: {
|
|
3313
3553
|
paginationType: PaginationType.OFFSET,
|
|
3314
3554
|
itemsField: CHOICESET_VALUES_PAGINATION.ITEMS_FIELD,
|
|
@@ -3319,7 +3559,7 @@ class ChoiceSetService extends BaseService {
|
|
|
3319
3559
|
countParam: ENTITY_OFFSET_PARAMS.COUNT_PARAM
|
|
3320
3560
|
}
|
|
3321
3561
|
}
|
|
3322
|
-
},
|
|
3562
|
+
}, downstreamOptions);
|
|
3323
3563
|
}
|
|
3324
3564
|
/**
|
|
3325
3565
|
* Creates a new Data Fabric choice set
|
|
@@ -3327,7 +3567,7 @@ class ChoiceSetService extends BaseService {
|
|
|
3327
3567
|
* @param name - Choice set name. Must start with a
|
|
3328
3568
|
* letter, may contain only letters, numbers, and underscores, length
|
|
3329
3569
|
* 3–100 characters (e.g., `"expenseTypes"`).
|
|
3330
|
-
* @param options - Optional choice-set-level settings ({@link ChoiceSetCreateOptions})
|
|
3570
|
+
* @param options - Optional choice-set-level settings ({@link ChoiceSetCreateOptions}) The `folderKey` property is **experimental**.
|
|
3331
3571
|
* @returns Promise resolving to the UUID of the created choice set
|
|
3332
3572
|
*
|
|
3333
3573
|
* @example
|
|
@@ -3358,7 +3598,7 @@ class ChoiceSetService extends BaseService {
|
|
|
3358
3598
|
folderId: opts.folderKey ?? DATA_FABRIC_TENANT_FOLDER_ID,
|
|
3359
3599
|
},
|
|
3360
3600
|
};
|
|
3361
|
-
const response = await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.CREATE, payload);
|
|
3601
|
+
const response = await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.CREATE, payload, { headers: createHeaders({ [FOLDER_KEY]: opts.folderKey }) });
|
|
3362
3602
|
return response.data;
|
|
3363
3603
|
}
|
|
3364
3604
|
/**
|
|
@@ -3368,7 +3608,7 @@ class ChoiceSetService extends BaseService {
|
|
|
3368
3608
|
* the call throws `ValidationError` if both are omitted.
|
|
3369
3609
|
*
|
|
3370
3610
|
* @param choiceSetId - UUID of the choice set to update
|
|
3371
|
-
* @param options - Metadata fields to change ({@link ChoiceSetUpdateOptions})
|
|
3611
|
+
* @param options - Metadata fields to change ({@link ChoiceSetUpdateOptions}) The `folderKey` property is **experimental**.
|
|
3372
3612
|
* @returns Promise resolving when the update is complete
|
|
3373
3613
|
*
|
|
3374
3614
|
* @example
|
|
@@ -3393,12 +3633,13 @@ class ChoiceSetService extends BaseService {
|
|
|
3393
3633
|
await this.patch(DATA_FABRIC_ENDPOINTS.CHOICESETS.UPDATE(choiceSetId), {
|
|
3394
3634
|
...(options.displayName !== undefined && { displayName: options.displayName }),
|
|
3395
3635
|
...(options.description !== undefined && { description: options.description }),
|
|
3396
|
-
});
|
|
3636
|
+
}, { headers: createHeaders({ [FOLDER_KEY]: options.folderKey }) });
|
|
3397
3637
|
}
|
|
3398
3638
|
/**
|
|
3399
3639
|
* Deletes a Data Fabric choice set and all its values.
|
|
3400
3640
|
*
|
|
3401
3641
|
* @param choiceSetId - UUID of the choice set to delete
|
|
3642
|
+
* @param options - Optional {@link ChoiceSetDeleteByIdOptions} (e.g. `folderKey` for folder-scoped choice sets) The `folderKey` property is **experimental**.
|
|
3402
3643
|
* @returns Promise resolving when the choice set is deleted
|
|
3403
3644
|
*
|
|
3404
3645
|
* @example
|
|
@@ -3408,18 +3649,21 @@ class ChoiceSetService extends BaseService {
|
|
|
3408
3649
|
* const expenseTypes = allChoiceSets.find(cs => cs.name === 'expense_types');
|
|
3409
3650
|
*
|
|
3410
3651
|
* await choicesets.deleteById(expenseTypes.id);
|
|
3652
|
+
*
|
|
3653
|
+
* // Folder-scoped choice set
|
|
3654
|
+
* await choicesets.deleteById(expenseTypes.id, { folderKey: "<folderKey>" });
|
|
3411
3655
|
* ```
|
|
3412
3656
|
* @internal
|
|
3413
3657
|
*/
|
|
3414
|
-
async deleteById(choiceSetId) {
|
|
3415
|
-
await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.DELETE(choiceSetId), {});
|
|
3658
|
+
async deleteById(choiceSetId, options) {
|
|
3659
|
+
await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.DELETE(choiceSetId), {}, { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
|
|
3416
3660
|
}
|
|
3417
3661
|
/**
|
|
3418
3662
|
* Inserts a single value into a choice set.
|
|
3419
3663
|
*
|
|
3420
3664
|
* @param choiceSetId - UUID of the parent choice set
|
|
3421
3665
|
* @param name - Identifier name of the new value (e.g., `"TRAVEL"`)
|
|
3422
|
-
* @param options - Optional fields ({@link ChoiceSetValueInsertOptions})
|
|
3666
|
+
* @param options - Optional fields ({@link ChoiceSetValueInsertOptions}) The `folderKey` property is **experimental**.
|
|
3423
3667
|
* @returns Promise resolving to the inserted value ({@link ChoiceSetValueInsertResponse})
|
|
3424
3668
|
*
|
|
3425
3669
|
* @example
|
|
@@ -3432,16 +3676,22 @@ class ChoiceSetService extends BaseService {
|
|
|
3432
3676
|
* displayName: 'Travel',
|
|
3433
3677
|
* });
|
|
3434
3678
|
* console.log(inserted.id);
|
|
3679
|
+
*
|
|
3680
|
+
* // Folder-scoped choice set: folderKey is required on the wire
|
|
3681
|
+
* await choicesets.insertValueById(expenseTypes.id, 'TRAVEL', {
|
|
3682
|
+
* displayName: 'Travel',
|
|
3683
|
+
* folderKey: "<folderKey>",
|
|
3684
|
+
* });
|
|
3435
3685
|
* ```
|
|
3436
3686
|
* @internal
|
|
3437
3687
|
*/
|
|
3438
3688
|
async insertValueById(choiceSetId, name, options) {
|
|
3439
|
-
const choiceSetName = await this.resolveChoiceSetName(choiceSetId);
|
|
3689
|
+
const choiceSetName = await this.resolveChoiceSetName(choiceSetId, options?.folderKey);
|
|
3440
3690
|
const payload = {
|
|
3441
3691
|
Name: name,
|
|
3442
3692
|
...(options?.displayName !== undefined && { DisplayName: options.displayName }),
|
|
3443
3693
|
};
|
|
3444
|
-
const response = await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.INSERT_BY_NAME(choiceSetName), payload);
|
|
3694
|
+
const response = await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.INSERT_BY_NAME(choiceSetName), payload, { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
|
|
3445
3695
|
const camelCased = pascalToCamelCaseKeys(response.data);
|
|
3446
3696
|
return transformData(camelCased, EntityMap);
|
|
3447
3697
|
}
|
|
@@ -3454,6 +3704,7 @@ class ChoiceSetService extends BaseService {
|
|
|
3454
3704
|
* @param choiceSetId - UUID of the parent choice set
|
|
3455
3705
|
* @param valueId - UUID of the value to update
|
|
3456
3706
|
* @param displayName - New human-readable display name for the value
|
|
3707
|
+
* @param options - Optional {@link ChoiceSetValueUpdateOptions} — pass `folderKey` for folder-scoped choice sets; omit for tenant-level. The `folderKey` property is **experimental**.
|
|
3457
3708
|
* @returns Promise resolving to the updated value ({@link ChoiceSetValueUpdateResponse})
|
|
3458
3709
|
*
|
|
3459
3710
|
* @example
|
|
@@ -3465,13 +3716,18 @@ class ChoiceSetService extends BaseService {
|
|
|
3465
3716
|
* const travel = values.items.find(v => v.name === 'TRAVEL');
|
|
3466
3717
|
*
|
|
3467
3718
|
* await choicesets.updateValueById(expenseTypes.id, travel.id, 'Business Travel');
|
|
3719
|
+
*
|
|
3720
|
+
* // Folder-scoped choice set: folderKey is required on the wire
|
|
3721
|
+
* await choicesets.updateValueById(expenseTypes.id, travel.id, 'Business Travel', {
|
|
3722
|
+
* folderKey: "<folderKey>",
|
|
3723
|
+
* });
|
|
3468
3724
|
* ```
|
|
3469
3725
|
* @internal
|
|
3470
3726
|
*/
|
|
3471
|
-
async updateValueById(choiceSetId, valueId, displayName) {
|
|
3472
|
-
const choiceSetName = await this.resolveChoiceSetName(choiceSetId);
|
|
3727
|
+
async updateValueById(choiceSetId, valueId, displayName, options) {
|
|
3728
|
+
const choiceSetName = await this.resolveChoiceSetName(choiceSetId, options?.folderKey);
|
|
3473
3729
|
const payload = { DisplayName: displayName };
|
|
3474
|
-
const response = await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.UPDATE_BY_NAME(choiceSetName, valueId), payload);
|
|
3730
|
+
const response = await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.UPDATE_BY_NAME(choiceSetName, valueId), payload, { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
|
|
3475
3731
|
const camelCased = pascalToCamelCaseKeys(response.data);
|
|
3476
3732
|
return transformData(camelCased, EntityMap);
|
|
3477
3733
|
}
|
|
@@ -3480,6 +3736,7 @@ class ChoiceSetService extends BaseService {
|
|
|
3480
3736
|
*
|
|
3481
3737
|
* @param choiceSetId - UUID of the parent choice set
|
|
3482
3738
|
* @param valueIds - Array of value UUIDs to delete
|
|
3739
|
+
* @param options - Optional {@link ChoiceSetValueDeleteOptions} (e.g. `folderKey` for folder-scoped choice sets) The `folderKey` property is **experimental**.
|
|
3483
3740
|
* @returns Promise resolving when the values are deleted
|
|
3484
3741
|
*
|
|
3485
3742
|
* @example
|
|
@@ -3489,14 +3746,20 @@ class ChoiceSetService extends BaseService {
|
|
|
3489
3746
|
* const idsToDelete = values.items.slice(0, 2).map(v => v.id);
|
|
3490
3747
|
*
|
|
3491
3748
|
* await choicesets.deleteValuesById('<choiceSetId>', idsToDelete);
|
|
3749
|
+
*
|
|
3750
|
+
* // Folder-scoped choice set
|
|
3751
|
+
* await choicesets.deleteValuesById('<choiceSetId>', idsToDelete, { folderKey: "<folderKey>" });
|
|
3492
3752
|
* ```
|
|
3493
3753
|
* @internal
|
|
3494
3754
|
*/
|
|
3495
|
-
async deleteValuesById(choiceSetId, valueIds) {
|
|
3496
|
-
await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.DELETE_BY_ID(choiceSetId), valueIds);
|
|
3755
|
+
async deleteValuesById(choiceSetId, valueIds, options) {
|
|
3756
|
+
await this.post(DATA_FABRIC_ENDPOINTS.CHOICESETS.DELETE_BY_ID(choiceSetId), valueIds, { headers: createHeaders({ [FOLDER_KEY]: options?.folderKey }) });
|
|
3497
3757
|
}
|
|
3498
|
-
async resolveChoiceSetName(choiceSetId) {
|
|
3499
|
-
|
|
3758
|
+
async resolveChoiceSetName(choiceSetId, folderKey) {
|
|
3759
|
+
// Use the un-tracked helper directly so we don't fire a duplicate
|
|
3760
|
+
// `Choicesets.GetAll` telemetry event for every insertValueById /
|
|
3761
|
+
// updateValueById call.
|
|
3762
|
+
const all = await this.fetchAllChoiceSets(folderKey === undefined ? undefined : { folderKey });
|
|
3500
3763
|
const match = all.find(cs => cs.id === choiceSetId);
|
|
3501
3764
|
if (!match) {
|
|
3502
3765
|
throw new NotFoundError({ message: `Choice set with id '${choiceSetId}' not found.` });
|