@uipath/uipath-typescript 1.0.0-beta.13 → 1.0.0-beta.14
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/{Readme.md → README.md} +53 -10
- package/dist/index.d.ts +1323 -516
- package/dist/index.esm.js +1859 -1060
- package/dist/index.js +1859 -1059
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2092,8 +2092,11 @@ class TokenManager {
|
|
|
2092
2092
|
* Maestro Process Service Endpoints
|
|
2093
2093
|
*/
|
|
2094
2094
|
const MAESTRO_ENDPOINTS = {
|
|
2095
|
+
BASE_PATH: 'pims_/api/v1',
|
|
2095
2096
|
PROCESSES: {
|
|
2096
|
-
GET_ALL: 'pims_/api/v1/processes/summary'
|
|
2097
|
+
GET_ALL: 'pims_/api/v1/processes/summary',
|
|
2098
|
+
GET_SETTINGS: (processKey) => `pims_/api/v1/processes/${processKey}/settings`,
|
|
2099
|
+
},
|
|
2097
2100
|
INSTANCES: {
|
|
2098
2101
|
GET_ALL: 'pims_/api/v1/instances',
|
|
2099
2102
|
GET_BY_ID: (instanceId) => `pims_/api/v1/instances/${instanceId}`,
|
|
@@ -2104,6 +2107,10 @@ const MAESTRO_ENDPOINTS = {
|
|
|
2104
2107
|
PAUSE: (instanceId) => `pims_/api/v1/instances/${instanceId}/pause`,
|
|
2105
2108
|
RESUME: (instanceId) => `pims_/api/v1/instances/${instanceId}/resume`,
|
|
2106
2109
|
},
|
|
2110
|
+
CASES: {
|
|
2111
|
+
GET_CASE_JSON: (instanceId) => `pims_/api/v1/cases/${instanceId}/case-json`,
|
|
2112
|
+
GET_ELEMENT_EXECUTIONS: (instanceId) => `pims_/api/v1alpha1/element-executions/case-instances/${instanceId}`,
|
|
2113
|
+
},
|
|
2107
2114
|
};
|
|
2108
2115
|
/**
|
|
2109
2116
|
* Task Service (Action Center) Endpoints
|
|
@@ -2111,7 +2118,7 @@ const MAESTRO_ENDPOINTS = {
|
|
|
2111
2118
|
const TASK_ENDPOINTS = {
|
|
2112
2119
|
CREATE_GENERIC_TASK: '/tasks/GenericTasks/CreateTask',
|
|
2113
2120
|
GET_TASK_USERS: (folderId) => `/odata/Tasks/UiPath.Server.Configuration.OData.GetTaskUsers(organizationUnitId=${folderId})`,
|
|
2114
|
-
GET_TASKS_ACROSS_FOLDERS: '/odata/Tasks/UiPath.Server.Configuration.OData.
|
|
2121
|
+
GET_TASKS_ACROSS_FOLDERS: '/odata/Tasks/UiPath.Server.Configuration.OData.GetTasksAcrossFoldersForAdmin',
|
|
2115
2122
|
GET_BY_ID: (id) => `/odata/Tasks(${id})`,
|
|
2116
2123
|
ASSIGN_TASKS: '/odata/Tasks/UiPath.Server.Configuration.OData.AssignTasks',
|
|
2117
2124
|
REASSIGN_TASKS: '/odata/Tasks/UiPath.Server.Configuration.OData.ReassignTasks',
|
|
@@ -2179,11 +2186,66 @@ const ASSET_ENDPOINTS = {
|
|
|
2179
2186
|
|
|
2180
2187
|
class AuthService extends BaseService {
|
|
2181
2188
|
constructor(config, executionContext) {
|
|
2182
|
-
|
|
2183
|
-
const
|
|
2184
|
-
|
|
2189
|
+
// Check if we should use stored OAuth context instead of provided config
|
|
2190
|
+
const storedContext = AuthService.getStoredOAuthContext();
|
|
2191
|
+
const effectiveConfig = storedContext ? AuthService._mergeConfigWithContext(config, storedContext) : config;
|
|
2192
|
+
const isOAuth = hasOAuthConfig(effectiveConfig);
|
|
2193
|
+
const tokenManager = new TokenManager(executionContext, effectiveConfig, isOAuth);
|
|
2194
|
+
super(effectiveConfig, executionContext, tokenManager);
|
|
2185
2195
|
this.tokenManager = tokenManager;
|
|
2186
2196
|
}
|
|
2197
|
+
/**
|
|
2198
|
+
* Check if we're in an OAuth callback state
|
|
2199
|
+
*/
|
|
2200
|
+
static isInOAuthCallback() {
|
|
2201
|
+
if (!isBrowser)
|
|
2202
|
+
return false;
|
|
2203
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
2204
|
+
const code = urlParams.get('code');
|
|
2205
|
+
const hasCodeVerifier = sessionStorage.getItem('uipath_sdk_code_verifier');
|
|
2206
|
+
return !!(code && hasCodeVerifier);
|
|
2207
|
+
}
|
|
2208
|
+
/**
|
|
2209
|
+
* Get stored OAuth context
|
|
2210
|
+
*/
|
|
2211
|
+
static getStoredOAuthContext() {
|
|
2212
|
+
if (!isBrowser) {
|
|
2213
|
+
return null;
|
|
2214
|
+
}
|
|
2215
|
+
try {
|
|
2216
|
+
const stored = sessionStorage.getItem('uipath_sdk_oauth_context');
|
|
2217
|
+
if (!stored) {
|
|
2218
|
+
return null;
|
|
2219
|
+
}
|
|
2220
|
+
const context = JSON.parse(stored);
|
|
2221
|
+
// Validate required fields
|
|
2222
|
+
if (!context.codeVerifier || !context.clientId || !context.redirectUri ||
|
|
2223
|
+
!context.baseUrl || !context.orgName) {
|
|
2224
|
+
sessionStorage.removeItem('uipath_sdk_oauth_context');
|
|
2225
|
+
return null;
|
|
2226
|
+
}
|
|
2227
|
+
return context;
|
|
2228
|
+
}
|
|
2229
|
+
catch (error) {
|
|
2230
|
+
sessionStorage.removeItem('uipath_sdk_oauth_context');
|
|
2231
|
+
console.warn('Failed to parse stored OAuth context from session storage', error);
|
|
2232
|
+
return null;
|
|
2233
|
+
}
|
|
2234
|
+
}
|
|
2235
|
+
/**
|
|
2236
|
+
* Merges provided config with stored OAuth context, prioritizing stored values
|
|
2237
|
+
*/
|
|
2238
|
+
static _mergeConfigWithContext(config, context) {
|
|
2239
|
+
return {
|
|
2240
|
+
...config,
|
|
2241
|
+
baseUrl: context.baseUrl,
|
|
2242
|
+
orgName: context.orgName,
|
|
2243
|
+
tenantName: context.tenantName,
|
|
2244
|
+
clientId: context.clientId,
|
|
2245
|
+
redirectUri: context.redirectUri,
|
|
2246
|
+
scope: context.scope
|
|
2247
|
+
};
|
|
2248
|
+
}
|
|
2187
2249
|
/**
|
|
2188
2250
|
* Get the token manager instance
|
|
2189
2251
|
*/
|
|
@@ -2199,13 +2261,34 @@ class AuthService extends BaseService {
|
|
|
2199
2261
|
* In an OAuth flow, this method will trigger a page redirect and the promise will not resolve.
|
|
2200
2262
|
*/
|
|
2201
2263
|
async authenticate(config) {
|
|
2202
|
-
|
|
2264
|
+
if (!isBrowser) {
|
|
2265
|
+
return false;
|
|
2266
|
+
}
|
|
2267
|
+
// First priority: Complete OAuth callback if we detect it
|
|
2268
|
+
if (AuthService.isInOAuthCallback()) {
|
|
2269
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
2270
|
+
const code = urlParams.get('code');
|
|
2271
|
+
if (!code) {
|
|
2272
|
+
throw new Error('Authorization code missing in OAuth callback');
|
|
2273
|
+
}
|
|
2274
|
+
// Check if token already exists (prevents duplicate processing)
|
|
2275
|
+
if (this.tokenManager.hasValidToken()) {
|
|
2276
|
+
return true;
|
|
2277
|
+
}
|
|
2278
|
+
// Ensure we have OAuth config for callback completion
|
|
2279
|
+
if (!hasOAuthConfig(config)) {
|
|
2280
|
+
throw new Error('OAuth configuration incomplete: clientId, redirectUri, and scope are required for OAuth callback');
|
|
2281
|
+
}
|
|
2282
|
+
const result = await this._authenticateWithOAuth(config.clientId, config.redirectUri, config.scope);
|
|
2283
|
+
return result;
|
|
2284
|
+
}
|
|
2285
|
+
// Secondly: Try to load existing valid token from storage
|
|
2203
2286
|
const loadedFromStorage = this.tokenManager.loadFromStorage();
|
|
2204
2287
|
// If we have a valid token from storage, return true
|
|
2205
2288
|
if (loadedFromStorage && this.tokenManager.hasValidToken()) {
|
|
2206
2289
|
return true;
|
|
2207
2290
|
}
|
|
2208
|
-
//
|
|
2291
|
+
// Start new OAuth flow if config has OAuth fields
|
|
2209
2292
|
if (hasOAuthConfig(config)) {
|
|
2210
2293
|
return await this._authenticateWithOAuth(config.clientId, config.redirectUri, config.scope);
|
|
2211
2294
|
}
|
|
@@ -2388,6 +2471,17 @@ class AuthService extends BaseService {
|
|
|
2388
2471
|
async _initiateOAuthFlow(clientId, redirectUri, scope) {
|
|
2389
2472
|
const codeVerifier = this.generateCodeVerifier();
|
|
2390
2473
|
const codeChallenge = await this.generateCodeChallenge(codeVerifier);
|
|
2474
|
+
// Store complete OAuth context for callback completion
|
|
2475
|
+
const oauthContext = {
|
|
2476
|
+
codeVerifier,
|
|
2477
|
+
clientId,
|
|
2478
|
+
redirectUri,
|
|
2479
|
+
baseUrl: this.config.baseUrl,
|
|
2480
|
+
orgName: this.config.orgName,
|
|
2481
|
+
tenantName: this.config.tenantName,
|
|
2482
|
+
scope
|
|
2483
|
+
};
|
|
2484
|
+
sessionStorage.setItem('uipath_sdk_oauth_context', JSON.stringify(oauthContext));
|
|
2391
2485
|
sessionStorage.setItem('uipath_sdk_code_verifier', codeVerifier);
|
|
2392
2486
|
const authUrl = this.getAuthorizationUrl({
|
|
2393
2487
|
clientId,
|
|
@@ -2402,13 +2496,15 @@ class AuthService extends BaseService {
|
|
|
2402
2496
|
if (!codeVerifier) {
|
|
2403
2497
|
throw new Error('Code verifier not found in session storage. Authentication may have been interrupted.');
|
|
2404
2498
|
}
|
|
2405
|
-
sessionStorage.removeItem('uipath_sdk_code_verifier');
|
|
2406
2499
|
await this._getAccessToken({
|
|
2407
2500
|
clientId,
|
|
2408
2501
|
redirectUri,
|
|
2409
2502
|
code,
|
|
2410
2503
|
codeVerifier
|
|
2411
2504
|
});
|
|
2505
|
+
// Clear OAuth context and code verifier after successful token exchange
|
|
2506
|
+
sessionStorage.removeItem('uipath_sdk_oauth_context');
|
|
2507
|
+
sessionStorage.removeItem('uipath_sdk_code_verifier');
|
|
2412
2508
|
const url = new URL(window.location.href);
|
|
2413
2509
|
url.searchParams.delete('code');
|
|
2414
2510
|
url.searchParams.delete('state');
|
|
@@ -2637,7 +2733,7 @@ const EntityFieldTypeMap = {
|
|
|
2637
2733
|
// Connection string placeholder that will be replaced during build
|
|
2638
2734
|
const CONNECTION_STRING = "InstrumentationKey=a6efa11d-1feb-4508-9738-e13e12dcae5e;IngestionEndpoint=https://westeurope-5.in.applicationinsights.azure.com/;LiveEndpoint=https://westeurope.livediagnostics.monitor.azure.com/;ApplicationId=7c58eb1c-9581-4ba6-839e-11725848a037";
|
|
2639
2735
|
// SDK Version placeholder
|
|
2640
|
-
const SDK_VERSION = "1.0.0-beta.
|
|
2736
|
+
const SDK_VERSION = "1.0.0-beta.14";
|
|
2641
2737
|
const VERSION = "Version";
|
|
2642
2738
|
const SERVICE = "Service";
|
|
2643
2739
|
const CLOUD_ORGANIZATION_NAME = "CloudOrganizationName";
|
|
@@ -3301,6 +3397,94 @@ function createProcessInstanceWithMethods(instanceData, service) {
|
|
|
3301
3397
|
return Object.assign({}, instanceData, methods);
|
|
3302
3398
|
}
|
|
3303
3399
|
|
|
3400
|
+
/**
|
|
3401
|
+
* Case Instance Types
|
|
3402
|
+
* Types and interfaces for Maestro case instance management
|
|
3403
|
+
*/
|
|
3404
|
+
/**
|
|
3405
|
+
* Case stage task type
|
|
3406
|
+
*/
|
|
3407
|
+
exports.StageTaskType = void 0;
|
|
3408
|
+
(function (StageTaskType) {
|
|
3409
|
+
StageTaskType["EXTERNAL_AGENT"] = "external-agent";
|
|
3410
|
+
StageTaskType["RPA"] = "rpa";
|
|
3411
|
+
StageTaskType["AGENTIC_PROCESS"] = "process";
|
|
3412
|
+
StageTaskType["AGENT"] = "agent";
|
|
3413
|
+
StageTaskType["ACTION"] = "action";
|
|
3414
|
+
StageTaskType["API_WORKFLOW"] = "api-workflow";
|
|
3415
|
+
})(exports.StageTaskType || (exports.StageTaskType = {}));
|
|
3416
|
+
/**
|
|
3417
|
+
* Escalation recipient scope
|
|
3418
|
+
*/
|
|
3419
|
+
exports.EscalationRecipientScope = void 0;
|
|
3420
|
+
(function (EscalationRecipientScope) {
|
|
3421
|
+
EscalationRecipientScope["USER"] = "user";
|
|
3422
|
+
EscalationRecipientScope["USER_GROUP"] = "usergroup";
|
|
3423
|
+
})(exports.EscalationRecipientScope || (exports.EscalationRecipientScope = {}));
|
|
3424
|
+
/**
|
|
3425
|
+
* Escalation action type
|
|
3426
|
+
*/
|
|
3427
|
+
exports.EscalationActionType = void 0;
|
|
3428
|
+
(function (EscalationActionType) {
|
|
3429
|
+
EscalationActionType["NOTIFICATION"] = "notification";
|
|
3430
|
+
})(exports.EscalationActionType || (exports.EscalationActionType = {}));
|
|
3431
|
+
/**
|
|
3432
|
+
* Escalation rule trigger type
|
|
3433
|
+
*/
|
|
3434
|
+
exports.EscalationTriggerType = void 0;
|
|
3435
|
+
(function (EscalationTriggerType) {
|
|
3436
|
+
EscalationTriggerType["SLA_BREACHED"] = "sla-breached";
|
|
3437
|
+
EscalationTriggerType["AT_RISK"] = "at-risk";
|
|
3438
|
+
})(exports.EscalationTriggerType || (exports.EscalationTriggerType = {}));
|
|
3439
|
+
/**
|
|
3440
|
+
* SLA duration unit
|
|
3441
|
+
*/
|
|
3442
|
+
exports.SLADurationUnit = void 0;
|
|
3443
|
+
(function (SLADurationUnit) {
|
|
3444
|
+
SLADurationUnit["HOURS"] = "h";
|
|
3445
|
+
SLADurationUnit["DAYS"] = "d";
|
|
3446
|
+
SLADurationUnit["WEEKS"] = "w";
|
|
3447
|
+
SLADurationUnit["MONTHS"] = "m";
|
|
3448
|
+
})(exports.SLADurationUnit || (exports.SLADurationUnit = {}));
|
|
3449
|
+
|
|
3450
|
+
/**
|
|
3451
|
+
* Creates methods for a case instance
|
|
3452
|
+
*
|
|
3453
|
+
* @param instanceData - The case instance data (response from API)
|
|
3454
|
+
* @param service - The case instance service instance
|
|
3455
|
+
* @returns Object containing case instance methods
|
|
3456
|
+
*/
|
|
3457
|
+
function createCaseInstanceMethods(instanceData, service) {
|
|
3458
|
+
return {
|
|
3459
|
+
async close(options) {
|
|
3460
|
+
if (!instanceData.instanceId)
|
|
3461
|
+
throw new Error('Case instance ID is undefined');
|
|
3462
|
+
return service.close(instanceData.instanceId, instanceData.folderKey, options);
|
|
3463
|
+
},
|
|
3464
|
+
async pause(options) {
|
|
3465
|
+
if (!instanceData.instanceId)
|
|
3466
|
+
throw new Error('Case instance ID is undefined');
|
|
3467
|
+
return service.pause(instanceData.instanceId, instanceData.folderKey, options);
|
|
3468
|
+
},
|
|
3469
|
+
async resume(options) {
|
|
3470
|
+
if (!instanceData.instanceId)
|
|
3471
|
+
throw new Error('Case instance ID is undefined');
|
|
3472
|
+
return service.resume(instanceData.instanceId, instanceData.folderKey, options);
|
|
3473
|
+
}
|
|
3474
|
+
};
|
|
3475
|
+
}
|
|
3476
|
+
/**
|
|
3477
|
+
* Creates an actionable case instance by combining API case instance data with operational methods.
|
|
3478
|
+
*
|
|
3479
|
+
* @param instanceData - The case instance data from API
|
|
3480
|
+
* @param service - The case instance service instance
|
|
3481
|
+
* @returns A case instance object with added methods
|
|
3482
|
+
*/
|
|
3483
|
+
function createCaseInstanceWithMethods(instanceData, service) {
|
|
3484
|
+
const methods = createCaseInstanceMethods(instanceData, service);
|
|
3485
|
+
return Object.assign({}, instanceData, methods);
|
|
3486
|
+
}
|
|
3487
|
+
|
|
3304
3488
|
/**
|
|
3305
3489
|
* Maps fields for Process Instance entities to ensure consistent naming
|
|
3306
3490
|
*/
|
|
@@ -3610,48 +3794,21 @@ __decorate([
|
|
|
3610
3794
|
], ProcessInstancesService.prototype, "getVariables", null);
|
|
3611
3795
|
|
|
3612
3796
|
/**
|
|
3613
|
-
*
|
|
3797
|
+
* Internal types for Maestro Cases
|
|
3798
|
+
* These types are used internally by the cases service
|
|
3614
3799
|
*/
|
|
3615
|
-
class FolderScopedService extends BaseService {
|
|
3616
|
-
constructor(config, executionContext, tokenManager) {
|
|
3617
|
-
super(config, executionContext, tokenManager);
|
|
3618
|
-
}
|
|
3619
|
-
/**
|
|
3620
|
-
* Gets resources in a folder with optional query parameters
|
|
3621
|
-
*
|
|
3622
|
-
* @param endpoint - API endpoint to call
|
|
3623
|
-
* @param folderId - required folder ID
|
|
3624
|
-
* @param options - Query options
|
|
3625
|
-
* @param transformFn - Optional function to transform the response data
|
|
3626
|
-
* @returns Promise resolving to an array of resources
|
|
3627
|
-
*/
|
|
3628
|
-
async _getByFolder(endpoint, folderId, options = {}, transformFn) {
|
|
3629
|
-
const headers = createHeaders({ [FOLDER_ID]: folderId });
|
|
3630
|
-
const keysToPrefix = Object.keys(options);
|
|
3631
|
-
const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
|
|
3632
|
-
const response = await this.get(endpoint, {
|
|
3633
|
-
params: apiOptions,
|
|
3634
|
-
headers
|
|
3635
|
-
});
|
|
3636
|
-
if (transformFn) {
|
|
3637
|
-
return response.data?.value.map(transformFn);
|
|
3638
|
-
}
|
|
3639
|
-
return response.data?.value;
|
|
3640
|
-
}
|
|
3641
|
-
}
|
|
3642
|
-
|
|
3643
3800
|
/**
|
|
3644
|
-
*
|
|
3801
|
+
* Process type enum for filtering
|
|
3645
3802
|
*/
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
};
|
|
3803
|
+
var ProcessType;
|
|
3804
|
+
(function (ProcessType) {
|
|
3805
|
+
ProcessType["CaseManagement"] = "CaseManagement";
|
|
3806
|
+
})(ProcessType || (ProcessType = {}));
|
|
3650
3807
|
|
|
3651
3808
|
/**
|
|
3652
|
-
* Service for interacting with UiPath
|
|
3809
|
+
* Service for interacting with UiPath Maestro Cases
|
|
3653
3810
|
*/
|
|
3654
|
-
class
|
|
3811
|
+
class CasesService extends BaseService {
|
|
3655
3812
|
/**
|
|
3656
3813
|
* @hideconstructor
|
|
3657
3814
|
*/
|
|
@@ -3659,195 +3816,346 @@ class AssetService extends FolderScopedService {
|
|
|
3659
3816
|
super(config, executionContext, tokenManager);
|
|
3660
3817
|
}
|
|
3661
3818
|
/**
|
|
3662
|
-
*
|
|
3663
|
-
*
|
|
3664
|
-
* @signature getAll(options?) -> Promise<AssetGetResponse[]>
|
|
3665
|
-
* @param options Query options including optional folderId and pagination options
|
|
3666
|
-
* @returns Promise resolving to array of assets or paginated response
|
|
3819
|
+
* Get all case management processes with their instance statistics
|
|
3820
|
+
* @returns Promise resolving to array of Case objects
|
|
3667
3821
|
*
|
|
3668
3822
|
* @example
|
|
3669
3823
|
* ```typescript
|
|
3670
|
-
* //
|
|
3671
|
-
* const
|
|
3672
|
-
*
|
|
3673
|
-
* // With folder
|
|
3674
|
-
* const folderAssets = await sdk.assets.getAll({ folderId: 123 });
|
|
3675
|
-
*
|
|
3676
|
-
* // First page with pagination
|
|
3677
|
-
* const page1 = await sdk.assets.getAll({ pageSize: 10 });
|
|
3824
|
+
* // Get all case management processes
|
|
3825
|
+
* const cases = await sdk.maestro.cases.getAll();
|
|
3678
3826
|
*
|
|
3679
|
-
* //
|
|
3680
|
-
*
|
|
3681
|
-
*
|
|
3827
|
+
* // Access case information
|
|
3828
|
+
* for (const caseProcess of cases) {
|
|
3829
|
+
* console.log(`Case Process: ${caseProcess.processKey}`);
|
|
3830
|
+
* console.log(`Running instances: ${caseProcess.runningCount}`);
|
|
3831
|
+
* console.log(`Completed instances: ${caseProcess.completedCount}`);
|
|
3682
3832
|
* }
|
|
3683
3833
|
*
|
|
3684
|
-
* // Jump to specific page
|
|
3685
|
-
* const page5 = await sdk.assets.getAll({
|
|
3686
|
-
* jumpToPage: 5,
|
|
3687
|
-
* pageSize: 10
|
|
3688
|
-
* });
|
|
3689
3834
|
* ```
|
|
3690
3835
|
*/
|
|
3691
|
-
async getAll(
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
totalCountField: ODATA_PAGINATION.TOTAL_COUNT_FIELD,
|
|
3703
|
-
paginationParams: {
|
|
3704
|
-
pageSizeParam: ODATA_OFFSET_PARAMS.PAGE_SIZE_PARAM,
|
|
3705
|
-
offsetParam: ODATA_OFFSET_PARAMS.OFFSET_PARAM,
|
|
3706
|
-
countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM
|
|
3707
|
-
}
|
|
3708
|
-
}
|
|
3709
|
-
}, options);
|
|
3836
|
+
async getAll() {
|
|
3837
|
+
const params = createParams({
|
|
3838
|
+
processType: ProcessType.CaseManagement
|
|
3839
|
+
});
|
|
3840
|
+
const response = await this.get(MAESTRO_ENDPOINTS.PROCESSES.GET_ALL, { params });
|
|
3841
|
+
// Extract processes array from response data and add name field
|
|
3842
|
+
const cases = response.data?.processes || [];
|
|
3843
|
+
return cases.map(caseItem => ({
|
|
3844
|
+
...caseItem,
|
|
3845
|
+
name: this.extractCaseName(caseItem.packageId)
|
|
3846
|
+
}));
|
|
3710
3847
|
}
|
|
3711
3848
|
/**
|
|
3712
|
-
*
|
|
3713
|
-
*
|
|
3714
|
-
* @
|
|
3715
|
-
* @
|
|
3716
|
-
* @param options - Optional query parameters (expand, select)
|
|
3717
|
-
* @returns Promise resolving to a single asset
|
|
3718
|
-
*
|
|
3719
|
-
* @example
|
|
3720
|
-
* ```typescript
|
|
3721
|
-
* // Get asset by ID
|
|
3722
|
-
* const asset = await sdk.assets.getById(123, 456);
|
|
3723
|
-
* ```
|
|
3849
|
+
* Extract a readable case name from the packageId
|
|
3850
|
+
* @param packageId - The full package identifier
|
|
3851
|
+
* @returns A human-readable case name
|
|
3852
|
+
* @private
|
|
3724
3853
|
*/
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
const
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
return
|
|
3854
|
+
extractCaseName(packageId) {
|
|
3855
|
+
// Check if packageId contains "CaseManagement."
|
|
3856
|
+
const caseManagementIndex = packageId.indexOf('CaseManagement.');
|
|
3857
|
+
if (caseManagementIndex !== -1) {
|
|
3858
|
+
// Extract everything after "CaseManagement."
|
|
3859
|
+
const afterCaseManagement = packageId.substring(caseManagementIndex + 'CaseManagement.'.length);
|
|
3860
|
+
// Replace hyphens with spaces for better readability
|
|
3861
|
+
return afterCaseManagement.replace(/-/g, ' ');
|
|
3862
|
+
}
|
|
3863
|
+
// If no "CaseManagement.", return the whole packageId
|
|
3864
|
+
return packageId;
|
|
3735
3865
|
}
|
|
3736
3866
|
}
|
|
3737
3867
|
__decorate([
|
|
3738
|
-
track('
|
|
3739
|
-
],
|
|
3740
|
-
__decorate([
|
|
3741
|
-
track('Assets.GetById')
|
|
3742
|
-
], AssetService.prototype, "getById", null);
|
|
3868
|
+
track('Cases.GetAll')
|
|
3869
|
+
], CasesService.prototype, "getAll", null);
|
|
3743
3870
|
|
|
3744
3871
|
/**
|
|
3745
|
-
* Maps fields for
|
|
3872
|
+
* Maps fields for Case Instance entities to ensure consistent naming
|
|
3746
3873
|
*/
|
|
3747
|
-
const
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3874
|
+
const CaseInstanceMap = {
|
|
3875
|
+
startedTimeUtc: 'startedTime',
|
|
3876
|
+
completedTimeUtc: 'completedTime',
|
|
3877
|
+
expiryTimeUtc: 'expiredTime',
|
|
3878
|
+
createdAt: 'createdTime',
|
|
3879
|
+
updatedAt: 'updatedTime',
|
|
3880
|
+
externalId: 'caseId',
|
|
3881
|
+
};
|
|
3882
|
+
/**
|
|
3883
|
+
* Maps fields for Case App Config
|
|
3884
|
+
*/
|
|
3885
|
+
const CaseAppConfigMap = {
|
|
3886
|
+
sections: 'overview',
|
|
3887
|
+
};
|
|
3888
|
+
/**
|
|
3889
|
+
* Maps fields for Stage SLA configuration
|
|
3890
|
+
*/
|
|
3891
|
+
const StageSLAMap = {
|
|
3892
|
+
count: 'length',
|
|
3893
|
+
unit: 'duration',
|
|
3894
|
+
};
|
|
3895
|
+
/**
|
|
3896
|
+
* Maps UTC time fields to simpler field names
|
|
3897
|
+
* Used for transforming execution history responses
|
|
3898
|
+
*/
|
|
3899
|
+
const TimeFieldTransformMap = {
|
|
3900
|
+
startedTimeUtc: 'startedTime',
|
|
3901
|
+
completedTimeUtc: 'completedTime',
|
|
3902
|
+
};
|
|
3903
|
+
/**
|
|
3904
|
+
* Constants for case instance stage processing
|
|
3905
|
+
*/
|
|
3906
|
+
const CASE_STAGE_CONSTANTS = {
|
|
3907
|
+
TRIGGER_NODE_TYPE: 'case-management:Trigger',
|
|
3908
|
+
UNDEFINED_VALUE: 'Undefined',
|
|
3909
|
+
NOT_STARTED_STATUS: 'Not Started'
|
|
3751
3910
|
};
|
|
3911
|
+
/**
|
|
3912
|
+
* Function to generate case instance task filter by case instance ID
|
|
3913
|
+
*/
|
|
3914
|
+
const CASE_INSTANCE_TASK_FILTER = (caseInstanceId) => `Tags/any(tags:tags/DisplayName eq '${caseInstanceId}') and (IsDeleted eq false)`;
|
|
3915
|
+
/**
|
|
3916
|
+
* Default expand parameters for case instance tasks
|
|
3917
|
+
*/
|
|
3918
|
+
const CASE_INSTANCE_TASK_EXPAND = 'AssignedToUser,Activities';
|
|
3752
3919
|
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3920
|
+
exports.TaskType = void 0;
|
|
3921
|
+
(function (TaskType) {
|
|
3922
|
+
TaskType["Form"] = "FormTask";
|
|
3923
|
+
TaskType["External"] = "ExternalTask";
|
|
3924
|
+
TaskType["App"] = "AppTask";
|
|
3925
|
+
})(exports.TaskType || (exports.TaskType = {}));
|
|
3926
|
+
exports.TaskPriority = void 0;
|
|
3927
|
+
(function (TaskPriority) {
|
|
3928
|
+
TaskPriority["Low"] = "Low";
|
|
3929
|
+
TaskPriority["Medium"] = "Medium";
|
|
3930
|
+
TaskPriority["High"] = "High";
|
|
3931
|
+
TaskPriority["Critical"] = "Critical";
|
|
3932
|
+
})(exports.TaskPriority || (exports.TaskPriority = {}));
|
|
3933
|
+
exports.TaskStatus = void 0;
|
|
3934
|
+
(function (TaskStatus) {
|
|
3935
|
+
TaskStatus["Unassigned"] = "Unassigned";
|
|
3936
|
+
TaskStatus["Pending"] = "Pending";
|
|
3937
|
+
TaskStatus["Completed"] = "Completed";
|
|
3938
|
+
})(exports.TaskStatus || (exports.TaskStatus = {}));
|
|
3939
|
+
exports.TaskSlaCriteria = void 0;
|
|
3940
|
+
(function (TaskSlaCriteria) {
|
|
3941
|
+
TaskSlaCriteria["TaskCreated"] = "TaskCreated";
|
|
3942
|
+
TaskSlaCriteria["TaskAssigned"] = "TaskAssigned";
|
|
3943
|
+
TaskSlaCriteria["TaskCompleted"] = "TaskCompleted";
|
|
3944
|
+
})(exports.TaskSlaCriteria || (exports.TaskSlaCriteria = {}));
|
|
3945
|
+
exports.TaskSlaStatus = void 0;
|
|
3946
|
+
(function (TaskSlaStatus) {
|
|
3947
|
+
TaskSlaStatus["OverdueLater"] = "OverdueLater";
|
|
3948
|
+
TaskSlaStatus["OverdueSoon"] = "OverdueSoon";
|
|
3949
|
+
TaskSlaStatus["Overdue"] = "Overdue";
|
|
3950
|
+
TaskSlaStatus["CompletedInTime"] = "CompletedInTime";
|
|
3951
|
+
})(exports.TaskSlaStatus || (exports.TaskSlaStatus = {}));
|
|
3952
|
+
exports.TaskSourceName = void 0;
|
|
3953
|
+
(function (TaskSourceName) {
|
|
3954
|
+
TaskSourceName["Agent"] = "Agent";
|
|
3955
|
+
TaskSourceName["Workflow"] = "Workflow";
|
|
3956
|
+
TaskSourceName["Maestro"] = "Maestro";
|
|
3957
|
+
TaskSourceName["Default"] = "Default";
|
|
3958
|
+
})(exports.TaskSourceName || (exports.TaskSourceName = {}));
|
|
3959
|
+
/**
|
|
3960
|
+
* Task activity types
|
|
3961
|
+
*/
|
|
3962
|
+
exports.TaskActivityType = void 0;
|
|
3963
|
+
(function (TaskActivityType) {
|
|
3964
|
+
TaskActivityType["Created"] = "Created";
|
|
3965
|
+
TaskActivityType["Assigned"] = "Assigned";
|
|
3966
|
+
TaskActivityType["Reassigned"] = "Reassigned";
|
|
3967
|
+
TaskActivityType["Unassigned"] = "Unassigned";
|
|
3968
|
+
TaskActivityType["Saved"] = "Saved";
|
|
3969
|
+
TaskActivityType["Forwarded"] = "Forwarded";
|
|
3970
|
+
TaskActivityType["Completed"] = "Completed";
|
|
3971
|
+
TaskActivityType["Commented"] = "Commented";
|
|
3972
|
+
TaskActivityType["Deleted"] = "Deleted";
|
|
3973
|
+
TaskActivityType["BulkSaved"] = "BulkSaved";
|
|
3974
|
+
TaskActivityType["BulkCompleted"] = "BulkCompleted";
|
|
3975
|
+
TaskActivityType["FirstOpened"] = "FirstOpened";
|
|
3976
|
+
})(exports.TaskActivityType || (exports.TaskActivityType = {}));
|
|
3977
|
+
|
|
3978
|
+
/**
|
|
3979
|
+
* Creates methods for a task
|
|
3980
|
+
*
|
|
3981
|
+
* @param taskData - The task data (response from API)
|
|
3982
|
+
* @param service - The task service instance
|
|
3983
|
+
* @returns Object containing task methods
|
|
3984
|
+
*/
|
|
3985
|
+
function createTaskMethods(taskData, service) {
|
|
3986
|
+
return {
|
|
3987
|
+
async assign(options) {
|
|
3988
|
+
if (!taskData.id)
|
|
3989
|
+
throw new Error('Task ID is undefined');
|
|
3990
|
+
const assignmentOptions = {
|
|
3991
|
+
taskId: taskData.id,
|
|
3992
|
+
userId: options.userId || 0, // Will be handled by userNameOrEmail if userId is not provided, 0 is considered as invalid user id
|
|
3993
|
+
userNameOrEmail: options.userNameOrEmail
|
|
3994
|
+
};
|
|
3995
|
+
return service.assign(assignmentOptions, taskData.organizationUnitId);
|
|
3996
|
+
},
|
|
3997
|
+
async reassign(options) {
|
|
3998
|
+
if (!taskData.id)
|
|
3999
|
+
throw new Error('Task ID is undefined');
|
|
4000
|
+
const assignmentOptions = {
|
|
4001
|
+
taskId: taskData.id,
|
|
4002
|
+
userId: options.userId || 0, // Will be handled by userNameOrEmail if userId is not provided, 0 is considered as invalid user id
|
|
4003
|
+
userNameOrEmail: options.userNameOrEmail
|
|
4004
|
+
};
|
|
4005
|
+
return service.reassign(assignmentOptions, taskData.organizationUnitId);
|
|
4006
|
+
},
|
|
4007
|
+
async unassign() {
|
|
4008
|
+
if (!taskData.id)
|
|
4009
|
+
throw new Error('Task ID is undefined');
|
|
4010
|
+
return service.unassign(taskData.id, taskData.organizationUnitId);
|
|
4011
|
+
},
|
|
4012
|
+
async complete(options) {
|
|
4013
|
+
if (!taskData.id)
|
|
4014
|
+
throw new Error('Task ID is undefined');
|
|
4015
|
+
const folderId = taskData.organizationUnitId;
|
|
4016
|
+
if (!folderId)
|
|
4017
|
+
throw new Error('Folder ID is required');
|
|
4018
|
+
return service.complete(options.type, {
|
|
4019
|
+
taskId: taskData.id,
|
|
4020
|
+
data: options.data,
|
|
4021
|
+
action: options.action
|
|
4022
|
+
}, folderId);
|
|
4023
|
+
}
|
|
4024
|
+
};
|
|
4025
|
+
}
|
|
4026
|
+
/**
|
|
4027
|
+
* Creates an actionable task by combining API task data with operational methods.
|
|
4028
|
+
*
|
|
4029
|
+
* @param taskData - The task data from API
|
|
4030
|
+
* @param service - The task service instance
|
|
4031
|
+
* @returns A task object with added methods
|
|
4032
|
+
*/
|
|
4033
|
+
function createTaskWithMethods(taskData, service) {
|
|
4034
|
+
const methods = createTaskMethods(taskData, service);
|
|
4035
|
+
return Object.assign({}, taskData, methods);
|
|
4036
|
+
}
|
|
4037
|
+
|
|
4038
|
+
/**
|
|
4039
|
+
* Maps numeric TaskStatus values (from API) to TaskStatus enum values.
|
|
4040
|
+
* Extend this file with additional field mappings as needed.
|
|
4041
|
+
*/
|
|
4042
|
+
const TaskStatusMap = {
|
|
4043
|
+
0: exports.TaskStatus.Unassigned,
|
|
4044
|
+
1: exports.TaskStatus.Pending,
|
|
4045
|
+
2: exports.TaskStatus.Completed,
|
|
4046
|
+
};
|
|
4047
|
+
// Field mapping for time-related fields to ensure consistent naming
|
|
4048
|
+
const TaskMap = {
|
|
4049
|
+
completionTime: 'completedTime',
|
|
4050
|
+
deletionTime: 'deletedTime',
|
|
4051
|
+
lastModificationTime: 'lastModifiedTime',
|
|
4052
|
+
creationTime: 'createdTime',
|
|
4053
|
+
organizationUnitId: 'folderId'
|
|
4054
|
+
};
|
|
4055
|
+
|
|
4056
|
+
/**
|
|
4057
|
+
* Service for interacting with UiPath Tasks API
|
|
4058
|
+
*/
|
|
4059
|
+
class TaskService extends BaseService {
|
|
4060
|
+
/**
|
|
4061
|
+
* @hideconstructor
|
|
4062
|
+
*/
|
|
4063
|
+
constructor(config, executionContext, tokenManager) {
|
|
4064
|
+
super(config, executionContext, tokenManager);
|
|
4065
|
+
/**
|
|
4066
|
+
* Process parameters for task queries with folder filtering
|
|
4067
|
+
* @param options - The REST API options to process
|
|
4068
|
+
* @param folderId - Optional folder ID to filter by
|
|
4069
|
+
* @returns Processed options with folder filtering applied if needed
|
|
4070
|
+
* @private
|
|
4071
|
+
*/
|
|
4072
|
+
this.processTaskParameters = (options, folderId) => {
|
|
4073
|
+
const processedOptions = { ...options };
|
|
4074
|
+
if (folderId) {
|
|
4075
|
+
// Create or add to existing filter for folder-specific queries
|
|
4076
|
+
if (processedOptions.filter) {
|
|
4077
|
+
processedOptions.filter = `${processedOptions.filter} and organizationUnitId eq ${folderId}`;
|
|
4078
|
+
}
|
|
4079
|
+
else {
|
|
4080
|
+
processedOptions.filter = `organizationUnitId eq ${folderId}`;
|
|
4081
|
+
}
|
|
4082
|
+
}
|
|
4083
|
+
return processedOptions;
|
|
4084
|
+
};
|
|
3802
4085
|
}
|
|
3803
4086
|
/**
|
|
3804
|
-
*
|
|
4087
|
+
* Creates a new task
|
|
4088
|
+
* @param task - The task to be created
|
|
4089
|
+
* @param folderId - Required folder ID
|
|
4090
|
+
* @returns Promise resolving to the created task
|
|
4091
|
+
*
|
|
4092
|
+
* @example
|
|
4093
|
+
* ```typescript
|
|
4094
|
+
* const task = await sdk.tasks.create({
|
|
4095
|
+
* title: "My Task",
|
|
4096
|
+
* priority: TaskPriority.Medium,
|
|
4097
|
+
* data: { key: "value" }
|
|
4098
|
+
* }, 123); // folderId is required
|
|
4099
|
+
* ```
|
|
4100
|
+
*/
|
|
4101
|
+
async create(task, folderId) {
|
|
4102
|
+
const headers = createHeaders({ [FOLDER_ID]: folderId });
|
|
4103
|
+
const externalTask = {
|
|
4104
|
+
...task,
|
|
4105
|
+
type: exports.TaskType.External //currently only external task is supported
|
|
4106
|
+
};
|
|
4107
|
+
const response = await this.post(TASK_ENDPOINTS.CREATE_GENERIC_TASK, externalTask, { headers });
|
|
4108
|
+
// Transform time fields for consistency
|
|
4109
|
+
const normalizedData = transformData(response.data, TaskMap);
|
|
4110
|
+
const transformedData = applyDataTransforms(normalizedData, { field: 'status', valueMap: TaskStatusMap });
|
|
4111
|
+
return createTaskWithMethods(transformedData, this);
|
|
4112
|
+
}
|
|
4113
|
+
/**
|
|
4114
|
+
* Gets users in the given folder who have Tasks.View and Tasks.Edit permissions
|
|
3805
4115
|
*
|
|
3806
4116
|
* The method returns either:
|
|
3807
|
-
* - An array of
|
|
4117
|
+
* - An array of users (when no pagination parameters are provided)
|
|
3808
4118
|
* - A paginated result with navigation cursors (when any pagination parameter is provided)
|
|
3809
4119
|
*
|
|
3810
|
-
* @param
|
|
3811
|
-
* @
|
|
4120
|
+
* @param folderId - The folder ID to get users from
|
|
4121
|
+
* @param options - Optional query and pagination parameters
|
|
4122
|
+
* @returns Promise resolving to an array of users or paginated result
|
|
3812
4123
|
*
|
|
3813
4124
|
* @example
|
|
3814
4125
|
* ```typescript
|
|
3815
|
-
* //
|
|
3816
|
-
* const
|
|
3817
|
-
*
|
|
3818
|
-
* // Get buckets within a specific folder
|
|
3819
|
-
* const buckets = await sdk.buckets.getAll({
|
|
3820
|
-
* folderId: 123
|
|
3821
|
-
* });
|
|
4126
|
+
* // Standard array return
|
|
4127
|
+
* const users = await sdk.tasks.getUsers(123);
|
|
3822
4128
|
*
|
|
3823
|
-
* // Get
|
|
3824
|
-
* const
|
|
3825
|
-
* filter: "name eq '
|
|
4129
|
+
* // Get users with filtering
|
|
4130
|
+
* const users = await sdk.tasks.getUsers(123, {
|
|
4131
|
+
* filter: "name eq 'abc'"
|
|
3826
4132
|
* });
|
|
3827
4133
|
*
|
|
3828
4134
|
* // First page with pagination
|
|
3829
|
-
* const page1 = await sdk.
|
|
4135
|
+
* const page1 = await sdk.tasks.getUsers(123, { pageSize: 10 });
|
|
3830
4136
|
*
|
|
3831
4137
|
* // Navigate using cursor
|
|
3832
4138
|
* if (page1.hasNextPage) {
|
|
3833
|
-
* const page2 = await sdk.
|
|
4139
|
+
* const page2 = await sdk.tasks.getUsers(123, { cursor: page1.nextCursor });
|
|
3834
4140
|
* }
|
|
3835
4141
|
*
|
|
3836
4142
|
* // Jump to specific page
|
|
3837
|
-
* const page5 = await sdk.
|
|
4143
|
+
* const page5 = await sdk.tasks.getUsers(123, {
|
|
3838
4144
|
* jumpToPage: 5,
|
|
3839
4145
|
* pageSize: 10
|
|
3840
4146
|
* });
|
|
3841
4147
|
* ```
|
|
3842
4148
|
*/
|
|
3843
|
-
async
|
|
3844
|
-
// Transformation function for
|
|
3845
|
-
const
|
|
4149
|
+
async getUsers(folderId, options) {
|
|
4150
|
+
// Transformation function for users
|
|
4151
|
+
const transformUserResponse = (user) => pascalToCamelCaseKeys(user);
|
|
4152
|
+
// Add folderId to options so the centralized helper can handle it properly
|
|
4153
|
+
const optionsWithFolder = { ...options, folderId };
|
|
3846
4154
|
return PaginationHelpers.getAll({
|
|
3847
4155
|
serviceAccess: this.createPaginationServiceAccess(),
|
|
3848
|
-
getEndpoint: (folderId) => folderId
|
|
3849
|
-
getByFolderEndpoint:
|
|
3850
|
-
transformFn:
|
|
4156
|
+
getEndpoint: (folderId) => TASK_ENDPOINTS.GET_TASK_USERS(folderId), // Use folderId from centralized helper
|
|
4157
|
+
getByFolderEndpoint: TASK_ENDPOINTS.GET_TASK_USERS(folderId), // Use the passed folderId
|
|
4158
|
+
transformFn: transformUserResponse,
|
|
3851
4159
|
pagination: {
|
|
3852
4160
|
paginationType: PaginationType.OFFSET,
|
|
3853
4161
|
itemsField: ODATA_PAGINATION.ITEMS_FIELD,
|
|
@@ -3858,498 +4166,788 @@ class BucketService extends FolderScopedService {
|
|
|
3858
4166
|
countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM
|
|
3859
4167
|
}
|
|
3860
4168
|
}
|
|
3861
|
-
},
|
|
4169
|
+
}, optionsWithFolder);
|
|
3862
4170
|
}
|
|
3863
4171
|
/**
|
|
3864
|
-
* Gets
|
|
4172
|
+
* Gets tasks across folders with optional filtering and folder scoping
|
|
3865
4173
|
*
|
|
3866
4174
|
* The method returns either:
|
|
3867
|
-
* -
|
|
3868
|
-
* - A
|
|
4175
|
+
* - An array of tasks (when no pagination parameters are provided)
|
|
4176
|
+
* - A paginated result with navigation cursors (when any pagination parameter is provided)
|
|
3869
4177
|
*
|
|
3870
|
-
* @param
|
|
3871
|
-
* @
|
|
3872
|
-
* @param options - Optional parameters for filtering, pagination and access URL generation
|
|
3873
|
-
* @returns Promise resolving to the list of file metadata in the bucket or paginated result
|
|
4178
|
+
* @param options - Query options including optional folderId and pagination options
|
|
4179
|
+
* @returns Promise resolving to an array of tasks or paginated result
|
|
3874
4180
|
*
|
|
3875
4181
|
* @example
|
|
3876
4182
|
* ```typescript
|
|
3877
|
-
* //
|
|
3878
|
-
* const
|
|
4183
|
+
* // Standard array return
|
|
4184
|
+
* const tasks = await sdk.tasks.getAll();
|
|
3879
4185
|
*
|
|
3880
|
-
* // Get
|
|
3881
|
-
* const
|
|
3882
|
-
*
|
|
4186
|
+
* // Get tasks within a specific folder
|
|
4187
|
+
* const tasks = await sdk.tasks.getAll({
|
|
4188
|
+
* folderId: 123
|
|
3883
4189
|
* });
|
|
3884
4190
|
*
|
|
3885
4191
|
* // First page with pagination
|
|
3886
|
-
* const page1 = await sdk.
|
|
4192
|
+
* const page1 = await sdk.tasks.getAll({ pageSize: 10 });
|
|
3887
4193
|
*
|
|
3888
4194
|
* // Navigate using cursor
|
|
3889
4195
|
* if (page1.hasNextPage) {
|
|
3890
|
-
* const page2 = await sdk.
|
|
4196
|
+
* const page2 = await sdk.tasks.getAll({ cursor: page1.nextCursor });
|
|
3891
4197
|
* }
|
|
3892
|
-
*
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
// Transformation function for
|
|
3902
|
-
const
|
|
4198
|
+
*
|
|
4199
|
+
* // Jump to specific page
|
|
4200
|
+
* const page5 = await sdk.tasks.getAll({
|
|
4201
|
+
* jumpToPage: 5,
|
|
4202
|
+
* pageSize: 10
|
|
4203
|
+
* });
|
|
4204
|
+
* ```
|
|
4205
|
+
*/
|
|
4206
|
+
async getAll(options) {
|
|
4207
|
+
// Transformation function for tasks
|
|
4208
|
+
const transformTaskResponse = (task) => {
|
|
4209
|
+
const transformedTask = transformData(pascalToCamelCaseKeys(task), TaskMap);
|
|
4210
|
+
return createTaskWithMethods(applyDataTransforms(transformedTask, { field: 'status', valueMap: TaskStatusMap }), this);
|
|
4211
|
+
};
|
|
3903
4212
|
return PaginationHelpers.getAll({
|
|
3904
4213
|
serviceAccess: this.createPaginationServiceAccess(),
|
|
3905
|
-
getEndpoint: () =>
|
|
3906
|
-
transformFn:
|
|
4214
|
+
getEndpoint: () => TASK_ENDPOINTS.GET_TASKS_ACROSS_FOLDERS,
|
|
4215
|
+
transformFn: transformTaskResponse,
|
|
4216
|
+
processParametersFn: this.processTaskParameters,
|
|
4217
|
+
excludeFromPrefix: ['event'], // Exclude 'event' key from ODATA prefix transformation
|
|
3907
4218
|
pagination: {
|
|
3908
|
-
paginationType: PaginationType.
|
|
3909
|
-
itemsField:
|
|
3910
|
-
|
|
4219
|
+
paginationType: PaginationType.OFFSET,
|
|
4220
|
+
itemsField: ODATA_PAGINATION.ITEMS_FIELD,
|
|
4221
|
+
totalCountField: ODATA_PAGINATION.TOTAL_COUNT_FIELD,
|
|
3911
4222
|
paginationParams: {
|
|
3912
|
-
pageSizeParam:
|
|
3913
|
-
|
|
4223
|
+
pageSizeParam: ODATA_OFFSET_PARAMS.PAGE_SIZE_PARAM, // OData OFFSET parameter
|
|
4224
|
+
offsetParam: ODATA_OFFSET_PARAMS.OFFSET_PARAM, // OData OFFSET parameter
|
|
4225
|
+
countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM // OData OFFSET parameter
|
|
3914
4226
|
}
|
|
3915
|
-
}
|
|
3916
|
-
|
|
3917
|
-
}, { ...options, folderId });
|
|
4227
|
+
}
|
|
4228
|
+
}, options);
|
|
3918
4229
|
}
|
|
3919
4230
|
/**
|
|
3920
|
-
*
|
|
4231
|
+
* Gets a task by ID
|
|
3921
4232
|
*
|
|
3922
|
-
* @param
|
|
3923
|
-
* @
|
|
4233
|
+
* @param id - The ID of the task to retrieve
|
|
4234
|
+
* @param options - Optional query parameters
|
|
4235
|
+
* @param folderId - Optional folder ID
|
|
4236
|
+
* @returns Promise resolving to the task (form tasks will return form-specific data)
|
|
3924
4237
|
*
|
|
3925
4238
|
* @example
|
|
3926
4239
|
* ```typescript
|
|
3927
|
-
* //
|
|
3928
|
-
* const
|
|
3929
|
-
* const result = await sdk.buckets.uploadFile({
|
|
3930
|
-
* bucketId: 123,
|
|
3931
|
-
* folderId: 456,
|
|
3932
|
-
* path: '/folder/example.txt',
|
|
3933
|
-
* content: file
|
|
3934
|
-
* });
|
|
4240
|
+
* // Get task by ID
|
|
4241
|
+
* const task = await sdk.tasks.getById(123);
|
|
3935
4242
|
*
|
|
3936
|
-
* //
|
|
3937
|
-
* const buffer = Buffer.from('file content');
|
|
3938
|
-
* const result = await sdk.buckets.uploadFile({
|
|
3939
|
-
* bucketId: 123,
|
|
3940
|
-
* folderId: 456,
|
|
3941
|
-
* path: '/folder/example.txt',
|
|
3942
|
-
* content: buffer,
|
|
3943
|
-
* contentType: 'text/plain'
|
|
3944
|
-
* });
|
|
4243
|
+
* // If the task is a form task, it will automatically return form-specific data
|
|
3945
4244
|
* ```
|
|
3946
4245
|
*/
|
|
3947
|
-
async
|
|
3948
|
-
const { bucketId, folderId, path, content, contentType } = options;
|
|
3949
|
-
if (!bucketId) {
|
|
3950
|
-
throw new ValidationError({ message: 'bucketId is required for uploadFile' });
|
|
3951
|
-
}
|
|
3952
|
-
if (!folderId) {
|
|
3953
|
-
throw new ValidationError({ message: 'folderId is required for uploadFile' });
|
|
3954
|
-
}
|
|
3955
|
-
if (!path) {
|
|
3956
|
-
throw new ValidationError({ message: 'path is required for uploadFile' });
|
|
3957
|
-
}
|
|
3958
|
-
if (!content) {
|
|
3959
|
-
throw new ValidationError({ message: 'content is required for uploadFile' });
|
|
3960
|
-
}
|
|
3961
|
-
try {
|
|
3962
|
-
// Get write URI for upload with detected content type if not provided
|
|
3963
|
-
let detectedContentType = contentType;
|
|
3964
|
-
if (!detectedContentType) {
|
|
3965
|
-
detectedContentType = await this._determineContentType(content, path);
|
|
3966
|
-
}
|
|
3967
|
-
const uriResponse = await this._getWriteUri({
|
|
3968
|
-
bucketId,
|
|
3969
|
-
folderId,
|
|
3970
|
-
path,
|
|
3971
|
-
contentType: detectedContentType
|
|
3972
|
-
});
|
|
3973
|
-
// Upload file to the provided URI
|
|
3974
|
-
const response = await this._uploadToUri(uriResponse, content, detectedContentType);
|
|
3975
|
-
return {
|
|
3976
|
-
success: response.status >= 200 && response.status < 300,
|
|
3977
|
-
statusCode: response.status
|
|
3978
|
-
};
|
|
3979
|
-
}
|
|
3980
|
-
catch (error) {
|
|
3981
|
-
throw error;
|
|
3982
|
-
}
|
|
3983
|
-
}
|
|
3984
|
-
/**
|
|
3985
|
-
* Determines the content type of the file based on the content and path
|
|
3986
|
-
* Uses a hybrid approach:
|
|
3987
|
-
* 1. Checks Blob/File type if available (browser)
|
|
3988
|
-
* 2. Uses content-based detection with file-type (primarily Node.js)
|
|
3989
|
-
* 3. Falls back to extension-based detection with mime-types
|
|
3990
|
-
* 4. Finally defaults to application/octet-stream
|
|
3991
|
-
*
|
|
3992
|
-
* @param content - The file content
|
|
3993
|
-
* @param path - The file path
|
|
3994
|
-
* @returns The determined content type or default
|
|
3995
|
-
*/
|
|
3996
|
-
async _determineContentType(content, path) {
|
|
3997
|
-
// 1. If content is a File or Blob with type, use that (works in browser)
|
|
3998
|
-
if ('type' in content && content.type) {
|
|
3999
|
-
return content.type;
|
|
4000
|
-
}
|
|
4001
|
-
// 2. Try content-based detection (primarily for Node.js)
|
|
4002
|
-
if (content instanceof Buffer && fileTypeFromBuffer) {
|
|
4003
|
-
try {
|
|
4004
|
-
const fileTypeResult = await fileTypeFromBuffer(content);
|
|
4005
|
-
if (fileTypeResult?.mime) {
|
|
4006
|
-
return fileTypeResult.mime;
|
|
4007
|
-
}
|
|
4008
|
-
}
|
|
4009
|
-
catch (error) {
|
|
4010
|
-
// Silently continue to next detection method if this fails
|
|
4011
|
-
console.debug('Content-based type detection failed:', error);
|
|
4012
|
-
}
|
|
4013
|
-
}
|
|
4014
|
-
// 3. Try to infer from file extension using mime-types library
|
|
4015
|
-
const mimeType = mimeTypes__namespace.lookup(path);
|
|
4016
|
-
if (mimeType) {
|
|
4017
|
-
return mimeType;
|
|
4018
|
-
}
|
|
4019
|
-
// 4. Final fallback
|
|
4020
|
-
return CONTENT_TYPES.OCTET_STREAM;
|
|
4021
|
-
}
|
|
4022
|
-
/**
|
|
4023
|
-
* Uploads content to the provided URI
|
|
4024
|
-
* @param uriResponse - Response from getWriteUri containing URL and headers
|
|
4025
|
-
* @param content - The content to upload
|
|
4026
|
-
* @param contentType - The content type of the file
|
|
4027
|
-
* @returns The response from the upload request with status info
|
|
4028
|
-
*/
|
|
4029
|
-
async _uploadToUri(uriResponse, content, contentType) {
|
|
4030
|
-
const { uri, headers = {}, requiresAuth } = uriResponse;
|
|
4031
|
-
if (!uri) {
|
|
4032
|
-
throw new ValidationError({ message: 'Upload URI not available', statusCode: HttpStatus.BAD_REQUEST });
|
|
4033
|
-
}
|
|
4034
|
-
// Create headers for the request
|
|
4035
|
-
let requestHeaders = { ...headers };
|
|
4036
|
-
// Ensure content-type is set if provided
|
|
4037
|
-
if (contentType && !requestHeaders['content-type']) {
|
|
4038
|
-
requestHeaders['content-type'] = contentType;
|
|
4039
|
-
}
|
|
4040
|
-
// Add auth header if required
|
|
4041
|
-
if (requiresAuth) {
|
|
4042
|
-
try {
|
|
4043
|
-
const tokenInfo = this.executionContext.get('tokenInfo');
|
|
4044
|
-
if (!tokenInfo) {
|
|
4045
|
-
throw new AuthenticationError({ message: 'No authentication token available. Make sure to initialize the SDK first.' });
|
|
4046
|
-
}
|
|
4047
|
-
let token;
|
|
4048
|
-
// For secret-based tokens, they never expire so use directly
|
|
4049
|
-
if (tokenInfo.type === 'secret') {
|
|
4050
|
-
token = tokenInfo.token;
|
|
4051
|
-
}
|
|
4052
|
-
// For non-secret tokens, check expiration and refresh if needed
|
|
4053
|
-
else if (!this.tokenManager.isTokenExpired(tokenInfo)) {
|
|
4054
|
-
token = tokenInfo.token;
|
|
4055
|
-
}
|
|
4056
|
-
else {
|
|
4057
|
-
const newToken = await this.tokenManager.refreshAccessToken();
|
|
4058
|
-
token = newToken.access_token;
|
|
4059
|
-
}
|
|
4060
|
-
requestHeaders['Authorization'] = `Bearer ${token}`;
|
|
4061
|
-
}
|
|
4062
|
-
catch (error) {
|
|
4063
|
-
throw new AuthenticationError({
|
|
4064
|
-
message: `Authentication required but failed: ${error instanceof Error ? error.message : ''}`,
|
|
4065
|
-
statusCode: HttpStatus.UNAUTHORIZED
|
|
4066
|
-
});
|
|
4067
|
-
}
|
|
4068
|
-
}
|
|
4069
|
-
return axios.put(uri, content, {
|
|
4070
|
-
headers: createHeaders(requestHeaders)
|
|
4071
|
-
});
|
|
4072
|
-
}
|
|
4073
|
-
/**
|
|
4074
|
-
* Private method to handle common URI request logic
|
|
4075
|
-
* @param endpoint - The API endpoint to call
|
|
4076
|
-
* @param bucketId - The bucket ID
|
|
4077
|
-
* @param folderId - The folder ID
|
|
4078
|
-
* @param path - The file path
|
|
4079
|
-
* @param queryOptions - Additional query parameters
|
|
4080
|
-
* @returns Promise resolving to blob file access information
|
|
4081
|
-
*/
|
|
4082
|
-
async _getUri(endpoint, bucketId, folderId, path, queryOptions = {}) {
|
|
4083
|
-
if (!bucketId) {
|
|
4084
|
-
throw new ValidationError({ message: 'bucketId is required for getUri' });
|
|
4085
|
-
}
|
|
4086
|
-
if (!folderId) {
|
|
4087
|
-
throw new ValidationError({ message: 'folderId is required for getUri' });
|
|
4088
|
-
}
|
|
4089
|
-
if (!path) {
|
|
4090
|
-
throw new ValidationError({ message: 'path is required for getUri' });
|
|
4091
|
-
}
|
|
4092
|
-
// Create headers with required folder ID
|
|
4246
|
+
async getById(id, options = {}, folderId) {
|
|
4093
4247
|
const headers = createHeaders({ [FOLDER_ID]: folderId });
|
|
4094
|
-
//
|
|
4095
|
-
const
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
// Make the API call to get URI
|
|
4100
|
-
const response = await this.get(endpoint, {
|
|
4101
|
-
params: queryParams,
|
|
4248
|
+
// prefix all keys in options
|
|
4249
|
+
const keysToPrefix = Object.keys(options);
|
|
4250
|
+
const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
|
|
4251
|
+
const response = await this.get(TASK_ENDPOINTS.GET_BY_ID(id), {
|
|
4252
|
+
params: apiOptions,
|
|
4102
4253
|
headers
|
|
4103
4254
|
});
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
if
|
|
4107
|
-
|
|
4255
|
+
// Transform response from PascalCase to camelCase and normalize time fields
|
|
4256
|
+
const transformedTask = transformData(pascalToCamelCaseKeys(response.data), TaskMap);
|
|
4257
|
+
// Check if this is a form task and get form-specific data if it is
|
|
4258
|
+
if (transformedTask.type === exports.TaskType.Form) {
|
|
4259
|
+
const formOptions = { expandOnFormLayout: true };
|
|
4260
|
+
return this.getFormTaskById(id, folderId || transformedTask.organizationUnitId, formOptions);
|
|
4108
4261
|
}
|
|
4109
|
-
return
|
|
4262
|
+
return createTaskWithMethods(applyDataTransforms(transformedTask, { field: 'status', valueMap: TaskStatusMap }), this);
|
|
4110
4263
|
}
|
|
4111
4264
|
/**
|
|
4112
|
-
*
|
|
4265
|
+
* Assigns tasks to users
|
|
4113
4266
|
*
|
|
4114
|
-
* @param
|
|
4115
|
-
* @
|
|
4267
|
+
* @param taskAssignments - Single task assignment or array of task assignments
|
|
4268
|
+
* @param folderId - Optional folder ID
|
|
4269
|
+
* @returns Promise resolving to array of task assignment results
|
|
4116
4270
|
*
|
|
4117
4271
|
* @example
|
|
4118
4272
|
* ```typescript
|
|
4119
|
-
* //
|
|
4120
|
-
* const
|
|
4121
|
-
*
|
|
4122
|
-
*
|
|
4123
|
-
* path: '/folder/file.pdf'
|
|
4273
|
+
* // Assign a single task to a user by ID
|
|
4274
|
+
* const result = await sdk.tasks.assign({
|
|
4275
|
+
* taskId: 123,
|
|
4276
|
+
* userId: 456
|
|
4124
4277
|
* });
|
|
4278
|
+
*
|
|
4279
|
+
* // Assign a single task to a user by email
|
|
4280
|
+
* const result = await sdk.tasks.assign({
|
|
4281
|
+
* taskId: 123,
|
|
4282
|
+
* userNameOrEmail: "user@example.com"
|
|
4283
|
+
* });
|
|
4284
|
+
*
|
|
4285
|
+
* // Assign multiple tasks
|
|
4286
|
+
* const result = await sdk.tasks.assign([
|
|
4287
|
+
* {
|
|
4288
|
+
* taskId: 123,
|
|
4289
|
+
* userId: 456
|
|
4290
|
+
* },
|
|
4291
|
+
* {
|
|
4292
|
+
* taskId: 789,
|
|
4293
|
+
* userNameOrEmail: "user@example.com"
|
|
4294
|
+
* }
|
|
4295
|
+
* ]);
|
|
4125
4296
|
* ```
|
|
4126
4297
|
*/
|
|
4127
|
-
async
|
|
4128
|
-
const {
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4298
|
+
async assign(taskAssignments, folderId) {
|
|
4299
|
+
const headers = createHeaders({ [FOLDER_ID]: folderId });
|
|
4300
|
+
// Normalize input to array
|
|
4301
|
+
const assignmentArray = Array.isArray(taskAssignments) ? taskAssignments : [taskAssignments];
|
|
4302
|
+
const options = {
|
|
4303
|
+
taskAssignments: assignmentArray
|
|
4132
4304
|
};
|
|
4133
|
-
|
|
4305
|
+
// Convert options to PascalCase for API
|
|
4306
|
+
const pascalOptions = camelToPascalCaseKeys(options);
|
|
4307
|
+
const response = await this.post(TASK_ENDPOINTS.ASSIGN_TASKS, pascalOptions, { headers });
|
|
4308
|
+
// Transform response from PascalCase to camelCase
|
|
4309
|
+
const transformedResponse = pascalToCamelCaseKeys(response.data);
|
|
4310
|
+
// Process OData array response - empty array = success, non-empty = error
|
|
4311
|
+
return processODataArrayResponse(transformedResponse, assignmentArray);
|
|
4134
4312
|
}
|
|
4135
4313
|
/**
|
|
4136
|
-
*
|
|
4314
|
+
* Reassigns tasks to new users
|
|
4137
4315
|
*
|
|
4138
|
-
* @param
|
|
4139
|
-
* @
|
|
4316
|
+
* @param taskAssignments - Single task assignment or array of task assignments
|
|
4317
|
+
* @param folderId - Optional folder ID
|
|
4318
|
+
* @returns Promise resolving to array of task assignment results
|
|
4319
|
+
*
|
|
4320
|
+
* @example
|
|
4321
|
+
* ```typescript
|
|
4322
|
+
* // Reassign a single task to a user by ID
|
|
4323
|
+
* const result = await sdk.tasks.reassign({
|
|
4324
|
+
* taskId: 123,
|
|
4325
|
+
* userId: 456
|
|
4326
|
+
* });
|
|
4327
|
+
*
|
|
4328
|
+
* // Reassign a single task to a user by email
|
|
4329
|
+
* const result = await sdk.tasks.reassign({
|
|
4330
|
+
* taskId: 123,
|
|
4331
|
+
* userNameOrEmail: "user@example.com"
|
|
4332
|
+
* });
|
|
4333
|
+
*
|
|
4334
|
+
* // Reassign multiple tasks
|
|
4335
|
+
* const result = await sdk.tasks.reassign([
|
|
4336
|
+
* {
|
|
4337
|
+
* taskId: 123,
|
|
4338
|
+
* userId: 456
|
|
4339
|
+
* },
|
|
4340
|
+
* {
|
|
4341
|
+
* taskId: 789,
|
|
4342
|
+
* userNameOrEmail: "user@example.com"
|
|
4343
|
+
* }
|
|
4344
|
+
* ]);
|
|
4345
|
+
* ```
|
|
4140
4346
|
*/
|
|
4141
|
-
async
|
|
4142
|
-
const {
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4347
|
+
async reassign(taskAssignments, folderId) {
|
|
4348
|
+
const headers = createHeaders({ [FOLDER_ID]: folderId });
|
|
4349
|
+
// Normalize input to array
|
|
4350
|
+
const assignmentArray = Array.isArray(taskAssignments) ? taskAssignments : [taskAssignments];
|
|
4351
|
+
const options = {
|
|
4352
|
+
taskAssignments: assignmentArray
|
|
4147
4353
|
};
|
|
4148
|
-
|
|
4354
|
+
// Convert options to PascalCase for API
|
|
4355
|
+
const pascalOptions = camelToPascalCaseKeys(options);
|
|
4356
|
+
const response = await this.post(TASK_ENDPOINTS.REASSIGN_TASKS, pascalOptions, { headers });
|
|
4357
|
+
// Transform response from PascalCase to camelCase
|
|
4358
|
+
const transformedResponse = pascalToCamelCaseKeys(response.data);
|
|
4359
|
+
// Process OData array response - empty array = success, non-empty = error
|
|
4360
|
+
return processODataArrayResponse(transformedResponse, assignmentArray);
|
|
4361
|
+
}
|
|
4362
|
+
/**
|
|
4363
|
+
* Unassigns tasks (removes current assignees)
|
|
4364
|
+
*
|
|
4365
|
+
* @param taskIds - Single task ID or array of task IDs to unassign
|
|
4366
|
+
* @param folderId - Optional folder ID
|
|
4367
|
+
* @returns Promise resolving to array of task assignment results
|
|
4368
|
+
*
|
|
4369
|
+
* @example
|
|
4370
|
+
* ```typescript
|
|
4371
|
+
* // Unassign a single task
|
|
4372
|
+
* const result = await sdk.tasks.unassign(123);
|
|
4373
|
+
*
|
|
4374
|
+
* // Unassign multiple tasks
|
|
4375
|
+
* const result = await sdk.tasks.unassign([123, 456, 789]);
|
|
4376
|
+
* ```
|
|
4377
|
+
*/
|
|
4378
|
+
async unassign(taskIds, folderId) {
|
|
4379
|
+
const headers = createHeaders({ [FOLDER_ID]: folderId });
|
|
4380
|
+
// Normalize input to array
|
|
4381
|
+
const taskIdArray = Array.isArray(taskIds) ? taskIds : [taskIds];
|
|
4382
|
+
const options = {
|
|
4383
|
+
taskIds: taskIdArray
|
|
4384
|
+
};
|
|
4385
|
+
const response = await this.post(TASK_ENDPOINTS.UNASSIGN_TASKS, options, { headers });
|
|
4386
|
+
// Transform response from PascalCase to camelCase
|
|
4387
|
+
const transformedResponse = pascalToCamelCaseKeys(response.data);
|
|
4388
|
+
// Process OData array response - empty array = success, non-empty = error
|
|
4389
|
+
// Return the task IDs that were unassigned
|
|
4390
|
+
return processODataArrayResponse(transformedResponse, taskIdArray.map(id => ({ taskId: id })));
|
|
4391
|
+
}
|
|
4392
|
+
/**
|
|
4393
|
+
* Completes a task with the specified type and data
|
|
4394
|
+
*
|
|
4395
|
+
* @param completionType - The type of task (Form, App, or Generic)
|
|
4396
|
+
* @param options - The completion options
|
|
4397
|
+
* @param folderId - Required folder ID
|
|
4398
|
+
* @returns Promise resolving to void
|
|
4399
|
+
*
|
|
4400
|
+
* @example
|
|
4401
|
+
* ```typescript
|
|
4402
|
+
* // Complete an app task
|
|
4403
|
+
* await sdk.tasks.complete(TaskType.App, {
|
|
4404
|
+
* taskId: 456,
|
|
4405
|
+
* data: {},
|
|
4406
|
+
* action: "submit"
|
|
4407
|
+
* }, 123); // folderId is required
|
|
4408
|
+
*
|
|
4409
|
+
* // Complete an external task
|
|
4410
|
+
* await sdk.tasks.complete(TaskType.ExternalTask, {
|
|
4411
|
+
* taskId: 789
|
|
4412
|
+
* }, 123); // folderId is required
|
|
4413
|
+
* ```
|
|
4414
|
+
*/
|
|
4415
|
+
async complete(completionType, options, folderId) {
|
|
4416
|
+
const headers = createHeaders({ [FOLDER_ID]: folderId });
|
|
4417
|
+
let endpoint;
|
|
4418
|
+
switch (completionType) {
|
|
4419
|
+
case exports.TaskType.Form:
|
|
4420
|
+
endpoint = TASK_ENDPOINTS.COMPLETE_FORM_TASK;
|
|
4421
|
+
break;
|
|
4422
|
+
case exports.TaskType.App:
|
|
4423
|
+
endpoint = TASK_ENDPOINTS.COMPLETE_APP_TASK;
|
|
4424
|
+
break;
|
|
4425
|
+
default:
|
|
4426
|
+
endpoint = TASK_ENDPOINTS.COMPLETE_GENERIC_TASK;
|
|
4427
|
+
break;
|
|
4428
|
+
}
|
|
4429
|
+
// CompleteAppTask returns 204 no content
|
|
4430
|
+
await this.post(endpoint, options, { headers });
|
|
4431
|
+
// Return success with the request context data
|
|
4432
|
+
return {
|
|
4433
|
+
success: true,
|
|
4434
|
+
data: options
|
|
4435
|
+
};
|
|
4436
|
+
}
|
|
4437
|
+
/**
|
|
4438
|
+
* Gets a form task by ID (private method)
|
|
4439
|
+
*
|
|
4440
|
+
* @param id - The ID of the form task to retrieve
|
|
4441
|
+
* @param folderId - Required folder ID
|
|
4442
|
+
* @param options - Optional query parameters
|
|
4443
|
+
* @returns Promise resolving to the form task
|
|
4444
|
+
*/
|
|
4445
|
+
async getFormTaskById(id, folderId, options = {}) {
|
|
4446
|
+
const headers = createHeaders({ [FOLDER_ID]: folderId });
|
|
4447
|
+
const response = await this.get(TASK_ENDPOINTS.GET_TASK_FORM_BY_ID, {
|
|
4448
|
+
params: {
|
|
4449
|
+
taskId: id,
|
|
4450
|
+
...options
|
|
4451
|
+
},
|
|
4452
|
+
headers
|
|
4453
|
+
});
|
|
4454
|
+
const transformedFormTask = transformData(response.data, TaskMap);
|
|
4455
|
+
return createTaskWithMethods(applyDataTransforms(transformedFormTask, { field: 'status', valueMap: TaskStatusMap }), this);
|
|
4149
4456
|
}
|
|
4150
4457
|
}
|
|
4151
4458
|
__decorate([
|
|
4152
|
-
track('
|
|
4153
|
-
],
|
|
4459
|
+
track('Tasks.Create')
|
|
4460
|
+
], TaskService.prototype, "create", null);
|
|
4154
4461
|
__decorate([
|
|
4155
|
-
track('
|
|
4156
|
-
],
|
|
4462
|
+
track('Tasks.GetUsers')
|
|
4463
|
+
], TaskService.prototype, "getUsers", null);
|
|
4157
4464
|
__decorate([
|
|
4158
|
-
track('
|
|
4159
|
-
],
|
|
4465
|
+
track('Tasks.GetAll')
|
|
4466
|
+
], TaskService.prototype, "getAll", null);
|
|
4160
4467
|
__decorate([
|
|
4161
|
-
track('
|
|
4162
|
-
],
|
|
4468
|
+
track('Tasks.GetById')
|
|
4469
|
+
], TaskService.prototype, "getById", null);
|
|
4163
4470
|
__decorate([
|
|
4164
|
-
track('
|
|
4165
|
-
],
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
releaseKey: 'processKey',
|
|
4176
|
-
releaseName: 'processName',
|
|
4177
|
-
releaseVersionId: 'processVersionId',
|
|
4178
|
-
processType: 'packageType',
|
|
4179
|
-
processKey: 'packageKey',
|
|
4180
|
-
processVersion: 'packageVersion',
|
|
4181
|
-
isProcessDeleted: 'isPackageDeleted',
|
|
4182
|
-
};
|
|
4471
|
+
track('Tasks.Assign')
|
|
4472
|
+
], TaskService.prototype, "assign", null);
|
|
4473
|
+
__decorate([
|
|
4474
|
+
track('Tasks.Reassign')
|
|
4475
|
+
], TaskService.prototype, "reassign", null);
|
|
4476
|
+
__decorate([
|
|
4477
|
+
track('Tasks.Unassign')
|
|
4478
|
+
], TaskService.prototype, "unassign", null);
|
|
4479
|
+
__decorate([
|
|
4480
|
+
track('Tasks.Complete')
|
|
4481
|
+
], TaskService.prototype, "complete", null);
|
|
4183
4482
|
|
|
4184
|
-
|
|
4185
|
-
* Service for interacting with UiPath Orchestrator Processes API
|
|
4186
|
-
*/
|
|
4187
|
-
class ProcessService extends BaseService {
|
|
4483
|
+
class CaseInstancesService extends BaseService {
|
|
4188
4484
|
/**
|
|
4189
4485
|
* @hideconstructor
|
|
4190
4486
|
*/
|
|
4191
4487
|
constructor(config, executionContext, tokenManager) {
|
|
4192
4488
|
super(config, executionContext, tokenManager);
|
|
4489
|
+
this.taskService = new TaskService(config, executionContext, tokenManager);
|
|
4193
4490
|
}
|
|
4194
4491
|
/**
|
|
4195
|
-
*
|
|
4492
|
+
* Get all case instances with optional filtering and pagination
|
|
4196
4493
|
*
|
|
4197
4494
|
* The method returns either:
|
|
4198
|
-
* -
|
|
4199
|
-
* - A
|
|
4495
|
+
* - A NonPaginatedResponse with items array (when no pagination parameters are provided)
|
|
4496
|
+
* - A PaginatedResponse with navigation cursors (when any pagination parameter is provided)
|
|
4200
4497
|
*
|
|
4201
|
-
* @param options -
|
|
4202
|
-
* @returns Promise resolving to
|
|
4498
|
+
* @param options -Query parameters for filtering instances and pagination
|
|
4499
|
+
* @returns Promise resolving to case instances or paginated result
|
|
4203
4500
|
*
|
|
4204
4501
|
* @example
|
|
4205
4502
|
* ```typescript
|
|
4206
|
-
* //
|
|
4207
|
-
* const
|
|
4503
|
+
* // Get all case instances (non-paginated)
|
|
4504
|
+
* const instances = await sdk.maestro.cases.instances.getAll();
|
|
4208
4505
|
*
|
|
4209
|
-
* //
|
|
4210
|
-
* const
|
|
4211
|
-
*
|
|
4212
|
-
* });
|
|
4506
|
+
* // Close faulted instances using methods directly on instances
|
|
4507
|
+
* for (const instance of instances.items) {
|
|
4508
|
+
* if (instance.latestRunStatus === 'Faulted') {
|
|
4509
|
+
* await instance.close({ comment: 'Closing faulted case instance' });
|
|
4510
|
+
* }
|
|
4511
|
+
* }
|
|
4213
4512
|
*
|
|
4214
|
-
* //
|
|
4215
|
-
* const
|
|
4216
|
-
*
|
|
4513
|
+
* // With filtering
|
|
4514
|
+
* const instances = await sdk.maestro.cases.instances.getAll({
|
|
4515
|
+
* processKey: 'MyCaseProcess'
|
|
4217
4516
|
* });
|
|
4218
4517
|
*
|
|
4219
4518
|
* // First page with pagination
|
|
4220
|
-
* const page1 = await sdk.
|
|
4519
|
+
* const page1 = await sdk.maestro.cases.instances.getAll({ pageSize: 10 });
|
|
4221
4520
|
*
|
|
4222
4521
|
* // Navigate using cursor
|
|
4223
4522
|
* if (page1.hasNextPage) {
|
|
4224
|
-
* const page2 = await sdk.
|
|
4523
|
+
* const page2 = await sdk.maestro.cases.instances.getAll({ cursor: page1.nextCursor });
|
|
4225
4524
|
* }
|
|
4226
|
-
*
|
|
4227
|
-
* // Jump to specific page
|
|
4228
|
-
* const page5 = await sdk.processes.getAll({
|
|
4229
|
-
* jumpToPage: 5,
|
|
4230
|
-
* pageSize: 10
|
|
4231
|
-
* });
|
|
4232
4525
|
* ```
|
|
4233
4526
|
*/
|
|
4234
4527
|
async getAll(options) {
|
|
4235
|
-
//
|
|
4236
|
-
const
|
|
4237
|
-
|
|
4528
|
+
// Add processType filter to only get case management instances
|
|
4529
|
+
const enhancedOptions = {
|
|
4530
|
+
...options,
|
|
4531
|
+
processType: ProcessType.CaseManagement
|
|
4532
|
+
};
|
|
4533
|
+
// Base transformation function for case instances (synchronous)
|
|
4534
|
+
const transformCaseInstance = (item) => {
|
|
4535
|
+
const rawInstance = transformData(item, CaseInstanceMap);
|
|
4536
|
+
return createCaseInstanceWithMethods(rawInstance, this);
|
|
4537
|
+
};
|
|
4538
|
+
// Get the paginated result with basic transformation
|
|
4539
|
+
const result = await PaginationHelpers.getAll({
|
|
4238
4540
|
serviceAccess: this.createPaginationServiceAccess(),
|
|
4239
|
-
getEndpoint: () =>
|
|
4240
|
-
|
|
4241
|
-
transformFn: transformProcessResponse,
|
|
4541
|
+
getEndpoint: () => MAESTRO_ENDPOINTS.INSTANCES.GET_ALL,
|
|
4542
|
+
transformFn: transformCaseInstance,
|
|
4242
4543
|
pagination: {
|
|
4243
|
-
paginationType: PaginationType.
|
|
4244
|
-
itemsField:
|
|
4245
|
-
|
|
4544
|
+
paginationType: PaginationType.TOKEN,
|
|
4545
|
+
itemsField: PROCESS_INSTANCE_PAGINATION.ITEMS_FIELD,
|
|
4546
|
+
continuationTokenField: PROCESS_INSTANCE_PAGINATION.CONTINUATION_TOKEN_FIELD,
|
|
4246
4547
|
paginationParams: {
|
|
4247
|
-
pageSizeParam:
|
|
4248
|
-
|
|
4249
|
-
countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM
|
|
4548
|
+
pageSizeParam: PROCESS_INSTANCE_TOKEN_PARAMS.PAGE_SIZE_PARAM,
|
|
4549
|
+
tokenParam: PROCESS_INSTANCE_TOKEN_PARAMS.TOKEN_PARAM
|
|
4250
4550
|
}
|
|
4551
|
+
},
|
|
4552
|
+
excludeFromPrefix: Object.keys(enhancedOptions || {})
|
|
4553
|
+
}, enhancedOptions);
|
|
4554
|
+
// Enhance instances with case JSON data if requested
|
|
4555
|
+
if (result.items && result.items.length > 0) {
|
|
4556
|
+
const enhancedItems = await this.enhanceInstancesWithCaseJson(result.items);
|
|
4557
|
+
return {
|
|
4558
|
+
...result,
|
|
4559
|
+
items: enhancedItems
|
|
4560
|
+
};
|
|
4561
|
+
}
|
|
4562
|
+
return result;
|
|
4563
|
+
}
|
|
4564
|
+
/**
|
|
4565
|
+
* Get a case instance by ID with operation methods (close, pause, resume)
|
|
4566
|
+
* @param instanceId - The ID of the instance to retrieve
|
|
4567
|
+
* @param folderKey - Required folder key
|
|
4568
|
+
* @returns Promise<CaseInstanceGetResponse>
|
|
4569
|
+
*/
|
|
4570
|
+
async getById(instanceId, folderKey) {
|
|
4571
|
+
const response = await this.get(MAESTRO_ENDPOINTS.INSTANCES.GET_BY_ID(instanceId), {
|
|
4572
|
+
headers: createHeaders({ [FOLDER_KEY]: folderKey })
|
|
4573
|
+
});
|
|
4574
|
+
const transformedInstance = transformData(response.data, CaseInstanceMap);
|
|
4575
|
+
const instanceWithMethods = createCaseInstanceWithMethods(transformedInstance, this);
|
|
4576
|
+
// Enhance with case JSON data
|
|
4577
|
+
return this.enhanceInstanceWithCaseJson(instanceWithMethods);
|
|
4578
|
+
}
|
|
4579
|
+
/**
|
|
4580
|
+
* Enhance a single case instance with case JSON data
|
|
4581
|
+
* @param instance - The case instance to enhance
|
|
4582
|
+
* @returns Promise resolving to enhanced instance
|
|
4583
|
+
* @private
|
|
4584
|
+
*/
|
|
4585
|
+
async enhanceInstanceWithCaseJson(instance) {
|
|
4586
|
+
if (!instance.folderKey) {
|
|
4587
|
+
return instance;
|
|
4588
|
+
}
|
|
4589
|
+
try {
|
|
4590
|
+
const caseJson = await this.getCaseJson(instance.instanceId, instance.folderKey);
|
|
4591
|
+
if (caseJson && caseJson.root) {
|
|
4592
|
+
// Transform caseAppConfig
|
|
4593
|
+
const transformedCaseAppConfig = caseJson.root.caseAppConfig ? (() => {
|
|
4594
|
+
const transformed = transformData(caseJson.root.caseAppConfig, CaseAppConfigMap);
|
|
4595
|
+
// Remove id field from each overview item
|
|
4596
|
+
if (transformed.overview) {
|
|
4597
|
+
transformed.overview = transformed.overview.map(({ id, ...rest }) => rest);
|
|
4598
|
+
}
|
|
4599
|
+
return transformed;
|
|
4600
|
+
})() : undefined;
|
|
4601
|
+
return {
|
|
4602
|
+
...instance,
|
|
4603
|
+
...(transformedCaseAppConfig && { caseAppConfig: transformedCaseAppConfig }),
|
|
4604
|
+
...(caseJson.root.name && { caseType: caseJson.root.name }),
|
|
4605
|
+
...(caseJson.root.description && { caseTitle: caseJson.root.description })
|
|
4606
|
+
};
|
|
4251
4607
|
}
|
|
4252
|
-
}
|
|
4608
|
+
}
|
|
4609
|
+
catch (error) {
|
|
4610
|
+
console.debug(`Failed to fetch case JSON for instance ${instance.instanceId}:`, error);
|
|
4611
|
+
}
|
|
4612
|
+
return instance;
|
|
4253
4613
|
}
|
|
4254
4614
|
/**
|
|
4255
|
-
*
|
|
4256
|
-
*
|
|
4257
|
-
* @
|
|
4258
|
-
* @
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4615
|
+
* Enhance multiple case instances with case JSON data
|
|
4616
|
+
* @param instances - Array of case instances to enhance
|
|
4617
|
+
* @returns Promise resolving to array of enhanced instances
|
|
4618
|
+
* @private
|
|
4619
|
+
*/
|
|
4620
|
+
async enhanceInstancesWithCaseJson(instances) {
|
|
4621
|
+
return Promise.all(instances.map(instance => this.enhanceInstanceWithCaseJson(instance)));
|
|
4622
|
+
}
|
|
4623
|
+
/**
|
|
4624
|
+
* Get case JSON for a specific instance
|
|
4625
|
+
* @param instanceId - The case instance ID
|
|
4626
|
+
* @param folderKey - Required folder key
|
|
4627
|
+
* @returns Promise resolving to case JSON data
|
|
4628
|
+
* @private
|
|
4629
|
+
*/
|
|
4630
|
+
async getCaseJson(instanceId, folderKey) {
|
|
4631
|
+
try {
|
|
4632
|
+
const response = await this.get(MAESTRO_ENDPOINTS.CASES.GET_CASE_JSON(instanceId), {
|
|
4633
|
+
headers: createHeaders({ [FOLDER_KEY]: folderKey })
|
|
4634
|
+
});
|
|
4635
|
+
return response.data;
|
|
4636
|
+
}
|
|
4637
|
+
catch (error) {
|
|
4638
|
+
// Return null if the case JSON is not available
|
|
4639
|
+
return null;
|
|
4640
|
+
}
|
|
4641
|
+
}
|
|
4642
|
+
/**
|
|
4643
|
+
* Close a case instance
|
|
4644
|
+
* @param instanceId - The ID of the instance to cancel
|
|
4645
|
+
* @param folderKey - Required folder key
|
|
4646
|
+
* @param options - Optional cancellation options with comment
|
|
4647
|
+
* @returns Promise resolving to operation result with updated instance data
|
|
4648
|
+
*/
|
|
4649
|
+
async close(instanceId, folderKey, options) {
|
|
4650
|
+
const response = await this.post(MAESTRO_ENDPOINTS.INSTANCES.CANCEL(instanceId), options || {}, {
|
|
4651
|
+
headers: createHeaders({ [FOLDER_KEY]: folderKey })
|
|
4652
|
+
});
|
|
4653
|
+
return {
|
|
4654
|
+
success: true,
|
|
4655
|
+
data: response.data
|
|
4656
|
+
};
|
|
4657
|
+
}
|
|
4658
|
+
/**
|
|
4659
|
+
* Pause a case instance
|
|
4660
|
+
* @param instanceId - The ID of the instance to pause
|
|
4661
|
+
* @param folderKey - Required folder key
|
|
4662
|
+
* @param options - Optional pause options with comment
|
|
4663
|
+
* @returns Promise resolving to operation result with updated instance data
|
|
4664
|
+
*/
|
|
4665
|
+
async pause(instanceId, folderKey, options) {
|
|
4666
|
+
const response = await this.post(MAESTRO_ENDPOINTS.INSTANCES.PAUSE(instanceId), options || {}, {
|
|
4667
|
+
headers: createHeaders({ [FOLDER_KEY]: folderKey })
|
|
4668
|
+
});
|
|
4669
|
+
return {
|
|
4670
|
+
success: true,
|
|
4671
|
+
data: response.data
|
|
4672
|
+
};
|
|
4673
|
+
}
|
|
4674
|
+
/**
|
|
4675
|
+
* Resume a case instance
|
|
4676
|
+
* @param instanceId - The ID of the instance to resume
|
|
4677
|
+
* @param folderKey - Required folder key
|
|
4678
|
+
* @param options - Optional resume options with comment
|
|
4679
|
+
* @returns Promise resolving to operation result with updated instance data
|
|
4680
|
+
*/
|
|
4681
|
+
async resume(instanceId, folderKey, options) {
|
|
4682
|
+
const response = await this.post(MAESTRO_ENDPOINTS.INSTANCES.RESUME(instanceId), options || {}, {
|
|
4683
|
+
headers: createHeaders({ [FOLDER_KEY]: folderKey })
|
|
4684
|
+
});
|
|
4685
|
+
return {
|
|
4686
|
+
success: true,
|
|
4687
|
+
data: response.data
|
|
4688
|
+
};
|
|
4689
|
+
}
|
|
4690
|
+
/**
|
|
4691
|
+
* Get execution history for a case instance
|
|
4692
|
+
* @param instanceId - The ID of the case instance
|
|
4693
|
+
* @param folderKey - Required folder key
|
|
4694
|
+
* @returns Promise resolving to instance execution history
|
|
4262
4695
|
* @example
|
|
4263
4696
|
* ```typescript
|
|
4264
|
-
* //
|
|
4265
|
-
* const
|
|
4266
|
-
*
|
|
4267
|
-
*
|
|
4268
|
-
*
|
|
4269
|
-
* // Start a process by name with specific robots
|
|
4270
|
-
* const jobs = await sdk.processes.start({
|
|
4271
|
-
* processName: "MyProcess"
|
|
4272
|
-
* }, 123); // folderId is required
|
|
4697
|
+
* // Get execution history for a case instance
|
|
4698
|
+
* const history = await sdk.maestro.cases.instances.getExecutionHistory(
|
|
4699
|
+
* 'instance-id',
|
|
4700
|
+
* 'folder-key'
|
|
4701
|
+
* );
|
|
4273
4702
|
* ```
|
|
4274
4703
|
*/
|
|
4275
|
-
async
|
|
4276
|
-
const
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
//
|
|
4280
|
-
const
|
|
4281
|
-
//
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4704
|
+
async getExecutionHistory(instanceId, folderKey) {
|
|
4705
|
+
const response = await this.get(MAESTRO_ENDPOINTS.CASES.GET_ELEMENT_EXECUTIONS(instanceId), {
|
|
4706
|
+
headers: createHeaders({ [FOLDER_KEY]: folderKey })
|
|
4707
|
+
});
|
|
4708
|
+
// Transform the main response
|
|
4709
|
+
const transformedResponse = transformData(response.data, TimeFieldTransformMap);
|
|
4710
|
+
// Transform each element execution and its nested element runs
|
|
4711
|
+
if (transformedResponse.elementExecutions && Array.isArray(transformedResponse.elementExecutions)) {
|
|
4712
|
+
transformedResponse.elementExecutions = transformedResponse.elementExecutions.map((execution) => {
|
|
4713
|
+
// Transform the element execution itself
|
|
4714
|
+
const transformedExecution = transformData(execution, TimeFieldTransformMap);
|
|
4715
|
+
// Transform nested element runs if they exist
|
|
4716
|
+
if (transformedExecution.elementRuns && Array.isArray(transformedExecution.elementRuns)) {
|
|
4717
|
+
transformedExecution.elementRuns = transformedExecution.elementRuns.map((run) => transformData(run, TimeFieldTransformMap));
|
|
4718
|
+
}
|
|
4719
|
+
return transformedExecution;
|
|
4720
|
+
});
|
|
4721
|
+
}
|
|
4722
|
+
return transformedResponse;
|
|
4723
|
+
}
|
|
4724
|
+
/**
|
|
4725
|
+
* Get case stages with their associated tasks and execution status
|
|
4726
|
+
* @param caseInstanceId - The ID of the case instance
|
|
4727
|
+
* @param folderKey - Required folder key
|
|
4728
|
+
* @returns Promise resolving to an array of case stages, each containing their tasks with execution details
|
|
4729
|
+
*/
|
|
4730
|
+
async getStages(caseInstanceId, folderKey) {
|
|
4731
|
+
// Fetch both execution history and case JSON in parallel, but handle execution failures gracefully
|
|
4732
|
+
const [executionHistoryResponse, caseJsonResponse] = await Promise.allSettled([
|
|
4733
|
+
this.getExecutionHistory(caseInstanceId, folderKey),
|
|
4734
|
+
this.getCaseJson(caseInstanceId, folderKey)
|
|
4735
|
+
]);
|
|
4736
|
+
// Extract execution history if successful, otherwise use null
|
|
4737
|
+
const executionHistory = executionHistoryResponse.status === 'fulfilled'
|
|
4738
|
+
? executionHistoryResponse.value
|
|
4739
|
+
: null;
|
|
4740
|
+
// Extract case JSON - the null check below will handle failures
|
|
4741
|
+
const caseJson = caseJsonResponse.status === 'fulfilled'
|
|
4742
|
+
? caseJsonResponse.value
|
|
4743
|
+
: null;
|
|
4744
|
+
if (!caseJson || !caseJson.nodes) {
|
|
4745
|
+
return [];
|
|
4746
|
+
}
|
|
4747
|
+
// Create lookup maps for efficient data access
|
|
4748
|
+
const executionMap = this.createExecutionMap(executionHistory);
|
|
4749
|
+
const bindingsMap = this.createBindingsMap(caseJson);
|
|
4750
|
+
// Process nodes to extract stages (exclude triggers)
|
|
4751
|
+
const stages = caseJson.nodes
|
|
4752
|
+
.filter((node) => node.type !== CASE_STAGE_CONSTANTS.TRIGGER_NODE_TYPE)
|
|
4753
|
+
.map((node) => this.createStageFromNode(node, executionMap, bindingsMap));
|
|
4754
|
+
return stages;
|
|
4755
|
+
}
|
|
4756
|
+
/**
|
|
4757
|
+
* Create a map of element ID to execution data
|
|
4758
|
+
* @param executionHistory - The execution history response
|
|
4759
|
+
* @returns Map of elementId to execution metadata
|
|
4760
|
+
* @private
|
|
4761
|
+
*/
|
|
4762
|
+
createExecutionMap(executionHistory) {
|
|
4763
|
+
const executionMap = new Map();
|
|
4764
|
+
if (executionHistory?.elementExecutions) {
|
|
4765
|
+
for (const execution of executionHistory.elementExecutions) {
|
|
4766
|
+
executionMap.set(execution.elementId, execution);
|
|
4767
|
+
}
|
|
4768
|
+
}
|
|
4769
|
+
return executionMap;
|
|
4770
|
+
}
|
|
4771
|
+
/**
|
|
4772
|
+
* Create a map of binding IDs to their values
|
|
4773
|
+
* @param caseJsonResponse - The case JSON response
|
|
4774
|
+
* @returns Map of binding ID to binding object
|
|
4775
|
+
* @private
|
|
4776
|
+
*/
|
|
4777
|
+
createBindingsMap(caseJsonResponse) {
|
|
4778
|
+
const bindingsMap = new Map();
|
|
4779
|
+
if (caseJsonResponse?.root?.data?.uipath?.bindings) {
|
|
4780
|
+
for (const binding of caseJsonResponse.root.data.uipath.bindings) {
|
|
4781
|
+
if (binding.id) {
|
|
4782
|
+
bindingsMap.set(binding.id, binding);
|
|
4783
|
+
}
|
|
4784
|
+
}
|
|
4785
|
+
}
|
|
4786
|
+
return bindingsMap;
|
|
4787
|
+
}
|
|
4788
|
+
/**
|
|
4789
|
+
* Resolve binding values from binding expressions
|
|
4790
|
+
* @param value - The value that may contain binding references
|
|
4791
|
+
* @param bindingsMap - Map of binding IDs to binding objects
|
|
4792
|
+
* @returns Resolved value
|
|
4793
|
+
* @private
|
|
4794
|
+
*/
|
|
4795
|
+
resolveBinding(value, bindingsMap) {
|
|
4796
|
+
if (typeof value === 'string' && value.startsWith('=bindings.')) {
|
|
4797
|
+
const bindingId = value.substring('=bindings.'.length);
|
|
4798
|
+
const binding = bindingsMap.get(bindingId);
|
|
4799
|
+
return binding?.default || binding?.name || value;
|
|
4800
|
+
}
|
|
4801
|
+
return value;
|
|
4802
|
+
}
|
|
4803
|
+
/**
|
|
4804
|
+
* Process tasks for a stage node
|
|
4805
|
+
* @param node - The stage node containing tasks
|
|
4806
|
+
* @param executionMap - Map of element IDs to execution data
|
|
4807
|
+
* @param bindingsMap - Map of binding IDs to binding objects
|
|
4808
|
+
* @returns Processed tasks array
|
|
4809
|
+
* @private
|
|
4810
|
+
*/
|
|
4811
|
+
processTasks(node, executionMap, bindingsMap) {
|
|
4812
|
+
if (!node.data?.tasks || !Array.isArray(node.data.tasks)) {
|
|
4813
|
+
return [];
|
|
4814
|
+
}
|
|
4815
|
+
return node.data.tasks.map((taskGroup) => {
|
|
4816
|
+
if (Array.isArray(taskGroup)) {
|
|
4817
|
+
return taskGroup.map((task) => {
|
|
4818
|
+
const taskId = task.id;
|
|
4819
|
+
// Find the execution data using the task's id
|
|
4820
|
+
const taskExecution = taskId ? executionMap.get(taskId) : undefined;
|
|
4821
|
+
// Resolve task name from bindings
|
|
4822
|
+
let taskName = task.displayName;
|
|
4823
|
+
if (!taskName && task.data?.name) {
|
|
4824
|
+
taskName = this.resolveBinding(task.data.name, bindingsMap);
|
|
4825
|
+
}
|
|
4826
|
+
const stageTask = {
|
|
4827
|
+
id: taskId || task.elementId || CASE_STAGE_CONSTANTS.UNDEFINED_VALUE,
|
|
4828
|
+
name: taskName || CASE_STAGE_CONSTANTS.UNDEFINED_VALUE,
|
|
4829
|
+
completedTime: taskExecution?.completedTime || CASE_STAGE_CONSTANTS.UNDEFINED_VALUE,
|
|
4830
|
+
startedTime: taskExecution?.startedTime || CASE_STAGE_CONSTANTS.UNDEFINED_VALUE,
|
|
4831
|
+
status: taskExecution?.status || CASE_STAGE_CONSTANTS.NOT_STARTED_STATUS,
|
|
4832
|
+
type: task.type || CASE_STAGE_CONSTANTS.UNDEFINED_VALUE
|
|
4833
|
+
};
|
|
4834
|
+
return stageTask;
|
|
4835
|
+
});
|
|
4286
4836
|
}
|
|
4837
|
+
return [];
|
|
4287
4838
|
});
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4839
|
+
}
|
|
4840
|
+
/**
|
|
4841
|
+
* Create a stage from a case node
|
|
4842
|
+
* @param node - The case node to process
|
|
4843
|
+
* @param executionMap - Map of element IDs to execution data
|
|
4844
|
+
* @param bindingsMap - Map of binding IDs to binding objects
|
|
4845
|
+
* @returns CaseGetStageResponse object
|
|
4846
|
+
* @private
|
|
4847
|
+
*/
|
|
4848
|
+
createStageFromNode(node, executionMap, bindingsMap) {
|
|
4849
|
+
const execution = executionMap.get(node.id);
|
|
4850
|
+
const stage = {
|
|
4851
|
+
id: node.id,
|
|
4852
|
+
name: node.data?.label || CASE_STAGE_CONSTANTS.UNDEFINED_VALUE,
|
|
4853
|
+
sla: node.data?.sla ? transformData(node.data.sla, StageSLAMap) : undefined,
|
|
4854
|
+
status: execution?.status || CASE_STAGE_CONSTANTS.NOT_STARTED_STATUS,
|
|
4855
|
+
tasks: this.processTasks(node, executionMap, bindingsMap)
|
|
4293
4856
|
};
|
|
4294
|
-
|
|
4295
|
-
const keysToPrefix = Object.keys(options);
|
|
4296
|
-
const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
|
|
4297
|
-
const response = await this.post(PROCESS_ENDPOINTS.START_PROCESS, requestBody, {
|
|
4298
|
-
params: apiOptions,
|
|
4299
|
-
headers
|
|
4300
|
-
});
|
|
4301
|
-
const transformedProcess = response.data?.value.map(process => transformData(pascalToCamelCaseKeys(process), ProcessMap));
|
|
4302
|
-
return transformedProcess;
|
|
4857
|
+
return stage;
|
|
4303
4858
|
}
|
|
4304
4859
|
/**
|
|
4305
|
-
*
|
|
4306
|
-
*
|
|
4307
|
-
* @param
|
|
4308
|
-
* @
|
|
4309
|
-
|
|
4310
|
-
|
|
4860
|
+
* Get human in the loop tasks associated with a case instance
|
|
4861
|
+
* @param caseInstanceId - The ID of the case instance
|
|
4862
|
+
* @param options - Optional filtering and pagination options
|
|
4863
|
+
* @returns Promise resolving to human in the loop tasks associated with the case instance
|
|
4864
|
+
*/
|
|
4865
|
+
async getActionTasks(caseInstanceId, options) {
|
|
4866
|
+
// Build filter to match tasks by case instance ID using tags
|
|
4867
|
+
const tagFilter = CASE_INSTANCE_TASK_FILTER(caseInstanceId);
|
|
4868
|
+
// Combine with any existing filter
|
|
4869
|
+
const filter = options?.filter
|
|
4870
|
+
? `(${tagFilter}) and (${options.filter})`
|
|
4871
|
+
: tagFilter;
|
|
4872
|
+
// Add expand to include AssignedToUser and Activities
|
|
4873
|
+
const expand = CASE_INSTANCE_TASK_EXPAND;
|
|
4874
|
+
// Prepare the enhanced options with proper typing
|
|
4875
|
+
const enhancedOptions = {
|
|
4876
|
+
...options,
|
|
4877
|
+
filter,
|
|
4878
|
+
expand
|
|
4879
|
+
};
|
|
4880
|
+
return await this.taskService.getAll(enhancedOptions);
|
|
4881
|
+
}
|
|
4882
|
+
}
|
|
4883
|
+
__decorate([
|
|
4884
|
+
track('CaseInstances.GetAll')
|
|
4885
|
+
], CaseInstancesService.prototype, "getAll", null);
|
|
4886
|
+
__decorate([
|
|
4887
|
+
track('CaseInstances.GetById')
|
|
4888
|
+
], CaseInstancesService.prototype, "getById", null);
|
|
4889
|
+
__decorate([
|
|
4890
|
+
track('CaseInstances.Close')
|
|
4891
|
+
], CaseInstancesService.prototype, "close", null);
|
|
4892
|
+
__decorate([
|
|
4893
|
+
track('CaseInstances.Pause')
|
|
4894
|
+
], CaseInstancesService.prototype, "pause", null);
|
|
4895
|
+
__decorate([
|
|
4896
|
+
track('CaseInstances.Resume')
|
|
4897
|
+
], CaseInstancesService.prototype, "resume", null);
|
|
4898
|
+
__decorate([
|
|
4899
|
+
track('CaseInstances.GetExecutionHistory')
|
|
4900
|
+
], CaseInstancesService.prototype, "getExecutionHistory", null);
|
|
4901
|
+
__decorate([
|
|
4902
|
+
track('CaseInstances.GetStages')
|
|
4903
|
+
], CaseInstancesService.prototype, "getStages", null);
|
|
4904
|
+
__decorate([
|
|
4905
|
+
track('CaseInstances.GetActionTasks')
|
|
4906
|
+
], CaseInstancesService.prototype, "getActionTasks", null);
|
|
4907
|
+
|
|
4908
|
+
/**
|
|
4909
|
+
* Base service for services that need folder-specific functionality
|
|
4910
|
+
*/
|
|
4911
|
+
class FolderScopedService extends BaseService {
|
|
4912
|
+
constructor(config, executionContext, tokenManager) {
|
|
4913
|
+
super(config, executionContext, tokenManager);
|
|
4914
|
+
}
|
|
4915
|
+
/**
|
|
4916
|
+
* Gets resources in a folder with optional query parameters
|
|
4311
4917
|
*
|
|
4312
|
-
* @
|
|
4313
|
-
*
|
|
4314
|
-
*
|
|
4315
|
-
*
|
|
4316
|
-
*
|
|
4918
|
+
* @param endpoint - API endpoint to call
|
|
4919
|
+
* @param folderId - required folder ID
|
|
4920
|
+
* @param options - Query options
|
|
4921
|
+
* @param transformFn - Optional function to transform the response data
|
|
4922
|
+
* @returns Promise resolving to an array of resources
|
|
4317
4923
|
*/
|
|
4318
|
-
async
|
|
4924
|
+
async _getByFolder(endpoint, folderId, options = {}, transformFn) {
|
|
4319
4925
|
const headers = createHeaders({ [FOLDER_ID]: folderId });
|
|
4320
4926
|
const keysToPrefix = Object.keys(options);
|
|
4321
4927
|
const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
|
|
4322
|
-
const response = await this.get(
|
|
4323
|
-
|
|
4324
|
-
|
|
4928
|
+
const response = await this.get(endpoint, {
|
|
4929
|
+
params: apiOptions,
|
|
4930
|
+
headers
|
|
4325
4931
|
});
|
|
4326
|
-
|
|
4327
|
-
|
|
4932
|
+
if (transformFn) {
|
|
4933
|
+
return response.data?.value.map(transformFn);
|
|
4934
|
+
}
|
|
4935
|
+
return response.data?.value;
|
|
4328
4936
|
}
|
|
4329
4937
|
}
|
|
4330
|
-
__decorate([
|
|
4331
|
-
track('Processes.GetAll')
|
|
4332
|
-
], ProcessService.prototype, "getAll", null);
|
|
4333
|
-
__decorate([
|
|
4334
|
-
track('Processes.Start')
|
|
4335
|
-
], ProcessService.prototype, "start", null);
|
|
4336
|
-
__decorate([
|
|
4337
|
-
track('Processes.GetById')
|
|
4338
|
-
], ProcessService.prototype, "getById", null);
|
|
4339
4938
|
|
|
4340
4939
|
/**
|
|
4341
|
-
* Maps fields for
|
|
4940
|
+
* Maps fields for Asset entities to ensure consistent naming
|
|
4342
4941
|
*/
|
|
4343
|
-
const
|
|
4942
|
+
const AssetMap = {
|
|
4344
4943
|
creationTime: 'createdTime',
|
|
4345
|
-
|
|
4346
|
-
organizationUnitFullyQualifiedName: 'folderName'
|
|
4944
|
+
lastModificationTime: 'lastModifiedTime'
|
|
4347
4945
|
};
|
|
4348
4946
|
|
|
4349
4947
|
/**
|
|
4350
|
-
* Service for interacting with UiPath Orchestrator
|
|
4948
|
+
* Service for interacting with UiPath Orchestrator Assets API
|
|
4351
4949
|
*/
|
|
4352
|
-
class
|
|
4950
|
+
class AssetService extends FolderScopedService {
|
|
4353
4951
|
/**
|
|
4354
4952
|
* @hideconstructor
|
|
4355
4953
|
*/
|
|
@@ -4357,53 +4955,43 @@ class QueueService extends FolderScopedService {
|
|
|
4357
4955
|
super(config, executionContext, tokenManager);
|
|
4358
4956
|
}
|
|
4359
4957
|
/**
|
|
4360
|
-
* Gets all
|
|
4361
|
-
*
|
|
4362
|
-
* The method returns either:
|
|
4363
|
-
* - An array of queues (when no pagination parameters are provided)
|
|
4364
|
-
* - A paginated result with navigation cursors (when any pagination parameter is provided)
|
|
4958
|
+
* Gets all assets across folders with optional filtering and folder scoping
|
|
4365
4959
|
*
|
|
4366
|
-
* @
|
|
4367
|
-
* @
|
|
4960
|
+
* @signature getAll(options?) -> Promise<AssetGetResponse[]>
|
|
4961
|
+
* @param options Query options including optional folderId and pagination options
|
|
4962
|
+
* @returns Promise resolving to array of assets or paginated response
|
|
4368
4963
|
*
|
|
4369
4964
|
* @example
|
|
4370
4965
|
* ```typescript
|
|
4371
4966
|
* // Standard array return
|
|
4372
|
-
* const
|
|
4373
|
-
*
|
|
4374
|
-
* // Get queues within a specific folder
|
|
4375
|
-
* const queues = await sdk.queues.getAll({
|
|
4376
|
-
* folderId: 123
|
|
4377
|
-
* });
|
|
4967
|
+
* const assets = await sdk.assets.getAll();
|
|
4378
4968
|
*
|
|
4379
|
-
* //
|
|
4380
|
-
* const
|
|
4381
|
-
* filter: "name eq 'MyQueue'"
|
|
4382
|
-
* });
|
|
4969
|
+
* // With folder
|
|
4970
|
+
* const folderAssets = await sdk.assets.getAll({ folderId: 123 });
|
|
4383
4971
|
*
|
|
4384
4972
|
* // First page with pagination
|
|
4385
|
-
* const page1 = await sdk.
|
|
4973
|
+
* const page1 = await sdk.assets.getAll({ pageSize: 10 });
|
|
4386
4974
|
*
|
|
4387
4975
|
* // Navigate using cursor
|
|
4388
4976
|
* if (page1.hasNextPage) {
|
|
4389
|
-
* const page2 = await sdk.
|
|
4977
|
+
* const page2 = await sdk.assets.getAll({ cursor: page1.nextCursor });
|
|
4390
4978
|
* }
|
|
4391
4979
|
*
|
|
4392
4980
|
* // Jump to specific page
|
|
4393
|
-
* const page5 = await sdk.
|
|
4981
|
+
* const page5 = await sdk.assets.getAll({
|
|
4394
4982
|
* jumpToPage: 5,
|
|
4395
4983
|
* pageSize: 10
|
|
4396
4984
|
* });
|
|
4397
4985
|
* ```
|
|
4398
4986
|
*/
|
|
4399
4987
|
async getAll(options) {
|
|
4400
|
-
// Transformation function for
|
|
4401
|
-
const
|
|
4988
|
+
// Transformation function for assets
|
|
4989
|
+
const transformAssetResponse = (asset) => transformData(pascalToCamelCaseKeys(asset), AssetMap);
|
|
4402
4990
|
return PaginationHelpers.getAll({
|
|
4403
4991
|
serviceAccess: this.createPaginationServiceAccess(),
|
|
4404
|
-
getEndpoint: (folderId) => folderId ?
|
|
4405
|
-
getByFolderEndpoint:
|
|
4406
|
-
transformFn:
|
|
4992
|
+
getEndpoint: (folderId) => folderId ? ASSET_ENDPOINTS.GET_BY_FOLDER : ASSET_ENDPOINTS.GET_ALL,
|
|
4993
|
+
getByFolderEndpoint: ASSET_ENDPOINTS.GET_BY_FOLDER,
|
|
4994
|
+
transformFn: transformAssetResponse,
|
|
4407
4995
|
pagination: {
|
|
4408
4996
|
paginationType: PaginationType.OFFSET,
|
|
4409
4997
|
itemsField: ODATA_PAGINATION.ITEMS_FIELD,
|
|
@@ -4417,579 +5005,743 @@ class QueueService extends FolderScopedService {
|
|
|
4417
5005
|
}, options);
|
|
4418
5006
|
}
|
|
4419
5007
|
/**
|
|
4420
|
-
* Gets a single
|
|
5008
|
+
* Gets a single asset by ID
|
|
4421
5009
|
*
|
|
4422
|
-
* @param id -
|
|
5010
|
+
* @param id - Asset ID
|
|
4423
5011
|
* @param folderId - Required folder ID
|
|
4424
|
-
* @
|
|
5012
|
+
* @param options - Optional query parameters (expand, select)
|
|
5013
|
+
* @returns Promise resolving to a single asset
|
|
4425
5014
|
*
|
|
4426
5015
|
* @example
|
|
4427
5016
|
* ```typescript
|
|
4428
|
-
* // Get
|
|
4429
|
-
* const
|
|
5017
|
+
* // Get asset by ID
|
|
5018
|
+
* const asset = await sdk.assets.getById(123, 456);
|
|
4430
5019
|
* ```
|
|
4431
5020
|
*/
|
|
4432
5021
|
async getById(id, folderId, options = {}) {
|
|
4433
5022
|
const headers = createHeaders({ [FOLDER_ID]: folderId });
|
|
4434
5023
|
const keysToPrefix = Object.keys(options);
|
|
4435
5024
|
const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
|
|
4436
|
-
const response = await this.get(
|
|
5025
|
+
const response = await this.get(ASSET_ENDPOINTS.GET_BY_ID(id), {
|
|
4437
5026
|
headers,
|
|
4438
5027
|
params: apiOptions
|
|
4439
5028
|
});
|
|
4440
|
-
|
|
5029
|
+
const transformedAsset = transformData(pascalToCamelCaseKeys(response.data), AssetMap);
|
|
5030
|
+
return transformedAsset;
|
|
4441
5031
|
}
|
|
4442
5032
|
}
|
|
4443
5033
|
__decorate([
|
|
4444
|
-
track('
|
|
4445
|
-
],
|
|
5034
|
+
track('Assets.GetAll')
|
|
5035
|
+
], AssetService.prototype, "getAll", null);
|
|
4446
5036
|
__decorate([
|
|
4447
|
-
track('
|
|
4448
|
-
],
|
|
4449
|
-
|
|
4450
|
-
exports.TaskType = void 0;
|
|
4451
|
-
(function (TaskType) {
|
|
4452
|
-
TaskType["Form"] = "FormTask";
|
|
4453
|
-
TaskType["External"] = "ExternalTask";
|
|
4454
|
-
TaskType["App"] = "AppTask";
|
|
4455
|
-
})(exports.TaskType || (exports.TaskType = {}));
|
|
4456
|
-
exports.TaskPriority = void 0;
|
|
4457
|
-
(function (TaskPriority) {
|
|
4458
|
-
TaskPriority["Low"] = "Low";
|
|
4459
|
-
TaskPriority["Medium"] = "Medium";
|
|
4460
|
-
TaskPriority["High"] = "High";
|
|
4461
|
-
TaskPriority["Critical"] = "Critical";
|
|
4462
|
-
})(exports.TaskPriority || (exports.TaskPriority = {}));
|
|
4463
|
-
exports.TaskStatus = void 0;
|
|
4464
|
-
(function (TaskStatus) {
|
|
4465
|
-
TaskStatus["Unassigned"] = "Unassigned";
|
|
4466
|
-
TaskStatus["Pending"] = "Pending";
|
|
4467
|
-
TaskStatus["Completed"] = "Completed";
|
|
4468
|
-
})(exports.TaskStatus || (exports.TaskStatus = {}));
|
|
4469
|
-
exports.TaskSlaCriteria = void 0;
|
|
4470
|
-
(function (TaskSlaCriteria) {
|
|
4471
|
-
TaskSlaCriteria["TaskCreated"] = "TaskCreated";
|
|
4472
|
-
TaskSlaCriteria["TaskAssigned"] = "TaskAssigned";
|
|
4473
|
-
TaskSlaCriteria["TaskCompleted"] = "TaskCompleted";
|
|
4474
|
-
})(exports.TaskSlaCriteria || (exports.TaskSlaCriteria = {}));
|
|
4475
|
-
exports.TaskSlaStatus = void 0;
|
|
4476
|
-
(function (TaskSlaStatus) {
|
|
4477
|
-
TaskSlaStatus["OverdueLater"] = "OverdueLater";
|
|
4478
|
-
TaskSlaStatus["OverdueSoon"] = "OverdueSoon";
|
|
4479
|
-
TaskSlaStatus["Overdue"] = "Overdue";
|
|
4480
|
-
TaskSlaStatus["CompletedInTime"] = "CompletedInTime";
|
|
4481
|
-
})(exports.TaskSlaStatus || (exports.TaskSlaStatus = {}));
|
|
4482
|
-
exports.TaskSourceName = void 0;
|
|
4483
|
-
(function (TaskSourceName) {
|
|
4484
|
-
TaskSourceName["Agent"] = "Agent";
|
|
4485
|
-
TaskSourceName["Workflow"] = "Workflow";
|
|
4486
|
-
TaskSourceName["Maestro"] = "Maestro";
|
|
4487
|
-
TaskSourceName["Default"] = "Default";
|
|
4488
|
-
})(exports.TaskSourceName || (exports.TaskSourceName = {}));
|
|
4489
|
-
|
|
4490
|
-
/**
|
|
4491
|
-
* Creates methods for a task
|
|
4492
|
-
*
|
|
4493
|
-
* @param taskData - The task data (response from API)
|
|
4494
|
-
* @param service - The task service instance
|
|
4495
|
-
* @returns Object containing task methods
|
|
4496
|
-
*/
|
|
4497
|
-
function createTaskMethods(taskData, service) {
|
|
4498
|
-
return {
|
|
4499
|
-
async assign(options) {
|
|
4500
|
-
if (!taskData.id)
|
|
4501
|
-
throw new Error('Task ID is undefined');
|
|
4502
|
-
const assignmentOptions = {
|
|
4503
|
-
taskId: taskData.id,
|
|
4504
|
-
userId: options.userId || 0, // Will be handled by userNameOrEmail if userId is not provided, 0 is considered as invalid user id
|
|
4505
|
-
userNameOrEmail: options.userNameOrEmail
|
|
4506
|
-
};
|
|
4507
|
-
return service.assign(assignmentOptions, taskData.organizationUnitId);
|
|
4508
|
-
},
|
|
4509
|
-
async reassign(options) {
|
|
4510
|
-
if (!taskData.id)
|
|
4511
|
-
throw new Error('Task ID is undefined');
|
|
4512
|
-
const assignmentOptions = {
|
|
4513
|
-
taskId: taskData.id,
|
|
4514
|
-
userId: options.userId || 0, // Will be handled by userNameOrEmail if userId is not provided, 0 is considered as invalid user id
|
|
4515
|
-
userNameOrEmail: options.userNameOrEmail
|
|
4516
|
-
};
|
|
4517
|
-
return service.reassign(assignmentOptions, taskData.organizationUnitId);
|
|
4518
|
-
},
|
|
4519
|
-
async unassign() {
|
|
4520
|
-
if (!taskData.id)
|
|
4521
|
-
throw new Error('Task ID is undefined');
|
|
4522
|
-
return service.unassign(taskData.id, taskData.organizationUnitId);
|
|
4523
|
-
},
|
|
4524
|
-
async complete(options) {
|
|
4525
|
-
if (!taskData.id)
|
|
4526
|
-
throw new Error('Task ID is undefined');
|
|
4527
|
-
const folderId = taskData.organizationUnitId;
|
|
4528
|
-
if (!folderId)
|
|
4529
|
-
throw new Error('Folder ID is required');
|
|
4530
|
-
return service.complete(options.type, {
|
|
4531
|
-
taskId: taskData.id,
|
|
4532
|
-
data: options.data,
|
|
4533
|
-
action: options.action
|
|
4534
|
-
}, folderId);
|
|
4535
|
-
}
|
|
4536
|
-
};
|
|
4537
|
-
}
|
|
4538
|
-
/**
|
|
4539
|
-
* Creates an actionable task by combining API task data with operational methods.
|
|
4540
|
-
*
|
|
4541
|
-
* @param taskData - The task data from API
|
|
4542
|
-
* @param service - The task service instance
|
|
4543
|
-
* @returns A task object with added methods
|
|
4544
|
-
*/
|
|
4545
|
-
function createTaskWithMethods(taskData, service) {
|
|
4546
|
-
const methods = createTaskMethods(taskData, service);
|
|
4547
|
-
return Object.assign({}, taskData, methods);
|
|
4548
|
-
}
|
|
5037
|
+
track('Assets.GetById')
|
|
5038
|
+
], AssetService.prototype, "getById", null);
|
|
4549
5039
|
|
|
4550
5040
|
/**
|
|
4551
|
-
* Maps
|
|
4552
|
-
* Extend this file with additional field mappings as needed.
|
|
5041
|
+
* Maps fields for Bucket entities to ensure consistent naming
|
|
4553
5042
|
*/
|
|
4554
|
-
const
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
};
|
|
4559
|
-
// Field mapping for time-related fields to ensure consistent naming
|
|
4560
|
-
const TaskTimeMap = {
|
|
4561
|
-
completionTime: 'completedTime',
|
|
4562
|
-
deletionTime: 'deletedTime',
|
|
4563
|
-
lastModificationTime: 'lastModifiedTime',
|
|
4564
|
-
creationTime: 'createdTime',
|
|
5043
|
+
const BucketMap = {
|
|
5044
|
+
fullPath: 'path',
|
|
5045
|
+
items: 'blobItems',
|
|
5046
|
+
verb: 'httpMethod'
|
|
4565
5047
|
};
|
|
4566
5048
|
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
5049
|
+
// Import file-type dynamically to avoid issues in browser environment
|
|
5050
|
+
// This variable will hold the fileTypeFromBuffer function when in Node.js environment
|
|
5051
|
+
let fileTypeFromBuffer;
|
|
5052
|
+
// Only import in Node.js environment
|
|
5053
|
+
if (!isBrowser) {
|
|
5054
|
+
import('file-type').then(module => {
|
|
5055
|
+
fileTypeFromBuffer = module.fileTypeFromBuffer;
|
|
5056
|
+
}).catch(err => {
|
|
5057
|
+
console.debug('Could not load file-type module:', err);
|
|
5058
|
+
});
|
|
5059
|
+
}
|
|
5060
|
+
class BucketService extends FolderScopedService {
|
|
4571
5061
|
/**
|
|
4572
5062
|
* @hideconstructor
|
|
4573
5063
|
*/
|
|
4574
5064
|
constructor(config, executionContext, tokenManager) {
|
|
4575
5065
|
super(config, executionContext, tokenManager);
|
|
4576
|
-
|
|
4577
|
-
* Process parameters for task queries with folder filtering
|
|
4578
|
-
* @param options - The REST API options to process
|
|
4579
|
-
* @param folderId - Optional folder ID to filter by
|
|
4580
|
-
* @returns Processed options with folder filtering applied if needed
|
|
4581
|
-
* @private
|
|
4582
|
-
*/
|
|
4583
|
-
this.processTaskParameters = (options, folderId) => {
|
|
4584
|
-
const processedOptions = { ...options };
|
|
4585
|
-
if (folderId) {
|
|
4586
|
-
// Create or add to existing filter for folder-specific queries
|
|
4587
|
-
if (processedOptions.filter) {
|
|
4588
|
-
processedOptions.filter = `${processedOptions.filter} and organizationUnitId eq ${folderId}`;
|
|
4589
|
-
}
|
|
4590
|
-
else {
|
|
4591
|
-
processedOptions.filter = `organizationUnitId eq ${folderId}`;
|
|
4592
|
-
}
|
|
4593
|
-
}
|
|
4594
|
-
return processedOptions;
|
|
4595
|
-
};
|
|
5066
|
+
this.tokenManager = tokenManager;
|
|
4596
5067
|
}
|
|
4597
5068
|
/**
|
|
4598
|
-
*
|
|
4599
|
-
* @param
|
|
4600
|
-
* @param folderId -
|
|
4601
|
-
* @
|
|
5069
|
+
* Gets a bucket by ID
|
|
5070
|
+
* @param bucketId - The ID of the bucket to retrieve
|
|
5071
|
+
* @param folderId - Folder ID for organization unit context
|
|
5072
|
+
* @param options - Optional query parameters (expand, select)
|
|
5073
|
+
* @returns Promise resolving to the bucket
|
|
4602
5074
|
*
|
|
4603
5075
|
* @example
|
|
4604
5076
|
* ```typescript
|
|
4605
|
-
*
|
|
4606
|
-
*
|
|
4607
|
-
* priority: TaskPriority.Medium,
|
|
4608
|
-
* data: { key: "value" }
|
|
4609
|
-
* }, 123); // folderId is required
|
|
5077
|
+
* // Get bucket by ID
|
|
5078
|
+
* const bucket = await sdk.buckets.getById(123, 456);
|
|
4610
5079
|
* ```
|
|
4611
5080
|
*/
|
|
4612
|
-
async
|
|
5081
|
+
async getById(id, folderId, options = {}) {
|
|
5082
|
+
if (!id) {
|
|
5083
|
+
throw new ValidationError({ message: 'bucketId is required for getById' });
|
|
5084
|
+
}
|
|
5085
|
+
if (!folderId) {
|
|
5086
|
+
throw new ValidationError({ message: 'folderId is required for getById' });
|
|
5087
|
+
}
|
|
4613
5088
|
const headers = createHeaders({ [FOLDER_ID]: folderId });
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
return
|
|
5089
|
+
// Prefix all keys in options with $ for OData
|
|
5090
|
+
const keysToPrefix = Object.keys(options);
|
|
5091
|
+
const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
|
|
5092
|
+
const response = await this.get(BUCKET_ENDPOINTS.GET_BY_ID(id), {
|
|
5093
|
+
params: apiOptions,
|
|
5094
|
+
headers
|
|
5095
|
+
});
|
|
5096
|
+
// Transform response from PascalCase to camelCase
|
|
5097
|
+
return pascalToCamelCaseKeys(response.data);
|
|
4623
5098
|
}
|
|
4624
5099
|
/**
|
|
4625
|
-
* Gets
|
|
4626
|
-
*
|
|
4627
|
-
* The method returns either:
|
|
4628
|
-
* - An array of
|
|
4629
|
-
* - A paginated result with navigation cursors (when any pagination parameter is provided)
|
|
4630
|
-
*
|
|
4631
|
-
* @param
|
|
4632
|
-
* @
|
|
4633
|
-
*
|
|
4634
|
-
*
|
|
4635
|
-
*
|
|
4636
|
-
*
|
|
4637
|
-
*
|
|
4638
|
-
*
|
|
4639
|
-
*
|
|
4640
|
-
*
|
|
4641
|
-
*
|
|
4642
|
-
*
|
|
4643
|
-
*
|
|
4644
|
-
*
|
|
4645
|
-
*
|
|
4646
|
-
*
|
|
4647
|
-
*
|
|
4648
|
-
*
|
|
4649
|
-
*
|
|
4650
|
-
*
|
|
4651
|
-
*
|
|
4652
|
-
*
|
|
4653
|
-
*
|
|
4654
|
-
*
|
|
4655
|
-
*
|
|
4656
|
-
*
|
|
4657
|
-
*
|
|
4658
|
-
*
|
|
5100
|
+
* Gets all buckets across folders with optional filtering and folder scoping
|
|
5101
|
+
*
|
|
5102
|
+
* The method returns either:
|
|
5103
|
+
* - An array of buckets (when no pagination parameters are provided)
|
|
5104
|
+
* - A paginated result with navigation cursors (when any pagination parameter is provided)
|
|
5105
|
+
*
|
|
5106
|
+
* @param options - Query options including optional folderId
|
|
5107
|
+
* @returns Promise resolving to an array of buckets or paginated result
|
|
5108
|
+
*
|
|
5109
|
+
* @example
|
|
5110
|
+
* ```typescript
|
|
5111
|
+
* // Get all buckets across folders
|
|
5112
|
+
* const buckets = await sdk.buckets.getAll();
|
|
5113
|
+
*
|
|
5114
|
+
* // Get buckets within a specific folder
|
|
5115
|
+
* const buckets = await sdk.buckets.getAll({
|
|
5116
|
+
* folderId: 123
|
|
5117
|
+
* });
|
|
5118
|
+
*
|
|
5119
|
+
* // Get buckets with filtering
|
|
5120
|
+
* const buckets = await sdk.buckets.getAll({
|
|
5121
|
+
* filter: "name eq 'MyBucket'"
|
|
5122
|
+
* });
|
|
5123
|
+
*
|
|
5124
|
+
* // First page with pagination
|
|
5125
|
+
* const page1 = await sdk.buckets.getAll({ pageSize: 10 });
|
|
5126
|
+
*
|
|
5127
|
+
* // Navigate using cursor
|
|
5128
|
+
* if (page1.hasNextPage) {
|
|
5129
|
+
* const page2 = await sdk.buckets.getAll({ cursor: page1.nextCursor });
|
|
5130
|
+
* }
|
|
5131
|
+
*
|
|
5132
|
+
* // Jump to specific page
|
|
5133
|
+
* const page5 = await sdk.buckets.getAll({
|
|
5134
|
+
* jumpToPage: 5,
|
|
5135
|
+
* pageSize: 10
|
|
5136
|
+
* });
|
|
5137
|
+
* ```
|
|
5138
|
+
*/
|
|
5139
|
+
async getAll(options) {
|
|
5140
|
+
// Transformation function for buckets
|
|
5141
|
+
const transformBucketResponse = (bucket) => pascalToCamelCaseKeys(bucket);
|
|
5142
|
+
return PaginationHelpers.getAll({
|
|
5143
|
+
serviceAccess: this.createPaginationServiceAccess(),
|
|
5144
|
+
getEndpoint: (folderId) => folderId ? BUCKET_ENDPOINTS.GET_BY_FOLDER : BUCKET_ENDPOINTS.GET_ALL,
|
|
5145
|
+
getByFolderEndpoint: BUCKET_ENDPOINTS.GET_BY_FOLDER,
|
|
5146
|
+
transformFn: transformBucketResponse,
|
|
5147
|
+
pagination: {
|
|
5148
|
+
paginationType: PaginationType.OFFSET,
|
|
5149
|
+
itemsField: ODATA_PAGINATION.ITEMS_FIELD,
|
|
5150
|
+
totalCountField: ODATA_PAGINATION.TOTAL_COUNT_FIELD,
|
|
5151
|
+
paginationParams: {
|
|
5152
|
+
pageSizeParam: ODATA_OFFSET_PARAMS.PAGE_SIZE_PARAM,
|
|
5153
|
+
offsetParam: ODATA_OFFSET_PARAMS.OFFSET_PARAM,
|
|
5154
|
+
countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM
|
|
5155
|
+
}
|
|
5156
|
+
}
|
|
5157
|
+
}, options);
|
|
5158
|
+
}
|
|
5159
|
+
/**
|
|
5160
|
+
* Gets metadata for files in a bucket with optional filtering and pagination
|
|
5161
|
+
*
|
|
5162
|
+
* The method returns either:
|
|
5163
|
+
* - A NonPaginatedResponse with items array (when no pagination parameters are provided)
|
|
5164
|
+
* - A PaginatedResponse with navigation cursors (when any pagination parameter is provided)
|
|
5165
|
+
*
|
|
5166
|
+
* @param bucketId - The ID of the bucket to get file metadata from
|
|
5167
|
+
* @param folderId - Required folder ID for organization unit context
|
|
5168
|
+
* @param options - Optional parameters for filtering, pagination and access URL generation
|
|
5169
|
+
* @returns Promise resolving to the list of file metadata in the bucket or paginated result
|
|
5170
|
+
*
|
|
5171
|
+
* @example
|
|
5172
|
+
* ```typescript
|
|
5173
|
+
* // Get metadata for all files in a bucket
|
|
5174
|
+
* const fileMetadata = await sdk.buckets.getFileMetaData(123, 456);
|
|
5175
|
+
*
|
|
5176
|
+
* // Get file metadata with a specific prefix
|
|
5177
|
+
* const fileMetadata = await sdk.buckets.getFileMetaData(123, 456, {
|
|
5178
|
+
* prefix: '/folder1'
|
|
5179
|
+
* });
|
|
5180
|
+
*
|
|
5181
|
+
* // First page with pagination
|
|
5182
|
+
* const page1 = await sdk.buckets.getFileMetaData(123, 456, { pageSize: 10 });
|
|
5183
|
+
*
|
|
5184
|
+
* // Navigate using cursor
|
|
5185
|
+
* if (page1.hasNextPage) {
|
|
5186
|
+
* const page2 = await sdk.buckets.getFileMetaData(123, 456, { cursor: page1.nextCursor });
|
|
5187
|
+
* }
|
|
5188
|
+
* ```
|
|
5189
|
+
*/
|
|
5190
|
+
async getFileMetaData(bucketId, folderId, options) {
|
|
5191
|
+
if (!bucketId) {
|
|
5192
|
+
throw new ValidationError({ message: 'bucketId is required for getFileMetaData' });
|
|
5193
|
+
}
|
|
5194
|
+
if (!folderId) {
|
|
5195
|
+
throw new ValidationError({ message: 'folderId is required for getFileMetaData' });
|
|
5196
|
+
}
|
|
5197
|
+
// Transformation function for blob items
|
|
5198
|
+
const transformBlobItem = (item) => transformData(item, BucketMap);
|
|
5199
|
+
return PaginationHelpers.getAll({
|
|
5200
|
+
serviceAccess: this.createPaginationServiceAccess(),
|
|
5201
|
+
getEndpoint: () => BUCKET_ENDPOINTS.GET_FILE_META_DATA(bucketId),
|
|
5202
|
+
transformFn: transformBlobItem,
|
|
5203
|
+
pagination: {
|
|
5204
|
+
paginationType: PaginationType.TOKEN,
|
|
5205
|
+
itemsField: BUCKET_PAGINATION.ITEMS_FIELD,
|
|
5206
|
+
continuationTokenField: BUCKET_PAGINATION.CONTINUATION_TOKEN_FIELD,
|
|
5207
|
+
paginationParams: {
|
|
5208
|
+
pageSizeParam: BUCKET_TOKEN_PARAMS.PAGE_SIZE_PARAM,
|
|
5209
|
+
tokenParam: BUCKET_TOKEN_PARAMS.TOKEN_PARAM
|
|
5210
|
+
}
|
|
5211
|
+
},
|
|
5212
|
+
excludeFromPrefix: ['prefix'] // Bucket-specific param, not OData
|
|
5213
|
+
}, { ...options, folderId });
|
|
5214
|
+
}
|
|
5215
|
+
/**
|
|
5216
|
+
* Uploads a file to a bucket
|
|
5217
|
+
*
|
|
5218
|
+
* @param options - Options for file upload including bucket ID, folder ID, path, content, and optional parameters
|
|
5219
|
+
* @returns Promise resolving to a response with success status and HTTP status code
|
|
5220
|
+
*
|
|
5221
|
+
* @example
|
|
5222
|
+
* ```typescript
|
|
5223
|
+
* // Upload a file from browser
|
|
5224
|
+
* const file = new File(['file content'], 'example.txt');
|
|
5225
|
+
* const result = await sdk.buckets.uploadFile({
|
|
5226
|
+
* bucketId: 123,
|
|
5227
|
+
* folderId: 456,
|
|
5228
|
+
* path: '/folder/example.txt',
|
|
5229
|
+
* content: file
|
|
5230
|
+
* });
|
|
5231
|
+
*
|
|
5232
|
+
* // In Node env with explicit content type
|
|
5233
|
+
* const buffer = Buffer.from('file content');
|
|
5234
|
+
* const result = await sdk.buckets.uploadFile({
|
|
5235
|
+
* bucketId: 123,
|
|
5236
|
+
* folderId: 456,
|
|
5237
|
+
* path: '/folder/example.txt',
|
|
5238
|
+
* content: buffer,
|
|
5239
|
+
* contentType: 'text/plain'
|
|
5240
|
+
* });
|
|
5241
|
+
* ```
|
|
5242
|
+
*/
|
|
5243
|
+
async uploadFile(options) {
|
|
5244
|
+
const { bucketId, folderId, path, content, contentType } = options;
|
|
5245
|
+
if (!bucketId) {
|
|
5246
|
+
throw new ValidationError({ message: 'bucketId is required for uploadFile' });
|
|
5247
|
+
}
|
|
5248
|
+
if (!folderId) {
|
|
5249
|
+
throw new ValidationError({ message: 'folderId is required for uploadFile' });
|
|
5250
|
+
}
|
|
5251
|
+
if (!path) {
|
|
5252
|
+
throw new ValidationError({ message: 'path is required for uploadFile' });
|
|
5253
|
+
}
|
|
5254
|
+
if (!content) {
|
|
5255
|
+
throw new ValidationError({ message: 'content is required for uploadFile' });
|
|
5256
|
+
}
|
|
5257
|
+
try {
|
|
5258
|
+
// Get write URI for upload with detected content type if not provided
|
|
5259
|
+
let detectedContentType = contentType;
|
|
5260
|
+
if (!detectedContentType) {
|
|
5261
|
+
detectedContentType = await this._determineContentType(content, path);
|
|
5262
|
+
}
|
|
5263
|
+
const uriResponse = await this._getWriteUri({
|
|
5264
|
+
bucketId,
|
|
5265
|
+
folderId,
|
|
5266
|
+
path,
|
|
5267
|
+
contentType: detectedContentType
|
|
5268
|
+
});
|
|
5269
|
+
// Upload file to the provided URI
|
|
5270
|
+
const response = await this._uploadToUri(uriResponse, content, detectedContentType);
|
|
5271
|
+
return {
|
|
5272
|
+
success: response.status >= 200 && response.status < 300,
|
|
5273
|
+
statusCode: response.status
|
|
5274
|
+
};
|
|
5275
|
+
}
|
|
5276
|
+
catch (error) {
|
|
5277
|
+
throw error;
|
|
5278
|
+
}
|
|
5279
|
+
}
|
|
5280
|
+
/**
|
|
5281
|
+
* Determines the content type of the file based on the content and path
|
|
5282
|
+
* Uses a hybrid approach:
|
|
5283
|
+
* 1. Checks Blob/File type if available (browser)
|
|
5284
|
+
* 2. Uses content-based detection with file-type (primarily Node.js)
|
|
5285
|
+
* 3. Falls back to extension-based detection with mime-types
|
|
5286
|
+
* 4. Finally defaults to application/octet-stream
|
|
5287
|
+
*
|
|
5288
|
+
* @param content - The file content
|
|
5289
|
+
* @param path - The file path
|
|
5290
|
+
* @returns The determined content type or default
|
|
5291
|
+
*/
|
|
5292
|
+
async _determineContentType(content, path) {
|
|
5293
|
+
// 1. If content is a File or Blob with type, use that (works in browser)
|
|
5294
|
+
if ('type' in content && content.type) {
|
|
5295
|
+
return content.type;
|
|
5296
|
+
}
|
|
5297
|
+
// 2. Try content-based detection (primarily for Node.js)
|
|
5298
|
+
if (content instanceof Buffer && fileTypeFromBuffer) {
|
|
5299
|
+
try {
|
|
5300
|
+
const fileTypeResult = await fileTypeFromBuffer(content);
|
|
5301
|
+
if (fileTypeResult?.mime) {
|
|
5302
|
+
return fileTypeResult.mime;
|
|
5303
|
+
}
|
|
5304
|
+
}
|
|
5305
|
+
catch (error) {
|
|
5306
|
+
// Silently continue to next detection method if this fails
|
|
5307
|
+
console.debug('Content-based type detection failed:', error);
|
|
5308
|
+
}
|
|
5309
|
+
}
|
|
5310
|
+
// 3. Try to infer from file extension using mime-types library
|
|
5311
|
+
const mimeType = mimeTypes__namespace.lookup(path);
|
|
5312
|
+
if (mimeType) {
|
|
5313
|
+
return mimeType;
|
|
5314
|
+
}
|
|
5315
|
+
// 4. Final fallback
|
|
5316
|
+
return CONTENT_TYPES.OCTET_STREAM;
|
|
5317
|
+
}
|
|
5318
|
+
/**
|
|
5319
|
+
* Uploads content to the provided URI
|
|
5320
|
+
* @param uriResponse - Response from getWriteUri containing URL and headers
|
|
5321
|
+
* @param content - The content to upload
|
|
5322
|
+
* @param contentType - The content type of the file
|
|
5323
|
+
* @returns The response from the upload request with status info
|
|
5324
|
+
*/
|
|
5325
|
+
async _uploadToUri(uriResponse, content, contentType) {
|
|
5326
|
+
const { uri, headers = {}, requiresAuth } = uriResponse;
|
|
5327
|
+
if (!uri) {
|
|
5328
|
+
throw new ValidationError({ message: 'Upload URI not available', statusCode: HttpStatus.BAD_REQUEST });
|
|
5329
|
+
}
|
|
5330
|
+
// Create headers for the request
|
|
5331
|
+
let requestHeaders = { ...headers };
|
|
5332
|
+
// Ensure content-type is set if provided
|
|
5333
|
+
if (contentType && !requestHeaders['content-type']) {
|
|
5334
|
+
requestHeaders['content-type'] = contentType;
|
|
5335
|
+
}
|
|
5336
|
+
// Add auth header if required
|
|
5337
|
+
if (requiresAuth) {
|
|
5338
|
+
try {
|
|
5339
|
+
const tokenInfo = this.executionContext.get('tokenInfo');
|
|
5340
|
+
if (!tokenInfo) {
|
|
5341
|
+
throw new AuthenticationError({ message: 'No authentication token available. Make sure to initialize the SDK first.' });
|
|
5342
|
+
}
|
|
5343
|
+
let token;
|
|
5344
|
+
// For secret-based tokens, they never expire so use directly
|
|
5345
|
+
if (tokenInfo.type === 'secret') {
|
|
5346
|
+
token = tokenInfo.token;
|
|
5347
|
+
}
|
|
5348
|
+
// For non-secret tokens, check expiration and refresh if needed
|
|
5349
|
+
else if (!this.tokenManager.isTokenExpired(tokenInfo)) {
|
|
5350
|
+
token = tokenInfo.token;
|
|
5351
|
+
}
|
|
5352
|
+
else {
|
|
5353
|
+
const newToken = await this.tokenManager.refreshAccessToken();
|
|
5354
|
+
token = newToken.access_token;
|
|
5355
|
+
}
|
|
5356
|
+
requestHeaders['Authorization'] = `Bearer ${token}`;
|
|
5357
|
+
}
|
|
5358
|
+
catch (error) {
|
|
5359
|
+
throw new AuthenticationError({
|
|
5360
|
+
message: `Authentication required but failed: ${error instanceof Error ? error.message : ''}`,
|
|
5361
|
+
statusCode: HttpStatus.UNAUTHORIZED
|
|
5362
|
+
});
|
|
5363
|
+
}
|
|
5364
|
+
}
|
|
5365
|
+
return axios.put(uri, content, {
|
|
5366
|
+
headers: createHeaders(requestHeaders)
|
|
5367
|
+
});
|
|
5368
|
+
}
|
|
5369
|
+
/**
|
|
5370
|
+
* Private method to handle common URI request logic
|
|
5371
|
+
* @param endpoint - The API endpoint to call
|
|
5372
|
+
* @param bucketId - The bucket ID
|
|
5373
|
+
* @param folderId - The folder ID
|
|
5374
|
+
* @param path - The file path
|
|
5375
|
+
* @param queryOptions - Additional query parameters
|
|
5376
|
+
* @returns Promise resolving to blob file access information
|
|
5377
|
+
*/
|
|
5378
|
+
async _getUri(endpoint, bucketId, folderId, path, queryOptions = {}) {
|
|
5379
|
+
if (!bucketId) {
|
|
5380
|
+
throw new ValidationError({ message: 'bucketId is required for getUri' });
|
|
5381
|
+
}
|
|
5382
|
+
if (!folderId) {
|
|
5383
|
+
throw new ValidationError({ message: 'folderId is required for getUri' });
|
|
5384
|
+
}
|
|
5385
|
+
if (!path) {
|
|
5386
|
+
throw new ValidationError({ message: 'path is required for getUri' });
|
|
5387
|
+
}
|
|
5388
|
+
// Create headers with required folder ID
|
|
5389
|
+
const headers = createHeaders({ [FOLDER_ID]: folderId });
|
|
5390
|
+
// Filter out undefined values and build query params
|
|
5391
|
+
const queryParams = filterUndefined({
|
|
5392
|
+
path,
|
|
5393
|
+
...queryOptions
|
|
5394
|
+
});
|
|
5395
|
+
// Make the API call to get URI
|
|
5396
|
+
const response = await this.get(endpoint, {
|
|
5397
|
+
params: queryParams,
|
|
5398
|
+
headers
|
|
5399
|
+
});
|
|
5400
|
+
const transformedData = transformData(pascalToCamelCaseKeys(response.data), BucketMap);
|
|
5401
|
+
// Convert headers from array-based to record if needed
|
|
5402
|
+
if (transformedData.headers && 'keys' in transformedData.headers && 'values' in transformedData.headers) {
|
|
5403
|
+
transformedData.headers = arrayDictionaryToRecord(transformedData.headers);
|
|
5404
|
+
}
|
|
5405
|
+
return transformedData;
|
|
5406
|
+
}
|
|
5407
|
+
/**
|
|
5408
|
+
* Gets a direct download URL for a file in the bucket
|
|
5409
|
+
*
|
|
5410
|
+
* @param options - Contains bucketId, folderId, file path and optional expiry time
|
|
5411
|
+
* @returns Promise resolving to blob file access information
|
|
5412
|
+
*
|
|
5413
|
+
* @example
|
|
5414
|
+
* ```typescript
|
|
5415
|
+
* // Get download URL for a file
|
|
5416
|
+
* const fileAccess = await sdk.buckets.getReadUri({
|
|
5417
|
+
* bucketId: 123,
|
|
5418
|
+
* folderId: 456,
|
|
5419
|
+
* path: '/folder/file.pdf'
|
|
5420
|
+
* });
|
|
5421
|
+
* ```
|
|
5422
|
+
*/
|
|
5423
|
+
async getReadUri(options) {
|
|
5424
|
+
const { bucketId, folderId, path, expiryInMinutes, ...restOptions } = options;
|
|
5425
|
+
const queryOptions = {
|
|
5426
|
+
expiryInMinutes,
|
|
5427
|
+
...addPrefixToKeys(restOptions, ODATA_PREFIX, Object.keys(restOptions))
|
|
5428
|
+
};
|
|
5429
|
+
return this._getUri(BUCKET_ENDPOINTS.GET_READ_URI(bucketId), bucketId, folderId, path, queryOptions);
|
|
5430
|
+
}
|
|
5431
|
+
/**
|
|
5432
|
+
* Gets a direct upload URL for a file in the bucket
|
|
5433
|
+
*
|
|
5434
|
+
* @param options - Contains bucketId, folderId, file path, optional expiry time and content type
|
|
5435
|
+
* @returns Promise resolving to blob file access information
|
|
5436
|
+
*/
|
|
5437
|
+
async _getWriteUri(options) {
|
|
5438
|
+
const { bucketId, folderId, path, expiryInMinutes, contentType, ...restOptions } = options;
|
|
5439
|
+
const queryOptions = {
|
|
5440
|
+
expiryInMinutes,
|
|
5441
|
+
contentType,
|
|
5442
|
+
...addPrefixToKeys(restOptions, ODATA_PREFIX, Object.keys(restOptions))
|
|
5443
|
+
};
|
|
5444
|
+
return this._getUri(BUCKET_ENDPOINTS.GET_WRITE_URI(bucketId), bucketId, folderId, path, queryOptions);
|
|
5445
|
+
}
|
|
5446
|
+
}
|
|
5447
|
+
__decorate([
|
|
5448
|
+
track('Buckets.GetById')
|
|
5449
|
+
], BucketService.prototype, "getById", null);
|
|
5450
|
+
__decorate([
|
|
5451
|
+
track('Buckets.GetAll')
|
|
5452
|
+
], BucketService.prototype, "getAll", null);
|
|
5453
|
+
__decorate([
|
|
5454
|
+
track('Buckets.GetFileMetaData')
|
|
5455
|
+
], BucketService.prototype, "getFileMetaData", null);
|
|
5456
|
+
__decorate([
|
|
5457
|
+
track('Buckets.UploadFile')
|
|
5458
|
+
], BucketService.prototype, "uploadFile", null);
|
|
5459
|
+
__decorate([
|
|
5460
|
+
track('Buckets.GetReadUri')
|
|
5461
|
+
], BucketService.prototype, "getReadUri", null);
|
|
5462
|
+
|
|
5463
|
+
/**
|
|
5464
|
+
* Maps fields for Process entities to ensure consistent naming
|
|
5465
|
+
*/
|
|
5466
|
+
const ProcessMap = {
|
|
5467
|
+
lastModificationTime: 'lastModifiedTime',
|
|
5468
|
+
creationTime: 'createdTime',
|
|
5469
|
+
organizationUnitId: 'folderId',
|
|
5470
|
+
organizationUnitFullyQualifiedName: 'folderName',
|
|
5471
|
+
releaseKey: 'processKey',
|
|
5472
|
+
releaseName: 'processName',
|
|
5473
|
+
releaseVersionId: 'processVersionId',
|
|
5474
|
+
processType: 'packageType',
|
|
5475
|
+
processKey: 'packageKey',
|
|
5476
|
+
processVersion: 'packageVersion',
|
|
5477
|
+
isProcessDeleted: 'isPackageDeleted',
|
|
5478
|
+
};
|
|
5479
|
+
|
|
5480
|
+
/**
|
|
5481
|
+
* Service for interacting with UiPath Orchestrator Processes API
|
|
5482
|
+
*/
|
|
5483
|
+
class ProcessService extends BaseService {
|
|
5484
|
+
/**
|
|
5485
|
+
* @hideconstructor
|
|
4659
5486
|
*/
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
const transformUserResponse = (user) => pascalToCamelCaseKeys(user);
|
|
4663
|
-
// Add folderId to options so the centralized helper can handle it properly
|
|
4664
|
-
const optionsWithFolder = { ...options, folderId };
|
|
4665
|
-
return PaginationHelpers.getAll({
|
|
4666
|
-
serviceAccess: this.createPaginationServiceAccess(),
|
|
4667
|
-
getEndpoint: (folderId) => TASK_ENDPOINTS.GET_TASK_USERS(folderId), // Use folderId from centralized helper
|
|
4668
|
-
getByFolderEndpoint: TASK_ENDPOINTS.GET_TASK_USERS(folderId), // Use the passed folderId
|
|
4669
|
-
transformFn: transformUserResponse,
|
|
4670
|
-
pagination: {
|
|
4671
|
-
paginationType: PaginationType.OFFSET,
|
|
4672
|
-
itemsField: ODATA_PAGINATION.ITEMS_FIELD,
|
|
4673
|
-
totalCountField: ODATA_PAGINATION.TOTAL_COUNT_FIELD,
|
|
4674
|
-
paginationParams: {
|
|
4675
|
-
pageSizeParam: ODATA_OFFSET_PARAMS.PAGE_SIZE_PARAM,
|
|
4676
|
-
offsetParam: ODATA_OFFSET_PARAMS.OFFSET_PARAM,
|
|
4677
|
-
countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM
|
|
4678
|
-
}
|
|
4679
|
-
}
|
|
4680
|
-
}, optionsWithFolder);
|
|
5487
|
+
constructor(config, executionContext, tokenManager) {
|
|
5488
|
+
super(config, executionContext, tokenManager);
|
|
4681
5489
|
}
|
|
4682
5490
|
/**
|
|
4683
|
-
* Gets
|
|
5491
|
+
* Gets all processes across folders with optional filtering and folder scoping
|
|
4684
5492
|
*
|
|
4685
5493
|
* The method returns either:
|
|
4686
|
-
* - An array of
|
|
5494
|
+
* - An array of processes (when no pagination parameters are provided)
|
|
4687
5495
|
* - A paginated result with navigation cursors (when any pagination parameter is provided)
|
|
4688
5496
|
*
|
|
4689
|
-
* @param options - Query options including optional folderId
|
|
4690
|
-
* @returns Promise resolving to an array of
|
|
5497
|
+
* @param options - Query options including optional folderId
|
|
5498
|
+
* @returns Promise resolving to an array of processes or paginated result
|
|
4691
5499
|
*
|
|
4692
5500
|
* @example
|
|
4693
5501
|
* ```typescript
|
|
4694
5502
|
* // Standard array return
|
|
4695
|
-
* const
|
|
5503
|
+
* const processes = await sdk.processes.getAll();
|
|
4696
5504
|
*
|
|
4697
|
-
* // Get
|
|
4698
|
-
* const
|
|
5505
|
+
* // Get processes within a specific folder
|
|
5506
|
+
* const processes = await sdk.processes.getAll({
|
|
4699
5507
|
* folderId: 123
|
|
4700
5508
|
* });
|
|
4701
5509
|
*
|
|
5510
|
+
* // Get processes with filtering
|
|
5511
|
+
* const processes = await sdk.processes.getAll({
|
|
5512
|
+
* filter: "name eq 'MyProcess'"
|
|
5513
|
+
* });
|
|
5514
|
+
*
|
|
4702
5515
|
* // First page with pagination
|
|
4703
|
-
* const page1 = await sdk.
|
|
5516
|
+
* const page1 = await sdk.processes.getAll({ pageSize: 10 });
|
|
4704
5517
|
*
|
|
4705
5518
|
* // Navigate using cursor
|
|
4706
5519
|
* if (page1.hasNextPage) {
|
|
4707
|
-
* const page2 = await sdk.
|
|
5520
|
+
* const page2 = await sdk.processes.getAll({ cursor: page1.nextCursor });
|
|
4708
5521
|
* }
|
|
4709
5522
|
*
|
|
4710
5523
|
* // Jump to specific page
|
|
4711
|
-
* const page5 = await sdk.
|
|
5524
|
+
* const page5 = await sdk.processes.getAll({
|
|
4712
5525
|
* jumpToPage: 5,
|
|
4713
5526
|
* pageSize: 10
|
|
4714
5527
|
* });
|
|
4715
5528
|
* ```
|
|
4716
5529
|
*/
|
|
4717
5530
|
async getAll(options) {
|
|
4718
|
-
// Transformation function for
|
|
4719
|
-
const
|
|
4720
|
-
const transformedTask = transformData(pascalToCamelCaseKeys(task), TaskTimeMap);
|
|
4721
|
-
return createTaskWithMethods(applyDataTransforms(transformedTask, { field: 'status', valueMap: TaskStatusMap }), this);
|
|
4722
|
-
};
|
|
5531
|
+
// Transformation function for processes
|
|
5532
|
+
const transformProcessResponse = (process) => transformData(pascalToCamelCaseKeys(process), ProcessMap);
|
|
4723
5533
|
return PaginationHelpers.getAll({
|
|
4724
5534
|
serviceAccess: this.createPaginationServiceAccess(),
|
|
4725
|
-
getEndpoint: () =>
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
excludeFromPrefix: ['event'], // Exclude 'event' key from ODATA prefix transformation
|
|
5535
|
+
getEndpoint: () => PROCESS_ENDPOINTS.GET_ALL,
|
|
5536
|
+
getByFolderEndpoint: PROCESS_ENDPOINTS.GET_ALL, // Processes use same endpoint for both
|
|
5537
|
+
transformFn: transformProcessResponse,
|
|
4729
5538
|
pagination: {
|
|
4730
5539
|
paginationType: PaginationType.OFFSET,
|
|
4731
5540
|
itemsField: ODATA_PAGINATION.ITEMS_FIELD,
|
|
4732
5541
|
totalCountField: ODATA_PAGINATION.TOTAL_COUNT_FIELD,
|
|
4733
5542
|
paginationParams: {
|
|
4734
|
-
pageSizeParam: ODATA_OFFSET_PARAMS.PAGE_SIZE_PARAM,
|
|
4735
|
-
offsetParam: ODATA_OFFSET_PARAMS.OFFSET_PARAM,
|
|
4736
|
-
countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM
|
|
5543
|
+
pageSizeParam: ODATA_OFFSET_PARAMS.PAGE_SIZE_PARAM,
|
|
5544
|
+
offsetParam: ODATA_OFFSET_PARAMS.OFFSET_PARAM,
|
|
5545
|
+
countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM
|
|
4737
5546
|
}
|
|
4738
5547
|
}
|
|
4739
5548
|
}, options);
|
|
4740
5549
|
}
|
|
4741
5550
|
/**
|
|
4742
|
-
*
|
|
5551
|
+
* Starts a process execution (job)
|
|
4743
5552
|
*
|
|
4744
|
-
* @param
|
|
5553
|
+
* @param request - Process start request body
|
|
5554
|
+
* @param folderId - Required folder ID
|
|
4745
5555
|
* @param options - Optional query parameters
|
|
4746
|
-
* @
|
|
4747
|
-
* @returns Promise resolving to the task (form tasks will return form-specific data)
|
|
5556
|
+
* @returns Promise resolving to the created jobs
|
|
4748
5557
|
*
|
|
4749
5558
|
* @example
|
|
4750
5559
|
* ```typescript
|
|
4751
|
-
* //
|
|
4752
|
-
* const
|
|
5560
|
+
* // Start a process by process key
|
|
5561
|
+
* const jobs = await sdk.processes.start({
|
|
5562
|
+
* processKey: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
5563
|
+
* }, 123); // folderId is required
|
|
4753
5564
|
*
|
|
4754
|
-
* //
|
|
5565
|
+
* // Start a process by name with specific robots
|
|
5566
|
+
* const jobs = await sdk.processes.start({
|
|
5567
|
+
* processName: "MyProcess"
|
|
5568
|
+
* }, 123); // folderId is required
|
|
4755
5569
|
* ```
|
|
4756
5570
|
*/
|
|
4757
|
-
async
|
|
5571
|
+
async start(request, folderId, options = {}) {
|
|
4758
5572
|
const headers = createHeaders({ [FOLDER_ID]: folderId });
|
|
4759
|
-
//
|
|
4760
|
-
const
|
|
4761
|
-
|
|
4762
|
-
const
|
|
4763
|
-
|
|
4764
|
-
|
|
5573
|
+
// Transform processKey/processName to releaseKey/releaseName for API compatibility
|
|
5574
|
+
const apiRequest = { ...request };
|
|
5575
|
+
// Create a reverse mapping using ProcessMap
|
|
5576
|
+
const reversedPropertiesMap = reverseMap(ProcessMap);
|
|
5577
|
+
// Apply transformations for any client properties found in the request
|
|
5578
|
+
Object.entries(reversedPropertiesMap).forEach(([clientKey, apiKey]) => {
|
|
5579
|
+
if (clientKey in apiRequest) {
|
|
5580
|
+
apiRequest[apiKey] = apiRequest[clientKey];
|
|
5581
|
+
delete apiRequest[clientKey];
|
|
5582
|
+
}
|
|
4765
5583
|
});
|
|
4766
|
-
//
|
|
4767
|
-
const
|
|
4768
|
-
//
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
return this.getFormTaskById(id, folderId || transformedTask.organizationUnitId, formOptions);
|
|
4772
|
-
}
|
|
4773
|
-
return createTaskWithMethods(applyDataTransforms(transformedTask, { field: 'status', valueMap: TaskStatusMap }), this);
|
|
4774
|
-
}
|
|
4775
|
-
/**
|
|
4776
|
-
* Assigns tasks to users
|
|
4777
|
-
*
|
|
4778
|
-
* @param taskAssignments - Single task assignment or array of task assignments
|
|
4779
|
-
* @param folderId - Optional folder ID
|
|
4780
|
-
* @returns Promise resolving to array of task assignment results
|
|
4781
|
-
*
|
|
4782
|
-
* @example
|
|
4783
|
-
* ```typescript
|
|
4784
|
-
* // Assign a single task to a user by ID
|
|
4785
|
-
* const result = await sdk.tasks.assign({
|
|
4786
|
-
* taskId: 123,
|
|
4787
|
-
* userId: 456
|
|
4788
|
-
* });
|
|
4789
|
-
*
|
|
4790
|
-
* // Assign a single task to a user by email
|
|
4791
|
-
* const result = await sdk.tasks.assign({
|
|
4792
|
-
* taskId: 123,
|
|
4793
|
-
* userNameOrEmail: "user@example.com"
|
|
4794
|
-
* });
|
|
4795
|
-
*
|
|
4796
|
-
* // Assign multiple tasks
|
|
4797
|
-
* const result = await sdk.tasks.assign([
|
|
4798
|
-
* {
|
|
4799
|
-
* taskId: 123,
|
|
4800
|
-
* userId: 456
|
|
4801
|
-
* },
|
|
4802
|
-
* {
|
|
4803
|
-
* taskId: 789,
|
|
4804
|
-
* userNameOrEmail: "user@example.com"
|
|
4805
|
-
* }
|
|
4806
|
-
* ]);
|
|
4807
|
-
* ```
|
|
4808
|
-
*/
|
|
4809
|
-
async assign(taskAssignments, folderId) {
|
|
4810
|
-
const headers = createHeaders({ [FOLDER_ID]: folderId });
|
|
4811
|
-
// Normalize input to array
|
|
4812
|
-
const assignmentArray = Array.isArray(taskAssignments) ? taskAssignments : [taskAssignments];
|
|
4813
|
-
const options = {
|
|
4814
|
-
taskAssignments: assignmentArray
|
|
4815
|
-
};
|
|
4816
|
-
// Convert options to PascalCase for API
|
|
4817
|
-
const pascalOptions = camelToPascalCaseKeys(options);
|
|
4818
|
-
const response = await this.post(TASK_ENDPOINTS.ASSIGN_TASKS, pascalOptions, { headers });
|
|
4819
|
-
// Transform response from PascalCase to camelCase
|
|
4820
|
-
const transformedResponse = pascalToCamelCaseKeys(response.data);
|
|
4821
|
-
// Process OData array response - empty array = success, non-empty = error
|
|
4822
|
-
return processODataArrayResponse(transformedResponse, assignmentArray);
|
|
4823
|
-
}
|
|
4824
|
-
/**
|
|
4825
|
-
* Reassigns tasks to new users
|
|
4826
|
-
*
|
|
4827
|
-
* @param taskAssignments - Single task assignment or array of task assignments
|
|
4828
|
-
* @param folderId - Optional folder ID
|
|
4829
|
-
* @returns Promise resolving to array of task assignment results
|
|
4830
|
-
*
|
|
4831
|
-
* @example
|
|
4832
|
-
* ```typescript
|
|
4833
|
-
* // Reassign a single task to a user by ID
|
|
4834
|
-
* const result = await sdk.tasks.reassign({
|
|
4835
|
-
* taskId: 123,
|
|
4836
|
-
* userId: 456
|
|
4837
|
-
* });
|
|
4838
|
-
*
|
|
4839
|
-
* // Reassign a single task to a user by email
|
|
4840
|
-
* const result = await sdk.tasks.reassign({
|
|
4841
|
-
* taskId: 123,
|
|
4842
|
-
* userNameOrEmail: "user@example.com"
|
|
4843
|
-
* });
|
|
4844
|
-
*
|
|
4845
|
-
* // Reassign multiple tasks
|
|
4846
|
-
* const result = await sdk.tasks.reassign([
|
|
4847
|
-
* {
|
|
4848
|
-
* taskId: 123,
|
|
4849
|
-
* userId: 456
|
|
4850
|
-
* },
|
|
4851
|
-
* {
|
|
4852
|
-
* taskId: 789,
|
|
4853
|
-
* userNameOrEmail: "user@example.com"
|
|
4854
|
-
* }
|
|
4855
|
-
* ]);
|
|
4856
|
-
* ```
|
|
4857
|
-
*/
|
|
4858
|
-
async reassign(taskAssignments, folderId) {
|
|
4859
|
-
const headers = createHeaders({ [FOLDER_ID]: folderId });
|
|
4860
|
-
// Normalize input to array
|
|
4861
|
-
const assignmentArray = Array.isArray(taskAssignments) ? taskAssignments : [taskAssignments];
|
|
4862
|
-
const options = {
|
|
4863
|
-
taskAssignments: assignmentArray
|
|
5584
|
+
// Convert to PascalCase for API
|
|
5585
|
+
const pascalOptions = camelToPascalCaseKeys(apiRequest);
|
|
5586
|
+
// Create the request object according to API spec
|
|
5587
|
+
const requestBody = {
|
|
5588
|
+
startInfo: pascalOptions
|
|
4864
5589
|
};
|
|
4865
|
-
//
|
|
4866
|
-
const
|
|
4867
|
-
const
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
5590
|
+
// Prefix all query parameter keys with '$' for OData
|
|
5591
|
+
const keysToPrefix = Object.keys(options);
|
|
5592
|
+
const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
|
|
5593
|
+
const response = await this.post(PROCESS_ENDPOINTS.START_PROCESS, requestBody, {
|
|
5594
|
+
params: apiOptions,
|
|
5595
|
+
headers
|
|
5596
|
+
});
|
|
5597
|
+
const transformedProcess = response.data?.value.map(process => transformData(pascalToCamelCaseKeys(process), ProcessMap));
|
|
5598
|
+
return transformedProcess;
|
|
4872
5599
|
}
|
|
4873
5600
|
/**
|
|
4874
|
-
*
|
|
5601
|
+
* Gets a single process by ID
|
|
4875
5602
|
*
|
|
4876
|
-
* @param
|
|
4877
|
-
* @param folderId -
|
|
4878
|
-
* @
|
|
5603
|
+
* @param id - Process ID
|
|
5604
|
+
* @param folderId - Required folder ID
|
|
5605
|
+
* @param options - Optional query parameters
|
|
5606
|
+
* @returns Promise resolving to a single process
|
|
4879
5607
|
*
|
|
4880
5608
|
* @example
|
|
4881
5609
|
* ```typescript
|
|
4882
|
-
* //
|
|
4883
|
-
* const
|
|
4884
|
-
*
|
|
4885
|
-
* // Unassign multiple tasks
|
|
4886
|
-
* const result = await sdk.tasks.unassign([123, 456, 789]);
|
|
5610
|
+
* // Get process by ID
|
|
5611
|
+
* const process = await sdk.processes.getById(123, 456);
|
|
4887
5612
|
* ```
|
|
4888
5613
|
*/
|
|
4889
|
-
async
|
|
5614
|
+
async getById(id, folderId, options = {}) {
|
|
4890
5615
|
const headers = createHeaders({ [FOLDER_ID]: folderId });
|
|
4891
|
-
|
|
4892
|
-
const
|
|
4893
|
-
const
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
5616
|
+
const keysToPrefix = Object.keys(options);
|
|
5617
|
+
const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
|
|
5618
|
+
const response = await this.get(PROCESS_ENDPOINTS.GET_BY_ID(id), {
|
|
5619
|
+
headers,
|
|
5620
|
+
params: apiOptions
|
|
5621
|
+
});
|
|
5622
|
+
const transformedProcess = transformData(pascalToCamelCaseKeys(response.data), ProcessMap);
|
|
5623
|
+
return transformedProcess;
|
|
5624
|
+
}
|
|
5625
|
+
}
|
|
5626
|
+
__decorate([
|
|
5627
|
+
track('Processes.GetAll')
|
|
5628
|
+
], ProcessService.prototype, "getAll", null);
|
|
5629
|
+
__decorate([
|
|
5630
|
+
track('Processes.Start')
|
|
5631
|
+
], ProcessService.prototype, "start", null);
|
|
5632
|
+
__decorate([
|
|
5633
|
+
track('Processes.GetById')
|
|
5634
|
+
], ProcessService.prototype, "getById", null);
|
|
5635
|
+
|
|
5636
|
+
/**
|
|
5637
|
+
* Maps fields for Queue entities to ensure consistent naming
|
|
5638
|
+
*/
|
|
5639
|
+
const QueueMap = {
|
|
5640
|
+
creationTime: 'createdTime',
|
|
5641
|
+
organizationUnitId: 'folderId',
|
|
5642
|
+
organizationUnitFullyQualifiedName: 'folderName'
|
|
5643
|
+
};
|
|
5644
|
+
|
|
5645
|
+
/**
|
|
5646
|
+
* Service for interacting with UiPath Orchestrator Queues API
|
|
5647
|
+
*/
|
|
5648
|
+
class QueueService extends FolderScopedService {
|
|
5649
|
+
/**
|
|
5650
|
+
* @hideconstructor
|
|
5651
|
+
*/
|
|
5652
|
+
constructor(config, executionContext, tokenManager) {
|
|
5653
|
+
super(config, executionContext, tokenManager);
|
|
4902
5654
|
}
|
|
4903
5655
|
/**
|
|
4904
|
-
*
|
|
5656
|
+
* Gets all queues across folders with optional filtering and folder scoping
|
|
4905
5657
|
*
|
|
4906
|
-
*
|
|
4907
|
-
*
|
|
4908
|
-
*
|
|
4909
|
-
*
|
|
5658
|
+
* The method returns either:
|
|
5659
|
+
* - An array of queues (when no pagination parameters are provided)
|
|
5660
|
+
* - A paginated result with navigation cursors (when any pagination parameter is provided)
|
|
5661
|
+
*
|
|
5662
|
+
* @param options - Query options including optional folderId
|
|
5663
|
+
* @returns Promise resolving to an array of queues or paginated result
|
|
4910
5664
|
*
|
|
4911
5665
|
* @example
|
|
4912
5666
|
* ```typescript
|
|
4913
|
-
* //
|
|
4914
|
-
* await sdk.
|
|
4915
|
-
* taskId: 456,
|
|
4916
|
-
* data: {},
|
|
4917
|
-
* action: "submit"
|
|
4918
|
-
* }, 123); // folderId is required
|
|
5667
|
+
* // Standard array return
|
|
5668
|
+
* const queues = await sdk.queues.getAll();
|
|
4919
5669
|
*
|
|
4920
|
-
* //
|
|
4921
|
-
* await sdk.
|
|
4922
|
-
*
|
|
4923
|
-
* }
|
|
5670
|
+
* // Get queues within a specific folder
|
|
5671
|
+
* const queues = await sdk.queues.getAll({
|
|
5672
|
+
* folderId: 123
|
|
5673
|
+
* });
|
|
5674
|
+
*
|
|
5675
|
+
* // Get queues with filtering
|
|
5676
|
+
* const queues = await sdk.queues.getAll({
|
|
5677
|
+
* filter: "name eq 'MyQueue'"
|
|
5678
|
+
* });
|
|
5679
|
+
*
|
|
5680
|
+
* // First page with pagination
|
|
5681
|
+
* const page1 = await sdk.queues.getAll({ pageSize: 10 });
|
|
5682
|
+
*
|
|
5683
|
+
* // Navigate using cursor
|
|
5684
|
+
* if (page1.hasNextPage) {
|
|
5685
|
+
* const page2 = await sdk.queues.getAll({ cursor: page1.nextCursor });
|
|
5686
|
+
* }
|
|
5687
|
+
*
|
|
5688
|
+
* // Jump to specific page
|
|
5689
|
+
* const page5 = await sdk.queues.getAll({
|
|
5690
|
+
* jumpToPage: 5,
|
|
5691
|
+
* pageSize: 10
|
|
5692
|
+
* });
|
|
4924
5693
|
* ```
|
|
4925
5694
|
*/
|
|
4926
|
-
async
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
4936
|
-
|
|
4937
|
-
|
|
4938
|
-
|
|
4939
|
-
|
|
4940
|
-
|
|
4941
|
-
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
data: options
|
|
4946
|
-
};
|
|
5695
|
+
async getAll(options) {
|
|
5696
|
+
// Transformation function for queues
|
|
5697
|
+
const transformQueueResponse = (queue) => transformData(pascalToCamelCaseKeys(queue), QueueMap);
|
|
5698
|
+
return PaginationHelpers.getAll({
|
|
5699
|
+
serviceAccess: this.createPaginationServiceAccess(),
|
|
5700
|
+
getEndpoint: (folderId) => folderId ? QUEUE_ENDPOINTS.GET_BY_FOLDER : QUEUE_ENDPOINTS.GET_ALL,
|
|
5701
|
+
getByFolderEndpoint: QUEUE_ENDPOINTS.GET_BY_FOLDER,
|
|
5702
|
+
transformFn: transformQueueResponse,
|
|
5703
|
+
pagination: {
|
|
5704
|
+
paginationType: PaginationType.OFFSET,
|
|
5705
|
+
itemsField: ODATA_PAGINATION.ITEMS_FIELD,
|
|
5706
|
+
totalCountField: ODATA_PAGINATION.TOTAL_COUNT_FIELD,
|
|
5707
|
+
paginationParams: {
|
|
5708
|
+
pageSizeParam: ODATA_OFFSET_PARAMS.PAGE_SIZE_PARAM,
|
|
5709
|
+
offsetParam: ODATA_OFFSET_PARAMS.OFFSET_PARAM,
|
|
5710
|
+
countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM
|
|
5711
|
+
}
|
|
5712
|
+
}
|
|
5713
|
+
}, options);
|
|
4947
5714
|
}
|
|
4948
5715
|
/**
|
|
4949
|
-
* Gets a
|
|
5716
|
+
* Gets a single queue by ID
|
|
4950
5717
|
*
|
|
4951
|
-
* @param id -
|
|
5718
|
+
* @param id - Queue ID
|
|
4952
5719
|
* @param folderId - Required folder ID
|
|
4953
|
-
* @
|
|
4954
|
-
*
|
|
5720
|
+
* @returns Promise resolving to a queue definition
|
|
5721
|
+
*
|
|
5722
|
+
* @example
|
|
5723
|
+
* ```typescript
|
|
5724
|
+
* // Get queue by ID
|
|
5725
|
+
* const queue = await sdk.queues.getById(123, 456);
|
|
5726
|
+
* ```
|
|
4955
5727
|
*/
|
|
4956
|
-
async
|
|
5728
|
+
async getById(id, folderId, options = {}) {
|
|
4957
5729
|
const headers = createHeaders({ [FOLDER_ID]: folderId });
|
|
4958
|
-
const
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
headers
|
|
5730
|
+
const keysToPrefix = Object.keys(options);
|
|
5731
|
+
const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
|
|
5732
|
+
const response = await this.get(QUEUE_ENDPOINTS.GET_BY_ID(id), {
|
|
5733
|
+
headers,
|
|
5734
|
+
params: apiOptions
|
|
4964
5735
|
});
|
|
4965
|
-
|
|
4966
|
-
return createTaskWithMethods(applyDataTransforms(transformedFormTask, { field: 'status', valueMap: TaskStatusMap }), this);
|
|
5736
|
+
return transformData(pascalToCamelCaseKeys(response.data), QueueMap);
|
|
4967
5737
|
}
|
|
4968
5738
|
}
|
|
4969
5739
|
__decorate([
|
|
4970
|
-
track('
|
|
4971
|
-
],
|
|
4972
|
-
__decorate([
|
|
4973
|
-
track('Tasks.GetUsers')
|
|
4974
|
-
], TaskService.prototype, "getUsers", null);
|
|
4975
|
-
__decorate([
|
|
4976
|
-
track('Tasks.GetAll')
|
|
4977
|
-
], TaskService.prototype, "getAll", null);
|
|
4978
|
-
__decorate([
|
|
4979
|
-
track('Tasks.GetById')
|
|
4980
|
-
], TaskService.prototype, "getById", null);
|
|
4981
|
-
__decorate([
|
|
4982
|
-
track('Tasks.Assign')
|
|
4983
|
-
], TaskService.prototype, "assign", null);
|
|
4984
|
-
__decorate([
|
|
4985
|
-
track('Tasks.Reassign')
|
|
4986
|
-
], TaskService.prototype, "reassign", null);
|
|
4987
|
-
__decorate([
|
|
4988
|
-
track('Tasks.Unassign')
|
|
4989
|
-
], TaskService.prototype, "unassign", null);
|
|
5740
|
+
track('Queues.GetAll')
|
|
5741
|
+
], QueueService.prototype, "getAll", null);
|
|
4990
5742
|
__decorate([
|
|
4991
|
-
track('
|
|
4992
|
-
],
|
|
5743
|
+
track('Queues.GetById')
|
|
5744
|
+
], QueueService.prototype, "getById", null);
|
|
4993
5745
|
|
|
4994
5746
|
function validateConfig(config) {
|
|
4995
5747
|
if (!config.baseUrl || !config.orgName || !config.tenantName) {
|
|
@@ -5039,25 +5791,31 @@ class UiPath {
|
|
|
5039
5791
|
}
|
|
5040
5792
|
/**
|
|
5041
5793
|
* Initialize the SDK based on the provided configuration.
|
|
5042
|
-
* This method
|
|
5794
|
+
* This method handles both OAuth flow initiation and completion automatically.
|
|
5043
5795
|
* For secret-based authentication, initialization is automatic.
|
|
5044
5796
|
*/
|
|
5045
5797
|
async initialize() {
|
|
5046
|
-
//
|
|
5047
|
-
if (
|
|
5798
|
+
// For secret-based auth, it's already initialized in constructor
|
|
5799
|
+
if (hasSecretConfig(this.config)) {
|
|
5048
5800
|
return;
|
|
5049
5801
|
}
|
|
5050
5802
|
try {
|
|
5051
|
-
//
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5803
|
+
// Check for OAuth callback first
|
|
5804
|
+
if (AuthService.isInOAuthCallback()) {
|
|
5805
|
+
if (await this.completeOAuth()) {
|
|
5806
|
+
return;
|
|
5807
|
+
}
|
|
5808
|
+
}
|
|
5809
|
+
// Check if already authenticated
|
|
5810
|
+
if (this.isAuthenticated()) {
|
|
5811
|
+
this.initialized = true;
|
|
5812
|
+
return;
|
|
5813
|
+
}
|
|
5814
|
+
// Start new OAuth flow
|
|
5815
|
+
await this.authService.authenticate(this.config);
|
|
5816
|
+
if (this.isAuthenticated()) {
|
|
5817
|
+
this.initialized = true;
|
|
5059
5818
|
}
|
|
5060
|
-
this.initialized = true;
|
|
5061
5819
|
}
|
|
5062
5820
|
catch (error) {
|
|
5063
5821
|
const errorMessage = error instanceof Error ? error.message : 'An unknown error occurred';
|
|
@@ -5070,6 +5828,38 @@ class UiPath {
|
|
|
5070
5828
|
isInitialized() {
|
|
5071
5829
|
return this.initialized;
|
|
5072
5830
|
}
|
|
5831
|
+
/**
|
|
5832
|
+
* Check if we're in an OAuth callback state
|
|
5833
|
+
*/
|
|
5834
|
+
isInOAuthCallback() {
|
|
5835
|
+
return AuthService.isInOAuthCallback();
|
|
5836
|
+
}
|
|
5837
|
+
/**
|
|
5838
|
+
* Complete OAuth authentication flow (only call if isInOAuthCallback() is true)
|
|
5839
|
+
*/
|
|
5840
|
+
async completeOAuth() {
|
|
5841
|
+
if (!AuthService.isInOAuthCallback()) {
|
|
5842
|
+
throw new Error('Not in OAuth callback state. Call initialize() first to start OAuth flow.');
|
|
5843
|
+
}
|
|
5844
|
+
try {
|
|
5845
|
+
const success = await this.authService.authenticate(this.config);
|
|
5846
|
+
if (success && this.isAuthenticated()) {
|
|
5847
|
+
this.initialized = true;
|
|
5848
|
+
return true;
|
|
5849
|
+
}
|
|
5850
|
+
return false;
|
|
5851
|
+
}
|
|
5852
|
+
catch (error) {
|
|
5853
|
+
const errorMessage = error instanceof Error ? error.message : 'An unknown error occurred';
|
|
5854
|
+
throw new Error(`Failed to complete OAuth: ${errorMessage}`);
|
|
5855
|
+
}
|
|
5856
|
+
}
|
|
5857
|
+
/**
|
|
5858
|
+
* Check if the user is authenticated (has valid token)
|
|
5859
|
+
*/
|
|
5860
|
+
isAuthenticated() {
|
|
5861
|
+
return this.authService.hasValidToken();
|
|
5862
|
+
}
|
|
5073
5863
|
/**
|
|
5074
5864
|
* Get the current authentication token
|
|
5075
5865
|
*/
|
|
@@ -5097,6 +5887,15 @@ class UiPath {
|
|
|
5097
5887
|
* Access to Process Instances service
|
|
5098
5888
|
*/
|
|
5099
5889
|
instances: this.getService(ProcessInstancesService)
|
|
5890
|
+
}),
|
|
5891
|
+
/**
|
|
5892
|
+
* Access to Maestro Cases service
|
|
5893
|
+
*/
|
|
5894
|
+
cases: Object.assign(this.getService(CasesService), {
|
|
5895
|
+
/**
|
|
5896
|
+
* Access to Case Instances service
|
|
5897
|
+
*/
|
|
5898
|
+
instances: this.getService(CaseInstancesService)
|
|
5100
5899
|
})
|
|
5101
5900
|
};
|
|
5102
5901
|
}
|
|
@@ -5326,6 +6125,7 @@ exports.UiPath = UiPath;
|
|
|
5326
6125
|
exports.UiPathError = UiPathError;
|
|
5327
6126
|
exports.VERSION = VERSION;
|
|
5328
6127
|
exports.ValidationError = ValidationError;
|
|
6128
|
+
exports.createCaseInstanceWithMethods = createCaseInstanceWithMethods;
|
|
5329
6129
|
exports.createEntityWithMethods = createEntityWithMethods;
|
|
5330
6130
|
exports.createProcessInstanceWithMethods = createProcessInstanceWithMethods;
|
|
5331
6131
|
exports.createTaskWithMethods = createTaskWithMethods;
|