@uipath/uipath-typescript 1.0.0-beta.13 → 1.0.0-beta.15

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.
@@ -1,6 +1,5 @@
1
1
  import { z } from 'zod';
2
2
  import { BatchLogRecordProcessor, LoggerProvider } from '@opentelemetry/sdk-logs';
3
- import * as mimeTypes from 'mime-types';
4
3
  import axios from 'axios';
5
4
 
6
5
  z.object({
@@ -560,7 +559,7 @@ class ErrorFactory {
560
559
  * Creates appropriate error instance based on HTTP status code
561
560
  */
562
561
  static createFromHttpStatus(statusCode, errorInfo) {
563
- const { message, requestId, details } = errorInfo;
562
+ const { message, requestId } = errorInfo;
564
563
  // Map status codes to error types
565
564
  switch (statusCode) {
566
565
  case HttpStatus.BAD_REQUEST:
@@ -978,6 +977,8 @@ function createHeaders(headersObj) {
978
977
  * Prefix used for OData query parameters
979
978
  */
980
979
  const ODATA_PREFIX = '$';
980
+ const UNKNOWN$1 = 'Unknown';
981
+ const NO_INSTANCE = 'no-instance';
981
982
  /**
982
983
  * OData pagination constants
983
984
  */
@@ -1470,12 +1471,12 @@ class PaginationHelpers {
1470
1471
  throw new Error('jumpToPage is not supported for token-based pagination. Use cursor-based navigation instead.');
1471
1472
  }
1472
1473
  // Get processed parameters
1473
- return PaginationHelpers.getRequestParameters(options);
1474
+ return PaginationHelpers.getRequestParameters(options, paginationType);
1474
1475
  }
1475
1476
  /**
1476
1477
  * Convert a unified pagination options to service-specific parameters
1477
1478
  */
1478
- static getRequestParameters(options) {
1479
+ static getRequestParameters(options, paginationType) {
1479
1480
  // Handle jumpToPage
1480
1481
  if (options.jumpToPage !== undefined) {
1481
1482
  const jumpToPageOptions = {
@@ -1488,7 +1489,8 @@ class PaginationHelpers {
1488
1489
  if (!options.cursor) {
1489
1490
  const firstPageOptions = {
1490
1491
  pageSize: options.pageSize,
1491
- pageNumber: 1
1492
+ // Only set pageNumber for OFFSET pagination
1493
+ pageNumber: paginationType === PaginationType.OFFSET ? 1 : undefined
1492
1494
  };
1493
1495
  return filterUndefined(firstPageOptions);
1494
1496
  }
@@ -1779,7 +1781,7 @@ class BaseService {
1779
1781
  pageInfo: {
1780
1782
  hasMore,
1781
1783
  totalCount,
1782
- currentPage: params.pageNumber || 1,
1784
+ currentPage: params.pageNumber,
1783
1785
  pageSize: params.pageSize,
1784
1786
  continuationToken
1785
1787
  },
@@ -2071,8 +2073,11 @@ class TokenManager {
2071
2073
  * Maestro Process Service Endpoints
2072
2074
  */
2073
2075
  const MAESTRO_ENDPOINTS = {
2076
+ BASE_PATH: 'pims_/api/v1',
2074
2077
  PROCESSES: {
2075
- GET_ALL: 'pims_/api/v1/processes/summary'},
2078
+ GET_ALL: 'pims_/api/v1/processes/summary',
2079
+ GET_SETTINGS: (processKey) => `pims_/api/v1/processes/${processKey}/settings`,
2080
+ },
2076
2081
  INSTANCES: {
2077
2082
  GET_ALL: 'pims_/api/v1/instances',
2078
2083
  GET_BY_ID: (instanceId) => `pims_/api/v1/instances/${instanceId}`,
@@ -2083,6 +2088,15 @@ const MAESTRO_ENDPOINTS = {
2083
2088
  PAUSE: (instanceId) => `pims_/api/v1/instances/${instanceId}/pause`,
2084
2089
  RESUME: (instanceId) => `pims_/api/v1/instances/${instanceId}/resume`,
2085
2090
  },
2091
+ INCIDENTS: {
2092
+ GET_ALL: 'pims_/api/v1/incidents/summary',
2093
+ GET_BY_PROCESS: (processKey) => `pims_/api/v1/incidents/process/${processKey}`,
2094
+ GET_BY_INSTANCE: (instanceId) => `pims_/api/v1/instances/${instanceId}/incidents`,
2095
+ },
2096
+ CASES: {
2097
+ GET_CASE_JSON: (instanceId) => `pims_/api/v1/cases/${instanceId}/case-json`,
2098
+ GET_ELEMENT_EXECUTIONS: (instanceId) => `pims_/api/v1alpha1/element-executions/case-instances/${instanceId}`,
2099
+ },
2086
2100
  };
2087
2101
  /**
2088
2102
  * Task Service (Action Center) Endpoints
@@ -2090,7 +2104,7 @@ const MAESTRO_ENDPOINTS = {
2090
2104
  const TASK_ENDPOINTS = {
2091
2105
  CREATE_GENERIC_TASK: '/tasks/GenericTasks/CreateTask',
2092
2106
  GET_TASK_USERS: (folderId) => `/odata/Tasks/UiPath.Server.Configuration.OData.GetTaskUsers(organizationUnitId=${folderId})`,
2093
- GET_TASKS_ACROSS_FOLDERS: '/odata/Tasks/UiPath.Server.Configuration.OData.GetTasksAcrossFolders',
2107
+ GET_TASKS_ACROSS_FOLDERS: '/odata/Tasks/UiPath.Server.Configuration.OData.GetTasksAcrossFoldersForAdmin',
2094
2108
  GET_BY_ID: (id) => `/odata/Tasks(${id})`,
2095
2109
  ASSIGN_TASKS: '/odata/Tasks/UiPath.Server.Configuration.OData.AssignTasks',
2096
2110
  REASSIGN_TASKS: '/odata/Tasks/UiPath.Server.Configuration.OData.ReassignTasks',
@@ -2158,11 +2172,66 @@ const ASSET_ENDPOINTS = {
2158
2172
 
2159
2173
  class AuthService extends BaseService {
2160
2174
  constructor(config, executionContext) {
2161
- const isOAuth = hasOAuthConfig(config);
2162
- const tokenManager = new TokenManager(executionContext, config, isOAuth);
2163
- super(config, executionContext, tokenManager);
2175
+ // Check if we should use stored OAuth context instead of provided config
2176
+ const storedContext = AuthService.getStoredOAuthContext();
2177
+ const effectiveConfig = storedContext ? AuthService._mergeConfigWithContext(config, storedContext) : config;
2178
+ const isOAuth = hasOAuthConfig(effectiveConfig);
2179
+ const tokenManager = new TokenManager(executionContext, effectiveConfig, isOAuth);
2180
+ super(effectiveConfig, executionContext, tokenManager);
2164
2181
  this.tokenManager = tokenManager;
2165
2182
  }
2183
+ /**
2184
+ * Check if we're in an OAuth callback state
2185
+ */
2186
+ static isInOAuthCallback() {
2187
+ if (!isBrowser)
2188
+ return false;
2189
+ const urlParams = new URLSearchParams(window.location.search);
2190
+ const code = urlParams.get('code');
2191
+ const hasCodeVerifier = sessionStorage.getItem('uipath_sdk_code_verifier');
2192
+ return !!(code && hasCodeVerifier);
2193
+ }
2194
+ /**
2195
+ * Get stored OAuth context
2196
+ */
2197
+ static getStoredOAuthContext() {
2198
+ if (!isBrowser) {
2199
+ return null;
2200
+ }
2201
+ try {
2202
+ const stored = sessionStorage.getItem('uipath_sdk_oauth_context');
2203
+ if (!stored) {
2204
+ return null;
2205
+ }
2206
+ const context = JSON.parse(stored);
2207
+ // Validate required fields
2208
+ if (!context.codeVerifier || !context.clientId || !context.redirectUri ||
2209
+ !context.baseUrl || !context.orgName) {
2210
+ sessionStorage.removeItem('uipath_sdk_oauth_context');
2211
+ return null;
2212
+ }
2213
+ return context;
2214
+ }
2215
+ catch (error) {
2216
+ sessionStorage.removeItem('uipath_sdk_oauth_context');
2217
+ console.warn('Failed to parse stored OAuth context from session storage', error);
2218
+ return null;
2219
+ }
2220
+ }
2221
+ /**
2222
+ * Merges provided config with stored OAuth context, prioritizing stored values
2223
+ */
2224
+ static _mergeConfigWithContext(config, context) {
2225
+ return {
2226
+ ...config,
2227
+ baseUrl: context.baseUrl,
2228
+ orgName: context.orgName,
2229
+ tenantName: context.tenantName,
2230
+ clientId: context.clientId,
2231
+ redirectUri: context.redirectUri,
2232
+ scope: context.scope
2233
+ };
2234
+ }
2166
2235
  /**
2167
2236
  * Get the token manager instance
2168
2237
  */
@@ -2178,13 +2247,34 @@ class AuthService extends BaseService {
2178
2247
  * In an OAuth flow, this method will trigger a page redirect and the promise will not resolve.
2179
2248
  */
2180
2249
  async authenticate(config) {
2181
- // Try to load token from storage first (only works for OAuth tokens)
2250
+ if (!isBrowser) {
2251
+ return false;
2252
+ }
2253
+ // First priority: Complete OAuth callback if we detect it
2254
+ if (AuthService.isInOAuthCallback()) {
2255
+ const urlParams = new URLSearchParams(window.location.search);
2256
+ const code = urlParams.get('code');
2257
+ if (!code) {
2258
+ throw new Error('Authorization code missing in OAuth callback');
2259
+ }
2260
+ // Check if token already exists (prevents duplicate processing)
2261
+ if (this.tokenManager.hasValidToken()) {
2262
+ return true;
2263
+ }
2264
+ // Ensure we have OAuth config for callback completion
2265
+ if (!hasOAuthConfig(config)) {
2266
+ throw new Error('OAuth configuration incomplete: clientId, redirectUri, and scope are required for OAuth callback');
2267
+ }
2268
+ const result = await this._authenticateWithOAuth(config.clientId, config.redirectUri, config.scope);
2269
+ return result;
2270
+ }
2271
+ // Secondly: Try to load existing valid token from storage
2182
2272
  const loadedFromStorage = this.tokenManager.loadFromStorage();
2183
2273
  // If we have a valid token from storage, return true
2184
2274
  if (loadedFromStorage && this.tokenManager.hasValidToken()) {
2185
2275
  return true;
2186
2276
  }
2187
- // If we don't have a valid token from storage, authenticate with OAuth
2277
+ // Start new OAuth flow if config has OAuth fields
2188
2278
  if (hasOAuthConfig(config)) {
2189
2279
  return await this._authenticateWithOAuth(config.clientId, config.redirectUri, config.scope);
2190
2280
  }
@@ -2367,6 +2457,17 @@ class AuthService extends BaseService {
2367
2457
  async _initiateOAuthFlow(clientId, redirectUri, scope) {
2368
2458
  const codeVerifier = this.generateCodeVerifier();
2369
2459
  const codeChallenge = await this.generateCodeChallenge(codeVerifier);
2460
+ // Store complete OAuth context for callback completion
2461
+ const oauthContext = {
2462
+ codeVerifier,
2463
+ clientId,
2464
+ redirectUri,
2465
+ baseUrl: this.config.baseUrl,
2466
+ orgName: this.config.orgName,
2467
+ tenantName: this.config.tenantName,
2468
+ scope
2469
+ };
2470
+ sessionStorage.setItem('uipath_sdk_oauth_context', JSON.stringify(oauthContext));
2370
2471
  sessionStorage.setItem('uipath_sdk_code_verifier', codeVerifier);
2371
2472
  const authUrl = this.getAuthorizationUrl({
2372
2473
  clientId,
@@ -2381,13 +2482,15 @@ class AuthService extends BaseService {
2381
2482
  if (!codeVerifier) {
2382
2483
  throw new Error('Code verifier not found in session storage. Authentication may have been interrupted.');
2383
2484
  }
2384
- sessionStorage.removeItem('uipath_sdk_code_verifier');
2385
2485
  await this._getAccessToken({
2386
2486
  clientId,
2387
2487
  redirectUri,
2388
2488
  code,
2389
2489
  codeVerifier
2390
2490
  });
2491
+ // Clear OAuth context and code verifier after successful token exchange
2492
+ sessionStorage.removeItem('uipath_sdk_oauth_context');
2493
+ sessionStorage.removeItem('uipath_sdk_code_verifier');
2391
2494
  const url = new URL(window.location.href);
2392
2495
  url.searchParams.delete('code');
2393
2496
  url.searchParams.delete('state');
@@ -2616,7 +2719,7 @@ const EntityFieldTypeMap = {
2616
2719
  // Connection string placeholder that will be replaced during build
2617
2720
  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";
2618
2721
  // SDK Version placeholder
2619
- const SDK_VERSION = "1.0.0-beta.13";
2722
+ const SDK_VERSION = "1.0.0-beta.15";
2620
2723
  const VERSION = "Version";
2621
2724
  const SERVICE = "Service";
2622
2725
  const CLOUD_ORGANIZATION_NAME = "CloudOrganizationName";
@@ -3201,46 +3304,161 @@ __decorate([
3201
3304
  ], EntityService.prototype, "getAll", null);
3202
3305
 
3203
3306
  /**
3204
- * Service for interacting with Maestro Processes
3307
+ * Maestro Process Models
3308
+ * Model classes for Maestro processes
3205
3309
  */
3206
- class MaestroProcessesService extends BaseService {
3310
+ /**
3311
+ * Creates methods for a process object
3312
+ *
3313
+ * @param processData - The process data (response from API)
3314
+ * @param service - The process service instance
3315
+ * @returns Object containing process methods
3316
+ */
3317
+ function createProcessMethods(processData, service) {
3318
+ return {
3319
+ async getIncidents() {
3320
+ if (!processData.processKey)
3321
+ throw new Error('Process key is undefined');
3322
+ if (!processData.folderKey)
3323
+ throw new Error('Folder key is undefined');
3324
+ return service.getIncidents(processData.processKey, processData.folderKey);
3325
+ }
3326
+ };
3327
+ }
3328
+ /**
3329
+ * Creates an actionable process by combining API process data with operational methods.
3330
+ *
3331
+ * @param processData - The process data from API
3332
+ * @param service - The process service instance
3333
+ * @returns A process object with added methods
3334
+ */
3335
+ function createProcessWithMethods(processData, service) {
3336
+ const methods = createProcessMethods(processData, service);
3337
+ return Object.assign({}, processData, methods);
3338
+ }
3339
+
3340
+ /**
3341
+ * Maps fields for Incident entities
3342
+ */
3343
+ const ProcessIncidentMap = {
3344
+ errorTimeUtc: 'errorTime'
3345
+ };
3346
+ /**
3347
+ * Maps fields for Incident Summary entities
3348
+ */
3349
+ const ProcessIncidentSummaryMap = {
3350
+ firstTimeUtc: 'firstOccuranceTime'
3351
+ };
3352
+
3353
+ /**
3354
+ * Helpers for fetching BPMN XML and extracting element details used to annotate responses
3355
+ */
3356
+ class BpmnHelpers {
3207
3357
  /**
3208
- * @hideconstructor
3358
+ * Parse BPMN XML and extract element id → {name,type} used for incidents
3209
3359
  */
3210
- constructor(config, executionContext, tokenManager) {
3211
- super(config, executionContext, tokenManager);
3360
+ static parseBpmnElementsForIncidents(bpmnXml) {
3361
+ const elementInfo = {};
3362
+ try {
3363
+ // Find <bpmn:...> start tags and capture the element type.
3364
+ // Then read 'id' and 'name' attributes from each tag.
3365
+ const bpmnOpenTagRegex = /<bpmn:([A-Za-z][\w.-]*)\b[^>]*>/g;
3366
+ for (const tagMatch of bpmnXml.matchAll(bpmnOpenTagRegex)) {
3367
+ const [fullTag, elementType] = tagMatch;
3368
+ // Extract attributes from the current tag text.
3369
+ const idMatch = /\bid\s*=\s*"([^"]*)"/.exec(fullTag);
3370
+ if (!idMatch) {
3371
+ continue;
3372
+ }
3373
+ const elementId = idMatch[1];
3374
+ const nameMatch = /\bname\s*=\s*"([^"]*)"/.exec(fullTag);
3375
+ const name = nameMatch ? nameMatch[1] : '';
3376
+ // Convert BPMN element type to human-readable format
3377
+ const activityType = this.formatActivityTypeForIncidents(elementType);
3378
+ const activityName = name || elementId;
3379
+ elementInfo[elementId] = {
3380
+ type: activityType,
3381
+ name: activityName
3382
+ };
3383
+ }
3384
+ }
3385
+ catch (error) {
3386
+ console.warn('Failed to parse BPMN XML for incidents:', error);
3387
+ }
3388
+ return elementInfo;
3212
3389
  }
3213
3390
  /**
3214
- * Get all processes with their instance statistics
3215
- * @returns Promise resolving to array of MaestroProcess objects
3216
- *
3217
- * @example
3218
- * ```typescript
3219
- * // Get all processes
3220
- * const processes = await sdk.maestro.processes.getAll();
3221
- *
3222
- * // Access process information
3223
- * for (const process of processes) {
3224
- * console.log(`Process: ${process.processKey}`);
3225
- * console.log(`Running instances: ${process.runningCount}`);
3226
- * console.log(`Faulted instances: ${process.faultedCount}`);
3227
- * }
3228
- *
3229
- * ```
3391
+ * Format BPMN element type to human-readable activity type for incidents
3230
3392
  */
3231
- async getAll() {
3232
- const response = await this.get(MAESTRO_ENDPOINTS.PROCESSES.GET_ALL);
3233
- // Extract processes array from response data and add name field
3234
- const processes = response.data?.processes || [];
3235
- return processes.map(process => ({
3236
- ...process,
3237
- name: process.packageId
3393
+ static formatActivityTypeForIncidents(elementType) {
3394
+ // Convert camelCase BPMN element types to human-readable format
3395
+ // e.g., "serviceTask" -> "Service Task", "exclusiveGateway" -> "Exclusive Gateway"
3396
+ return elementType
3397
+ .replace(/([A-Z])/g, ' $1') // Add space before uppercase letters
3398
+ .replace(/^./, str => str.toUpperCase()) // Capitalize first letter
3399
+ .trim(); // Remove any leading/trailing spaces
3400
+ }
3401
+ /**
3402
+ * Fetch BPMN via getBpmn and add element name/type to each incident
3403
+ */
3404
+ static async enrichIncidentsWithBpmnData(incidents, folderKey, service) {
3405
+ // Check if all incidents have the same instanceId
3406
+ const uniqueInstanceIds = [...new Set(incidents.map(i => i.instanceId))];
3407
+ if (uniqueInstanceIds.length === 1) {
3408
+ // Single instance optimization (in case of process instance incidents)
3409
+ const elementInfo = await this.getBpmnElementInfo(uniqueInstanceIds[0], folderKey, service);
3410
+ return incidents.map((incident) => this.transformIncidentWithBpmn(incident, elementInfo));
3411
+ }
3412
+ else {
3413
+ // Multiple instances optimization (in case of process incidents)
3414
+ return this.enrichMultipleInstanceIncidents(incidents, folderKey, service);
3415
+ }
3416
+ }
3417
+ /**
3418
+ * When incidents span multiple instances, fetch BPMN per instance and annotate
3419
+ */
3420
+ static async enrichMultipleInstanceIncidents(incidents, folderKey, service) {
3421
+ const groups = incidents.reduce((acc, incident) => {
3422
+ const id = incident.instanceId || NO_INSTANCE;
3423
+ (acc[id] = acc[id] || []).push(incident);
3424
+ return acc;
3425
+ }, {});
3426
+ const results = await Promise.all(Object.entries(groups).map(async (entry) => {
3427
+ const [instanceId, groupIncidents] = entry;
3428
+ const elementInfo = await this.getBpmnElementInfo(instanceId, folderKey, service);
3429
+ return groupIncidents.map((incident) => this.transformIncidentWithBpmn(incident, elementInfo));
3238
3430
  }));
3431
+ return results.flat();
3432
+ }
3433
+ /**
3434
+ * Retrieve BPMN XML for an instance and derive element id → {name,type}
3435
+ */
3436
+ static async getBpmnElementInfo(instanceId, folderKey, service) {
3437
+ if (!instanceId || instanceId === NO_INSTANCE) {
3438
+ return {};
3439
+ }
3440
+ try {
3441
+ const bpmnXml = await service.getBpmn(instanceId, folderKey);
3442
+ return this.parseBpmnElementsForIncidents(bpmnXml);
3443
+ }
3444
+ catch (error) {
3445
+ console.warn(`Failed to get BPMN for instance ${instanceId}:`, error);
3446
+ return {};
3447
+ }
3448
+ }
3449
+ /**
3450
+ * Transform a raw incident by attaching element name/type from BPMN
3451
+ */
3452
+ static transformIncidentWithBpmn(incident, elementInfo) {
3453
+ const element = elementInfo[incident.elementId];
3454
+ const transformed = transformData(incident, ProcessIncidentMap);
3455
+ return {
3456
+ ...transformed,
3457
+ incidentElementActivityType: element?.type || UNKNOWN$1,
3458
+ incidentElementActivityName: element?.name || UNKNOWN$1
3459
+ };
3239
3460
  }
3240
3461
  }
3241
- __decorate([
3242
- track('MaestroProcesses.GetAll')
3243
- ], MaestroProcessesService.prototype, "getAll", null);
3244
3462
 
3245
3463
  /**
3246
3464
  * Creates methods for a process instance
@@ -3254,17 +3472,49 @@ function createProcessInstanceMethods(instanceData, service) {
3254
3472
  async cancel(options) {
3255
3473
  if (!instanceData.instanceId)
3256
3474
  throw new Error('Process instance ID is undefined');
3475
+ if (!instanceData.folderKey)
3476
+ throw new Error('Process instance folder key is undefined');
3257
3477
  return service.cancel(instanceData.instanceId, instanceData.folderKey, options);
3258
3478
  },
3259
3479
  async pause(options) {
3260
3480
  if (!instanceData.instanceId)
3261
3481
  throw new Error('Process instance ID is undefined');
3482
+ if (!instanceData.folderKey)
3483
+ throw new Error('Process instance folder key is undefined');
3262
3484
  return service.pause(instanceData.instanceId, instanceData.folderKey, options);
3263
3485
  },
3264
3486
  async resume(options) {
3265
3487
  if (!instanceData.instanceId)
3266
3488
  throw new Error('Process instance ID is undefined');
3489
+ if (!instanceData.folderKey)
3490
+ throw new Error('Process instance folder key is undefined');
3267
3491
  return service.resume(instanceData.instanceId, instanceData.folderKey, options);
3492
+ },
3493
+ async getIncidents() {
3494
+ if (!instanceData.instanceId)
3495
+ throw new Error('Process instance ID is undefined');
3496
+ if (!instanceData.folderKey)
3497
+ throw new Error('Process instance folder key is undefined');
3498
+ return service.getIncidents(instanceData.instanceId, instanceData.folderKey);
3499
+ },
3500
+ async getExecutionHistory() {
3501
+ if (!instanceData.instanceId)
3502
+ throw new Error('Process instance ID is undefined');
3503
+ return service.getExecutionHistory(instanceData.instanceId);
3504
+ },
3505
+ async getBpmn() {
3506
+ if (!instanceData.instanceId)
3507
+ throw new Error('Process instance ID is undefined');
3508
+ if (!instanceData.folderKey)
3509
+ throw new Error('Process instance folder key is undefined');
3510
+ return service.getBpmn(instanceData.instanceId, instanceData.folderKey);
3511
+ },
3512
+ async getVariables(options) {
3513
+ if (!instanceData.instanceId)
3514
+ throw new Error('Process instance ID is undefined');
3515
+ if (!instanceData.folderKey)
3516
+ throw new Error('Process instance folder key is undefined');
3517
+ return service.getVariables(instanceData.instanceId, instanceData.folderKey, options);
3268
3518
  }
3269
3519
  };
3270
3520
  }
@@ -3280,6 +3530,155 @@ function createProcessInstanceWithMethods(instanceData, service) {
3280
3530
  return Object.assign({}, instanceData, methods);
3281
3531
  }
3282
3532
 
3533
+ /**
3534
+ * Process Incident Status
3535
+ */
3536
+ var ProcessIncidentStatus;
3537
+ (function (ProcessIncidentStatus) {
3538
+ ProcessIncidentStatus["Open"] = "Open";
3539
+ ProcessIncidentStatus["Closed"] = "Closed";
3540
+ })(ProcessIncidentStatus || (ProcessIncidentStatus = {}));
3541
+ /**
3542
+ * Process Incident Type
3543
+ */
3544
+ var ProcessIncidentType;
3545
+ (function (ProcessIncidentType) {
3546
+ ProcessIncidentType["System"] = "System";
3547
+ ProcessIncidentType["User"] = "User";
3548
+ ProcessIncidentType["Deployment"] = "Deployment";
3549
+ })(ProcessIncidentType || (ProcessIncidentType = {}));
3550
+ /**
3551
+ * Process Incident Severity
3552
+ */
3553
+ var ProcessIncidentSeverity;
3554
+ (function (ProcessIncidentSeverity) {
3555
+ ProcessIncidentSeverity["Error"] = "Error";
3556
+ ProcessIncidentSeverity["Warning"] = "Warning";
3557
+ })(ProcessIncidentSeverity || (ProcessIncidentSeverity = {}));
3558
+ /**
3559
+ * Process Incident Debug Mode
3560
+ */
3561
+ var DebugMode;
3562
+ (function (DebugMode) {
3563
+ DebugMode["None"] = "None";
3564
+ DebugMode["Default"] = "Default";
3565
+ DebugMode["StepByStep"] = "StepByStep";
3566
+ DebugMode["SingleStep"] = "SingleStep";
3567
+ })(DebugMode || (DebugMode = {}));
3568
+
3569
+ /**
3570
+ * Case Instance Types
3571
+ * Types and interfaces for Maestro case instance management
3572
+ */
3573
+ /**
3574
+ * Case stage task type
3575
+ */
3576
+ var StageTaskType;
3577
+ (function (StageTaskType) {
3578
+ StageTaskType["EXTERNAL_AGENT"] = "external-agent";
3579
+ StageTaskType["RPA"] = "rpa";
3580
+ StageTaskType["AGENTIC_PROCESS"] = "process";
3581
+ StageTaskType["AGENT"] = "agent";
3582
+ StageTaskType["ACTION"] = "action";
3583
+ StageTaskType["API_WORKFLOW"] = "api-workflow";
3584
+ })(StageTaskType || (StageTaskType = {}));
3585
+ /**
3586
+ * Escalation recipient scope
3587
+ */
3588
+ var EscalationRecipientScope;
3589
+ (function (EscalationRecipientScope) {
3590
+ EscalationRecipientScope["USER"] = "user";
3591
+ EscalationRecipientScope["USER_GROUP"] = "usergroup";
3592
+ })(EscalationRecipientScope || (EscalationRecipientScope = {}));
3593
+ /**
3594
+ * Escalation action type
3595
+ */
3596
+ var EscalationActionType;
3597
+ (function (EscalationActionType) {
3598
+ EscalationActionType["NOTIFICATION"] = "notification";
3599
+ })(EscalationActionType || (EscalationActionType = {}));
3600
+ /**
3601
+ * Escalation rule trigger type
3602
+ */
3603
+ var EscalationTriggerType;
3604
+ (function (EscalationTriggerType) {
3605
+ EscalationTriggerType["SLA_BREACHED"] = "sla-breached";
3606
+ EscalationTriggerType["AT_RISK"] = "at-risk";
3607
+ })(EscalationTriggerType || (EscalationTriggerType = {}));
3608
+ /**
3609
+ * SLA duration unit
3610
+ */
3611
+ var SLADurationUnit;
3612
+ (function (SLADurationUnit) {
3613
+ SLADurationUnit["HOURS"] = "h";
3614
+ SLADurationUnit["DAYS"] = "d";
3615
+ SLADurationUnit["WEEKS"] = "w";
3616
+ SLADurationUnit["MONTHS"] = "m";
3617
+ })(SLADurationUnit || (SLADurationUnit = {}));
3618
+
3619
+ /**
3620
+ * Creates methods for a case instance
3621
+ *
3622
+ * @param instanceData - The case instance data (response from API)
3623
+ * @param service - The case instance service instance
3624
+ * @returns Object containing case instance methods
3625
+ */
3626
+ function createCaseInstanceMethods(instanceData, service) {
3627
+ return {
3628
+ async close(options) {
3629
+ if (!instanceData.instanceId)
3630
+ throw new Error('Case instance ID is undefined');
3631
+ if (!instanceData.folderKey)
3632
+ throw new Error('Case instance folder key is undefined');
3633
+ return service.close(instanceData.instanceId, instanceData.folderKey, options);
3634
+ },
3635
+ async pause(options) {
3636
+ if (!instanceData.instanceId)
3637
+ throw new Error('Case instance ID is undefined');
3638
+ if (!instanceData.folderKey)
3639
+ throw new Error('Case instance folder key is undefined');
3640
+ return service.pause(instanceData.instanceId, instanceData.folderKey, options);
3641
+ },
3642
+ async resume(options) {
3643
+ if (!instanceData.instanceId)
3644
+ throw new Error('Case instance ID is undefined');
3645
+ if (!instanceData.folderKey)
3646
+ throw new Error('Case instance folder key is undefined');
3647
+ return service.resume(instanceData.instanceId, instanceData.folderKey, options);
3648
+ },
3649
+ async getExecutionHistory() {
3650
+ if (!instanceData.instanceId)
3651
+ throw new Error('Case instance ID is undefined');
3652
+ if (!instanceData.folderKey)
3653
+ throw new Error('Case instance folder key is undefined');
3654
+ return service.getExecutionHistory(instanceData.instanceId, instanceData.folderKey);
3655
+ },
3656
+ async getStages() {
3657
+ if (!instanceData.instanceId)
3658
+ throw new Error('Case instance ID is undefined');
3659
+ if (!instanceData.folderKey)
3660
+ throw new Error('Case instance folder key is undefined');
3661
+ return service.getStages(instanceData.instanceId, instanceData.folderKey);
3662
+ },
3663
+ async getActionTasks(options) {
3664
+ if (!instanceData.instanceId)
3665
+ throw new Error('Case instance ID is undefined');
3666
+ return service.getActionTasks(instanceData.instanceId, options);
3667
+ }
3668
+ };
3669
+ }
3670
+ /**
3671
+ * Creates an actionable case instance by combining API case instance data with operational methods.
3672
+ *
3673
+ * @param instanceData - The case instance data from API
3674
+ * @param service - The case instance service instance
3675
+ * @returns A case instance object with added methods
3676
+ */
3677
+ function createCaseInstanceWithMethods(instanceData, service) {
3678
+ const methods = createCaseInstanceMethods(instanceData, service);
3679
+ return Object.assign({}, instanceData, methods);
3680
+ }
3681
+
3283
3682
  /**
3284
3683
  * Maps fields for Process Instance entities to ensure consistent naming
3285
3684
  */
@@ -3562,6 +3961,19 @@ class ProcessInstancesService extends BaseService {
3562
3961
  };
3563
3962
  return variablesResponse;
3564
3963
  }
3964
+ /**
3965
+ * Get incidents for a process instance
3966
+ * @param instanceId The ID of the instance to get incidents for
3967
+ * @param folderKey The folder key for authorization
3968
+ * @returns Promise<ProcessIncidentGetResponse[]>
3969
+ */
3970
+ async getIncidents(instanceId, folderKey) {
3971
+ const rawResponse = await this.get(MAESTRO_ENDPOINTS.INCIDENTS.GET_BY_INSTANCE(instanceId), {
3972
+ headers: createHeaders({ [FOLDER_KEY]: folderKey })
3973
+ });
3974
+ // Filter out excluded fields and transform response, then enrich with BPMN data
3975
+ return BpmnHelpers.enrichIncidentsWithBpmnData(rawResponse.data || [], folderKey, this);
3976
+ }
3565
3977
  }
3566
3978
  __decorate([
3567
3979
  track('ProcessInstances.GetAll')
@@ -3587,583 +3999,1270 @@ __decorate([
3587
3999
  __decorate([
3588
4000
  track('ProcessInstances.GetVariables')
3589
4001
  ], ProcessInstancesService.prototype, "getVariables", null);
4002
+ __decorate([
4003
+ track('ProcessInstances.GetIncidents')
4004
+ ], ProcessInstancesService.prototype, "getIncidents", null);
3590
4005
 
3591
4006
  /**
3592
- * Base service for services that need folder-specific functionality
4007
+ * Service for interacting with Maestro Processes
3593
4008
  */
3594
- class FolderScopedService extends BaseService {
4009
+ class MaestroProcessesService extends BaseService {
4010
+ /**
4011
+ * @hideconstructor
4012
+ */
3595
4013
  constructor(config, executionContext, tokenManager) {
3596
4014
  super(config, executionContext, tokenManager);
4015
+ this.processInstancesService = new ProcessInstancesService(config, executionContext, tokenManager);
3597
4016
  }
3598
4017
  /**
3599
- * Gets resources in a folder with optional query parameters
4018
+ * Get all processes with their instance statistics
4019
+ * @returns Promise resolving to array of MaestroProcess objects
3600
4020
  *
3601
- * @param endpoint - API endpoint to call
3602
- * @param folderId - required folder ID
3603
- * @param options - Query options
3604
- * @param transformFn - Optional function to transform the response data
3605
- * @returns Promise resolving to an array of resources
4021
+ * @example
4022
+ * ```typescript
4023
+ * // Get all processes
4024
+ * const processes = await sdk.maestro.processes.getAll();
4025
+ *
4026
+ * // Access process information
4027
+ * for (const process of processes) {
4028
+ * console.log(`Process: ${process.processKey}`);
4029
+ * console.log(`Running instances: ${process.runningCount}`);
4030
+ * console.log(`Faulted instances: ${process.faultedCount}`);
4031
+ * }
4032
+ *
4033
+ * ```
3606
4034
  */
3607
- async _getByFolder(endpoint, folderId, options = {}, transformFn) {
3608
- const headers = createHeaders({ [FOLDER_ID]: folderId });
3609
- const keysToPrefix = Object.keys(options);
3610
- const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
3611
- const response = await this.get(endpoint, {
3612
- params: apiOptions,
3613
- headers
4035
+ async getAll() {
4036
+ const response = await this.get(MAESTRO_ENDPOINTS.PROCESSES.GET_ALL);
4037
+ // Extract processes array from response data and add name field
4038
+ const processes = response.data?.processes || [];
4039
+ const processesWithName = processes.map(process => ({
4040
+ ...process,
4041
+ name: process.packageId
4042
+ }));
4043
+ // Add methods to each process
4044
+ return processesWithName.map(process => createProcessWithMethods(process, this));
4045
+ }
4046
+ /**
4047
+ * Get incidents for a specific process
4048
+ */
4049
+ async getIncidents(processKey, folderKey) {
4050
+ const rawResponse = await this.get(MAESTRO_ENDPOINTS.INCIDENTS.GET_BY_PROCESS(processKey), {
4051
+ headers: createHeaders({ [FOLDER_KEY]: folderKey })
3614
4052
  });
3615
- if (transformFn) {
3616
- return response.data?.value.map(transformFn);
3617
- }
3618
- return response.data?.value;
4053
+ // Fetch BPMN XML and add element name/type to each incident
4054
+ return BpmnHelpers.enrichIncidentsWithBpmnData(rawResponse.data || [], folderKey, this.processInstancesService);
3619
4055
  }
3620
4056
  }
4057
+ __decorate([
4058
+ track('MaestroProcesses.GetAll')
4059
+ ], MaestroProcessesService.prototype, "getAll", null);
4060
+ __decorate([
4061
+ track('MaestroProcesses.GetIncidents')
4062
+ ], MaestroProcessesService.prototype, "getIncidents", null);
3621
4063
 
3622
4064
  /**
3623
- * Maps fields for Asset entities to ensure consistent naming
3624
- */
3625
- const AssetMap = {
3626
- creationTime: 'createdTime',
3627
- lastModificationTime: 'lastModifiedTime'
3628
- };
3629
-
3630
- /**
3631
- * Service for interacting with UiPath Orchestrator Assets API
4065
+ * Service class for Maestro Process Incidents
3632
4066
  */
3633
- class AssetService extends FolderScopedService {
4067
+ class ProcessIncidentsService extends BaseService {
3634
4068
  /**
3635
- * @hideconstructor
3636
- */
3637
- constructor(config, executionContext, tokenManager) {
3638
- super(config, executionContext, tokenManager);
3639
- }
3640
- /**
3641
- * Gets all assets across folders with optional filtering and folder scoping
3642
- *
3643
- * @signature getAll(options?) -> Promise<AssetGetResponse[]>
3644
- * @param options Query options including optional folderId and pagination options
3645
- * @returns Promise resolving to array of assets or paginated response
4069
+ * Get all process incidents across all folders
3646
4070
  *
4071
+ * @returns Promise resolving to array of process incident
4072
+ * {@link ProcessIncidentGetAllResponse}
3647
4073
  * @example
3648
4074
  * ```typescript
3649
- * // Standard array return
3650
- * const assets = await sdk.assets.getAll();
3651
- *
3652
- * // With folder
3653
- * const folderAssets = await sdk.assets.getAll({ folderId: 123 });
3654
- *
3655
- * // First page with pagination
3656
- * const page1 = await sdk.assets.getAll({ pageSize: 10 });
4075
+ * // Get all process incidents across all folders
4076
+ * const incidents = await sdk.maestro.processes.incidents.getAll();
3657
4077
  *
3658
- * // Navigate using cursor
3659
- * if (page1.hasNextPage) {
3660
- * const page2 = await sdk.assets.getAll({ cursor: page1.nextCursor });
4078
+ * // Access process incident information
4079
+ * for (const incident of incidents) {
4080
+ * console.log(`Process: ${incident.processKey}`);
4081
+ * console.log(`Error: ${incident.errorMessage}`);
4082
+ * console.log(`Count: ${incident.count}`);
4083
+ * console.log(`First occurrence: ${incident.firstOccuranceTime}`);
3661
4084
  * }
3662
- *
3663
- * // Jump to specific page
3664
- * const page5 = await sdk.assets.getAll({
3665
- * jumpToPage: 5,
3666
- * pageSize: 10
3667
- * });
3668
- * ```
3669
- */
3670
- async getAll(options) {
3671
- // Transformation function for assets
3672
- const transformAssetResponse = (asset) => transformData(pascalToCamelCaseKeys(asset), AssetMap);
3673
- return PaginationHelpers.getAll({
3674
- serviceAccess: this.createPaginationServiceAccess(),
3675
- getEndpoint: (folderId) => folderId ? ASSET_ENDPOINTS.GET_BY_FOLDER : ASSET_ENDPOINTS.GET_ALL,
3676
- getByFolderEndpoint: ASSET_ENDPOINTS.GET_BY_FOLDER,
3677
- transformFn: transformAssetResponse,
3678
- pagination: {
3679
- paginationType: PaginationType.OFFSET,
3680
- itemsField: ODATA_PAGINATION.ITEMS_FIELD,
3681
- totalCountField: ODATA_PAGINATION.TOTAL_COUNT_FIELD,
3682
- paginationParams: {
3683
- pageSizeParam: ODATA_OFFSET_PARAMS.PAGE_SIZE_PARAM,
3684
- offsetParam: ODATA_OFFSET_PARAMS.OFFSET_PARAM,
3685
- countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM
3686
- }
3687
- }
3688
- }, options);
3689
- }
3690
- /**
3691
- * Gets a single asset by ID
3692
- *
3693
- * @param id - Asset ID
3694
- * @param folderId - Required folder ID
3695
- * @param options - Optional query parameters (expand, select)
3696
- * @returns Promise resolving to a single asset
3697
- *
3698
- * @example
3699
- * ```typescript
3700
- * // Get asset by ID
3701
- * const asset = await sdk.assets.getById(123, 456);
3702
4085
  * ```
3703
4086
  */
3704
- async getById(id, folderId, options = {}) {
3705
- const headers = createHeaders({ [FOLDER_ID]: folderId });
3706
- const keysToPrefix = Object.keys(options);
3707
- const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
3708
- const response = await this.get(ASSET_ENDPOINTS.GET_BY_ID(id), {
3709
- headers,
3710
- params: apiOptions
3711
- });
3712
- const transformedAsset = transformData(pascalToCamelCaseKeys(response.data), AssetMap);
3713
- return transformedAsset;
4087
+ async getAll() {
4088
+ const rawResponse = await this.get(MAESTRO_ENDPOINTS.INCIDENTS.GET_ALL);
4089
+ // Transform field names
4090
+ const data = rawResponse.data || [];
4091
+ return data.map(incident => transformData(incident, ProcessIncidentSummaryMap));
3714
4092
  }
3715
4093
  }
3716
4094
  __decorate([
3717
- track('Assets.GetAll')
3718
- ], AssetService.prototype, "getAll", null);
3719
- __decorate([
3720
- track('Assets.GetById')
3721
- ], AssetService.prototype, "getById", null);
4095
+ track('ProcessIncidents.getAll')
4096
+ ], ProcessIncidentsService.prototype, "getAll", null);
3722
4097
 
3723
4098
  /**
3724
- * Maps fields for Bucket entities to ensure consistent naming
4099
+ * Internal types for Maestro Cases
4100
+ * These types are used internally by the cases service
3725
4101
  */
3726
- const BucketMap = {
3727
- fullPath: 'path',
3728
- items: 'blobItems',
3729
- verb: 'httpMethod'
3730
- };
4102
+ /**
4103
+ * Process type enum for filtering
4104
+ */
4105
+ var ProcessType;
4106
+ (function (ProcessType) {
4107
+ ProcessType["CaseManagement"] = "CaseManagement";
4108
+ })(ProcessType || (ProcessType = {}));
3731
4109
 
3732
- // Import file-type dynamically to avoid issues in browser environment
3733
- // This variable will hold the fileTypeFromBuffer function when in Node.js environment
3734
- let fileTypeFromBuffer;
3735
- // Only import in Node.js environment
3736
- if (!isBrowser) {
3737
- import('file-type').then(module => {
3738
- fileTypeFromBuffer = module.fileTypeFromBuffer;
3739
- }).catch(err => {
3740
- console.debug('Could not load file-type module:', err);
3741
- });
3742
- }
3743
- class BucketService extends FolderScopedService {
4110
+ /**
4111
+ * Service for interacting with UiPath Maestro Cases
4112
+ */
4113
+ class CasesService extends BaseService {
3744
4114
  /**
3745
4115
  * @hideconstructor
3746
4116
  */
3747
4117
  constructor(config, executionContext, tokenManager) {
3748
4118
  super(config, executionContext, tokenManager);
3749
- this.tokenManager = tokenManager;
3750
- }
3751
- /**
3752
- * Gets a bucket by ID
3753
- * @param bucketId - The ID of the bucket to retrieve
3754
- * @param folderId - Folder ID for organization unit context
3755
- * @param options - Optional query parameters (expand, select)
3756
- * @returns Promise resolving to the bucket
3757
- *
3758
- * @example
3759
- * ```typescript
3760
- * // Get bucket by ID
3761
- * const bucket = await sdk.buckets.getById(123, 456);
3762
- * ```
3763
- */
3764
- async getById(id, folderId, options = {}) {
3765
- if (!id) {
3766
- throw new ValidationError({ message: 'bucketId is required for getById' });
3767
- }
3768
- if (!folderId) {
3769
- throw new ValidationError({ message: 'folderId is required for getById' });
3770
- }
3771
- const headers = createHeaders({ [FOLDER_ID]: folderId });
3772
- // Prefix all keys in options with $ for OData
3773
- const keysToPrefix = Object.keys(options);
3774
- const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
3775
- const response = await this.get(BUCKET_ENDPOINTS.GET_BY_ID(id), {
3776
- params: apiOptions,
3777
- headers
3778
- });
3779
- // Transform response from PascalCase to camelCase
3780
- return pascalToCamelCaseKeys(response.data);
3781
4119
  }
3782
4120
  /**
3783
- * Gets all buckets across folders with optional filtering and folder scoping
3784
- *
3785
- * The method returns either:
3786
- * - An array of buckets (when no pagination parameters are provided)
3787
- * - A paginated result with navigation cursors (when any pagination parameter is provided)
3788
- *
3789
- * @param options - Query options including optional folderId
3790
- * @returns Promise resolving to an array of buckets or paginated result
4121
+ * Get all case management processes with their instance statistics
4122
+ * @returns Promise resolving to array of Case objects
3791
4123
  *
3792
4124
  * @example
3793
4125
  * ```typescript
3794
- * // Get all buckets across folders
3795
- * const buckets = await sdk.buckets.getAll();
3796
- *
3797
- * // Get buckets within a specific folder
3798
- * const buckets = await sdk.buckets.getAll({
3799
- * folderId: 123
3800
- * });
3801
- *
3802
- * // Get buckets with filtering
3803
- * const buckets = await sdk.buckets.getAll({
3804
- * filter: "name eq 'MyBucket'"
3805
- * });
4126
+ * // Get all case management processes
4127
+ * const cases = await sdk.maestro.cases.getAll();
3806
4128
  *
3807
- * // First page with pagination
3808
- * const page1 = await sdk.buckets.getAll({ pageSize: 10 });
3809
- *
3810
- * // Navigate using cursor
3811
- * if (page1.hasNextPage) {
3812
- * const page2 = await sdk.buckets.getAll({ cursor: page1.nextCursor });
4129
+ * // Access case information
4130
+ * for (const caseProcess of cases) {
4131
+ * console.log(`Case Process: ${caseProcess.processKey}`);
4132
+ * console.log(`Running instances: ${caseProcess.runningCount}`);
4133
+ * console.log(`Completed instances: ${caseProcess.completedCount}`);
3813
4134
  * }
3814
4135
  *
3815
- * // Jump to specific page
3816
- * const page5 = await sdk.buckets.getAll({
3817
- * jumpToPage: 5,
3818
- * pageSize: 10
3819
- * });
3820
4136
  * ```
3821
4137
  */
3822
- async getAll(options) {
3823
- // Transformation function for buckets
3824
- const transformBucketResponse = (bucket) => pascalToCamelCaseKeys(bucket);
3825
- return PaginationHelpers.getAll({
3826
- serviceAccess: this.createPaginationServiceAccess(),
3827
- getEndpoint: (folderId) => folderId ? BUCKET_ENDPOINTS.GET_BY_FOLDER : BUCKET_ENDPOINTS.GET_ALL,
3828
- getByFolderEndpoint: BUCKET_ENDPOINTS.GET_BY_FOLDER,
3829
- transformFn: transformBucketResponse,
3830
- pagination: {
3831
- paginationType: PaginationType.OFFSET,
3832
- itemsField: ODATA_PAGINATION.ITEMS_FIELD,
3833
- totalCountField: ODATA_PAGINATION.TOTAL_COUNT_FIELD,
3834
- paginationParams: {
3835
- pageSizeParam: ODATA_OFFSET_PARAMS.PAGE_SIZE_PARAM,
3836
- offsetParam: ODATA_OFFSET_PARAMS.OFFSET_PARAM,
3837
- countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM
3838
- }
3839
- }
3840
- }, options);
4138
+ async getAll() {
4139
+ const params = createParams({
4140
+ processType: ProcessType.CaseManagement
4141
+ });
4142
+ const response = await this.get(MAESTRO_ENDPOINTS.PROCESSES.GET_ALL, { params });
4143
+ // Extract processes array from response data and add name field
4144
+ const cases = response.data?.processes || [];
4145
+ return cases.map(caseItem => ({
4146
+ ...caseItem,
4147
+ name: this.extractCaseName(caseItem.packageId)
4148
+ }));
3841
4149
  }
3842
4150
  /**
3843
- * Gets metadata for files in a bucket with optional filtering and pagination
3844
- *
3845
- * The method returns either:
3846
- * - A NonPaginatedResponse with items array (when no pagination parameters are provided)
3847
- * - A PaginatedResponse with navigation cursors (when any pagination parameter is provided)
3848
- *
3849
- * @param bucketId - The ID of the bucket to get file metadata from
3850
- * @param folderId - Required folder ID for organization unit context
3851
- * @param options - Optional parameters for filtering, pagination and access URL generation
3852
- * @returns Promise resolving to the list of file metadata in the bucket or paginated result
3853
- *
3854
- * @example
3855
- * ```typescript
3856
- * // Get metadata for all files in a bucket
3857
- * const fileMetadata = await sdk.buckets.getFileMetaData(123, 456);
3858
- *
3859
- * // Get file metadata with a specific prefix
3860
- * const fileMetadata = await sdk.buckets.getFileMetaData(123, 456, {
3861
- * prefix: '/folder1'
3862
- * });
3863
- *
3864
- * // First page with pagination
3865
- * const page1 = await sdk.buckets.getFileMetaData(123, 456, { pageSize: 10 });
3866
- *
3867
- * // Navigate using cursor
3868
- * if (page1.hasNextPage) {
3869
- * const page2 = await sdk.buckets.getFileMetaData(123, 456, { cursor: page1.nextCursor });
3870
- * }
3871
- * ```
4151
+ * Extract a readable case name from the packageId
4152
+ * @param packageId - The full package identifier
4153
+ * @returns A human-readable case name
4154
+ * @private
3872
4155
  */
3873
- async getFileMetaData(bucketId, folderId, options) {
3874
- if (!bucketId) {
3875
- throw new ValidationError({ message: 'bucketId is required for getFileMetaData' });
4156
+ extractCaseName(packageId) {
4157
+ // Check if packageId contains "CaseManagement."
4158
+ const caseManagementIndex = packageId.indexOf('CaseManagement.');
4159
+ if (caseManagementIndex !== -1) {
4160
+ // Extract everything after "CaseManagement."
4161
+ const afterCaseManagement = packageId.substring(caseManagementIndex + 'CaseManagement.'.length);
4162
+ // Replace hyphens with spaces for better readability
4163
+ return afterCaseManagement.replace(/-/g, ' ');
3876
4164
  }
3877
- if (!folderId) {
3878
- throw new ValidationError({ message: 'folderId is required for getFileMetaData' });
3879
- }
3880
- // Transformation function for blob items
3881
- const transformBlobItem = (item) => transformData(item, BucketMap);
3882
- return PaginationHelpers.getAll({
3883
- serviceAccess: this.createPaginationServiceAccess(),
3884
- getEndpoint: () => BUCKET_ENDPOINTS.GET_FILE_META_DATA(bucketId),
3885
- transformFn: transformBlobItem,
3886
- pagination: {
3887
- paginationType: PaginationType.TOKEN,
3888
- itemsField: BUCKET_PAGINATION.ITEMS_FIELD,
3889
- continuationTokenField: BUCKET_PAGINATION.CONTINUATION_TOKEN_FIELD,
3890
- paginationParams: {
3891
- pageSizeParam: BUCKET_TOKEN_PARAMS.PAGE_SIZE_PARAM,
3892
- tokenParam: BUCKET_TOKEN_PARAMS.TOKEN_PARAM
3893
- }
3894
- },
3895
- excludeFromPrefix: ['prefix'] // Bucket-specific param, not OData
3896
- }, { ...options, folderId });
4165
+ // If no "CaseManagement.", return the whole packageId
4166
+ return packageId;
3897
4167
  }
3898
- /**
3899
- * Uploads a file to a bucket
3900
- *
3901
- * @param options - Options for file upload including bucket ID, folder ID, path, content, and optional parameters
3902
- * @returns Promise resolving to a response with success status and HTTP status code
3903
- *
3904
- * @example
3905
- * ```typescript
3906
- * // Upload a file from browser
3907
- * const file = new File(['file content'], 'example.txt');
3908
- * const result = await sdk.buckets.uploadFile({
3909
- * bucketId: 123,
3910
- * folderId: 456,
3911
- * path: '/folder/example.txt',
3912
- * content: file
3913
- * });
3914
- *
3915
- * // In Node env with explicit content type
3916
- * const buffer = Buffer.from('file content');
3917
- * const result = await sdk.buckets.uploadFile({
3918
- * bucketId: 123,
3919
- * folderId: 456,
3920
- * path: '/folder/example.txt',
3921
- * content: buffer,
3922
- * contentType: 'text/plain'
3923
- * });
3924
- * ```
3925
- */
3926
- async uploadFile(options) {
3927
- const { bucketId, folderId, path, content, contentType } = options;
3928
- if (!bucketId) {
3929
- throw new ValidationError({ message: 'bucketId is required for uploadFile' });
3930
- }
3931
- if (!folderId) {
3932
- throw new ValidationError({ message: 'folderId is required for uploadFile' });
4168
+ }
4169
+ __decorate([
4170
+ track('Cases.GetAll')
4171
+ ], CasesService.prototype, "getAll", null);
4172
+
4173
+ /**
4174
+ * Maps fields for Case Instance entities to ensure consistent naming
4175
+ */
4176
+ const CaseInstanceMap = {
4177
+ startedTimeUtc: 'startedTime',
4178
+ completedTimeUtc: 'completedTime',
4179
+ expiryTimeUtc: 'expiredTime',
4180
+ createdAt: 'createdTime',
4181
+ updatedAt: 'updatedTime',
4182
+ externalId: 'caseId',
4183
+ };
4184
+ /**
4185
+ * Maps fields for Case App Config
4186
+ */
4187
+ const CaseAppConfigMap = {
4188
+ sections: 'overview',
4189
+ };
4190
+ /**
4191
+ * Maps fields for Stage SLA configuration
4192
+ */
4193
+ const StageSLAMap = {
4194
+ count: 'length',
4195
+ unit: 'duration',
4196
+ };
4197
+ /**
4198
+ * Maps UTC time fields to simpler field names
4199
+ * Used for transforming execution history responses
4200
+ */
4201
+ const TimeFieldTransformMap = {
4202
+ startedTimeUtc: 'startedTime',
4203
+ completedTimeUtc: 'completedTime',
4204
+ };
4205
+ /**
4206
+ * Constants for case instance stage processing
4207
+ */
4208
+ const CASE_STAGE_CONSTANTS = {
4209
+ TRIGGER_NODE_TYPE: 'case-management:Trigger',
4210
+ UNDEFINED_VALUE: 'Undefined',
4211
+ NOT_STARTED_STATUS: 'Not Started'
4212
+ };
4213
+ /**
4214
+ * Function to generate case instance task filter by case instance ID
4215
+ */
4216
+ const CASE_INSTANCE_TASK_FILTER = (caseInstanceId) => `Tags/any(tags:tags/DisplayName eq '${caseInstanceId}') and (IsDeleted eq false)`;
4217
+ /**
4218
+ * Default expand parameters for case instance tasks
4219
+ */
4220
+ const CASE_INSTANCE_TASK_EXPAND = 'AssignedToUser,Activities';
4221
+
4222
+ var TaskType;
4223
+ (function (TaskType) {
4224
+ TaskType["Form"] = "FormTask";
4225
+ TaskType["External"] = "ExternalTask";
4226
+ TaskType["App"] = "AppTask";
4227
+ })(TaskType || (TaskType = {}));
4228
+ var TaskPriority;
4229
+ (function (TaskPriority) {
4230
+ TaskPriority["Low"] = "Low";
4231
+ TaskPriority["Medium"] = "Medium";
4232
+ TaskPriority["High"] = "High";
4233
+ TaskPriority["Critical"] = "Critical";
4234
+ })(TaskPriority || (TaskPriority = {}));
4235
+ var TaskStatus;
4236
+ (function (TaskStatus) {
4237
+ TaskStatus["Unassigned"] = "Unassigned";
4238
+ TaskStatus["Pending"] = "Pending";
4239
+ TaskStatus["Completed"] = "Completed";
4240
+ })(TaskStatus || (TaskStatus = {}));
4241
+ var TaskSlaCriteria;
4242
+ (function (TaskSlaCriteria) {
4243
+ TaskSlaCriteria["TaskCreated"] = "TaskCreated";
4244
+ TaskSlaCriteria["TaskAssigned"] = "TaskAssigned";
4245
+ TaskSlaCriteria["TaskCompleted"] = "TaskCompleted";
4246
+ })(TaskSlaCriteria || (TaskSlaCriteria = {}));
4247
+ var TaskSlaStatus;
4248
+ (function (TaskSlaStatus) {
4249
+ TaskSlaStatus["OverdueLater"] = "OverdueLater";
4250
+ TaskSlaStatus["OverdueSoon"] = "OverdueSoon";
4251
+ TaskSlaStatus["Overdue"] = "Overdue";
4252
+ TaskSlaStatus["CompletedInTime"] = "CompletedInTime";
4253
+ })(TaskSlaStatus || (TaskSlaStatus = {}));
4254
+ var TaskSourceName;
4255
+ (function (TaskSourceName) {
4256
+ TaskSourceName["Agent"] = "Agent";
4257
+ TaskSourceName["Workflow"] = "Workflow";
4258
+ TaskSourceName["Maestro"] = "Maestro";
4259
+ TaskSourceName["Default"] = "Default";
4260
+ })(TaskSourceName || (TaskSourceName = {}));
4261
+ /**
4262
+ * Task activity types
4263
+ */
4264
+ var TaskActivityType;
4265
+ (function (TaskActivityType) {
4266
+ TaskActivityType["Created"] = "Created";
4267
+ TaskActivityType["Assigned"] = "Assigned";
4268
+ TaskActivityType["Reassigned"] = "Reassigned";
4269
+ TaskActivityType["Unassigned"] = "Unassigned";
4270
+ TaskActivityType["Saved"] = "Saved";
4271
+ TaskActivityType["Forwarded"] = "Forwarded";
4272
+ TaskActivityType["Completed"] = "Completed";
4273
+ TaskActivityType["Commented"] = "Commented";
4274
+ TaskActivityType["Deleted"] = "Deleted";
4275
+ TaskActivityType["BulkSaved"] = "BulkSaved";
4276
+ TaskActivityType["BulkCompleted"] = "BulkCompleted";
4277
+ TaskActivityType["FirstOpened"] = "FirstOpened";
4278
+ })(TaskActivityType || (TaskActivityType = {}));
4279
+
4280
+ /**
4281
+ * Creates methods for a task
4282
+ *
4283
+ * @param taskData - The task data (response from API)
4284
+ * @param service - The task service instance
4285
+ * @returns Object containing task methods
4286
+ */
4287
+ function createTaskMethods(taskData, service) {
4288
+ return {
4289
+ async assign(options) {
4290
+ if (!taskData.id)
4291
+ throw new Error('Task ID is undefined');
4292
+ const assignmentOptions = 'userId' in options && options.userId !== undefined
4293
+ ? { taskId: taskData.id, userId: options.userId }
4294
+ : { taskId: taskData.id, userNameOrEmail: options.userNameOrEmail };
4295
+ return service.assign(assignmentOptions);
4296
+ },
4297
+ async reassign(options) {
4298
+ if (!taskData.id)
4299
+ throw new Error('Task ID is undefined');
4300
+ const assignmentOptions = 'userId' in options && options.userId !== undefined
4301
+ ? { taskId: taskData.id, userId: options.userId }
4302
+ : { taskId: taskData.id, userNameOrEmail: options.userNameOrEmail };
4303
+ return service.reassign(assignmentOptions);
4304
+ },
4305
+ async unassign() {
4306
+ if (!taskData.id)
4307
+ throw new Error('Task ID is undefined');
4308
+ return service.unassign(taskData.id);
4309
+ },
4310
+ async complete(options) {
4311
+ if (!taskData.id)
4312
+ throw new Error('Task ID is undefined');
4313
+ const folderId = taskData.folderId;
4314
+ if (!folderId)
4315
+ throw new Error('Folder ID is required');
4316
+ return service.complete({
4317
+ type: options.type,
4318
+ taskId: taskData.id,
4319
+ data: options.data,
4320
+ action: options.action
4321
+ }, folderId);
3933
4322
  }
3934
- if (!path) {
3935
- throw new ValidationError({ message: 'path is required for uploadFile' });
4323
+ };
4324
+ }
4325
+ /**
4326
+ * Creates an actionable task by combining API task data with operational methods.
4327
+ *
4328
+ * @param taskData - The task data from API
4329
+ * @param service - The task service instance
4330
+ * @returns A task object with added methods
4331
+ */
4332
+ function createTaskWithMethods(taskData, service) {
4333
+ const methods = createTaskMethods(taskData, service);
4334
+ return Object.assign({}, taskData, methods);
4335
+ }
4336
+
4337
+ /**
4338
+ * Maps numeric TaskStatus values (from API) to TaskStatus enum values.
4339
+ * Extend this file with additional field mappings as needed.
4340
+ */
4341
+ const TaskStatusMap = {
4342
+ 0: TaskStatus.Unassigned,
4343
+ 1: TaskStatus.Pending,
4344
+ 2: TaskStatus.Completed,
4345
+ };
4346
+ // Field mapping for time-related fields to ensure consistent naming
4347
+ const TaskMap = {
4348
+ completionTime: 'completedTime',
4349
+ deletionTime: 'deletedTime',
4350
+ lastModificationTime: 'lastModifiedTime',
4351
+ creationTime: 'createdTime',
4352
+ organizationUnitId: 'folderId'
4353
+ };
4354
+ /**
4355
+ * Default expand parameters
4356
+ */
4357
+ const DEFAULT_TASK_EXPAND = 'AssignedToUser,CreatorUser,LastModifierUser';
4358
+
4359
+ /**
4360
+ * Service for interacting with UiPath Tasks API
4361
+ */
4362
+ class TaskService extends BaseService {
4363
+ /**
4364
+ * @hideconstructor
4365
+ */
4366
+ constructor(config, executionContext, tokenManager) {
4367
+ super(config, executionContext, tokenManager);
4368
+ /**
4369
+ * Process parameters for task queries with folder filtering
4370
+ * @param options - The REST API options to process
4371
+ * @param folderId - Optional folder ID to filter by
4372
+ * @returns Processed options with folder filtering applied if needed
4373
+ * @private
4374
+ */
4375
+ this.processTaskParameters = (options, folderId) => {
4376
+ // Add default expand parameters
4377
+ const processedOptions = this.addDefaultExpand(options);
4378
+ if (folderId) {
4379
+ // Create or add to existing filter for folder-specific queries
4380
+ if (processedOptions.filter) {
4381
+ processedOptions.filter = `${processedOptions.filter} and organizationUnitId eq ${folderId}`;
4382
+ }
4383
+ else {
4384
+ processedOptions.filter = `organizationUnitId eq ${folderId}`;
4385
+ }
4386
+ }
4387
+ return processedOptions;
4388
+ };
4389
+ }
4390
+ /**
4391
+ * Creates a new task
4392
+ * @param task - The task to be created
4393
+ * @param folderId - Required folder ID
4394
+ * @returns Promise resolving to the created task
4395
+ *
4396
+ * @example
4397
+ * ```typescript
4398
+ * const task = await sdk.tasks.create({
4399
+ * title: "My Task",
4400
+ * priority: TaskPriority.Medium,
4401
+ * data: { key: "value" }
4402
+ * }, 123); // folderId is required
4403
+ * ```
4404
+ */
4405
+ async create(task, folderId) {
4406
+ const headers = createHeaders({ [FOLDER_ID]: folderId });
4407
+ const externalTask = {
4408
+ ...task,
4409
+ type: TaskType.External //currently only external task is supported
4410
+ };
4411
+ const response = await this.post(TASK_ENDPOINTS.CREATE_GENERIC_TASK, externalTask, { headers });
4412
+ // Transform time fields for consistency
4413
+ const normalizedData = transformData(response.data, TaskMap);
4414
+ const transformedData = applyDataTransforms(normalizedData, { field: 'status', valueMap: TaskStatusMap });
4415
+ return createTaskWithMethods(transformedData, this);
4416
+ }
4417
+ /**
4418
+ * Gets users in the given folder who have Tasks.View and Tasks.Edit permissions
4419
+ *
4420
+ * The method returns either:
4421
+ * - An array of users (when no pagination parameters are provided)
4422
+ * - A paginated result with navigation cursors (when any pagination parameter is provided)
4423
+ *
4424
+ * @param folderId - The folder ID to get users from
4425
+ * @param options - Optional query and pagination parameters
4426
+ * @returns Promise resolving to an array of users or paginated result
4427
+ *
4428
+ * @example
4429
+ * ```typescript
4430
+ * // Standard array return
4431
+ * const users = await sdk.tasks.getUsers(123);
4432
+ *
4433
+ * // Get users with filtering
4434
+ * const users = await sdk.tasks.getUsers(123, {
4435
+ * filter: "name eq 'abc'"
4436
+ * });
4437
+ *
4438
+ * // First page with pagination
4439
+ * const page1 = await sdk.tasks.getUsers(123, { pageSize: 10 });
4440
+ *
4441
+ * // Navigate using cursor
4442
+ * if (page1.hasNextPage) {
4443
+ * const page2 = await sdk.tasks.getUsers(123, { cursor: page1.nextCursor });
4444
+ * }
4445
+ *
4446
+ * // Jump to specific page
4447
+ * const page5 = await sdk.tasks.getUsers(123, {
4448
+ * jumpToPage: 5,
4449
+ * pageSize: 10
4450
+ * });
4451
+ * ```
4452
+ */
4453
+ async getUsers(folderId, options) {
4454
+ // Transformation function for users
4455
+ const transformUserResponse = (user) => pascalToCamelCaseKeys(user);
4456
+ // Add folderId to options so the centralized helper can handle it properly
4457
+ const optionsWithFolder = { ...options, folderId };
4458
+ return PaginationHelpers.getAll({
4459
+ serviceAccess: this.createPaginationServiceAccess(),
4460
+ getEndpoint: (folderId) => TASK_ENDPOINTS.GET_TASK_USERS(folderId), // Use folderId from centralized helper
4461
+ getByFolderEndpoint: TASK_ENDPOINTS.GET_TASK_USERS(folderId), // Use the passed folderId
4462
+ transformFn: transformUserResponse,
4463
+ pagination: {
4464
+ paginationType: PaginationType.OFFSET,
4465
+ itemsField: ODATA_PAGINATION.ITEMS_FIELD,
4466
+ totalCountField: ODATA_PAGINATION.TOTAL_COUNT_FIELD,
4467
+ paginationParams: {
4468
+ pageSizeParam: ODATA_OFFSET_PARAMS.PAGE_SIZE_PARAM,
4469
+ offsetParam: ODATA_OFFSET_PARAMS.OFFSET_PARAM,
4470
+ countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM
4471
+ }
4472
+ }
4473
+ }, optionsWithFolder);
4474
+ }
4475
+ /**
4476
+ * Gets tasks across folders with optional filtering and folder scoping
4477
+ *
4478
+ * The method returns either:
4479
+ * - An array of tasks (when no pagination parameters are provided)
4480
+ * - A paginated result with navigation cursors (when any pagination parameter is provided)
4481
+ *
4482
+ * @param options - Query options including optional folderId and pagination options
4483
+ * @returns Promise resolving to an array of tasks or paginated result
4484
+ *
4485
+ * @example
4486
+ * ```typescript
4487
+ * // Standard array return
4488
+ * const tasks = await sdk.tasks.getAll();
4489
+ *
4490
+ * // Get tasks within a specific folder
4491
+ * const tasks = await sdk.tasks.getAll({
4492
+ * folderId: 123
4493
+ * });
4494
+ *
4495
+ * // First page with pagination
4496
+ * const page1 = await sdk.tasks.getAll({ pageSize: 10 });
4497
+ *
4498
+ * // Navigate using cursor
4499
+ * if (page1.hasNextPage) {
4500
+ * const page2 = await sdk.tasks.getAll({ cursor: page1.nextCursor });
4501
+ * }
4502
+ *
4503
+ * // Jump to specific page
4504
+ * const page5 = await sdk.tasks.getAll({
4505
+ * jumpToPage: 5,
4506
+ * pageSize: 10
4507
+ * });
4508
+ * ```
4509
+ */
4510
+ async getAll(options) {
4511
+ // Transformation function for tasks
4512
+ const transformTaskResponse = (task) => {
4513
+ const transformedTask = transformData(pascalToCamelCaseKeys(task), TaskMap);
4514
+ return createTaskWithMethods(applyDataTransforms(transformedTask, { field: 'status', valueMap: TaskStatusMap }), this);
4515
+ };
4516
+ return PaginationHelpers.getAll({
4517
+ serviceAccess: this.createPaginationServiceAccess(),
4518
+ getEndpoint: () => TASK_ENDPOINTS.GET_TASKS_ACROSS_FOLDERS,
4519
+ transformFn: transformTaskResponse,
4520
+ processParametersFn: this.processTaskParameters,
4521
+ excludeFromPrefix: ['event'], // Exclude 'event' key from ODATA prefix transformation
4522
+ pagination: {
4523
+ paginationType: PaginationType.OFFSET,
4524
+ itemsField: ODATA_PAGINATION.ITEMS_FIELD,
4525
+ totalCountField: ODATA_PAGINATION.TOTAL_COUNT_FIELD,
4526
+ paginationParams: {
4527
+ pageSizeParam: ODATA_OFFSET_PARAMS.PAGE_SIZE_PARAM, // OData OFFSET parameter
4528
+ offsetParam: ODATA_OFFSET_PARAMS.OFFSET_PARAM, // OData OFFSET parameter
4529
+ countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM // OData OFFSET parameter
4530
+ }
4531
+ }
4532
+ }, options);
4533
+ }
4534
+ /**
4535
+ * Gets a task by ID
4536
+ * IMPORTANT: For form tasks, folderId must be provided.
4537
+ *
4538
+ * @param id - The ID of the task to retrieve
4539
+ * @param options - Optional query parameters
4540
+ * @param folderId - Optional folder ID (REQUIRED for form tasks)
4541
+ * @returns Promise resolving to the task (form tasks will return form-specific data)
4542
+ *
4543
+ * @example
4544
+ * ```typescript
4545
+ * // Get task by ID
4546
+ * const task = await sdk.tasks.getById(123);
4547
+ *
4548
+ * // If the task is a form task, it will automatically return form-specific data
4549
+ * ```
4550
+ */
4551
+ async getById(id, options = {}, folderId) {
4552
+ const headers = createHeaders({ [FOLDER_ID]: folderId });
4553
+ // Add default expand parameters
4554
+ const modifiedOptions = this.addDefaultExpand(options);
4555
+ // prefix all keys in options
4556
+ const keysToPrefix = Object.keys(modifiedOptions);
4557
+ const apiOptions = addPrefixToKeys(modifiedOptions, ODATA_PREFIX, keysToPrefix);
4558
+ const response = await this.get(TASK_ENDPOINTS.GET_BY_ID(id), {
4559
+ params: apiOptions,
4560
+ headers
4561
+ });
4562
+ // Transform response from PascalCase to camelCase and normalize time fields
4563
+ const transformedTask = transformData(pascalToCamelCaseKeys(response.data), TaskMap);
4564
+ // Check if this is a form task and get form-specific data if it is
4565
+ if (transformedTask.type === TaskType.Form) {
4566
+ const formOptions = { expandOnFormLayout: true };
4567
+ return this.getFormTaskById(id, folderId || transformedTask.folderId, formOptions);
3936
4568
  }
3937
- if (!content) {
3938
- throw new ValidationError({ message: 'content is required for uploadFile' });
4569
+ return createTaskWithMethods(applyDataTransforms(transformedTask, { field: 'status', valueMap: TaskStatusMap }), this);
4570
+ }
4571
+ /**
4572
+ * Assigns tasks to users
4573
+ *
4574
+ * @param taskAssignments - Single task assignment or array of task assignments
4575
+ * @returns Promise resolving to array of task assignment results
4576
+ *
4577
+ * @example
4578
+ * ```typescript
4579
+ * // Assign a single task to a user by ID
4580
+ * const result = await sdk.tasks.assign({
4581
+ * taskId: 123,
4582
+ * userId: 456
4583
+ * });
4584
+ *
4585
+ * // Assign a single task to a user by email
4586
+ * const result = await sdk.tasks.assign({
4587
+ * taskId: 123,
4588
+ * userNameOrEmail: "user@example.com"
4589
+ * });
4590
+ *
4591
+ * // Assign multiple tasks
4592
+ * const result = await sdk.tasks.assign([
4593
+ * {
4594
+ * taskId: 123,
4595
+ * userId: 456
4596
+ * },
4597
+ * {
4598
+ * taskId: 789,
4599
+ * userNameOrEmail: "user@example.com"
4600
+ * }
4601
+ * ]);
4602
+ * ```
4603
+ */
4604
+ async assign(taskAssignments) {
4605
+ // Normalize input to array
4606
+ const assignmentArray = Array.isArray(taskAssignments) ? taskAssignments : [taskAssignments];
4607
+ const options = {
4608
+ taskAssignments: assignmentArray
4609
+ };
4610
+ // Convert options to PascalCase for API
4611
+ const pascalOptions = camelToPascalCaseKeys(options);
4612
+ const response = await this.post(TASK_ENDPOINTS.ASSIGN_TASKS, pascalOptions);
4613
+ // Transform response from PascalCase to camelCase
4614
+ const transformedResponse = pascalToCamelCaseKeys(response.data);
4615
+ // Process OData array response - empty array = success, non-empty = error
4616
+ return processODataArrayResponse(transformedResponse, assignmentArray);
4617
+ }
4618
+ /**
4619
+ * Reassigns tasks to new users
4620
+ *
4621
+ * @param taskAssignments - Single task assignment or array of task assignments
4622
+ * @returns Promise resolving to array of task assignment results
4623
+ *
4624
+ * @example
4625
+ * ```typescript
4626
+ * // Reassign a single task to a user by ID
4627
+ * const result = await sdk.tasks.reassign({
4628
+ * taskId: 123,
4629
+ * userId: 456
4630
+ * });
4631
+ *
4632
+ * // Reassign a single task to a user by email
4633
+ * const result = await sdk.tasks.reassign({
4634
+ * taskId: 123,
4635
+ * userNameOrEmail: "user@example.com"
4636
+ * });
4637
+ *
4638
+ * // Reassign multiple tasks
4639
+ * const result = await sdk.tasks.reassign([
4640
+ * {
4641
+ * taskId: 123,
4642
+ * userId: 456
4643
+ * },
4644
+ * {
4645
+ * taskId: 789,
4646
+ * userNameOrEmail: "user@example.com"
4647
+ * }
4648
+ * ]);
4649
+ * ```
4650
+ */
4651
+ async reassign(taskAssignments) {
4652
+ // Normalize input to array
4653
+ const assignmentArray = Array.isArray(taskAssignments) ? taskAssignments : [taskAssignments];
4654
+ const options = {
4655
+ taskAssignments: assignmentArray
4656
+ };
4657
+ // Convert options to PascalCase for API
4658
+ const pascalOptions = camelToPascalCaseKeys(options);
4659
+ const response = await this.post(TASK_ENDPOINTS.REASSIGN_TASKS, pascalOptions);
4660
+ // Transform response from PascalCase to camelCase
4661
+ const transformedResponse = pascalToCamelCaseKeys(response.data);
4662
+ // Process OData array response - empty array = success, non-empty = error
4663
+ return processODataArrayResponse(transformedResponse, assignmentArray);
4664
+ }
4665
+ /**
4666
+ * Unassigns tasks (removes current assignees)
4667
+ *
4668
+ * @param taskIds - Single task ID or array of task IDs to unassign
4669
+ * @returns Promise resolving to array of task assignment results
4670
+ *
4671
+ * @example
4672
+ * ```typescript
4673
+ * // Unassign a single task
4674
+ * const result = await sdk.tasks.unassign(123);
4675
+ *
4676
+ * // Unassign multiple tasks
4677
+ * const result = await sdk.tasks.unassign([123, 456, 789]);
4678
+ * ```
4679
+ */
4680
+ async unassign(taskIds) {
4681
+ // Normalize input to array
4682
+ const taskIdArray = Array.isArray(taskIds) ? taskIds : [taskIds];
4683
+ const options = {
4684
+ taskIds: taskIdArray
4685
+ };
4686
+ const response = await this.post(TASK_ENDPOINTS.UNASSIGN_TASKS, options);
4687
+ // Transform response from PascalCase to camelCase
4688
+ const transformedResponse = pascalToCamelCaseKeys(response.data);
4689
+ // Process OData array response - empty array = success, non-empty = error
4690
+ // Return the task IDs that were unassigned
4691
+ return processODataArrayResponse(transformedResponse, taskIdArray.map(id => ({ taskId: id })));
4692
+ }
4693
+ /**
4694
+ * Completes a task with the specified type and data
4695
+ *
4696
+ * @param options - The completion options including task type, taskId, data, and action
4697
+ * @param folderId - Required folder ID
4698
+ * @returns Promise resolving to completion result
4699
+ *
4700
+ * @example
4701
+ * ```typescript
4702
+ * // Complete an app task
4703
+ * await sdk.tasks.complete({
4704
+ * type: TaskType.App,
4705
+ * taskId: 456,
4706
+ * data: {},
4707
+ * action: "submit"
4708
+ * }, 123); // folderId is required
4709
+ *
4710
+ * // Complete an external task
4711
+ * await sdk.tasks.complete({
4712
+ * type: TaskType.External,
4713
+ * taskId: 789
4714
+ * }, 123); // folderId is required
4715
+ * ```
4716
+ */
4717
+ async complete(options, folderId) {
4718
+ const headers = createHeaders({ [FOLDER_ID]: folderId });
4719
+ let endpoint;
4720
+ switch (options.type) {
4721
+ case TaskType.Form:
4722
+ endpoint = TASK_ENDPOINTS.COMPLETE_FORM_TASK;
4723
+ break;
4724
+ case TaskType.App:
4725
+ endpoint = TASK_ENDPOINTS.COMPLETE_APP_TASK;
4726
+ break;
4727
+ default:
4728
+ endpoint = TASK_ENDPOINTS.COMPLETE_GENERIC_TASK;
4729
+ break;
3939
4730
  }
3940
- try {
3941
- // Get write URI for upload with detected content type if not provided
3942
- let detectedContentType = contentType;
3943
- if (!detectedContentType) {
3944
- detectedContentType = await this._determineContentType(content, path);
3945
- }
3946
- const uriResponse = await this._getWriteUri({
3947
- bucketId,
3948
- folderId,
3949
- path,
3950
- contentType: detectedContentType
3951
- });
3952
- // Upload file to the provided URI
3953
- const response = await this._uploadToUri(uriResponse, content, detectedContentType);
4731
+ // CompleteAppTask returns 204 no content
4732
+ await this.post(endpoint, options, { headers });
4733
+ // Return success with the request context data
4734
+ return {
4735
+ success: true,
4736
+ data: options
4737
+ };
4738
+ }
4739
+ /**
4740
+ * Gets a form task by ID (private method)
4741
+ *
4742
+ * @param id - The ID of the form task to retrieve
4743
+ * @param folderId - Required folder ID
4744
+ * @param options - Optional query parameters
4745
+ * @returns Promise resolving to the form task
4746
+ */
4747
+ async getFormTaskById(id, folderId, options = {}) {
4748
+ const headers = createHeaders({ [FOLDER_ID]: folderId });
4749
+ const response = await this.get(TASK_ENDPOINTS.GET_TASK_FORM_BY_ID, {
4750
+ params: {
4751
+ taskId: id,
4752
+ ...options
4753
+ },
4754
+ headers
4755
+ });
4756
+ const transformedFormTask = transformData(response.data, TaskMap);
4757
+ return createTaskWithMethods(applyDataTransforms(transformedFormTask, { field: 'status', valueMap: TaskStatusMap }), this);
4758
+ }
4759
+ /**
4760
+ * Adds default expand parameters to options
4761
+ * @param options - The options object to add default expand to
4762
+ * @returns Options with default expand parameters added
4763
+ * @private
4764
+ */
4765
+ addDefaultExpand(options) {
4766
+ const processedOptions = { ...options };
4767
+ processedOptions.expand = processedOptions.expand
4768
+ ? `${DEFAULT_TASK_EXPAND},${processedOptions.expand}`
4769
+ : DEFAULT_TASK_EXPAND;
4770
+ return processedOptions;
4771
+ }
4772
+ }
4773
+ __decorate([
4774
+ track('Tasks.Create')
4775
+ ], TaskService.prototype, "create", null);
4776
+ __decorate([
4777
+ track('Tasks.GetUsers')
4778
+ ], TaskService.prototype, "getUsers", null);
4779
+ __decorate([
4780
+ track('Tasks.GetAll')
4781
+ ], TaskService.prototype, "getAll", null);
4782
+ __decorate([
4783
+ track('Tasks.GetById')
4784
+ ], TaskService.prototype, "getById", null);
4785
+ __decorate([
4786
+ track('Tasks.Assign')
4787
+ ], TaskService.prototype, "assign", null);
4788
+ __decorate([
4789
+ track('Tasks.Reassign')
4790
+ ], TaskService.prototype, "reassign", null);
4791
+ __decorate([
4792
+ track('Tasks.Unassign')
4793
+ ], TaskService.prototype, "unassign", null);
4794
+ __decorate([
4795
+ track('Tasks.Complete')
4796
+ ], TaskService.prototype, "complete", null);
4797
+
4798
+ class CaseInstancesService extends BaseService {
4799
+ /**
4800
+ * @hideconstructor
4801
+ */
4802
+ constructor(config, executionContext, tokenManager) {
4803
+ super(config, executionContext, tokenManager);
4804
+ this.taskService = new TaskService(config, executionContext, tokenManager);
4805
+ }
4806
+ /**
4807
+ * Get all case instances with optional filtering and pagination
4808
+ *
4809
+ * The method returns either:
4810
+ * - A NonPaginatedResponse with items array (when no pagination parameters are provided)
4811
+ * - A PaginatedResponse with navigation cursors (when any pagination parameter is provided)
4812
+ *
4813
+ * @param options -Query parameters for filtering instances and pagination
4814
+ * @returns Promise resolving to case instances or paginated result
4815
+ *
4816
+ * @example
4817
+ * ```typescript
4818
+ * // Get all case instances (non-paginated)
4819
+ * const instances = await sdk.maestro.cases.instances.getAll();
4820
+ *
4821
+ * // Close faulted instances using methods directly on instances
4822
+ * for (const instance of instances.items) {
4823
+ * if (instance.latestRunStatus === 'Faulted') {
4824
+ * await instance.close({ comment: 'Closing faulted case instance' });
4825
+ * }
4826
+ * }
4827
+ *
4828
+ * // With filtering
4829
+ * const instances = await sdk.maestro.cases.instances.getAll({
4830
+ * processKey: 'MyCaseProcess'
4831
+ * });
4832
+ *
4833
+ * // First page with pagination
4834
+ * const page1 = await sdk.maestro.cases.instances.getAll({ pageSize: 10 });
4835
+ *
4836
+ * // Navigate using cursor
4837
+ * if (page1.hasNextPage) {
4838
+ * const page2 = await sdk.maestro.cases.instances.getAll({ cursor: page1.nextCursor });
4839
+ * }
4840
+ * ```
4841
+ */
4842
+ async getAll(options) {
4843
+ // Add processType filter to only get case management instances
4844
+ const enhancedOptions = {
4845
+ ...options,
4846
+ processType: ProcessType.CaseManagement
4847
+ };
4848
+ // Base transformation function for case instances (synchronous)
4849
+ const transformCaseInstance = (item) => {
4850
+ const rawInstance = transformData(item, CaseInstanceMap);
4851
+ return createCaseInstanceWithMethods(rawInstance, this);
4852
+ };
4853
+ // Get the paginated result with basic transformation
4854
+ const result = await PaginationHelpers.getAll({
4855
+ serviceAccess: this.createPaginationServiceAccess(),
4856
+ getEndpoint: () => MAESTRO_ENDPOINTS.INSTANCES.GET_ALL,
4857
+ transformFn: transformCaseInstance,
4858
+ pagination: {
4859
+ paginationType: PaginationType.TOKEN,
4860
+ itemsField: PROCESS_INSTANCE_PAGINATION.ITEMS_FIELD,
4861
+ continuationTokenField: PROCESS_INSTANCE_PAGINATION.CONTINUATION_TOKEN_FIELD,
4862
+ paginationParams: {
4863
+ pageSizeParam: PROCESS_INSTANCE_TOKEN_PARAMS.PAGE_SIZE_PARAM,
4864
+ tokenParam: PROCESS_INSTANCE_TOKEN_PARAMS.TOKEN_PARAM
4865
+ }
4866
+ },
4867
+ excludeFromPrefix: Object.keys(enhancedOptions || {})
4868
+ }, enhancedOptions);
4869
+ // Enhance instances with case JSON data if requested
4870
+ if (result.items && result.items.length > 0) {
4871
+ const enhancedItems = await this.enhanceInstancesWithCaseJson(result.items);
3954
4872
  return {
3955
- success: response.status >= 200 && response.status < 300,
3956
- statusCode: response.status
4873
+ ...result,
4874
+ items: enhancedItems
3957
4875
  };
3958
4876
  }
3959
- catch (error) {
3960
- throw error;
3961
- }
4877
+ return result;
3962
4878
  }
3963
4879
  /**
3964
- * Determines the content type of the file based on the content and path
3965
- * Uses a hybrid approach:
3966
- * 1. Checks Blob/File type if available (browser)
3967
- * 2. Uses content-based detection with file-type (primarily Node.js)
3968
- * 3. Falls back to extension-based detection with mime-types
3969
- * 4. Finally defaults to application/octet-stream
3970
- *
3971
- * @param content - The file content
3972
- * @param path - The file path
3973
- * @returns The determined content type or default
4880
+ * Get a case instance by ID with operation methods (close, pause, resume)
4881
+ * @param instanceId - The ID of the instance to retrieve
4882
+ * @param folderKey - Required folder key
4883
+ * @returns Promise<CaseInstanceGetResponse>
4884
+ */
4885
+ async getById(instanceId, folderKey) {
4886
+ const response = await this.get(MAESTRO_ENDPOINTS.INSTANCES.GET_BY_ID(instanceId), {
4887
+ headers: createHeaders({ [FOLDER_KEY]: folderKey })
4888
+ });
4889
+ const transformedInstance = transformData(response.data, CaseInstanceMap);
4890
+ const instanceWithMethods = createCaseInstanceWithMethods(transformedInstance, this);
4891
+ // Enhance with case JSON data
4892
+ return this.enhanceInstanceWithCaseJson(instanceWithMethods);
4893
+ }
4894
+ /**
4895
+ * Enhance a single case instance with case JSON data
4896
+ * @param instance - The case instance to enhance
4897
+ * @returns Promise resolving to enhanced instance
4898
+ * @private
3974
4899
  */
3975
- async _determineContentType(content, path) {
3976
- // 1. If content is a File or Blob with type, use that (works in browser)
3977
- if ('type' in content && content.type) {
3978
- return content.type;
4900
+ async enhanceInstanceWithCaseJson(instance) {
4901
+ if (!instance.folderKey) {
4902
+ return instance;
3979
4903
  }
3980
- // 2. Try content-based detection (primarily for Node.js)
3981
- if (content instanceof Buffer && fileTypeFromBuffer) {
3982
- try {
3983
- const fileTypeResult = await fileTypeFromBuffer(content);
3984
- if (fileTypeResult?.mime) {
3985
- return fileTypeResult.mime;
3986
- }
3987
- }
3988
- catch (error) {
3989
- // Silently continue to next detection method if this fails
3990
- console.debug('Content-based type detection failed:', error);
4904
+ try {
4905
+ const caseJson = await this.getCaseJson(instance.instanceId, instance.folderKey);
4906
+ if (caseJson && caseJson.root) {
4907
+ // Transform caseAppConfig
4908
+ const transformedCaseAppConfig = caseJson.root.caseAppConfig ? (() => {
4909
+ const transformed = transformData(caseJson.root.caseAppConfig, CaseAppConfigMap);
4910
+ // Remove id field from each overview item
4911
+ if (transformed.overview) {
4912
+ transformed.overview = transformed.overview.map(({ id, ...rest }) => rest);
4913
+ }
4914
+ return transformed;
4915
+ })() : undefined;
4916
+ return {
4917
+ ...instance,
4918
+ ...(transformedCaseAppConfig && { caseAppConfig: transformedCaseAppConfig }),
4919
+ ...(caseJson.root.name && { caseType: caseJson.root.name }),
4920
+ ...(caseJson.root.description && { caseTitle: caseJson.root.description })
4921
+ };
3991
4922
  }
3992
4923
  }
3993
- // 3. Try to infer from file extension using mime-types library
3994
- const mimeType = mimeTypes.lookup(path);
3995
- if (mimeType) {
3996
- return mimeType;
4924
+ catch (error) {
4925
+ console.debug(`Failed to fetch case JSON for instance ${instance.instanceId}:`, error);
3997
4926
  }
3998
- // 4. Final fallback
3999
- return CONTENT_TYPES.OCTET_STREAM;
4927
+ return instance;
4000
4928
  }
4001
4929
  /**
4002
- * Uploads content to the provided URI
4003
- * @param uriResponse - Response from getWriteUri containing URL and headers
4004
- * @param content - The content to upload
4005
- * @param contentType - The content type of the file
4006
- * @returns The response from the upload request with status info
4930
+ * Enhance multiple case instances with case JSON data
4931
+ * @param instances - Array of case instances to enhance
4932
+ * @returns Promise resolving to array of enhanced instances
4933
+ * @private
4007
4934
  */
4008
- async _uploadToUri(uriResponse, content, contentType) {
4009
- const { uri, headers = {}, requiresAuth } = uriResponse;
4010
- if (!uri) {
4011
- throw new ValidationError({ message: 'Upload URI not available', statusCode: HttpStatus.BAD_REQUEST });
4935
+ async enhanceInstancesWithCaseJson(instances) {
4936
+ return Promise.all(instances.map(instance => this.enhanceInstanceWithCaseJson(instance)));
4937
+ }
4938
+ /**
4939
+ * Get case JSON for a specific instance
4940
+ * @param instanceId - The case instance ID
4941
+ * @param folderKey - Required folder key
4942
+ * @returns Promise resolving to case JSON data
4943
+ * @private
4944
+ */
4945
+ async getCaseJson(instanceId, folderKey) {
4946
+ try {
4947
+ const response = await this.get(MAESTRO_ENDPOINTS.CASES.GET_CASE_JSON(instanceId), {
4948
+ headers: createHeaders({ [FOLDER_KEY]: folderKey })
4949
+ });
4950
+ return response.data;
4012
4951
  }
4013
- // Create headers for the request
4014
- let requestHeaders = { ...headers };
4015
- // Ensure content-type is set if provided
4016
- if (contentType && !requestHeaders['content-type']) {
4017
- requestHeaders['content-type'] = contentType;
4952
+ catch (error) {
4953
+ // Return null if the case JSON is not available
4954
+ return null;
4018
4955
  }
4019
- // Add auth header if required
4020
- if (requiresAuth) {
4021
- try {
4022
- const tokenInfo = this.executionContext.get('tokenInfo');
4023
- if (!tokenInfo) {
4024
- throw new AuthenticationError({ message: 'No authentication token available. Make sure to initialize the SDK first.' });
4025
- }
4026
- let token;
4027
- // For secret-based tokens, they never expire so use directly
4028
- if (tokenInfo.type === 'secret') {
4029
- token = tokenInfo.token;
4030
- }
4031
- // For non-secret tokens, check expiration and refresh if needed
4032
- else if (!this.tokenManager.isTokenExpired(tokenInfo)) {
4033
- token = tokenInfo.token;
4034
- }
4035
- else {
4036
- const newToken = await this.tokenManager.refreshAccessToken();
4037
- token = newToken.access_token;
4956
+ }
4957
+ /**
4958
+ * Close a case instance
4959
+ * @param instanceId - The ID of the instance to cancel
4960
+ * @param folderKey - Required folder key
4961
+ * @param options - Optional cancellation options with comment
4962
+ * @returns Promise resolving to operation result with updated instance data
4963
+ */
4964
+ async close(instanceId, folderKey, options) {
4965
+ const response = await this.post(MAESTRO_ENDPOINTS.INSTANCES.CANCEL(instanceId), options || {}, {
4966
+ headers: createHeaders({ [FOLDER_KEY]: folderKey })
4967
+ });
4968
+ return {
4969
+ success: true,
4970
+ data: response.data
4971
+ };
4972
+ }
4973
+ /**
4974
+ * Pause a case instance
4975
+ * @param instanceId - The ID of the instance to pause
4976
+ * @param folderKey - Required folder key
4977
+ * @param options - Optional pause options with comment
4978
+ * @returns Promise resolving to operation result with updated instance data
4979
+ */
4980
+ async pause(instanceId, folderKey, options) {
4981
+ const response = await this.post(MAESTRO_ENDPOINTS.INSTANCES.PAUSE(instanceId), options || {}, {
4982
+ headers: createHeaders({ [FOLDER_KEY]: folderKey })
4983
+ });
4984
+ return {
4985
+ success: true,
4986
+ data: response.data
4987
+ };
4988
+ }
4989
+ /**
4990
+ * Resume a case instance
4991
+ * @param instanceId - The ID of the instance to resume
4992
+ * @param folderKey - Required folder key
4993
+ * @param options - Optional resume options with comment
4994
+ * @returns Promise resolving to operation result with updated instance data
4995
+ */
4996
+ async resume(instanceId, folderKey, options) {
4997
+ const response = await this.post(MAESTRO_ENDPOINTS.INSTANCES.RESUME(instanceId), options || {}, {
4998
+ headers: createHeaders({ [FOLDER_KEY]: folderKey })
4999
+ });
5000
+ return {
5001
+ success: true,
5002
+ data: response.data
5003
+ };
5004
+ }
5005
+ /**
5006
+ * Get execution history for a case instance
5007
+ * @param instanceId - The ID of the case instance
5008
+ * @param folderKey - Required folder key
5009
+ * @returns Promise resolving to instance execution history
5010
+ * @example
5011
+ * ```typescript
5012
+ * // Get execution history for a case instance
5013
+ * const history = await sdk.maestro.cases.instances.getExecutionHistory(
5014
+ * 'instance-id',
5015
+ * 'folder-key'
5016
+ * );
5017
+ * ```
5018
+ */
5019
+ async getExecutionHistory(instanceId, folderKey) {
5020
+ const response = await this.get(MAESTRO_ENDPOINTS.CASES.GET_ELEMENT_EXECUTIONS(instanceId), {
5021
+ headers: createHeaders({ [FOLDER_KEY]: folderKey })
5022
+ });
5023
+ // Transform the main response
5024
+ const transformedResponse = transformData(response.data, TimeFieldTransformMap);
5025
+ // Transform each element execution and its nested element runs
5026
+ if (transformedResponse.elementExecutions && Array.isArray(transformedResponse.elementExecutions)) {
5027
+ transformedResponse.elementExecutions = transformedResponse.elementExecutions.map((execution) => {
5028
+ // Transform the element execution itself
5029
+ const transformedExecution = transformData(execution, TimeFieldTransformMap);
5030
+ // Transform nested element runs if they exist
5031
+ if (transformedExecution.elementRuns && Array.isArray(transformedExecution.elementRuns)) {
5032
+ transformedExecution.elementRuns = transformedExecution.elementRuns.map((run) => transformData(run, TimeFieldTransformMap));
4038
5033
  }
4039
- requestHeaders['Authorization'] = `Bearer ${token}`;
4040
- }
4041
- catch (error) {
4042
- throw new AuthenticationError({
4043
- message: `Authentication required but failed: ${error instanceof Error ? error.message : ''}`,
4044
- statusCode: HttpStatus.UNAUTHORIZED
4045
- });
5034
+ return transformedExecution;
5035
+ });
5036
+ }
5037
+ return transformedResponse;
5038
+ }
5039
+ /**
5040
+ * Get case stages with their associated tasks and execution status
5041
+ * @param caseInstanceId - The ID of the case instance
5042
+ * @param folderKey - Required folder key
5043
+ * @returns Promise resolving to an array of case stages, each containing their tasks with execution details
5044
+ */
5045
+ async getStages(caseInstanceId, folderKey) {
5046
+ // Fetch both execution history and case JSON in parallel, but handle execution failures gracefully
5047
+ const [executionHistoryResponse, caseJsonResponse] = await Promise.allSettled([
5048
+ this.getExecutionHistory(caseInstanceId, folderKey),
5049
+ this.getCaseJson(caseInstanceId, folderKey)
5050
+ ]);
5051
+ // Extract execution history if successful, otherwise use null
5052
+ const executionHistory = executionHistoryResponse.status === 'fulfilled'
5053
+ ? executionHistoryResponse.value
5054
+ : null;
5055
+ // Extract case JSON - the null check below will handle failures
5056
+ const caseJson = caseJsonResponse.status === 'fulfilled'
5057
+ ? caseJsonResponse.value
5058
+ : null;
5059
+ if (!caseJson || !caseJson.nodes) {
5060
+ return [];
5061
+ }
5062
+ // Create lookup maps for efficient data access
5063
+ const executionMap = this.createExecutionMap(executionHistory);
5064
+ const bindingsMap = this.createBindingsMap(caseJson);
5065
+ // Process nodes to extract stages (exclude triggers)
5066
+ const stages = caseJson.nodes
5067
+ .filter((node) => node.type !== CASE_STAGE_CONSTANTS.TRIGGER_NODE_TYPE)
5068
+ .map((node) => this.createStageFromNode(node, executionMap, bindingsMap));
5069
+ return stages;
5070
+ }
5071
+ /**
5072
+ * Create a map of element ID to execution data
5073
+ * @param executionHistory - The execution history response
5074
+ * @returns Map of elementId to execution metadata
5075
+ * @private
5076
+ */
5077
+ createExecutionMap(executionHistory) {
5078
+ const executionMap = new Map();
5079
+ if (executionHistory?.elementExecutions) {
5080
+ for (const execution of executionHistory.elementExecutions) {
5081
+ executionMap.set(execution.elementId, execution);
4046
5082
  }
4047
5083
  }
4048
- return axios.put(uri, content, {
4049
- headers: createHeaders(requestHeaders)
4050
- });
5084
+ return executionMap;
4051
5085
  }
4052
5086
  /**
4053
- * Private method to handle common URI request logic
4054
- * @param endpoint - The API endpoint to call
4055
- * @param bucketId - The bucket ID
4056
- * @param folderId - The folder ID
4057
- * @param path - The file path
4058
- * @param queryOptions - Additional query parameters
4059
- * @returns Promise resolving to blob file access information
5087
+ * Create a map of binding IDs to their values
5088
+ * @param caseJsonResponse - The case JSON response
5089
+ * @returns Map of binding ID to binding object
5090
+ * @private
4060
5091
  */
4061
- async _getUri(endpoint, bucketId, folderId, path, queryOptions = {}) {
4062
- if (!bucketId) {
4063
- throw new ValidationError({ message: 'bucketId is required for getUri' });
5092
+ createBindingsMap(caseJsonResponse) {
5093
+ const bindingsMap = new Map();
5094
+ if (caseJsonResponse?.root?.data?.uipath?.bindings) {
5095
+ for (const binding of caseJsonResponse.root.data.uipath.bindings) {
5096
+ if (binding.id) {
5097
+ bindingsMap.set(binding.id, binding);
5098
+ }
5099
+ }
4064
5100
  }
4065
- if (!folderId) {
4066
- throw new ValidationError({ message: 'folderId is required for getUri' });
5101
+ return bindingsMap;
5102
+ }
5103
+ /**
5104
+ * Resolve binding values from binding expressions
5105
+ * @param value - The value that may contain binding references
5106
+ * @param bindingsMap - Map of binding IDs to binding objects
5107
+ * @returns Resolved value
5108
+ * @private
5109
+ */
5110
+ resolveBinding(value, bindingsMap) {
5111
+ if (typeof value === 'string' && value.startsWith('=bindings.')) {
5112
+ const bindingId = value.substring('=bindings.'.length);
5113
+ const binding = bindingsMap.get(bindingId);
5114
+ return binding?.default || binding?.name || value;
4067
5115
  }
4068
- if (!path) {
4069
- throw new ValidationError({ message: 'path is required for getUri' });
5116
+ return value;
5117
+ }
5118
+ /**
5119
+ * Process tasks for a stage node
5120
+ * @param node - The stage node containing tasks
5121
+ * @param executionMap - Map of element IDs to execution data
5122
+ * @param bindingsMap - Map of binding IDs to binding objects
5123
+ * @returns Processed tasks array
5124
+ * @private
5125
+ */
5126
+ processTasks(node, executionMap, bindingsMap) {
5127
+ if (!node.data?.tasks || !Array.isArray(node.data.tasks)) {
5128
+ return [];
4070
5129
  }
4071
- // Create headers with required folder ID
4072
- const headers = createHeaders({ [FOLDER_ID]: folderId });
4073
- // Filter out undefined values and build query params
4074
- const queryParams = filterUndefined({
4075
- path,
4076
- ...queryOptions
4077
- });
4078
- // Make the API call to get URI
4079
- const response = await this.get(endpoint, {
4080
- params: queryParams,
4081
- headers
5130
+ return node.data.tasks.map((taskGroup) => {
5131
+ if (Array.isArray(taskGroup)) {
5132
+ return taskGroup.map((task) => {
5133
+ const taskId = task.id;
5134
+ // Find the execution data using the task's id
5135
+ const taskExecution = taskId ? executionMap.get(taskId) : undefined;
5136
+ // Resolve task name from bindings
5137
+ let taskName = task.displayName;
5138
+ if (!taskName && task.data?.name) {
5139
+ taskName = this.resolveBinding(task.data.name, bindingsMap);
5140
+ }
5141
+ const stageTask = {
5142
+ id: taskId || task.elementId || CASE_STAGE_CONSTANTS.UNDEFINED_VALUE,
5143
+ name: taskName || CASE_STAGE_CONSTANTS.UNDEFINED_VALUE,
5144
+ completedTime: taskExecution?.completedTime || CASE_STAGE_CONSTANTS.UNDEFINED_VALUE,
5145
+ startedTime: taskExecution?.startedTime || CASE_STAGE_CONSTANTS.UNDEFINED_VALUE,
5146
+ status: taskExecution?.status || CASE_STAGE_CONSTANTS.NOT_STARTED_STATUS,
5147
+ type: task.type || CASE_STAGE_CONSTANTS.UNDEFINED_VALUE
5148
+ };
5149
+ return stageTask;
5150
+ });
5151
+ }
5152
+ return [];
4082
5153
  });
4083
- const transformedData = transformData(pascalToCamelCaseKeys(response.data), BucketMap);
4084
- // Convert headers from array-based to record if needed
4085
- if (transformedData.headers && 'keys' in transformedData.headers && 'values' in transformedData.headers) {
4086
- transformedData.headers = arrayDictionaryToRecord(transformedData.headers);
4087
- }
4088
- return transformedData;
4089
5154
  }
4090
5155
  /**
4091
- * Gets a direct download URL for a file in the bucket
4092
- *
4093
- * @param options - Contains bucketId, folderId, file path and optional expiry time
4094
- * @returns Promise resolving to blob file access information
4095
- *
4096
- * @example
4097
- * ```typescript
4098
- * // Get download URL for a file
4099
- * const fileAccess = await sdk.buckets.getReadUri({
4100
- * bucketId: 123,
4101
- * folderId: 456,
4102
- * path: '/folder/file.pdf'
4103
- * });
4104
- * ```
5156
+ * Create a stage from a case node
5157
+ * @param node - The case node to process
5158
+ * @param executionMap - Map of element IDs to execution data
5159
+ * @param bindingsMap - Map of binding IDs to binding objects
5160
+ * @returns CaseGetStageResponse object
5161
+ * @private
4105
5162
  */
4106
- async getReadUri(options) {
4107
- const { bucketId, folderId, path, expiryInMinutes, ...restOptions } = options;
4108
- const queryOptions = {
4109
- expiryInMinutes,
4110
- ...addPrefixToKeys(restOptions, ODATA_PREFIX, Object.keys(restOptions))
5163
+ createStageFromNode(node, executionMap, bindingsMap) {
5164
+ const execution = executionMap.get(node.id);
5165
+ const stage = {
5166
+ id: node.id,
5167
+ name: node.data?.label || CASE_STAGE_CONSTANTS.UNDEFINED_VALUE,
5168
+ sla: node.data?.sla ? transformData(node.data.sla, StageSLAMap) : undefined,
5169
+ status: execution?.status || CASE_STAGE_CONSTANTS.NOT_STARTED_STATUS,
5170
+ tasks: this.processTasks(node, executionMap, bindingsMap)
4111
5171
  };
4112
- return this._getUri(BUCKET_ENDPOINTS.GET_READ_URI(bucketId), bucketId, folderId, path, queryOptions);
5172
+ return stage;
4113
5173
  }
4114
5174
  /**
4115
- * Gets a direct upload URL for a file in the bucket
4116
- *
4117
- * @param options - Contains bucketId, folderId, file path, optional expiry time and content type
4118
- * @returns Promise resolving to blob file access information
5175
+ * Get human in the loop tasks associated with a case instance
5176
+ * @param caseInstanceId - The ID of the case instance
5177
+ * @param options - Optional filtering and pagination options
5178
+ * @returns Promise resolving to human in the loop tasks associated with the case instance
4119
5179
  */
4120
- async _getWriteUri(options) {
4121
- const { bucketId, folderId, path, expiryInMinutes, contentType, ...restOptions } = options;
4122
- const queryOptions = {
4123
- expiryInMinutes,
4124
- contentType,
4125
- ...addPrefixToKeys(restOptions, ODATA_PREFIX, Object.keys(restOptions))
5180
+ async getActionTasks(caseInstanceId, options) {
5181
+ // Build filter to match tasks by case instance ID using tags
5182
+ const tagFilter = CASE_INSTANCE_TASK_FILTER(caseInstanceId);
5183
+ // Combine with any existing filter
5184
+ const filter = options?.filter
5185
+ ? `(${tagFilter}) and (${options.filter})`
5186
+ : tagFilter;
5187
+ // Add expand to include AssignedToUser and Activities
5188
+ const expand = CASE_INSTANCE_TASK_EXPAND;
5189
+ // Prepare the enhanced options with proper typing
5190
+ const enhancedOptions = {
5191
+ ...options,
5192
+ filter,
5193
+ expand
4126
5194
  };
4127
- return this._getUri(BUCKET_ENDPOINTS.GET_WRITE_URI(bucketId), bucketId, folderId, path, queryOptions);
5195
+ return await this.taskService.getAll(enhancedOptions);
4128
5196
  }
4129
5197
  }
4130
5198
  __decorate([
4131
- track('Buckets.GetById')
4132
- ], BucketService.prototype, "getById", null);
5199
+ track('CaseInstances.GetAll')
5200
+ ], CaseInstancesService.prototype, "getAll", null);
4133
5201
  __decorate([
4134
- track('Buckets.GetAll')
4135
- ], BucketService.prototype, "getAll", null);
5202
+ track('CaseInstances.GetById')
5203
+ ], CaseInstancesService.prototype, "getById", null);
4136
5204
  __decorate([
4137
- track('Buckets.GetFileMetaData')
4138
- ], BucketService.prototype, "getFileMetaData", null);
5205
+ track('CaseInstances.Close')
5206
+ ], CaseInstancesService.prototype, "close", null);
4139
5207
  __decorate([
4140
- track('Buckets.UploadFile')
4141
- ], BucketService.prototype, "uploadFile", null);
5208
+ track('CaseInstances.Pause')
5209
+ ], CaseInstancesService.prototype, "pause", null);
4142
5210
  __decorate([
4143
- track('Buckets.GetReadUri')
4144
- ], BucketService.prototype, "getReadUri", null);
5211
+ track('CaseInstances.Resume')
5212
+ ], CaseInstancesService.prototype, "resume", null);
5213
+ __decorate([
5214
+ track('CaseInstances.GetExecutionHistory')
5215
+ ], CaseInstancesService.prototype, "getExecutionHistory", null);
5216
+ __decorate([
5217
+ track('CaseInstances.GetStages')
5218
+ ], CaseInstancesService.prototype, "getStages", null);
5219
+ __decorate([
5220
+ track('CaseInstances.GetActionTasks')
5221
+ ], CaseInstancesService.prototype, "getActionTasks", null);
4145
5222
 
4146
5223
  /**
4147
- * Maps fields for Process entities to ensure consistent naming
5224
+ * Base service for services that need folder-specific functionality
4148
5225
  */
4149
- const ProcessMap = {
4150
- lastModificationTime: 'lastModifiedTime',
5226
+ class FolderScopedService extends BaseService {
5227
+ constructor(config, executionContext, tokenManager) {
5228
+ super(config, executionContext, tokenManager);
5229
+ }
5230
+ /**
5231
+ * Gets resources in a folder with optional query parameters
5232
+ *
5233
+ * @param endpoint - API endpoint to call
5234
+ * @param folderId - required folder ID
5235
+ * @param options - Query options
5236
+ * @param transformFn - Optional function to transform the response data
5237
+ * @returns Promise resolving to an array of resources
5238
+ */
5239
+ async _getByFolder(endpoint, folderId, options = {}, transformFn) {
5240
+ const headers = createHeaders({ [FOLDER_ID]: folderId });
5241
+ const keysToPrefix = Object.keys(options);
5242
+ const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
5243
+ const response = await this.get(endpoint, {
5244
+ params: apiOptions,
5245
+ headers
5246
+ });
5247
+ if (transformFn) {
5248
+ return response.data?.value.map(transformFn);
5249
+ }
5250
+ return response.data?.value;
5251
+ }
5252
+ }
5253
+
5254
+ /**
5255
+ * Maps fields for Asset entities to ensure consistent naming
5256
+ */
5257
+ const AssetMap = {
4151
5258
  creationTime: 'createdTime',
4152
- organizationUnitId: 'folderId',
4153
- organizationUnitFullyQualifiedName: 'folderName',
4154
- releaseKey: 'processKey',
4155
- releaseName: 'processName',
4156
- releaseVersionId: 'processVersionId',
4157
- processType: 'packageType',
4158
- processKey: 'packageKey',
4159
- processVersion: 'packageVersion',
4160
- isProcessDeleted: 'isPackageDeleted',
5259
+ lastModificationTime: 'lastModifiedTime'
4161
5260
  };
4162
5261
 
4163
5262
  /**
4164
- * Service for interacting with UiPath Orchestrator Processes API
5263
+ * Service for interacting with UiPath Orchestrator Assets API
4165
5264
  */
4166
- class ProcessService extends BaseService {
5265
+ class AssetService extends FolderScopedService {
4167
5266
  /**
4168
5267
  * @hideconstructor
4169
5268
  */
@@ -4171,53 +5270,43 @@ class ProcessService extends BaseService {
4171
5270
  super(config, executionContext, tokenManager);
4172
5271
  }
4173
5272
  /**
4174
- * Gets all processes across folders with optional filtering and folder scoping
4175
- *
4176
- * The method returns either:
4177
- * - An array of processes (when no pagination parameters are provided)
4178
- * - A paginated result with navigation cursors (when any pagination parameter is provided)
5273
+ * Gets all assets across folders with optional filtering and folder scoping
4179
5274
  *
4180
- * @param options - Query options including optional folderId
4181
- * @returns Promise resolving to an array of processes or paginated result
5275
+ * @signature getAll(options?) -> Promise<AssetGetResponse[]>
5276
+ * @param options Query options including optional folderId and pagination options
5277
+ * @returns Promise resolving to array of assets or paginated response
4182
5278
  *
4183
5279
  * @example
4184
5280
  * ```typescript
4185
5281
  * // Standard array return
4186
- * const processes = await sdk.processes.getAll();
4187
- *
4188
- * // Get processes within a specific folder
4189
- * const processes = await sdk.processes.getAll({
4190
- * folderId: 123
4191
- * });
5282
+ * const assets = await sdk.assets.getAll();
4192
5283
  *
4193
- * // Get processes with filtering
4194
- * const processes = await sdk.processes.getAll({
4195
- * filter: "name eq 'MyProcess'"
4196
- * });
5284
+ * // With folder
5285
+ * const folderAssets = await sdk.assets.getAll({ folderId: 123 });
4197
5286
  *
4198
5287
  * // First page with pagination
4199
- * const page1 = await sdk.processes.getAll({ pageSize: 10 });
5288
+ * const page1 = await sdk.assets.getAll({ pageSize: 10 });
4200
5289
  *
4201
5290
  * // Navigate using cursor
4202
5291
  * if (page1.hasNextPage) {
4203
- * const page2 = await sdk.processes.getAll({ cursor: page1.nextCursor });
5292
+ * const page2 = await sdk.assets.getAll({ cursor: page1.nextCursor });
4204
5293
  * }
4205
5294
  *
4206
5295
  * // Jump to specific page
4207
- * const page5 = await sdk.processes.getAll({
5296
+ * const page5 = await sdk.assets.getAll({
4208
5297
  * jumpToPage: 5,
4209
5298
  * pageSize: 10
4210
5299
  * });
4211
5300
  * ```
4212
5301
  */
4213
5302
  async getAll(options) {
4214
- // Transformation function for processes
4215
- const transformProcessResponse = (process) => transformData(pascalToCamelCaseKeys(process), ProcessMap);
5303
+ // Transformation function for assets
5304
+ const transformAssetResponse = (asset) => transformData(pascalToCamelCaseKeys(asset), AssetMap);
4216
5305
  return PaginationHelpers.getAll({
4217
5306
  serviceAccess: this.createPaginationServiceAccess(),
4218
- getEndpoint: () => PROCESS_ENDPOINTS.GET_ALL,
4219
- getByFolderEndpoint: PROCESS_ENDPOINTS.GET_ALL, // Processes use same endpoint for both
4220
- transformFn: transformProcessResponse,
5307
+ getEndpoint: (folderId) => folderId ? ASSET_ENDPOINTS.GET_BY_FOLDER : ASSET_ENDPOINTS.GET_ALL,
5308
+ getByFolderEndpoint: ASSET_ENDPOINTS.GET_BY_FOLDER,
5309
+ transformFn: transformAssetResponse,
4221
5310
  pagination: {
4222
5311
  paginationType: PaginationType.OFFSET,
4223
5312
  itemsField: ODATA_PAGINATION.ITEMS_FIELD,
@@ -4231,158 +5320,134 @@ class ProcessService extends BaseService {
4231
5320
  }, options);
4232
5321
  }
4233
5322
  /**
4234
- * Starts a process execution (job)
4235
- *
4236
- * @param request - Process start request body
4237
- * @param folderId - Required folder ID
4238
- * @param options - Optional query parameters
4239
- * @returns Promise resolving to the created jobs
4240
- *
4241
- * @example
4242
- * ```typescript
4243
- * // Start a process by process key
4244
- * const jobs = await sdk.processes.start({
4245
- * processKey: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
4246
- * }, 123); // folderId is required
4247
- *
4248
- * // Start a process by name with specific robots
4249
- * const jobs = await sdk.processes.start({
4250
- * processName: "MyProcess"
4251
- * }, 123); // folderId is required
4252
- * ```
4253
- */
4254
- async start(request, folderId, options = {}) {
4255
- const headers = createHeaders({ [FOLDER_ID]: folderId });
4256
- // Transform processKey/processName to releaseKey/releaseName for API compatibility
4257
- const apiRequest = { ...request };
4258
- // Create a reverse mapping using ProcessMap
4259
- const reversedPropertiesMap = reverseMap(ProcessMap);
4260
- // Apply transformations for any client properties found in the request
4261
- Object.entries(reversedPropertiesMap).forEach(([clientKey, apiKey]) => {
4262
- if (clientKey in apiRequest) {
4263
- apiRequest[apiKey] = apiRequest[clientKey];
4264
- delete apiRequest[clientKey];
4265
- }
4266
- });
4267
- // Convert to PascalCase for API
4268
- const pascalOptions = camelToPascalCaseKeys(apiRequest);
4269
- // Create the request object according to API spec
4270
- const requestBody = {
4271
- startInfo: pascalOptions
4272
- };
4273
- // Prefix all query parameter keys with '$' for OData
4274
- const keysToPrefix = Object.keys(options);
4275
- const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
4276
- const response = await this.post(PROCESS_ENDPOINTS.START_PROCESS, requestBody, {
4277
- params: apiOptions,
4278
- headers
4279
- });
4280
- const transformedProcess = response.data?.value.map(process => transformData(pascalToCamelCaseKeys(process), ProcessMap));
4281
- return transformedProcess;
4282
- }
4283
- /**
4284
- * Gets a single process by ID
5323
+ * Gets a single asset by ID
4285
5324
  *
4286
- * @param id - Process ID
5325
+ * @param id - Asset ID
4287
5326
  * @param folderId - Required folder ID
4288
- * @param options - Optional query parameters
4289
- * @returns Promise resolving to a single process
5327
+ * @param options - Optional query parameters (expand, select)
5328
+ * @returns Promise resolving to a single asset
4290
5329
  *
4291
5330
  * @example
4292
5331
  * ```typescript
4293
- * // Get process by ID
4294
- * const process = await sdk.processes.getById(123, 456);
5332
+ * // Get asset by ID
5333
+ * const asset = await sdk.assets.getById(123, 456);
4295
5334
  * ```
4296
5335
  */
4297
5336
  async getById(id, folderId, options = {}) {
4298
5337
  const headers = createHeaders({ [FOLDER_ID]: folderId });
4299
5338
  const keysToPrefix = Object.keys(options);
4300
5339
  const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
4301
- const response = await this.get(PROCESS_ENDPOINTS.GET_BY_ID(id), {
5340
+ const response = await this.get(ASSET_ENDPOINTS.GET_BY_ID(id), {
4302
5341
  headers,
4303
5342
  params: apiOptions
4304
5343
  });
4305
- const transformedProcess = transformData(pascalToCamelCaseKeys(response.data), ProcessMap);
4306
- return transformedProcess;
5344
+ const transformedAsset = transformData(pascalToCamelCaseKeys(response.data), AssetMap);
5345
+ return transformedAsset;
4307
5346
  }
4308
5347
  }
4309
5348
  __decorate([
4310
- track('Processes.GetAll')
4311
- ], ProcessService.prototype, "getAll", null);
4312
- __decorate([
4313
- track('Processes.Start')
4314
- ], ProcessService.prototype, "start", null);
5349
+ track('Assets.GetAll')
5350
+ ], AssetService.prototype, "getAll", null);
4315
5351
  __decorate([
4316
- track('Processes.GetById')
4317
- ], ProcessService.prototype, "getById", null);
5352
+ track('Assets.GetById')
5353
+ ], AssetService.prototype, "getById", null);
4318
5354
 
4319
5355
  /**
4320
- * Maps fields for Queue entities to ensure consistent naming
5356
+ * Maps fields for Bucket entities to ensure consistent naming
4321
5357
  */
4322
- const QueueMap = {
4323
- creationTime: 'createdTime',
4324
- organizationUnitId: 'folderId',
4325
- organizationUnitFullyQualifiedName: 'folderName'
5358
+ const BucketMap = {
5359
+ fullPath: 'path',
5360
+ items: 'blobItems',
5361
+ verb: 'httpMethod'
4326
5362
  };
4327
5363
 
4328
- /**
4329
- * Service for interacting with UiPath Orchestrator Queues API
4330
- */
4331
- class QueueService extends FolderScopedService {
5364
+ class BucketService extends FolderScopedService {
4332
5365
  /**
4333
5366
  * @hideconstructor
4334
5367
  */
4335
5368
  constructor(config, executionContext, tokenManager) {
4336
5369
  super(config, executionContext, tokenManager);
5370
+ this.tokenManager = tokenManager;
4337
5371
  }
4338
5372
  /**
4339
- * Gets all queues across folders with optional filtering and folder scoping
5373
+ * Gets a bucket by ID
5374
+ * @param bucketId - The ID of the bucket to retrieve
5375
+ * @param folderId - Folder ID for organization unit context
5376
+ * @param options - Optional query parameters (expand, select)
5377
+ * @returns Promise resolving to the bucket
5378
+ *
5379
+ * @example
5380
+ * ```typescript
5381
+ * // Get bucket by ID
5382
+ * const bucket = await sdk.buckets.getById(123, 456);
5383
+ * ```
5384
+ */
5385
+ async getById(id, folderId, options = {}) {
5386
+ if (!id) {
5387
+ throw new ValidationError({ message: 'bucketId is required for getById' });
5388
+ }
5389
+ if (!folderId) {
5390
+ throw new ValidationError({ message: 'folderId is required for getById' });
5391
+ }
5392
+ const headers = createHeaders({ [FOLDER_ID]: folderId });
5393
+ // Prefix all keys in options with $ for OData
5394
+ const keysToPrefix = Object.keys(options);
5395
+ const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
5396
+ const response = await this.get(BUCKET_ENDPOINTS.GET_BY_ID(id), {
5397
+ params: apiOptions,
5398
+ headers
5399
+ });
5400
+ // Transform response from PascalCase to camelCase
5401
+ return pascalToCamelCaseKeys(response.data);
5402
+ }
5403
+ /**
5404
+ * Gets all buckets across folders with optional filtering and folder scoping
4340
5405
  *
4341
5406
  * The method returns either:
4342
- * - An array of queues (when no pagination parameters are provided)
5407
+ * - An array of buckets (when no pagination parameters are provided)
4343
5408
  * - A paginated result with navigation cursors (when any pagination parameter is provided)
4344
5409
  *
4345
5410
  * @param options - Query options including optional folderId
4346
- * @returns Promise resolving to an array of queues or paginated result
5411
+ * @returns Promise resolving to an array of buckets or paginated result
4347
5412
  *
4348
5413
  * @example
4349
5414
  * ```typescript
4350
- * // Standard array return
4351
- * const queues = await sdk.queues.getAll();
5415
+ * // Get all buckets across folders
5416
+ * const buckets = await sdk.buckets.getAll();
4352
5417
  *
4353
- * // Get queues within a specific folder
4354
- * const queues = await sdk.queues.getAll({
5418
+ * // Get buckets within a specific folder
5419
+ * const buckets = await sdk.buckets.getAll({
4355
5420
  * folderId: 123
4356
5421
  * });
4357
5422
  *
4358
- * // Get queues with filtering
4359
- * const queues = await sdk.queues.getAll({
4360
- * filter: "name eq 'MyQueue'"
5423
+ * // Get buckets with filtering
5424
+ * const buckets = await sdk.buckets.getAll({
5425
+ * filter: "name eq 'MyBucket'"
4361
5426
  * });
4362
5427
  *
4363
5428
  * // First page with pagination
4364
- * const page1 = await sdk.queues.getAll({ pageSize: 10 });
5429
+ * const page1 = await sdk.buckets.getAll({ pageSize: 10 });
4365
5430
  *
4366
5431
  * // Navigate using cursor
4367
5432
  * if (page1.hasNextPage) {
4368
- * const page2 = await sdk.queues.getAll({ cursor: page1.nextCursor });
5433
+ * const page2 = await sdk.buckets.getAll({ cursor: page1.nextCursor });
4369
5434
  * }
4370
5435
  *
4371
5436
  * // Jump to specific page
4372
- * const page5 = await sdk.queues.getAll({
5437
+ * const page5 = await sdk.buckets.getAll({
4373
5438
  * jumpToPage: 5,
4374
5439
  * pageSize: 10
4375
5440
  * });
4376
5441
  * ```
4377
5442
  */
4378
5443
  async getAll(options) {
4379
- // Transformation function for queues
4380
- const transformQueueResponse = (queue) => transformData(pascalToCamelCaseKeys(queue), QueueMap);
5444
+ // Transformation function for buckets
5445
+ const transformBucketResponse = (bucket) => pascalToCamelCaseKeys(bucket);
4381
5446
  return PaginationHelpers.getAll({
4382
5447
  serviceAccess: this.createPaginationServiceAccess(),
4383
- getEndpoint: (folderId) => folderId ? QUEUE_ENDPOINTS.GET_BY_FOLDER : QUEUE_ENDPOINTS.GET_ALL,
4384
- getByFolderEndpoint: QUEUE_ENDPOINTS.GET_BY_FOLDER,
4385
- transformFn: transformQueueResponse,
5448
+ getEndpoint: (folderId) => folderId ? BUCKET_ENDPOINTS.GET_BY_FOLDER : BUCKET_ENDPOINTS.GET_ALL,
5449
+ getByFolderEndpoint: BUCKET_ENDPOINTS.GET_BY_FOLDER,
5450
+ transformFn: transformBucketResponse,
4386
5451
  pagination: {
4387
5452
  paginationType: PaginationType.OFFSET,
4388
5453
  itemsField: ODATA_PAGINATION.ITEMS_FIELD,
@@ -4393,582 +5458,543 @@ class QueueService extends FolderScopedService {
4393
5458
  countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM
4394
5459
  }
4395
5460
  }
4396
- }, options);
5461
+ }, options);
5462
+ }
5463
+ /**
5464
+ * Gets metadata for files in a bucket with optional filtering and pagination
5465
+ *
5466
+ * The method returns either:
5467
+ * - A NonPaginatedResponse with items array (when no pagination parameters are provided)
5468
+ * - A PaginatedResponse with navigation cursors (when any pagination parameter is provided)
5469
+ *
5470
+ * @param bucketId - The ID of the bucket to get file metadata from
5471
+ * @param folderId - Required folder ID for organization unit context
5472
+ * @param options - Optional parameters for filtering, pagination and access URL generation
5473
+ * @returns Promise resolving to the list of file metadata in the bucket or paginated result
5474
+ *
5475
+ * @example
5476
+ * ```typescript
5477
+ * // Get metadata for all files in a bucket
5478
+ * const fileMetadata = await sdk.buckets.getFileMetaData(123, 456);
5479
+ *
5480
+ * // Get file metadata with a specific prefix
5481
+ * const fileMetadata = await sdk.buckets.getFileMetaData(123, 456, {
5482
+ * prefix: '/folder1'
5483
+ * });
5484
+ *
5485
+ * // First page with pagination
5486
+ * const page1 = await sdk.buckets.getFileMetaData(123, 456, { pageSize: 10 });
5487
+ *
5488
+ * // Navigate using cursor
5489
+ * if (page1.hasNextPage) {
5490
+ * const page2 = await sdk.buckets.getFileMetaData(123, 456, { cursor: page1.nextCursor });
5491
+ * }
5492
+ * ```
5493
+ */
5494
+ async getFileMetaData(bucketId, folderId, options) {
5495
+ if (!bucketId) {
5496
+ throw new ValidationError({ message: 'bucketId is required for getFileMetaData' });
5497
+ }
5498
+ if (!folderId) {
5499
+ throw new ValidationError({ message: 'folderId is required for getFileMetaData' });
5500
+ }
5501
+ // Transformation function for blob items
5502
+ const transformBlobItem = (item) => transformData(item, BucketMap);
5503
+ return PaginationHelpers.getAll({
5504
+ serviceAccess: this.createPaginationServiceAccess(),
5505
+ getEndpoint: () => BUCKET_ENDPOINTS.GET_FILE_META_DATA(bucketId),
5506
+ transformFn: transformBlobItem,
5507
+ pagination: {
5508
+ paginationType: PaginationType.TOKEN,
5509
+ itemsField: BUCKET_PAGINATION.ITEMS_FIELD,
5510
+ continuationTokenField: BUCKET_PAGINATION.CONTINUATION_TOKEN_FIELD,
5511
+ paginationParams: {
5512
+ pageSizeParam: BUCKET_TOKEN_PARAMS.PAGE_SIZE_PARAM,
5513
+ tokenParam: BUCKET_TOKEN_PARAMS.TOKEN_PARAM
5514
+ }
5515
+ },
5516
+ excludeFromPrefix: ['prefix'] // Bucket-specific param, not OData
5517
+ }, { ...options, folderId });
5518
+ }
5519
+ /**
5520
+ * Uploads a file to a bucket
5521
+ *
5522
+ * @param options - Options for file upload including bucket ID, folder ID, path, content, and optional parameters
5523
+ * @returns Promise resolving to a response with success status and HTTP status code
5524
+ *
5525
+ * @example
5526
+ * ```typescript
5527
+ * // Upload a file from browser
5528
+ * const file = new File(['file content'], 'example.txt');
5529
+ * const result = await sdk.buckets.uploadFile({
5530
+ * bucketId: 123,
5531
+ * folderId: 456,
5532
+ * path: '/folder/example.txt',
5533
+ * content: file
5534
+ * });
5535
+ *
5536
+ * // In Node env with Buffer
5537
+ * const buffer = Buffer.from('file content');
5538
+ * const result = await sdk.buckets.uploadFile({
5539
+ * bucketId: 123,
5540
+ * folderId: 456,
5541
+ * path: '/folder/example.txt',
5542
+ * content: buffer
5543
+ * });
5544
+ * ```
5545
+ */
5546
+ async uploadFile(options) {
5547
+ const { bucketId, folderId, path, content } = options;
5548
+ if (!bucketId) {
5549
+ throw new ValidationError({ message: 'bucketId is required for uploadFile' });
5550
+ }
5551
+ if (!folderId) {
5552
+ throw new ValidationError({ message: 'folderId is required for uploadFile' });
5553
+ }
5554
+ if (!path) {
5555
+ throw new ValidationError({ message: 'path is required for uploadFile' });
5556
+ }
5557
+ if (!content) {
5558
+ throw new ValidationError({ message: 'content is required for uploadFile' });
5559
+ }
5560
+ try {
5561
+ const uriResponse = await this._getWriteUri({
5562
+ bucketId,
5563
+ folderId,
5564
+ path,
5565
+ });
5566
+ // Upload file to the provided URI
5567
+ const response = await this._uploadToUri(uriResponse, content);
5568
+ return {
5569
+ success: response.status >= 200 && response.status < 300,
5570
+ statusCode: response.status
5571
+ };
5572
+ }
5573
+ catch (error) {
5574
+ throw error;
5575
+ }
5576
+ }
5577
+ /**
5578
+ * Gets a direct download URL for a file in the bucket
5579
+ *
5580
+ * @param options - Contains bucketId, folderId, file path and optional expiry time
5581
+ * @returns Promise resolving to blob file access information
5582
+ *
5583
+ * @example
5584
+ * ```typescript
5585
+ * // Get download URL for a file
5586
+ * const fileAccess = await sdk.buckets.getReadUri({
5587
+ * bucketId: 123,
5588
+ * folderId: 456,
5589
+ * path: '/folder/file.pdf'
5590
+ * });
5591
+ * ```
5592
+ */
5593
+ async getReadUri(options) {
5594
+ const { bucketId, folderId, path, expiryInMinutes, ...restOptions } = options;
5595
+ const queryOptions = {
5596
+ expiryInMinutes,
5597
+ ...addPrefixToKeys(restOptions, ODATA_PREFIX, Object.keys(restOptions))
5598
+ };
5599
+ return this._getUri(BUCKET_ENDPOINTS.GET_READ_URI(bucketId), bucketId, folderId, path, queryOptions);
5600
+ }
5601
+ /**
5602
+ * Uploads content to the provided URI
5603
+ * @param uriResponse - Response from getWriteUri containing URL and headers
5604
+ * @param content - The content to upload
5605
+ * @returns The response from the upload request with status info
5606
+ */
5607
+ async _uploadToUri(uriResponse, content) {
5608
+ const { uri, headers = {}, requiresAuth } = uriResponse;
5609
+ if (!uri) {
5610
+ throw new ValidationError({ message: 'Upload URI not available', statusCode: HttpStatus.BAD_REQUEST });
5611
+ }
5612
+ // Create headers for the request
5613
+ let requestHeaders = { ...headers };
5614
+ // Add auth header if required
5615
+ if (requiresAuth) {
5616
+ try {
5617
+ const tokenInfo = this.executionContext.get('tokenInfo');
5618
+ if (!tokenInfo) {
5619
+ throw new AuthenticationError({ message: 'No authentication token available. Make sure to initialize the SDK first.' });
5620
+ }
5621
+ let token;
5622
+ // For secret-based tokens, they never expire so use directly
5623
+ if (tokenInfo.type === 'secret') {
5624
+ token = tokenInfo.token;
5625
+ }
5626
+ // For non-secret tokens, check expiration and refresh if needed
5627
+ else if (!this.tokenManager.isTokenExpired(tokenInfo)) {
5628
+ token = tokenInfo.token;
5629
+ }
5630
+ else {
5631
+ const newToken = await this.tokenManager.refreshAccessToken();
5632
+ token = newToken.access_token;
5633
+ }
5634
+ requestHeaders['Authorization'] = `Bearer ${token}`;
5635
+ }
5636
+ catch (error) {
5637
+ throw new AuthenticationError({
5638
+ message: `Authentication required but failed: ${error instanceof Error ? error.message : ''}`,
5639
+ statusCode: HttpStatus.UNAUTHORIZED
5640
+ });
5641
+ }
5642
+ }
5643
+ return axios.put(uri, content, {
5644
+ headers: createHeaders(requestHeaders)
5645
+ });
4397
5646
  }
4398
5647
  /**
4399
- * Gets a single queue by ID
4400
- *
4401
- * @param id - Queue ID
4402
- * @param folderId - Required folder ID
4403
- * @returns Promise resolving to a queue definition
4404
- *
4405
- * @example
4406
- * ```typescript
4407
- * // Get queue by ID
4408
- * const queue = await sdk.queues.getById(123, 456);
4409
- * ```
5648
+ * Private method to handle common URI request logic
5649
+ * @param endpoint - The API endpoint to call
5650
+ * @param bucketId - The bucket ID
5651
+ * @param folderId - The folder ID
5652
+ * @param path - The file path
5653
+ * @param queryOptions - Additional query parameters
5654
+ * @returns Promise resolving to blob file access information
4410
5655
  */
4411
- async getById(id, folderId, options = {}) {
5656
+ async _getUri(endpoint, bucketId, folderId, path, queryOptions = {}) {
5657
+ if (!bucketId) {
5658
+ throw new ValidationError({ message: 'bucketId is required for getUri' });
5659
+ }
5660
+ if (!folderId) {
5661
+ throw new ValidationError({ message: 'folderId is required for getUri' });
5662
+ }
5663
+ if (!path) {
5664
+ throw new ValidationError({ message: 'path is required for getUri' });
5665
+ }
5666
+ // Create headers with required folder ID
4412
5667
  const headers = createHeaders({ [FOLDER_ID]: folderId });
4413
- const keysToPrefix = Object.keys(options);
4414
- const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
4415
- const response = await this.get(QUEUE_ENDPOINTS.GET_BY_ID(id), {
4416
- headers,
4417
- params: apiOptions
5668
+ // Filter out undefined values and build query params
5669
+ const queryParams = filterUndefined({
5670
+ path,
5671
+ ...queryOptions
4418
5672
  });
4419
- return transformData(pascalToCamelCaseKeys(response.data), QueueMap);
5673
+ // Make the API call to get URI
5674
+ const response = await this.get(endpoint, {
5675
+ params: queryParams,
5676
+ headers
5677
+ });
5678
+ const transformedData = transformData(pascalToCamelCaseKeys(response.data), BucketMap);
5679
+ // Convert headers from array-based to record if needed
5680
+ if (transformedData.headers && 'keys' in transformedData.headers && 'values' in transformedData.headers) {
5681
+ transformedData.headers = arrayDictionaryToRecord(transformedData.headers);
5682
+ }
5683
+ return transformedData;
5684
+ }
5685
+ /**
5686
+ * Gets a direct upload URL for a file in the bucket
5687
+ *
5688
+ * @param options - Contains bucketId, folderId, file path, optional expiry time
5689
+ * @returns Promise resolving to blob file access information
5690
+ */
5691
+ async _getWriteUri(options) {
5692
+ const { bucketId, folderId, path, expiryInMinutes, ...restOptions } = options;
5693
+ const queryOptions = {
5694
+ expiryInMinutes,
5695
+ ...addPrefixToKeys(restOptions, ODATA_PREFIX, Object.keys(restOptions))
5696
+ };
5697
+ return this._getUri(BUCKET_ENDPOINTS.GET_WRITE_URI(bucketId), bucketId, folderId, path, queryOptions);
4420
5698
  }
4421
5699
  }
4422
5700
  __decorate([
4423
- track('Queues.GetAll')
4424
- ], QueueService.prototype, "getAll", null);
5701
+ track('Buckets.GetById')
5702
+ ], BucketService.prototype, "getById", null);
4425
5703
  __decorate([
4426
- track('Queues.GetById')
4427
- ], QueueService.prototype, "getById", null);
4428
-
4429
- var TaskType;
4430
- (function (TaskType) {
4431
- TaskType["Form"] = "FormTask";
4432
- TaskType["External"] = "ExternalTask";
4433
- TaskType["App"] = "AppTask";
4434
- })(TaskType || (TaskType = {}));
4435
- var TaskPriority;
4436
- (function (TaskPriority) {
4437
- TaskPriority["Low"] = "Low";
4438
- TaskPriority["Medium"] = "Medium";
4439
- TaskPriority["High"] = "High";
4440
- TaskPriority["Critical"] = "Critical";
4441
- })(TaskPriority || (TaskPriority = {}));
4442
- var TaskStatus;
4443
- (function (TaskStatus) {
4444
- TaskStatus["Unassigned"] = "Unassigned";
4445
- TaskStatus["Pending"] = "Pending";
4446
- TaskStatus["Completed"] = "Completed";
4447
- })(TaskStatus || (TaskStatus = {}));
4448
- var TaskSlaCriteria;
4449
- (function (TaskSlaCriteria) {
4450
- TaskSlaCriteria["TaskCreated"] = "TaskCreated";
4451
- TaskSlaCriteria["TaskAssigned"] = "TaskAssigned";
4452
- TaskSlaCriteria["TaskCompleted"] = "TaskCompleted";
4453
- })(TaskSlaCriteria || (TaskSlaCriteria = {}));
4454
- var TaskSlaStatus;
4455
- (function (TaskSlaStatus) {
4456
- TaskSlaStatus["OverdueLater"] = "OverdueLater";
4457
- TaskSlaStatus["OverdueSoon"] = "OverdueSoon";
4458
- TaskSlaStatus["Overdue"] = "Overdue";
4459
- TaskSlaStatus["CompletedInTime"] = "CompletedInTime";
4460
- })(TaskSlaStatus || (TaskSlaStatus = {}));
4461
- var TaskSourceName;
4462
- (function (TaskSourceName) {
4463
- TaskSourceName["Agent"] = "Agent";
4464
- TaskSourceName["Workflow"] = "Workflow";
4465
- TaskSourceName["Maestro"] = "Maestro";
4466
- TaskSourceName["Default"] = "Default";
4467
- })(TaskSourceName || (TaskSourceName = {}));
4468
-
4469
- /**
4470
- * Creates methods for a task
4471
- *
4472
- * @param taskData - The task data (response from API)
4473
- * @param service - The task service instance
4474
- * @returns Object containing task methods
4475
- */
4476
- function createTaskMethods(taskData, service) {
4477
- return {
4478
- async assign(options) {
4479
- if (!taskData.id)
4480
- throw new Error('Task ID is undefined');
4481
- const assignmentOptions = {
4482
- taskId: taskData.id,
4483
- userId: options.userId || 0, // Will be handled by userNameOrEmail if userId is not provided, 0 is considered as invalid user id
4484
- userNameOrEmail: options.userNameOrEmail
4485
- };
4486
- return service.assign(assignmentOptions, taskData.organizationUnitId);
4487
- },
4488
- async reassign(options) {
4489
- if (!taskData.id)
4490
- throw new Error('Task ID is undefined');
4491
- const assignmentOptions = {
4492
- taskId: taskData.id,
4493
- userId: options.userId || 0, // Will be handled by userNameOrEmail if userId is not provided, 0 is considered as invalid user id
4494
- userNameOrEmail: options.userNameOrEmail
4495
- };
4496
- return service.reassign(assignmentOptions, taskData.organizationUnitId);
4497
- },
4498
- async unassign() {
4499
- if (!taskData.id)
4500
- throw new Error('Task ID is undefined');
4501
- return service.unassign(taskData.id, taskData.organizationUnitId);
4502
- },
4503
- async complete(options) {
4504
- if (!taskData.id)
4505
- throw new Error('Task ID is undefined');
4506
- const folderId = taskData.organizationUnitId;
4507
- if (!folderId)
4508
- throw new Error('Folder ID is required');
4509
- return service.complete(options.type, {
4510
- taskId: taskData.id,
4511
- data: options.data,
4512
- action: options.action
4513
- }, folderId);
4514
- }
4515
- };
4516
- }
4517
- /**
4518
- * Creates an actionable task by combining API task data with operational methods.
4519
- *
4520
- * @param taskData - The task data from API
4521
- * @param service - The task service instance
4522
- * @returns A task object with added methods
4523
- */
4524
- function createTaskWithMethods(taskData, service) {
4525
- const methods = createTaskMethods(taskData, service);
4526
- return Object.assign({}, taskData, methods);
4527
- }
5704
+ track('Buckets.GetAll')
5705
+ ], BucketService.prototype, "getAll", null);
5706
+ __decorate([
5707
+ track('Buckets.GetFileMetaData')
5708
+ ], BucketService.prototype, "getFileMetaData", null);
5709
+ __decorate([
5710
+ track('Buckets.UploadFile')
5711
+ ], BucketService.prototype, "uploadFile", null);
5712
+ __decorate([
5713
+ track('Buckets.GetReadUri')
5714
+ ], BucketService.prototype, "getReadUri", null);
4528
5715
 
4529
5716
  /**
4530
- * Maps numeric TaskStatus values (from API) to TaskStatus enum values.
4531
- * Extend this file with additional field mappings as needed.
5717
+ * Maps fields for Process entities to ensure consistent naming
4532
5718
  */
4533
- const TaskStatusMap = {
4534
- 0: TaskStatus.Unassigned,
4535
- 1: TaskStatus.Pending,
4536
- 2: TaskStatus.Completed,
4537
- };
4538
- // Field mapping for time-related fields to ensure consistent naming
4539
- const TaskTimeMap = {
4540
- completionTime: 'completedTime',
4541
- deletionTime: 'deletedTime',
5719
+ const ProcessMap = {
4542
5720
  lastModificationTime: 'lastModifiedTime',
4543
5721
  creationTime: 'createdTime',
4544
- };
4545
-
4546
- /**
4547
- * Service for interacting with UiPath Tasks API
4548
- */
4549
- class TaskService extends BaseService {
4550
- /**
4551
- * @hideconstructor
4552
- */
4553
- constructor(config, executionContext, tokenManager) {
4554
- super(config, executionContext, tokenManager);
4555
- /**
4556
- * Process parameters for task queries with folder filtering
4557
- * @param options - The REST API options to process
4558
- * @param folderId - Optional folder ID to filter by
4559
- * @returns Processed options with folder filtering applied if needed
4560
- * @private
4561
- */
4562
- this.processTaskParameters = (options, folderId) => {
4563
- const processedOptions = { ...options };
4564
- if (folderId) {
4565
- // Create or add to existing filter for folder-specific queries
4566
- if (processedOptions.filter) {
4567
- processedOptions.filter = `${processedOptions.filter} and organizationUnitId eq ${folderId}`;
4568
- }
4569
- else {
4570
- processedOptions.filter = `organizationUnitId eq ${folderId}`;
4571
- }
4572
- }
4573
- return processedOptions;
4574
- };
4575
- }
5722
+ organizationUnitId: 'folderId',
5723
+ organizationUnitFullyQualifiedName: 'folderName',
5724
+ releaseKey: 'processKey',
5725
+ releaseName: 'processName',
5726
+ releaseVersionId: 'processVersionId',
5727
+ processType: 'packageType',
5728
+ processKey: 'packageKey',
5729
+ processVersion: 'packageVersion',
5730
+ isProcessDeleted: 'isPackageDeleted',
5731
+ };
5732
+
5733
+ /**
5734
+ * Service for interacting with UiPath Orchestrator Processes API
5735
+ */
5736
+ class ProcessService extends BaseService {
4576
5737
  /**
4577
- * Creates a new task
4578
- * @param task - The task to be created
4579
- * @param folderId - Required folder ID
4580
- * @returns Promise resolving to the created task
4581
- *
4582
- * @example
4583
- * ```typescript
4584
- * const task = await sdk.tasks.create({
4585
- * title: "My Task",
4586
- * priority: TaskPriority.Medium,
4587
- * data: { key: "value" }
4588
- * }, 123); // folderId is required
4589
- * ```
5738
+ * @hideconstructor
4590
5739
  */
4591
- async create(task, folderId) {
4592
- const headers = createHeaders({ [FOLDER_ID]: folderId });
4593
- const externalTask = {
4594
- ...task,
4595
- type: TaskType.External //currently only external task is supported
4596
- };
4597
- const response = await this.post(TASK_ENDPOINTS.CREATE_GENERIC_TASK, externalTask, { headers });
4598
- // Transform time fields for consistency
4599
- const normalizedData = transformData(response.data, TaskTimeMap);
4600
- const transformedData = applyDataTransforms(normalizedData, { field: 'status', valueMap: TaskStatusMap });
4601
- return createTaskWithMethods(transformedData, this);
5740
+ constructor(config, executionContext, tokenManager) {
5741
+ super(config, executionContext, tokenManager);
4602
5742
  }
4603
5743
  /**
4604
- * Gets users in the given folder who have Tasks.View and Tasks.Edit permissions
5744
+ * Gets all processes across folders with optional filtering and folder scoping
4605
5745
  *
4606
5746
  * The method returns either:
4607
- * - An array of users (when no pagination parameters are provided)
5747
+ * - An array of processes (when no pagination parameters are provided)
4608
5748
  * - A paginated result with navigation cursors (when any pagination parameter is provided)
4609
5749
  *
4610
- * @param folderId - The folder ID to get users from
4611
- * @param options - Optional query and pagination parameters
4612
- * @returns Promise resolving to an array of users or paginated result
5750
+ * @param options - Query options including optional folderId
5751
+ * @returns Promise resolving to an array of processes or paginated result
4613
5752
  *
4614
5753
  * @example
4615
5754
  * ```typescript
4616
5755
  * // Standard array return
4617
- * const users = await sdk.tasks.getUsers(123);
4618
- *
4619
- * // Get users with filtering
4620
- * const users = await sdk.tasks.getUsers(123, {
4621
- * filter: "name eq 'abc'"
4622
- * });
4623
- *
4624
- * // First page with pagination
4625
- * const page1 = await sdk.tasks.getUsers(123, { pageSize: 10 });
4626
- *
4627
- * // Navigate using cursor
4628
- * if (page1.hasNextPage) {
4629
- * const page2 = await sdk.tasks.getUsers(123, { cursor: page1.nextCursor });
4630
- * }
5756
+ * const processes = await sdk.processes.getAll();
4631
5757
  *
4632
- * // Jump to specific page
4633
- * const page5 = await sdk.tasks.getUsers(123, {
4634
- * jumpToPage: 5,
4635
- * pageSize: 10
5758
+ * // Get processes within a specific folder
5759
+ * const processes = await sdk.processes.getAll({
5760
+ * folderId: 123
4636
5761
  * });
4637
- * ```
4638
- */
4639
- async getUsers(folderId, options) {
4640
- // Transformation function for users
4641
- const transformUserResponse = (user) => pascalToCamelCaseKeys(user);
4642
- // Add folderId to options so the centralized helper can handle it properly
4643
- const optionsWithFolder = { ...options, folderId };
4644
- return PaginationHelpers.getAll({
4645
- serviceAccess: this.createPaginationServiceAccess(),
4646
- getEndpoint: (folderId) => TASK_ENDPOINTS.GET_TASK_USERS(folderId), // Use folderId from centralized helper
4647
- getByFolderEndpoint: TASK_ENDPOINTS.GET_TASK_USERS(folderId), // Use the passed folderId
4648
- transformFn: transformUserResponse,
4649
- pagination: {
4650
- paginationType: PaginationType.OFFSET,
4651
- itemsField: ODATA_PAGINATION.ITEMS_FIELD,
4652
- totalCountField: ODATA_PAGINATION.TOTAL_COUNT_FIELD,
4653
- paginationParams: {
4654
- pageSizeParam: ODATA_OFFSET_PARAMS.PAGE_SIZE_PARAM,
4655
- offsetParam: ODATA_OFFSET_PARAMS.OFFSET_PARAM,
4656
- countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM
4657
- }
4658
- }
4659
- }, optionsWithFolder);
4660
- }
4661
- /**
4662
- * Gets tasks across folders with optional filtering and folder scoping
4663
- *
4664
- * The method returns either:
4665
- * - An array of tasks (when no pagination parameters are provided)
4666
- * - A paginated result with navigation cursors (when any pagination parameter is provided)
4667
5762
  *
4668
- * @param options - Query options including optional folderId and pagination options
4669
- * @returns Promise resolving to an array of tasks or paginated result
4670
- *
4671
- * @example
4672
- * ```typescript
4673
- * // Standard array return
4674
- * const tasks = await sdk.tasks.getAll();
4675
- *
4676
- * // Get tasks within a specific folder
4677
- * const tasks = await sdk.tasks.getAll({
4678
- * folderId: 123
5763
+ * // Get processes with filtering
5764
+ * const processes = await sdk.processes.getAll({
5765
+ * filter: "name eq 'MyProcess'"
4679
5766
  * });
4680
5767
  *
4681
5768
  * // First page with pagination
4682
- * const page1 = await sdk.tasks.getAll({ pageSize: 10 });
5769
+ * const page1 = await sdk.processes.getAll({ pageSize: 10 });
4683
5770
  *
4684
5771
  * // Navigate using cursor
4685
5772
  * if (page1.hasNextPage) {
4686
- * const page2 = await sdk.tasks.getAll({ cursor: page1.nextCursor });
5773
+ * const page2 = await sdk.processes.getAll({ cursor: page1.nextCursor });
4687
5774
  * }
4688
5775
  *
4689
5776
  * // Jump to specific page
4690
- * const page5 = await sdk.tasks.getAll({
5777
+ * const page5 = await sdk.processes.getAll({
4691
5778
  * jumpToPage: 5,
4692
5779
  * pageSize: 10
4693
5780
  * });
4694
5781
  * ```
4695
5782
  */
4696
5783
  async getAll(options) {
4697
- // Transformation function for tasks
4698
- const transformTaskResponse = (task) => {
4699
- const transformedTask = transformData(pascalToCamelCaseKeys(task), TaskTimeMap);
4700
- return createTaskWithMethods(applyDataTransforms(transformedTask, { field: 'status', valueMap: TaskStatusMap }), this);
4701
- };
5784
+ // Transformation function for processes
5785
+ const transformProcessResponse = (process) => transformData(pascalToCamelCaseKeys(process), ProcessMap);
4702
5786
  return PaginationHelpers.getAll({
4703
5787
  serviceAccess: this.createPaginationServiceAccess(),
4704
- getEndpoint: () => TASK_ENDPOINTS.GET_TASKS_ACROSS_FOLDERS,
4705
- transformFn: transformTaskResponse,
4706
- processParametersFn: this.processTaskParameters,
4707
- excludeFromPrefix: ['event'], // Exclude 'event' key from ODATA prefix transformation
5788
+ getEndpoint: () => PROCESS_ENDPOINTS.GET_ALL,
5789
+ getByFolderEndpoint: PROCESS_ENDPOINTS.GET_ALL, // Processes use same endpoint for both
5790
+ transformFn: transformProcessResponse,
4708
5791
  pagination: {
4709
5792
  paginationType: PaginationType.OFFSET,
4710
5793
  itemsField: ODATA_PAGINATION.ITEMS_FIELD,
4711
5794
  totalCountField: ODATA_PAGINATION.TOTAL_COUNT_FIELD,
4712
5795
  paginationParams: {
4713
- pageSizeParam: ODATA_OFFSET_PARAMS.PAGE_SIZE_PARAM, // OData OFFSET parameter
4714
- offsetParam: ODATA_OFFSET_PARAMS.OFFSET_PARAM, // OData OFFSET parameter
4715
- countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM // OData OFFSET parameter
5796
+ pageSizeParam: ODATA_OFFSET_PARAMS.PAGE_SIZE_PARAM,
5797
+ offsetParam: ODATA_OFFSET_PARAMS.OFFSET_PARAM,
5798
+ countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM
4716
5799
  }
4717
5800
  }
4718
5801
  }, options);
4719
5802
  }
4720
5803
  /**
4721
- * Gets a task by ID
5804
+ * Starts a process execution (job)
4722
5805
  *
4723
- * @param id - The ID of the task to retrieve
5806
+ * @param request - Process start request body
5807
+ * @param folderId - Required folder ID
4724
5808
  * @param options - Optional query parameters
4725
- * @param folderId - Optional folder ID
4726
- * @returns Promise resolving to the task (form tasks will return form-specific data)
4727
- *
4728
- * @example
4729
- * ```typescript
4730
- * // Get task by ID
4731
- * const task = await sdk.tasks.getById(123);
4732
- *
4733
- * // If the task is a form task, it will automatically return form-specific data
4734
- * ```
4735
- */
4736
- async getById(id, options = {}, folderId) {
4737
- const headers = createHeaders({ [FOLDER_ID]: folderId });
4738
- // prefix all keys in options
4739
- const keysToPrefix = Object.keys(options);
4740
- const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
4741
- const response = await this.get(TASK_ENDPOINTS.GET_BY_ID(id), {
4742
- params: apiOptions,
4743
- headers
4744
- });
4745
- // Transform response from PascalCase to camelCase and normalize time fields
4746
- const transformedTask = transformData(pascalToCamelCaseKeys(response.data), TaskTimeMap);
4747
- // Check if this is a form task and get form-specific data if it is
4748
- if (transformedTask.type === TaskType.Form) {
4749
- const formOptions = { expandOnFormLayout: true };
4750
- return this.getFormTaskById(id, folderId || transformedTask.organizationUnitId, formOptions);
4751
- }
4752
- return createTaskWithMethods(applyDataTransforms(transformedTask, { field: 'status', valueMap: TaskStatusMap }), this);
4753
- }
4754
- /**
4755
- * Assigns tasks to users
4756
- *
4757
- * @param taskAssignments - Single task assignment or array of task assignments
4758
- * @param folderId - Optional folder ID
4759
- * @returns Promise resolving to array of task assignment results
4760
- *
4761
- * @example
4762
- * ```typescript
4763
- * // Assign a single task to a user by ID
4764
- * const result = await sdk.tasks.assign({
4765
- * taskId: 123,
4766
- * userId: 456
4767
- * });
4768
- *
4769
- * // Assign a single task to a user by email
4770
- * const result = await sdk.tasks.assign({
4771
- * taskId: 123,
4772
- * userNameOrEmail: "user@example.com"
4773
- * });
4774
- *
4775
- * // Assign multiple tasks
4776
- * const result = await sdk.tasks.assign([
4777
- * {
4778
- * taskId: 123,
4779
- * userId: 456
4780
- * },
4781
- * {
4782
- * taskId: 789,
4783
- * userNameOrEmail: "user@example.com"
4784
- * }
4785
- * ]);
4786
- * ```
4787
- */
4788
- async assign(taskAssignments, folderId) {
4789
- const headers = createHeaders({ [FOLDER_ID]: folderId });
4790
- // Normalize input to array
4791
- const assignmentArray = Array.isArray(taskAssignments) ? taskAssignments : [taskAssignments];
4792
- const options = {
4793
- taskAssignments: assignmentArray
4794
- };
4795
- // Convert options to PascalCase for API
4796
- const pascalOptions = camelToPascalCaseKeys(options);
4797
- const response = await this.post(TASK_ENDPOINTS.ASSIGN_TASKS, pascalOptions, { headers });
4798
- // Transform response from PascalCase to camelCase
4799
- const transformedResponse = pascalToCamelCaseKeys(response.data);
4800
- // Process OData array response - empty array = success, non-empty = error
4801
- return processODataArrayResponse(transformedResponse, assignmentArray);
4802
- }
4803
- /**
4804
- * Reassigns tasks to new users
4805
- *
4806
- * @param taskAssignments - Single task assignment or array of task assignments
4807
- * @param folderId - Optional folder ID
4808
- * @returns Promise resolving to array of task assignment results
5809
+ * @returns Promise resolving to the created jobs
4809
5810
  *
4810
5811
  * @example
4811
5812
  * ```typescript
4812
- * // Reassign a single task to a user by ID
4813
- * const result = await sdk.tasks.reassign({
4814
- * taskId: 123,
4815
- * userId: 456
4816
- * });
4817
- *
4818
- * // Reassign a single task to a user by email
4819
- * const result = await sdk.tasks.reassign({
4820
- * taskId: 123,
4821
- * userNameOrEmail: "user@example.com"
4822
- * });
5813
+ * // Start a process by process key
5814
+ * const jobs = await sdk.processes.start({
5815
+ * processKey: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
5816
+ * }, 123); // folderId is required
4823
5817
  *
4824
- * // Reassign multiple tasks
4825
- * const result = await sdk.tasks.reassign([
4826
- * {
4827
- * taskId: 123,
4828
- * userId: 456
4829
- * },
4830
- * {
4831
- * taskId: 789,
4832
- * userNameOrEmail: "user@example.com"
4833
- * }
4834
- * ]);
5818
+ * // Start a process by name with specific robots
5819
+ * const jobs = await sdk.processes.start({
5820
+ * processName: "MyProcess"
5821
+ * }, 123); // folderId is required
4835
5822
  * ```
4836
5823
  */
4837
- async reassign(taskAssignments, folderId) {
5824
+ async start(request, folderId, options = {}) {
4838
5825
  const headers = createHeaders({ [FOLDER_ID]: folderId });
4839
- // Normalize input to array
4840
- const assignmentArray = Array.isArray(taskAssignments) ? taskAssignments : [taskAssignments];
4841
- const options = {
4842
- taskAssignments: assignmentArray
5826
+ // Transform processKey/processName to releaseKey/releaseName for API compatibility
5827
+ const apiRequest = { ...request };
5828
+ // Create a reverse mapping using ProcessMap
5829
+ const reversedPropertiesMap = reverseMap(ProcessMap);
5830
+ // Apply transformations for any client properties found in the request
5831
+ Object.entries(reversedPropertiesMap).forEach(([clientKey, apiKey]) => {
5832
+ if (clientKey in apiRequest) {
5833
+ apiRequest[apiKey] = apiRequest[clientKey];
5834
+ delete apiRequest[clientKey];
5835
+ }
5836
+ });
5837
+ // Convert to PascalCase for API
5838
+ const pascalOptions = camelToPascalCaseKeys(apiRequest);
5839
+ // Create the request object according to API spec
5840
+ const requestBody = {
5841
+ startInfo: pascalOptions
4843
5842
  };
4844
- // Convert options to PascalCase for API
4845
- const pascalOptions = camelToPascalCaseKeys(options);
4846
- const response = await this.post(TASK_ENDPOINTS.REASSIGN_TASKS, pascalOptions, { headers });
4847
- // Transform response from PascalCase to camelCase
4848
- const transformedResponse = pascalToCamelCaseKeys(response.data);
4849
- // Process OData array response - empty array = success, non-empty = error
4850
- return processODataArrayResponse(transformedResponse, assignmentArray);
5843
+ // Prefix all query parameter keys with '$' for OData
5844
+ const keysToPrefix = Object.keys(options);
5845
+ const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
5846
+ const response = await this.post(PROCESS_ENDPOINTS.START_PROCESS, requestBody, {
5847
+ params: apiOptions,
5848
+ headers
5849
+ });
5850
+ const transformedProcess = response.data?.value.map(process => transformData(pascalToCamelCaseKeys(process), ProcessMap));
5851
+ return transformedProcess;
4851
5852
  }
4852
5853
  /**
4853
- * Unassigns tasks (removes current assignees)
5854
+ * Gets a single process by ID
4854
5855
  *
4855
- * @param taskIds - Single task ID or array of task IDs to unassign
4856
- * @param folderId - Optional folder ID
4857
- * @returns Promise resolving to array of task assignment results
5856
+ * @param id - Process ID
5857
+ * @param folderId - Required folder ID
5858
+ * @param options - Optional query parameters
5859
+ * @returns Promise resolving to a single process
4858
5860
  *
4859
5861
  * @example
4860
5862
  * ```typescript
4861
- * // Unassign a single task
4862
- * const result = await sdk.tasks.unassign(123);
4863
- *
4864
- * // Unassign multiple tasks
4865
- * const result = await sdk.tasks.unassign([123, 456, 789]);
5863
+ * // Get process by ID
5864
+ * const process = await sdk.processes.getById(123, 456);
4866
5865
  * ```
4867
5866
  */
4868
- async unassign(taskIds, folderId) {
5867
+ async getById(id, folderId, options = {}) {
4869
5868
  const headers = createHeaders({ [FOLDER_ID]: folderId });
4870
- // Normalize input to array
4871
- const taskIdArray = Array.isArray(taskIds) ? taskIds : [taskIds];
4872
- const options = {
4873
- taskIds: taskIdArray
4874
- };
4875
- const response = await this.post(TASK_ENDPOINTS.UNASSIGN_TASKS, options, { headers });
4876
- // Transform response from PascalCase to camelCase
4877
- const transformedResponse = pascalToCamelCaseKeys(response.data);
4878
- // Process OData array response - empty array = success, non-empty = error
4879
- // Return the task IDs that were unassigned
4880
- return processODataArrayResponse(transformedResponse, taskIdArray.map(id => ({ taskId: id })));
5869
+ const keysToPrefix = Object.keys(options);
5870
+ const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
5871
+ const response = await this.get(PROCESS_ENDPOINTS.GET_BY_ID(id), {
5872
+ headers,
5873
+ params: apiOptions
5874
+ });
5875
+ const transformedProcess = transformData(pascalToCamelCaseKeys(response.data), ProcessMap);
5876
+ return transformedProcess;
5877
+ }
5878
+ }
5879
+ __decorate([
5880
+ track('Processes.GetAll')
5881
+ ], ProcessService.prototype, "getAll", null);
5882
+ __decorate([
5883
+ track('Processes.Start')
5884
+ ], ProcessService.prototype, "start", null);
5885
+ __decorate([
5886
+ track('Processes.GetById')
5887
+ ], ProcessService.prototype, "getById", null);
5888
+
5889
+ /**
5890
+ * Maps fields for Queue entities to ensure consistent naming
5891
+ */
5892
+ const QueueMap = {
5893
+ creationTime: 'createdTime',
5894
+ organizationUnitId: 'folderId',
5895
+ organizationUnitFullyQualifiedName: 'folderName'
5896
+ };
5897
+
5898
+ /**
5899
+ * Service for interacting with UiPath Orchestrator Queues API
5900
+ */
5901
+ class QueueService extends FolderScopedService {
5902
+ /**
5903
+ * @hideconstructor
5904
+ */
5905
+ constructor(config, executionContext, tokenManager) {
5906
+ super(config, executionContext, tokenManager);
4881
5907
  }
4882
5908
  /**
4883
- * Completes a task with the specified type and data
5909
+ * Gets all queues across folders with optional filtering and folder scoping
4884
5910
  *
4885
- * @param completionType - The type of task (Form, App, or Generic)
4886
- * @param options - The completion options
4887
- * @param folderId - Required folder ID
4888
- * @returns Promise resolving to void
5911
+ * The method returns either:
5912
+ * - An array of queues (when no pagination parameters are provided)
5913
+ * - A paginated result with navigation cursors (when any pagination parameter is provided)
5914
+ *
5915
+ * @param options - Query options including optional folderId
5916
+ * @returns Promise resolving to an array of queues or paginated result
4889
5917
  *
4890
5918
  * @example
4891
5919
  * ```typescript
4892
- * // Complete an app task
4893
- * await sdk.tasks.complete(TaskType.App, {
4894
- * taskId: 456,
4895
- * data: {},
4896
- * action: "submit"
4897
- * }, 123); // folderId is required
5920
+ * // Standard array return
5921
+ * const queues = await sdk.queues.getAll();
4898
5922
  *
4899
- * // Complete an external task
4900
- * await sdk.tasks.complete(TaskType.ExternalTask, {
4901
- * taskId: 789
4902
- * }, 123); // folderId is required
5923
+ * // Get queues within a specific folder
5924
+ * const queues = await sdk.queues.getAll({
5925
+ * folderId: 123
5926
+ * });
5927
+ *
5928
+ * // Get queues with filtering
5929
+ * const queues = await sdk.queues.getAll({
5930
+ * filter: "name eq 'MyQueue'"
5931
+ * });
5932
+ *
5933
+ * // First page with pagination
5934
+ * const page1 = await sdk.queues.getAll({ pageSize: 10 });
5935
+ *
5936
+ * // Navigate using cursor
5937
+ * if (page1.hasNextPage) {
5938
+ * const page2 = await sdk.queues.getAll({ cursor: page1.nextCursor });
5939
+ * }
5940
+ *
5941
+ * // Jump to specific page
5942
+ * const page5 = await sdk.queues.getAll({
5943
+ * jumpToPage: 5,
5944
+ * pageSize: 10
5945
+ * });
4903
5946
  * ```
4904
5947
  */
4905
- async complete(completionType, options, folderId) {
4906
- const headers = createHeaders({ [FOLDER_ID]: folderId });
4907
- let endpoint;
4908
- switch (completionType) {
4909
- case TaskType.Form:
4910
- endpoint = TASK_ENDPOINTS.COMPLETE_FORM_TASK;
4911
- break;
4912
- case TaskType.App:
4913
- endpoint = TASK_ENDPOINTS.COMPLETE_APP_TASK;
4914
- break;
4915
- default:
4916
- endpoint = TASK_ENDPOINTS.COMPLETE_GENERIC_TASK;
4917
- break;
4918
- }
4919
- // CompleteAppTask returns 204 no content
4920
- await this.post(endpoint, options, { headers });
4921
- // Return success with the request context data
4922
- return {
4923
- success: true,
4924
- data: options
4925
- };
5948
+ async getAll(options) {
5949
+ // Transformation function for queues
5950
+ const transformQueueResponse = (queue) => transformData(pascalToCamelCaseKeys(queue), QueueMap);
5951
+ return PaginationHelpers.getAll({
5952
+ serviceAccess: this.createPaginationServiceAccess(),
5953
+ getEndpoint: (folderId) => folderId ? QUEUE_ENDPOINTS.GET_BY_FOLDER : QUEUE_ENDPOINTS.GET_ALL,
5954
+ getByFolderEndpoint: QUEUE_ENDPOINTS.GET_BY_FOLDER,
5955
+ transformFn: transformQueueResponse,
5956
+ pagination: {
5957
+ paginationType: PaginationType.OFFSET,
5958
+ itemsField: ODATA_PAGINATION.ITEMS_FIELD,
5959
+ totalCountField: ODATA_PAGINATION.TOTAL_COUNT_FIELD,
5960
+ paginationParams: {
5961
+ pageSizeParam: ODATA_OFFSET_PARAMS.PAGE_SIZE_PARAM,
5962
+ offsetParam: ODATA_OFFSET_PARAMS.OFFSET_PARAM,
5963
+ countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM
5964
+ }
5965
+ }
5966
+ }, options);
4926
5967
  }
4927
5968
  /**
4928
- * Gets a form task by ID (private method)
5969
+ * Gets a single queue by ID
4929
5970
  *
4930
- * @param id - The ID of the form task to retrieve
5971
+ * @param id - Queue ID
4931
5972
  * @param folderId - Required folder ID
4932
- * @param options - Optional query parameters
4933
- * @returns Promise resolving to the form task
5973
+ * @returns Promise resolving to a queue definition
5974
+ *
5975
+ * @example
5976
+ * ```typescript
5977
+ * // Get queue by ID
5978
+ * const queue = await sdk.queues.getById(123, 456);
5979
+ * ```
4934
5980
  */
4935
- async getFormTaskById(id, folderId, options = {}) {
5981
+ async getById(id, folderId, options = {}) {
4936
5982
  const headers = createHeaders({ [FOLDER_ID]: folderId });
4937
- const response = await this.get(TASK_ENDPOINTS.GET_TASK_FORM_BY_ID, {
4938
- params: {
4939
- taskId: id,
4940
- ...options
4941
- },
4942
- headers
5983
+ const keysToPrefix = Object.keys(options);
5984
+ const apiOptions = addPrefixToKeys(options, ODATA_PREFIX, keysToPrefix);
5985
+ const response = await this.get(QUEUE_ENDPOINTS.GET_BY_ID(id), {
5986
+ headers,
5987
+ params: apiOptions
4943
5988
  });
4944
- const transformedFormTask = transformData(response.data, TaskTimeMap);
4945
- return createTaskWithMethods(applyDataTransforms(transformedFormTask, { field: 'status', valueMap: TaskStatusMap }), this);
5989
+ return transformData(pascalToCamelCaseKeys(response.data), QueueMap);
4946
5990
  }
4947
5991
  }
4948
5992
  __decorate([
4949
- track('Tasks.Create')
4950
- ], TaskService.prototype, "create", null);
4951
- __decorate([
4952
- track('Tasks.GetUsers')
4953
- ], TaskService.prototype, "getUsers", null);
4954
- __decorate([
4955
- track('Tasks.GetAll')
4956
- ], TaskService.prototype, "getAll", null);
4957
- __decorate([
4958
- track('Tasks.GetById')
4959
- ], TaskService.prototype, "getById", null);
4960
- __decorate([
4961
- track('Tasks.Assign')
4962
- ], TaskService.prototype, "assign", null);
4963
- __decorate([
4964
- track('Tasks.Reassign')
4965
- ], TaskService.prototype, "reassign", null);
4966
- __decorate([
4967
- track('Tasks.Unassign')
4968
- ], TaskService.prototype, "unassign", null);
5993
+ track('Queues.GetAll')
5994
+ ], QueueService.prototype, "getAll", null);
4969
5995
  __decorate([
4970
- track('Tasks.Complete')
4971
- ], TaskService.prototype, "complete", null);
5996
+ track('Queues.GetById')
5997
+ ], QueueService.prototype, "getById", null);
4972
5998
 
4973
5999
  function validateConfig(config) {
4974
6000
  if (!config.baseUrl || !config.orgName || !config.tenantName) {
@@ -5018,25 +6044,31 @@ class UiPath {
5018
6044
  }
5019
6045
  /**
5020
6046
  * Initialize the SDK based on the provided configuration.
5021
- * This method is only required for OAuth-based authentication.
6047
+ * This method handles both OAuth flow initiation and completion automatically.
5022
6048
  * For secret-based authentication, initialization is automatic.
5023
6049
  */
5024
6050
  async initialize() {
5025
- // If already initialized or using secret auth, return immediately
5026
- if (this.initialized || hasSecretConfig(this.config)) {
6051
+ // For secret-based auth, it's already initialized in constructor
6052
+ if (hasSecretConfig(this.config)) {
5027
6053
  return;
5028
6054
  }
5029
6055
  try {
5030
- // If the OAuth flow redirects, the promise from `authenticate` will not resolve,
5031
- // and execution will stop here.
5032
- const success = await this.authService.authenticate(this.config);
5033
- if (!success || !this.authService.hasValidToken()) {
5034
- // If authenticate() returns false, it means a valid token could not be obtained.
5035
- // This could be due to invalid config or a failure in the OAuth callback.
5036
- // We don't throw an error for the initial OAuth redirect because that won't return.
5037
- throw new Error('Failed to obtain a valid authentication token.');
6056
+ // Check for OAuth callback first
6057
+ if (AuthService.isInOAuthCallback()) {
6058
+ if (await this.completeOAuth()) {
6059
+ return;
6060
+ }
6061
+ }
6062
+ // Check if already authenticated
6063
+ if (this.isAuthenticated()) {
6064
+ this.initialized = true;
6065
+ return;
6066
+ }
6067
+ // Start new OAuth flow
6068
+ await this.authService.authenticate(this.config);
6069
+ if (this.isAuthenticated()) {
6070
+ this.initialized = true;
5038
6071
  }
5039
- this.initialized = true;
5040
6072
  }
5041
6073
  catch (error) {
5042
6074
  const errorMessage = error instanceof Error ? error.message : 'An unknown error occurred';
@@ -5049,6 +6081,38 @@ class UiPath {
5049
6081
  isInitialized() {
5050
6082
  return this.initialized;
5051
6083
  }
6084
+ /**
6085
+ * Check if we're in an OAuth callback state
6086
+ */
6087
+ isInOAuthCallback() {
6088
+ return AuthService.isInOAuthCallback();
6089
+ }
6090
+ /**
6091
+ * Complete OAuth authentication flow (only call if isInOAuthCallback() is true)
6092
+ */
6093
+ async completeOAuth() {
6094
+ if (!AuthService.isInOAuthCallback()) {
6095
+ throw new Error('Not in OAuth callback state. Call initialize() first to start OAuth flow.');
6096
+ }
6097
+ try {
6098
+ const success = await this.authService.authenticate(this.config);
6099
+ if (success && this.isAuthenticated()) {
6100
+ this.initialized = true;
6101
+ return true;
6102
+ }
6103
+ return false;
6104
+ }
6105
+ catch (error) {
6106
+ const errorMessage = error instanceof Error ? error.message : 'An unknown error occurred';
6107
+ throw new Error(`Failed to complete OAuth: ${errorMessage}`);
6108
+ }
6109
+ }
6110
+ /**
6111
+ * Check if the user is authenticated (has valid token)
6112
+ */
6113
+ isAuthenticated() {
6114
+ return this.authService.hasValidToken();
6115
+ }
5052
6116
  /**
5053
6117
  * Get the current authentication token
5054
6118
  */
@@ -5075,7 +6139,20 @@ class UiPath {
5075
6139
  /**
5076
6140
  * Access to Process Instances service
5077
6141
  */
5078
- instances: this.getService(ProcessInstancesService)
6142
+ instances: this.getService(ProcessInstancesService),
6143
+ /**
6144
+ * Access to Process Incidents service
6145
+ */
6146
+ incidents: this.getService(ProcessIncidentsService)
6147
+ }),
6148
+ /**
6149
+ * Access to Maestro Cases service
6150
+ */
6151
+ cases: Object.assign(this.getService(CasesService), {
6152
+ /**
6153
+ * Access to Case Instances service
6154
+ */
6155
+ instances: this.getService(CaseInstancesService)
5079
6156
  })
5080
6157
  };
5081
6158
  }
@@ -5275,4 +6352,4 @@ var JobType;
5275
6352
  JobType["ServerlessGeneric"] = "ServerlessGeneric";
5276
6353
  })(JobType || (JobType = {}));
5277
6354
 
5278
- export { APP_NAME, AssetValueScope, AssetValueType, AuthenticationError, AuthorizationError, BucketOptions, CLOUD_CLIENT_ID, CLOUD_ORGANIZATION_NAME, CLOUD_REDIRECT_URI, CLOUD_ROLE_NAME, CLOUD_TENANT_NAME, CLOUD_URL, CONNECTION_STRING, DEFAULT_ITEMS_FIELD, DEFAULT_PAGE_SIZE, DEFAULT_TOTAL_COUNT_FIELD, DataDirectionType, EntityFieldDataType, EntityType, ErrorType, FieldDisplayType, HttpStatus, JobPriority, JobState, JobType, JoinType, MAX_PAGE_SIZE, NetworkError, NotFoundError, PackageSourceType, PackageType, RateLimitError, ReferenceType, RemoteControlAccess, RobotSize, SDK_LOGGER_NAME, SDK_RUN_EVENT, SDK_SERVICE_NAME, SDK_VERSION, SERVICE, ServerError, StartStrategy, StopStrategy, TargetFramework, TaskPriority, TaskSlaCriteria, TaskSlaStatus, TaskSourceName, TaskStatus, TaskType, UNKNOWN, UiPath, UiPathError, VERSION, ValidationError, createEntityWithMethods, createProcessInstanceWithMethods, createTaskWithMethods, getErrorDetails, getLimitedPageSize, isAuthenticationError, isAuthorizationError, isNetworkError, isNotFoundError, isRateLimitError, isServerError, isUiPathError, isValidationError, telemetryClient, track, trackEvent };
6355
+ export { APP_NAME, AssetValueScope, AssetValueType, AuthenticationError, AuthorizationError, BucketOptions, CLOUD_CLIENT_ID, CLOUD_ORGANIZATION_NAME, CLOUD_REDIRECT_URI, CLOUD_ROLE_NAME, CLOUD_TENANT_NAME, CLOUD_URL, CONNECTION_STRING, DEFAULT_ITEMS_FIELD, DEFAULT_PAGE_SIZE, DEFAULT_TOTAL_COUNT_FIELD, DataDirectionType, DebugMode, EntityFieldDataType, EntityType, ErrorType, EscalationActionType, EscalationRecipientScope, EscalationTriggerType, FieldDisplayType, HttpStatus, JobPriority, JobState, JobType, JoinType, MAX_PAGE_SIZE, NetworkError, NotFoundError, PackageSourceType, PackageType, ProcessIncidentSeverity, ProcessIncidentStatus, ProcessIncidentType, RateLimitError, ReferenceType, RemoteControlAccess, RobotSize, SDK_LOGGER_NAME, SDK_RUN_EVENT, SDK_SERVICE_NAME, SDK_VERSION, SERVICE, SLADurationUnit, ServerError, StageTaskType, StartStrategy, StopStrategy, TargetFramework, TaskActivityType, TaskPriority, TaskSlaCriteria, TaskSlaStatus, TaskSourceName, TaskStatus, TaskType, UNKNOWN, UiPath, UiPathError, VERSION, ValidationError, createCaseInstanceWithMethods, createEntityWithMethods, createProcessInstanceWithMethods, createProcessWithMethods, createTaskWithMethods, getErrorDetails, getLimitedPageSize, isAuthenticationError, isAuthorizationError, isNetworkError, isNotFoundError, isRateLimitError, isServerError, isUiPathError, isValidationError, telemetryClient, track, trackEvent };