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