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

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