@uipath/uipath-typescript 1.0.0-beta.17 → 1.0.0

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.
@@ -0,0 +1,3493 @@
1
+ 'use strict';
2
+
3
+ var sdkLogs = require('@opentelemetry/sdk-logs');
4
+
5
+ /******************************************************************************
6
+ Copyright (c) Microsoft Corporation.
7
+
8
+ Permission to use, copy, modify, and/or distribute this software for any
9
+ purpose with or without fee is hereby granted.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
+ PERFORMANCE OF THIS SOFTWARE.
18
+ ***************************************************************************** */
19
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
20
+
21
+
22
+ function __decorate(decorators, target, key, desc) {
23
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
24
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
25
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
26
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
27
+ }
28
+
29
+ function __classPrivateFieldGet(receiver, state, kind, f) {
30
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
31
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
32
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
33
+ }
34
+
35
+ function __classPrivateFieldSet(receiver, state, value, kind, f) {
36
+ if (kind === "m") throw new TypeError("Private method is not writable");
37
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
38
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
39
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
40
+ }
41
+
42
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
43
+ var e = new Error(message);
44
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
45
+ };
46
+
47
+ /**
48
+ * Internal types for Maestro Cases
49
+ * These types are used internally by the cases service
50
+ */
51
+ /**
52
+ * Process type enum for filtering
53
+ */
54
+ var ProcessType;
55
+ (function (ProcessType) {
56
+ ProcessType["CaseManagement"] = "CaseManagement";
57
+ })(ProcessType || (ProcessType = {}));
58
+
59
+ /**
60
+ * Base error class for all UiPath SDK errors
61
+ * Pure TypeScript class with clean interface
62
+ */
63
+ class UiPathError {
64
+ constructor(type, params) {
65
+ this.type = type;
66
+ this.message = params.message;
67
+ this.statusCode = params.statusCode;
68
+ this.requestId = params.requestId;
69
+ this.timestamp = new Date();
70
+ // Capture stack trace for debugging
71
+ this.stack = (new Error()).stack;
72
+ }
73
+ /**
74
+ * Returns a clean JSON representation of the error
75
+ */
76
+ toJSON() {
77
+ return {
78
+ type: this.type,
79
+ message: this.message,
80
+ statusCode: this.statusCode,
81
+ requestId: this.requestId,
82
+ timestamp: this.timestamp
83
+ };
84
+ }
85
+ /**
86
+ * Returns detailed debug information including stack trace
87
+ */
88
+ getDebugInfo() {
89
+ return {
90
+ ...this.toJSON(),
91
+ stack: this.stack
92
+ };
93
+ }
94
+ }
95
+
96
+ /**
97
+ * HTTP status code constants for error handling
98
+ */
99
+ const HttpStatus = {
100
+ // Client errors (4xx)
101
+ BAD_REQUEST: 400,
102
+ UNAUTHORIZED: 401,
103
+ FORBIDDEN: 403,
104
+ NOT_FOUND: 404,
105
+ TOO_MANY_REQUESTS: 429,
106
+ // Server errors (5xx)
107
+ INTERNAL_SERVER_ERROR: 500,
108
+ BAD_GATEWAY: 502,
109
+ SERVICE_UNAVAILABLE: 503,
110
+ GATEWAY_TIMEOUT: 504
111
+ };
112
+ /**
113
+ * Error type constants for consistent error identification
114
+ */
115
+ const ErrorType = {
116
+ AUTHENTICATION: 'AuthenticationError',
117
+ AUTHORIZATION: 'AuthorizationError',
118
+ VALIDATION: 'ValidationError',
119
+ NOT_FOUND: 'NotFoundError',
120
+ RATE_LIMIT: 'RateLimitError',
121
+ SERVER: 'ServerError',
122
+ NETWORK: 'NetworkError'
123
+ };
124
+ /**
125
+ * HTTP header constants for error handling
126
+ */
127
+ const HttpHeaders = {
128
+ X_REQUEST_ID: 'x-request-id'
129
+ };
130
+ /**
131
+ * Standard error message constants
132
+ */
133
+ const ErrorMessages = {
134
+ // Authentication errors
135
+ AUTHENTICATION_FAILED: 'Authentication failed',
136
+ // Authorization errors
137
+ ACCESS_DENIED: 'Access denied',
138
+ // Validation errors
139
+ VALIDATION_FAILED: 'Validation failed',
140
+ // Not found errors
141
+ RESOURCE_NOT_FOUND: 'Resource not found',
142
+ // Rate limit errors
143
+ RATE_LIMIT_EXCEEDED: 'Rate limit exceeded',
144
+ // Server errors
145
+ INTERNAL_SERVER_ERROR: 'Internal Server error occurred',
146
+ // Network errors
147
+ NETWORK_ERROR: 'Network error occurred',
148
+ REQUEST_TIMEOUT: 'Request timed out',
149
+ REQUEST_ABORTED: 'Request was aborted',
150
+ };
151
+ /**
152
+ * Error name constants for network error identification
153
+ */
154
+ const ErrorNames = {
155
+ ABORT_ERROR: 'AbortError'};
156
+
157
+ /**
158
+ * Error thrown when authentication fails (401 errors)
159
+ * Common scenarios:
160
+ * - Invalid credentials
161
+ * - Expired token
162
+ * - Missing authentication
163
+ */
164
+ class AuthenticationError extends UiPathError {
165
+ constructor(params = {}) {
166
+ super(ErrorType.AUTHENTICATION, {
167
+ message: params.message || ErrorMessages.AUTHENTICATION_FAILED,
168
+ statusCode: params.statusCode ?? HttpStatus.UNAUTHORIZED,
169
+ requestId: params.requestId
170
+ });
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Error thrown when authorization fails (403 errors)
176
+ * Common scenarios:
177
+ * - Insufficient permissions
178
+ * - Access denied to resource
179
+ * - Invalid scope
180
+ */
181
+ class AuthorizationError extends UiPathError {
182
+ constructor(params = {}) {
183
+ super(ErrorType.AUTHORIZATION, {
184
+ message: params.message || ErrorMessages.ACCESS_DENIED,
185
+ statusCode: params.statusCode ?? HttpStatus.FORBIDDEN,
186
+ requestId: params.requestId
187
+ });
188
+ }
189
+ }
190
+
191
+ /**
192
+ * Error thrown when validation fails (400 errors or client-side validation)
193
+ * Common scenarios:
194
+ * - Invalid input parameters
195
+ * - Missing required fields
196
+ * - Invalid data format
197
+ */
198
+ class ValidationError extends UiPathError {
199
+ constructor(params = {}) {
200
+ super(ErrorType.VALIDATION, {
201
+ message: params.message || ErrorMessages.VALIDATION_FAILED,
202
+ statusCode: params.statusCode ?? HttpStatus.BAD_REQUEST,
203
+ requestId: params.requestId
204
+ });
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Error thrown when a resource is not found (404 errors)
210
+ * Common scenarios:
211
+ * - Resource doesn't exist
212
+ * - Invalid ID provided
213
+ * - Resource deleted
214
+ */
215
+ class NotFoundError extends UiPathError {
216
+ constructor(params = {}) {
217
+ super(ErrorType.NOT_FOUND, {
218
+ message: params.message || ErrorMessages.RESOURCE_NOT_FOUND,
219
+ statusCode: params.statusCode ?? HttpStatus.NOT_FOUND,
220
+ requestId: params.requestId
221
+ });
222
+ }
223
+ }
224
+
225
+ /**
226
+ * Error thrown when rate limit is exceeded (429 errors)
227
+ * Common scenarios:
228
+ * - Too many requests in a time window
229
+ * - API throttling
230
+ */
231
+ class RateLimitError extends UiPathError {
232
+ constructor(params = {}) {
233
+ super(ErrorType.RATE_LIMIT, {
234
+ message: params.message || ErrorMessages.RATE_LIMIT_EXCEEDED,
235
+ statusCode: params.statusCode ?? HttpStatus.TOO_MANY_REQUESTS,
236
+ requestId: params.requestId
237
+ });
238
+ }
239
+ }
240
+
241
+ /**
242
+ * Error thrown when server encounters an error (5xx errors)
243
+ * Common scenarios:
244
+ * - Internal server error
245
+ * - Service unavailable
246
+ * - Gateway timeout
247
+ */
248
+ class ServerError extends UiPathError {
249
+ constructor(params = {}) {
250
+ super(ErrorType.SERVER, {
251
+ message: params.message || ErrorMessages.INTERNAL_SERVER_ERROR,
252
+ statusCode: params.statusCode ?? HttpStatus.INTERNAL_SERVER_ERROR,
253
+ requestId: params.requestId
254
+ });
255
+ }
256
+ /**
257
+ * Checks if this is a temporary error that might succeed on retry
258
+ */
259
+ get isRetryable() {
260
+ return this.statusCode === HttpStatus.BAD_GATEWAY ||
261
+ this.statusCode === HttpStatus.SERVICE_UNAVAILABLE ||
262
+ this.statusCode === HttpStatus.GATEWAY_TIMEOUT;
263
+ }
264
+ }
265
+
266
+ /**
267
+ * Error thrown when network/connection issues occur
268
+ * Common scenarios:
269
+ * - Connection timeout
270
+ * - DNS resolution failure
271
+ * - Network unreachable
272
+ * - Request aborted
273
+ */
274
+ class NetworkError extends UiPathError {
275
+ constructor(params = {}) {
276
+ super(ErrorType.NETWORK, {
277
+ message: params.message || ErrorMessages.NETWORK_ERROR,
278
+ statusCode: params.statusCode, // Network errors typically don't have HTTP status codes
279
+ requestId: params.requestId
280
+ });
281
+ }
282
+ }
283
+
284
+ /**
285
+ * Type guards for error response types
286
+ */
287
+ function isOrchestratorError(error) {
288
+ return typeof error === 'object' &&
289
+ error !== null &&
290
+ 'message' in error &&
291
+ 'errorCode' in error &&
292
+ typeof error.message === 'string' &&
293
+ typeof error.errorCode === 'number';
294
+ }
295
+ function isEntityError(error) {
296
+ return typeof error === 'object' &&
297
+ error !== null &&
298
+ 'error' in error &&
299
+ typeof error.error === 'string';
300
+ }
301
+ function isPimsError(error) {
302
+ return typeof error === 'object' &&
303
+ error !== null &&
304
+ 'type' in error &&
305
+ 'title' in error &&
306
+ 'status' in error &&
307
+ typeof error.type === 'string' &&
308
+ typeof error.title === 'string' &&
309
+ typeof error.status === 'number';
310
+ }
311
+
312
+ /**
313
+ * Parser for Orchestrator/Task error format
314
+ */
315
+ class OrchestratorErrorParser {
316
+ canParse(errorBody) {
317
+ return isOrchestratorError(errorBody);
318
+ }
319
+ parse(errorBody, response) {
320
+ const error = errorBody;
321
+ return {
322
+ message: error.message,
323
+ code: response?.status?.toString(),
324
+ details: {
325
+ errorCode: error.errorCode,
326
+ traceId: error.traceId,
327
+ originalResponse: error
328
+ },
329
+ requestId: error.traceId
330
+ };
331
+ }
332
+ }
333
+ /**
334
+ * Parser for Entity (Data Fabric) error format
335
+ */
336
+ class EntityErrorParser {
337
+ canParse(errorBody) {
338
+ return isEntityError(errorBody);
339
+ }
340
+ parse(errorBody, response) {
341
+ const error = errorBody;
342
+ return {
343
+ message: error.error,
344
+ code: response?.status?.toString(),
345
+ details: {
346
+ error: error.error,
347
+ traceId: error.traceId,
348
+ originalResponse: error
349
+ },
350
+ requestId: error.traceId
351
+ };
352
+ }
353
+ }
354
+ /**
355
+ * Parser for PIMS error format
356
+ */
357
+ class PimsErrorParser {
358
+ canParse(errorBody) {
359
+ return isPimsError(errorBody);
360
+ }
361
+ parse(errorBody, response) {
362
+ const error = errorBody;
363
+ let message = error.title;
364
+ // If there are validation errors, append them to the message for better visibility
365
+ if (error.errors && Object.keys(error.errors).length > 0) {
366
+ const errorMessages = Object.entries(error.errors)
367
+ .map(([field, messages]) => `${field}: ${messages.join(', ')}`)
368
+ .join('; ');
369
+ message += `. Validation errors: ${errorMessages}`;
370
+ }
371
+ return {
372
+ message,
373
+ code: response?.status?.toString(),
374
+ details: {
375
+ type: error.type,
376
+ title: error.title,
377
+ status: error.status,
378
+ errors: error.errors,
379
+ traceId: error.traceId,
380
+ originalResponse: error
381
+ },
382
+ requestId: error.traceId
383
+ };
384
+ }
385
+ }
386
+ /**
387
+ * Fallback parser for unrecognized formats
388
+ */
389
+ class GenericErrorParser {
390
+ canParse(_errorBody) {
391
+ return true; // Always can parse as last resort
392
+ }
393
+ parse(errorBody, response) {
394
+ // For unknown error formats, just pass through the raw error with fallback message
395
+ const message = response?.statusText || 'An error occurred';
396
+ return {
397
+ message,
398
+ code: response?.status?.toString(),
399
+ details: {
400
+ originalResponse: errorBody
401
+ },
402
+ };
403
+ }
404
+ }
405
+ /**
406
+ * Main error response parser using Chain of Responsibility pattern
407
+ *
408
+ * This parser standardizes error responses from different UiPath services into a
409
+ * consistent format, regardless of the original error structure.
410
+ *
411
+ * Supported formats:
412
+ * 1. Orchestrator/Task: { message, errorCode, traceId }
413
+ * 2. Entity (Data Fabric): { error, traceId }
414
+ * 3. PIMS/Maestro: { type, title, status, errors?, traceId? }
415
+ * 4. Generic: Fallback for any other format
416
+ *
417
+ * @example
418
+ * const parser = new ErrorResponseParser();
419
+ * const errorInfo = await parser.parse(response);
420
+ * // errorInfo will have consistent structure regardless of service
421
+ */
422
+ class ErrorResponseParser {
423
+ constructor() {
424
+ this.strategies = [
425
+ new OrchestratorErrorParser(),
426
+ new EntityErrorParser(),
427
+ new PimsErrorParser(),
428
+ new GenericErrorParser() // Must be last
429
+ ];
430
+ }
431
+ /**
432
+ * Parses error response body into standardized format
433
+ * @param response - The HTTP response object
434
+ * @returns Standardized error information
435
+ */
436
+ async parse(response) {
437
+ try {
438
+ const errorBody = await response.json();
439
+ // Find the first strategy that can parse this error format
440
+ const strategy = this.strategies.find(s => s.canParse(errorBody));
441
+ // GenericErrorParser always returns true, so this will never be null
442
+ return strategy.parse(errorBody, response);
443
+ }
444
+ catch {
445
+ // Handle non-JSON responses
446
+ const responseText = await response.text().catch(() => '');
447
+ return {
448
+ message: response.statusText,
449
+ code: response.status.toString(),
450
+ details: {
451
+ parseError: 'Failed to parse error response as JSON',
452
+ responseText
453
+ },
454
+ requestId: response.headers.get(HttpHeaders.X_REQUEST_ID) || undefined
455
+ };
456
+ }
457
+ }
458
+ }
459
+ // Export singleton instance
460
+ const errorResponseParser = new ErrorResponseParser();
461
+
462
+ /**
463
+ * Factory for creating typed errors based on HTTP status codes
464
+ * Follows the Factory pattern for clean error instantiation
465
+ */
466
+ class ErrorFactory {
467
+ /**
468
+ * Creates appropriate error instance based on HTTP status code
469
+ */
470
+ static createFromHttpStatus(statusCode, errorInfo) {
471
+ const { message, requestId } = errorInfo;
472
+ // Map status codes to error types
473
+ switch (statusCode) {
474
+ case HttpStatus.BAD_REQUEST:
475
+ return new ValidationError({ message, statusCode, requestId });
476
+ case HttpStatus.UNAUTHORIZED:
477
+ return new AuthenticationError({ message, statusCode, requestId });
478
+ case HttpStatus.FORBIDDEN:
479
+ return new AuthorizationError({ message, statusCode, requestId });
480
+ case HttpStatus.NOT_FOUND:
481
+ return new NotFoundError({ message, statusCode, requestId });
482
+ case HttpStatus.TOO_MANY_REQUESTS:
483
+ return new RateLimitError({ message, statusCode, requestId });
484
+ default:
485
+ // For 5xx errors or any other status code
486
+ if (statusCode >= HttpStatus.INTERNAL_SERVER_ERROR) {
487
+ return new ServerError({ message, statusCode, requestId });
488
+ }
489
+ // For unknown client errors, treat as validation error
490
+ return new ValidationError({
491
+ message: `${message} (HTTP ${statusCode})`,
492
+ statusCode,
493
+ requestId
494
+ });
495
+ }
496
+ }
497
+ /**
498
+ * Creates a NetworkError from a fetch/network error
499
+ */
500
+ static createNetworkError(error) {
501
+ let message = ErrorMessages.NETWORK_ERROR;
502
+ if (error instanceof Error) {
503
+ if (error.name === ErrorNames.ABORT_ERROR) {
504
+ message = ErrorMessages.REQUEST_ABORTED;
505
+ }
506
+ else if (error.message.includes('timeout')) {
507
+ message = ErrorMessages.REQUEST_TIMEOUT;
508
+ }
509
+ else {
510
+ message = error.message;
511
+ }
512
+ }
513
+ return new NetworkError({ message });
514
+ }
515
+ }
516
+
517
+ const FOLDER_KEY = 'X-UIPATH-FolderKey';
518
+ const FOLDER_ID = 'X-UIPATH-OrganizationUnitId';
519
+ /**
520
+ * Content type constants for HTTP requests/responses
521
+ */
522
+ const CONTENT_TYPES = {
523
+ JSON: 'application/json',
524
+ XML: 'application/xml',
525
+ OCTET_STREAM: 'application/octet-stream'
526
+ };
527
+ /**
528
+ * Response type constants for HTTP requests
529
+ */
530
+ const RESPONSE_TYPES = {
531
+ JSON: 'json',
532
+ TEXT: 'text',
533
+ BLOB: 'blob',
534
+ ARRAYBUFFER: 'arraybuffer'
535
+ };
536
+
537
+ class ApiClient {
538
+ constructor(config, executionContext, tokenManager, clientConfig = {}) {
539
+ this.defaultHeaders = {};
540
+ this.config = config;
541
+ this.executionContext = executionContext;
542
+ this.clientConfig = clientConfig;
543
+ this.tokenManager = tokenManager;
544
+ }
545
+ setDefaultHeaders(headers) {
546
+ this.defaultHeaders = { ...this.defaultHeaders, ...headers };
547
+ }
548
+ /**
549
+ * Gets a valid authentication token, refreshing if necessary.
550
+ * Used internally for API requests and exposed for services that need manual auth headers.
551
+ *
552
+ * @returns The valid token
553
+ * @throws AuthenticationError if no token available or refresh fails
554
+ */
555
+ async getValidToken() {
556
+ // Try to get token info from context
557
+ const tokenInfo = this.executionContext.get('tokenInfo');
558
+ if (!tokenInfo) {
559
+ throw new AuthenticationError({ message: 'No authentication token available. Make sure to initialize the SDK first.' });
560
+ }
561
+ // For secret-based tokens, they never expire
562
+ if (tokenInfo.type === 'secret') {
563
+ return tokenInfo.token;
564
+ }
565
+ // If token is not expired, return it
566
+ if (!this.tokenManager.isTokenExpired(tokenInfo)) {
567
+ return tokenInfo.token;
568
+ }
569
+ try {
570
+ const newToken = await this.tokenManager.refreshAccessToken();
571
+ return newToken.access_token;
572
+ }
573
+ catch (error) {
574
+ throw new AuthenticationError({
575
+ message: `Token refresh failed: ${error.message}. Please re-authenticate.`,
576
+ statusCode: HttpStatus.UNAUTHORIZED
577
+ });
578
+ }
579
+ }
580
+ async getDefaultHeaders() {
581
+ // Get headers from execution context first
582
+ const contextHeaders = this.executionContext.getHeaders();
583
+ // If Authorization header is already set in context, use that
584
+ if (contextHeaders['Authorization']) {
585
+ return {
586
+ ...contextHeaders,
587
+ 'Content-Type': CONTENT_TYPES.JSON,
588
+ ...this.defaultHeaders,
589
+ ...this.clientConfig.headers
590
+ };
591
+ }
592
+ const token = await this.getValidToken();
593
+ return {
594
+ ...contextHeaders,
595
+ 'Authorization': `Bearer ${token}`,
596
+ 'Content-Type': CONTENT_TYPES.JSON,
597
+ ...this.defaultHeaders,
598
+ ...this.clientConfig.headers
599
+ };
600
+ }
601
+ async request(method, path, options = {}) {
602
+ // Ensure path starts with a forward slash
603
+ const normalizedPath = path.startsWith('/') ? path.substring(1) : path;
604
+ // Construct URL with org and tenant names
605
+ const url = new URL(`${this.config.orgName}/${this.config.tenantName}/${normalizedPath}`, this.config.baseUrl).toString();
606
+ const headers = {
607
+ ...await this.getDefaultHeaders(),
608
+ ...options.headers
609
+ };
610
+ // Convert params to URLSearchParams
611
+ const searchParams = new URLSearchParams();
612
+ if (options.params) {
613
+ Object.entries(options.params).forEach(([key, value]) => {
614
+ searchParams.append(key, value.toString());
615
+ });
616
+ }
617
+ const fullUrl = searchParams.toString() ? `${url}?${searchParams.toString()}` : url;
618
+ try {
619
+ const response = await fetch(fullUrl, {
620
+ method,
621
+ headers,
622
+ body: options.body ? JSON.stringify(options.body) : undefined,
623
+ signal: options.signal
624
+ });
625
+ if (!response.ok) {
626
+ const errorInfo = await errorResponseParser.parse(response);
627
+ throw ErrorFactory.createFromHttpStatus(response.status, errorInfo);
628
+ }
629
+ if (response.status === 204) {
630
+ return undefined;
631
+ }
632
+ // Handle blob response type for binary data (e.g., file downloads)
633
+ if (options.responseType === RESPONSE_TYPES.BLOB) {
634
+ const blob = await response.blob();
635
+ return blob;
636
+ }
637
+ // Check if we're expecting XML
638
+ const acceptHeader = headers['Accept'] || headers['accept'];
639
+ if (acceptHeader === CONTENT_TYPES.XML) {
640
+ const text = await response.text();
641
+ return text;
642
+ }
643
+ return response.json();
644
+ }
645
+ catch (error) {
646
+ // If it's already one of our errors, re-throw it
647
+ if (error.type && error.type.includes('Error')) {
648
+ throw error;
649
+ }
650
+ // Otherwise, it's likely a network error
651
+ throw ErrorFactory.createNetworkError(error);
652
+ }
653
+ }
654
+ async get(path, options = {}) {
655
+ return this.request('GET', path, options);
656
+ }
657
+ async post(path, data, options = {}) {
658
+ return this.request('POST', path, { ...options, body: data });
659
+ }
660
+ async put(path, data, options = {}) {
661
+ return this.request('PUT', path, { ...options, body: data });
662
+ }
663
+ async patch(path, data, options = {}) {
664
+ return this.request('PATCH', path, { ...options, body: data });
665
+ }
666
+ async delete(path, options = {}) {
667
+ return this.request('DELETE', path, options);
668
+ }
669
+ }
670
+
671
+ /**
672
+ * Pagination types supported by the SDK
673
+ */
674
+ var PaginationType;
675
+ (function (PaginationType) {
676
+ PaginationType["OFFSET"] = "offset";
677
+ PaginationType["TOKEN"] = "token";
678
+ })(PaginationType || (PaginationType = {}));
679
+
680
+ /**
681
+ * Collection of utility functions for working with objects
682
+ */
683
+ /**
684
+ * Filters out undefined values from an object
685
+ * @param obj The source object
686
+ * @returns A new object without undefined values
687
+ *
688
+ * @example
689
+ * ```typescript
690
+ * // Object with undefined values
691
+ * const options = {
692
+ * name: 'test',
693
+ * count: 5,
694
+ * prefix: undefined,
695
+ * suffix: null
696
+ * };
697
+ * const result = filterUndefined(options);
698
+ * // result = { name: 'test', count: 5, suffix: null }
699
+ * ```
700
+ */
701
+ function filterUndefined(obj) {
702
+ const result = {};
703
+ for (const [key, value] of Object.entries(obj)) {
704
+ if (value !== undefined) {
705
+ result[key] = value;
706
+ }
707
+ }
708
+ return result;
709
+ }
710
+ /**
711
+ * Helper function for OData responses that ALWAYS return 200 with array indication
712
+ * Empty array = success, Non-empty array = error
713
+ * Used for task assignment APIs that don't use HTTP status codes for errors
714
+ */
715
+ function processODataArrayResponse(oDataResponse, successData) {
716
+ // Empty array = success
717
+ if (oDataResponse.value.length === 0) {
718
+ return {
719
+ success: true,
720
+ data: successData
721
+ };
722
+ }
723
+ // Non-empty array = error details
724
+ return {
725
+ success: false,
726
+ data: oDataResponse.value
727
+ };
728
+ }
729
+
730
+ /**
731
+ * Utility functions for platform detection
732
+ */
733
+ /**
734
+ * Checks if code is running in a browser environment
735
+ */
736
+ const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
737
+
738
+ /**
739
+ * Base64 encoding/decoding
740
+ */
741
+ /**
742
+ * Encodes a string to base64
743
+ * @param str - The string to encode
744
+ * @returns Base64 encoded string
745
+ */
746
+ function encodeBase64(str) {
747
+ // TextEncoder for UTF-8 encoding (works in both browser and Node.js)
748
+ const encoder = new TextEncoder();
749
+ const data = encoder.encode(str);
750
+ // Convert Uint8Array to base64
751
+ if (isBrowser) {
752
+ // Browser environment
753
+ // Convert Uint8Array to binary string then to base64
754
+ const binaryString = Array.from(data, byte => String.fromCharCode(byte)).join('');
755
+ return btoa(binaryString);
756
+ }
757
+ else {
758
+ // Node.js environment
759
+ return Buffer.from(data).toString('base64');
760
+ }
761
+ }
762
+ /**
763
+ * Decodes a base64 string
764
+ * @param base64 - The base64 string to decode
765
+ * @returns Decoded string
766
+ */
767
+ function decodeBase64(base64) {
768
+ let bytes;
769
+ if (isBrowser) {
770
+ // Browser environment
771
+ const binaryString = atob(base64);
772
+ bytes = new Uint8Array(binaryString.length);
773
+ for (let i = 0; i < binaryString.length; i++) {
774
+ bytes[i] = binaryString.charCodeAt(i);
775
+ }
776
+ }
777
+ else {
778
+ // Node.js environment
779
+ bytes = new Uint8Array(Buffer.from(base64, 'base64'));
780
+ }
781
+ // TextDecoder for UTF-8 decoding (works in both browser and Node.js)
782
+ const decoder = new TextDecoder();
783
+ return decoder.decode(bytes);
784
+ }
785
+
786
+ /**
787
+ * PaginationManager handles the conversion between uniform cursor-based pagination
788
+ * and the specific pagination type for each service
789
+ */
790
+ class PaginationManager {
791
+ /**
792
+ * Create a pagination cursor for subsequent page requests
793
+ */
794
+ static createCursor({ pageInfo, type }) {
795
+ if (!pageInfo.hasMore) {
796
+ return undefined;
797
+ }
798
+ const cursorData = {
799
+ type,
800
+ pageSize: pageInfo.pageSize,
801
+ };
802
+ switch (type) {
803
+ case PaginationType.OFFSET:
804
+ if (pageInfo.currentPage) {
805
+ cursorData.pageNumber = pageInfo.currentPage + 1;
806
+ }
807
+ break;
808
+ case PaginationType.TOKEN:
809
+ if (pageInfo.continuationToken) {
810
+ cursorData.continuationToken = pageInfo.continuationToken;
811
+ }
812
+ else {
813
+ return undefined; // No continuation token, can't continue
814
+ }
815
+ break;
816
+ }
817
+ return {
818
+ value: encodeBase64(JSON.stringify(cursorData))
819
+ };
820
+ }
821
+ /**
822
+ * Create a paginated response with navigation cursors
823
+ */
824
+ static createPaginatedResponse({ pageInfo, type }, items) {
825
+ const nextCursor = PaginationManager.createCursor({ pageInfo, type });
826
+ // Create previous page cursor if applicable
827
+ let previousCursor = undefined;
828
+ if (pageInfo.currentPage && pageInfo.currentPage > 1) {
829
+ const prevCursorData = {
830
+ type,
831
+ pageNumber: pageInfo.currentPage - 1,
832
+ pageSize: pageInfo.pageSize,
833
+ };
834
+ previousCursor = {
835
+ value: encodeBase64(JSON.stringify(prevCursorData))
836
+ };
837
+ }
838
+ // Calculate total pages if we have totalCount and pageSize
839
+ let totalPages = undefined;
840
+ if (pageInfo.totalCount !== undefined && pageInfo.pageSize) {
841
+ totalPages = Math.ceil(pageInfo.totalCount / pageInfo.pageSize);
842
+ }
843
+ // Determine if this pagination type supports page jumping
844
+ const supportsPageJump = type === PaginationType.OFFSET;
845
+ // Create the result object with all fields, then filter out undefined values
846
+ const result = filterUndefined({
847
+ items,
848
+ totalCount: pageInfo.totalCount,
849
+ hasNextPage: pageInfo.hasMore,
850
+ nextCursor: nextCursor,
851
+ previousCursor: previousCursor,
852
+ currentPage: pageInfo.currentPage,
853
+ totalPages,
854
+ supportsPageJump
855
+ });
856
+ return result;
857
+ }
858
+ }
859
+
860
+ /**
861
+ * Creates headers object from key-value pairs
862
+ * @param headersObj - Object containing header key-value pairs
863
+ * @returns Headers object with all values converted to strings
864
+ *
865
+ * @example
866
+ * ```typescript
867
+ * // Single header
868
+ * const headers = createHeaders({ 'X-UIPATH-FolderKey': '1234567890' });
869
+ *
870
+ * // Multiple headers
871
+ * const headers = createHeaders({
872
+ * 'X-UIPATH-FolderKey': '1234567890',
873
+ * 'X-UIPATH-OrganizationUnitId': 123,
874
+ * 'Accept': 'application/json'
875
+ * });
876
+ *
877
+ * // Using constants
878
+ * import { FOLDER_KEY, FOLDER_ID } from '../constants/headers';
879
+ * const headers = createHeaders({
880
+ * [FOLDER_KEY]: 'abc-123',
881
+ * [FOLDER_ID]: 456
882
+ * });
883
+ *
884
+ * // Empty headers
885
+ * const headers = createHeaders();
886
+ * ```
887
+ */
888
+ function createHeaders(headersObj) {
889
+ const headers = {};
890
+ for (const [key, value] of Object.entries(headersObj)) {
891
+ if (value !== undefined && value !== null) {
892
+ headers[key] = value.toString();
893
+ }
894
+ }
895
+ return headers;
896
+ }
897
+
898
+ /**
899
+ * Common constants used across the SDK
900
+ */
901
+ /**
902
+ * Prefix used for OData query parameters
903
+ */
904
+ const ODATA_PREFIX = '$';
905
+ /**
906
+ * HTTP methods
907
+ */
908
+ const HTTP_METHODS = {
909
+ GET: 'GET',
910
+ POST: 'POST'};
911
+ /**
912
+ * OData pagination constants
913
+ */
914
+ const ODATA_PAGINATION = {
915
+ /** Default field name for items in a paginated OData response */
916
+ ITEMS_FIELD: 'value',
917
+ /** Default field name for total count in a paginated OData response */
918
+ TOTAL_COUNT_FIELD: '@odata.count'
919
+ };
920
+ /**
921
+ * Process Instance pagination constants for token-based pagination
922
+ */
923
+ const PROCESS_INSTANCE_PAGINATION = {
924
+ /** Field name for items in process instance response */
925
+ ITEMS_FIELD: 'instances',
926
+ /** Field name for continuation token in process instance response */
927
+ CONTINUATION_TOKEN_FIELD: 'nextPage'
928
+ };
929
+ /**
930
+ * OData OFFSET pagination parameter names (ODATA-style)
931
+ */
932
+ const ODATA_OFFSET_PARAMS = {
933
+ /** OData page size parameter name */
934
+ PAGE_SIZE_PARAM: '$top',
935
+ /** OData offset parameter name */
936
+ OFFSET_PARAM: '$skip',
937
+ /** OData count parameter name */
938
+ COUNT_PARAM: '$count'
939
+ };
940
+ /**
941
+ * Bucket TOKEN pagination parameter names
942
+ */
943
+ const BUCKET_TOKEN_PARAMS = {
944
+ /** Bucket page size parameter name */
945
+ PAGE_SIZE_PARAM: 'takeHint',
946
+ /** Bucket token parameter name */
947
+ TOKEN_PARAM: 'continuationToken'
948
+ };
949
+ /**
950
+ * Process Instance TOKEN pagination parameter names
951
+ */
952
+ const PROCESS_INSTANCE_TOKEN_PARAMS = {
953
+ /** Process instance page size parameter name */
954
+ PAGE_SIZE_PARAM: 'pageSize',
955
+ /** Process instance token parameter name */
956
+ TOKEN_PARAM: 'nextPage'
957
+ };
958
+
959
+ /**
960
+ * Transforms data by mapping fields according to the provided field mapping
961
+ * @param data The source data to transform
962
+ * @param fieldMapping Object mapping source field names to target field names
963
+ * @returns Transformed data with mapped field names
964
+ *
965
+ * @example
966
+ * ```typescript
967
+ * // Single object transformation
968
+ * const data = { id: '123', userName: 'john' };
969
+ * const mapping = { id: 'userId', userName: 'name' };
970
+ * const result = transformData(data, mapping);
971
+ * // result = { userId: '123', name: 'john' }
972
+ *
973
+ * // Array transformation
974
+ * const dataArray = [
975
+ * { id: '123', userName: 'john' },
976
+ * { id: '456', userName: 'jane' }
977
+ * ];
978
+ * const result = transformData(dataArray, mapping);
979
+ * // result = [
980
+ * // { userId: '123', name: 'john' },
981
+ * // { userId: '456', name: 'jane' }
982
+ * // ]
983
+ * ```
984
+ */
985
+ function transformData(data, fieldMapping) {
986
+ // Handle array of objects
987
+ if (Array.isArray(data)) {
988
+ return data.map(item => transformData(item, fieldMapping));
989
+ }
990
+ // Handle single object
991
+ const result = { ...data };
992
+ for (const [sourceField, targetField] of Object.entries(fieldMapping)) {
993
+ if (sourceField in result) {
994
+ const value = result[sourceField];
995
+ delete result[sourceField];
996
+ result[targetField] = value;
997
+ }
998
+ }
999
+ return result;
1000
+ }
1001
+ /**
1002
+ * Converts a string from PascalCase to camelCase
1003
+ * @param str The PascalCase string to convert
1004
+ * @returns The camelCase version of the string
1005
+ *
1006
+ * @example
1007
+ * ```typescript
1008
+ * pascalToCamelCase('HelloWorld'); // 'helloWorld'
1009
+ * pascalToCamelCase('TaskAssignmentCriteria'); // 'taskAssignmentCriteria'
1010
+ * ```
1011
+ */
1012
+ function pascalToCamelCase(str) {
1013
+ if (!str)
1014
+ return str;
1015
+ return str.charAt(0).toLowerCase() + str.slice(1);
1016
+ }
1017
+ /**
1018
+ * Converts a string from camelCase to PascalCase
1019
+ * @param str The camelCase string to convert
1020
+ * @returns The PascalCase version of the string
1021
+ *
1022
+ * @example
1023
+ * ```typescript
1024
+ * camelToPascalCase('helloWorld'); // 'HelloWorld'
1025
+ * camelToPascalCase('taskAssignmentCriteria'); // 'TaskAssignmentCriteria'
1026
+ * ```
1027
+ */
1028
+ function camelToPascalCase(str) {
1029
+ if (!str)
1030
+ return str;
1031
+ return str.charAt(0).toUpperCase() + str.slice(1);
1032
+ }
1033
+ /**
1034
+ * Generic function to transform object keys using a provided case conversion function
1035
+ * @param data The object to transform
1036
+ * @param convertCase The function to convert each key
1037
+ * @returns A new object with transformed keys
1038
+ */
1039
+ function transformCaseKeys(data, convertCase) {
1040
+ // Handle array of objects
1041
+ if (Array.isArray(data)) {
1042
+ return data.map(item => {
1043
+ // If the array element is a primitive (string, number, etc.), return it as is
1044
+ if (item === null || typeof item !== 'object' || typeof item === 'string') {
1045
+ return item;
1046
+ }
1047
+ // Only recursively transform if it's actually an object
1048
+ return transformCaseKeys(item, convertCase);
1049
+ });
1050
+ }
1051
+ const result = {};
1052
+ for (const [key, value] of Object.entries(data)) {
1053
+ const transformedKey = convertCase(key);
1054
+ // Recursively transform nested objects and arrays
1055
+ if (value !== null && typeof value === 'object') {
1056
+ result[transformedKey] = transformCaseKeys(value, convertCase);
1057
+ }
1058
+ else {
1059
+ result[transformedKey] = value;
1060
+ }
1061
+ }
1062
+ return result;
1063
+ }
1064
+ /**
1065
+ * Transforms an object's keys from PascalCase to camelCase
1066
+ * @param data The object with PascalCase keys
1067
+ * @returns A new object with all keys converted to camelCase
1068
+ *
1069
+ * @example
1070
+ * ```typescript
1071
+ * // Simple object
1072
+ * pascalToCamelCaseKeys({ Id: "123", TaskName: "Invoice" });
1073
+ * // Result: { id: "123", taskName: "Invoice" }
1074
+ *
1075
+ * // Nested object
1076
+ * pascalToCamelCaseKeys({
1077
+ * TaskId: "456",
1078
+ * TaskDetails: { AssignedUser: "John", Priority: "High" }
1079
+ * });
1080
+ * // Result: {
1081
+ * // taskId: "456",
1082
+ * // taskDetails: { assignedUser: "John", priority: "High" }
1083
+ * // }
1084
+ *
1085
+ * // Array of objects
1086
+ * pascalToCamelCaseKeys([
1087
+ * { Id: "1", IsComplete: false },
1088
+ * { Id: "2", IsComplete: true }
1089
+ * ]);
1090
+ * // Result: [
1091
+ * // { id: "1", isComplete: false },
1092
+ * // { id: "2", isComplete: true }
1093
+ * // ]
1094
+ * ```
1095
+ */
1096
+ function pascalToCamelCaseKeys(data) {
1097
+ return transformCaseKeys(data, pascalToCamelCase);
1098
+ }
1099
+ /**
1100
+ * Transforms an object's keys from camelCase to PascalCase
1101
+ * @param data The object with camelCase keys
1102
+ * @returns A new object with all keys converted to PascalCase
1103
+ *
1104
+ * @example
1105
+ * ```typescript
1106
+ * // Simple object
1107
+ * camelToPascalCaseKeys({ userId: "789", isActive: true });
1108
+ * // Result: { UserId: "789", IsActive: true }
1109
+ *
1110
+ * // Nested object
1111
+ * camelToPascalCaseKeys({
1112
+ * taskId: "ABC123",
1113
+ * submissionData: { customerName: "XYZ Corp" }
1114
+ * });
1115
+ * // Result: {
1116
+ * // TaskId: "ABC123",
1117
+ * // SubmissionData: { CustomerName: "XYZ Corp" }
1118
+ * // }
1119
+ *
1120
+ * // Array of objects
1121
+ * camelToPascalCaseKeys([
1122
+ * { userId: "u1", roleType: "admin" },
1123
+ * { userId: "u2", roleType: "user" }
1124
+ * ]);
1125
+ * // Result: [
1126
+ * // { UserId: "u1", RoleType: "admin" },
1127
+ * // { UserId: "u2", RoleType: "user" }
1128
+ * // ]
1129
+ * ```
1130
+ */
1131
+ function camelToPascalCaseKeys(data) {
1132
+ return transformCaseKeys(data, camelToPascalCase);
1133
+ }
1134
+ /**
1135
+ * Maps a field value in an object using a provided mapping object.
1136
+ * Returns a new object with the mapped field value.
1137
+ *
1138
+ * @param obj The object to map
1139
+ * @param field The field name to map
1140
+ * @param valueMap The mapping object (from input value to output value)
1141
+ * @returns A new object with the mapped field value
1142
+ *
1143
+ * @example
1144
+ * const statusMap = { 0: 'Unassigned', 1: 'Pending', 2: 'Completed' };
1145
+ * const task = { status: 1, id: 123 };
1146
+ * const mapped = mapFieldValue(task, 'status', statusMap);
1147
+ * // mapped = { status: 'Pending', id: 123 }
1148
+ */
1149
+ function _mapFieldValue(obj, field, valueMap) {
1150
+ const lookupKey = String(obj[field]);
1151
+ return {
1152
+ ...obj,
1153
+ [field]: lookupKey in valueMap
1154
+ ? valueMap[lookupKey]
1155
+ : obj[field],
1156
+ };
1157
+ }
1158
+ /**
1159
+ * General API response transformer with optional field value mapping.
1160
+ *
1161
+ * @param data - The API response data to transform
1162
+ * @param options - Optional mapping options:
1163
+ * - field: The field name to map (optional)
1164
+ * - valueMap: The mapping object for the field (optional)
1165
+ * - transform: A function to further transform the data (optional)
1166
+ * @returns The transformed data, with field value mapped if specified
1167
+ *
1168
+ * @example
1169
+ * // Just transform
1170
+ * const result = applyDataTransforms(data);
1171
+ *
1172
+ * // Map a field value, then transform
1173
+ * const result = applyDataTransforms(data, { field: 'status', valueMap: StatusMap });
1174
+ *
1175
+ * // Map a field value, then apply a custom transform
1176
+ * const result = applyDataTransforms(data, { field: 'status', valueMap: StatusMap, transform: customTransform });
1177
+ */
1178
+ function applyDataTransforms(data, options) {
1179
+ let result = data;
1180
+ if (options?.field && options?.valueMap) {
1181
+ result = _mapFieldValue(result, options.field, options.valueMap);
1182
+ }
1183
+ if (options?.transform) {
1184
+ result = options.transform(result);
1185
+ }
1186
+ return result;
1187
+ }
1188
+ /**
1189
+ * Adds a prefix to specified keys in an object, returning a new object.
1190
+ * Only the provided keys are prefixed; all others are left unchanged.
1191
+ *
1192
+ * @param obj The source object
1193
+ * @param prefix The prefix to add (e.g., '$')
1194
+ * @param keys The keys to prefix (e.g., ['expand', 'filter'])
1195
+ * @returns A new object with specified keys prefixed
1196
+ *
1197
+ * @example
1198
+ * addPrefixToKeys({ expand: 'a', foo: 1 }, '$', ['expand']) // { $expand: 'a', foo: 1 }
1199
+ */
1200
+ function addPrefixToKeys(obj, prefix, keys) {
1201
+ const result = {};
1202
+ for (const [key, value] of Object.entries(obj)) {
1203
+ if (keys.includes(key)) {
1204
+ result[`${prefix}${key}`] = value;
1205
+ }
1206
+ else {
1207
+ result[key] = value;
1208
+ }
1209
+ }
1210
+ return result;
1211
+ }
1212
+
1213
+ /**
1214
+ * Constants used throughout the pagination system
1215
+ */
1216
+ /** Maximum number of items that can be requested in a single page */
1217
+ const MAX_PAGE_SIZE = 1000;
1218
+ /** Default page size when jumpToPage is used without specifying pageSize */
1219
+ const DEFAULT_PAGE_SIZE = 50;
1220
+ /** Default field name for items in a paginated response */
1221
+ const DEFAULT_ITEMS_FIELD = 'value';
1222
+ /** Default field name for total count in a paginated response */
1223
+ const DEFAULT_TOTAL_COUNT_FIELD = '@odata.count';
1224
+ /**
1225
+ * Limits the page size to the maximum allowed value
1226
+ * @param pageSize - Requested page size
1227
+ * @returns Limited page size value
1228
+ */
1229
+ function getLimitedPageSize(pageSize) {
1230
+ if (pageSize === undefined || pageSize === null) {
1231
+ return DEFAULT_PAGE_SIZE;
1232
+ }
1233
+ return Math.max(1, Math.min(pageSize, MAX_PAGE_SIZE));
1234
+ }
1235
+
1236
+ /**
1237
+ * Helper functions for pagination that can be used across services
1238
+ */
1239
+ class PaginationHelpers {
1240
+ /**
1241
+ * Checks if any pagination parameters are provided
1242
+ *
1243
+ * @param options - The options object to check
1244
+ * @returns True if any pagination parameter is defined, false otherwise
1245
+ */
1246
+ static hasPaginationParameters(options = {}) {
1247
+ const { cursor, pageSize, jumpToPage } = options;
1248
+ return cursor !== undefined || pageSize !== undefined || jumpToPage !== undefined;
1249
+ }
1250
+ /**
1251
+ * Parse a pagination cursor string into cursor data
1252
+ */
1253
+ static parseCursor(cursorString) {
1254
+ try {
1255
+ const cursorData = JSON.parse(decodeBase64(cursorString));
1256
+ return cursorData;
1257
+ }
1258
+ catch {
1259
+ throw new Error('Invalid pagination cursor');
1260
+ }
1261
+ }
1262
+ /**
1263
+ * Validates cursor format and structure
1264
+ *
1265
+ * @param paginationOptions - The pagination options containing the cursor
1266
+ * @param paginationType - Optional pagination type to validate against
1267
+ */
1268
+ static validateCursor(paginationOptions, paginationType) {
1269
+ if (paginationOptions.cursor !== undefined) {
1270
+ if (!paginationOptions.cursor || typeof paginationOptions.cursor.value !== 'string' || !paginationOptions.cursor.value) {
1271
+ throw new Error('cursor must contain a valid cursor string');
1272
+ }
1273
+ try {
1274
+ // Try to parse the cursor to validate it
1275
+ const cursorData = PaginationHelpers.parseCursor(paginationOptions.cursor.value);
1276
+ // If type is provided, validate cursor contains expected type information
1277
+ if (paginationType) {
1278
+ if (!cursorData.type) {
1279
+ throw new Error('Invalid cursor: missing pagination type');
1280
+ }
1281
+ // Check pagination type compatibility
1282
+ if (cursorData.type !== paginationType) {
1283
+ throw new Error(`Pagination type mismatch: cursor is for ${cursorData.type} but service uses ${paginationType}`);
1284
+ }
1285
+ }
1286
+ }
1287
+ catch (error) {
1288
+ if (error instanceof Error) {
1289
+ // If it's already our error with specific message, pass it through
1290
+ if (error.message.startsWith('Invalid cursor') ||
1291
+ error.message.startsWith('Pagination type mismatch')) {
1292
+ throw error;
1293
+ }
1294
+ }
1295
+ throw new Error('Invalid pagination cursor format');
1296
+ }
1297
+ }
1298
+ }
1299
+ /**
1300
+ * Comprehensive validation for pagination options
1301
+ *
1302
+ * @param options - The pagination options to validate
1303
+ * @param paginationType - The pagination type these options will be used with
1304
+ * @returns Processed pagination parameters ready for use
1305
+ */
1306
+ static validatePaginationOptions(options, paginationType) {
1307
+ // Validate pageSize
1308
+ if (options.pageSize !== undefined && options.pageSize <= 0) {
1309
+ throw new Error('pageSize must be a positive number');
1310
+ }
1311
+ // Validate jumpToPage
1312
+ if (options.jumpToPage !== undefined && options.jumpToPage <= 0) {
1313
+ throw new Error('jumpToPage must be a positive number');
1314
+ }
1315
+ // Validate cursor
1316
+ PaginationHelpers.validateCursor(options, paginationType);
1317
+ // Validate service compatibility
1318
+ if (options.jumpToPage !== undefined && paginationType === PaginationType.TOKEN) {
1319
+ throw new Error('jumpToPage is not supported for token-based pagination. Use cursor-based navigation instead.');
1320
+ }
1321
+ // Get processed parameters
1322
+ return PaginationHelpers.getRequestParameters(options, paginationType);
1323
+ }
1324
+ /**
1325
+ * Convert a unified pagination options to service-specific parameters
1326
+ */
1327
+ static getRequestParameters(options, paginationType) {
1328
+ // Handle jumpToPage
1329
+ if (options.jumpToPage !== undefined) {
1330
+ const jumpToPageOptions = {
1331
+ pageSize: options.pageSize,
1332
+ pageNumber: options.jumpToPage
1333
+ };
1334
+ return filterUndefined(jumpToPageOptions);
1335
+ }
1336
+ // If no cursor is provided, it's a first page request
1337
+ if (!options.cursor) {
1338
+ const firstPageOptions = {
1339
+ pageSize: options.pageSize,
1340
+ // Only set pageNumber for OFFSET pagination
1341
+ pageNumber: paginationType === PaginationType.OFFSET ? 1 : undefined
1342
+ };
1343
+ return filterUndefined(firstPageOptions);
1344
+ }
1345
+ // Parse the cursor
1346
+ try {
1347
+ const cursorData = PaginationHelpers.parseCursor(options.cursor.value);
1348
+ const cursorBasedOptions = {
1349
+ pageSize: cursorData.pageSize || options.pageSize,
1350
+ pageNumber: cursorData.pageNumber,
1351
+ continuationToken: cursorData.continuationToken,
1352
+ type: cursorData.type,
1353
+ };
1354
+ return filterUndefined(cursorBasedOptions);
1355
+ }
1356
+ catch {
1357
+ throw new Error('Invalid pagination cursor');
1358
+ }
1359
+ }
1360
+ /**
1361
+ * Helper method for paginated resource retrieval
1362
+ *
1363
+ * @param params - Parameters for pagination
1364
+ * @returns Promise resolving to a paginated result
1365
+ */
1366
+ static async getAllPaginated(params) {
1367
+ const { serviceAccess, getEndpoint, folderId, paginationParams, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1368
+ const endpoint = getEndpoint(folderId);
1369
+ const headers = folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {};
1370
+ const paginatedResponse = await serviceAccess.requestWithPagination(method, endpoint, paginationParams, {
1371
+ headers,
1372
+ params: additionalParams,
1373
+ pagination: {
1374
+ paginationType: options.paginationType || PaginationType.OFFSET,
1375
+ itemsField: options.itemsField || DEFAULT_ITEMS_FIELD,
1376
+ totalCountField: options.totalCountField || DEFAULT_TOTAL_COUNT_FIELD,
1377
+ continuationTokenField: options.continuationTokenField,
1378
+ paginationParams: options.paginationParams
1379
+ }
1380
+ });
1381
+ // Parse items - automatically handle JSON string responses
1382
+ const rawItems = paginatedResponse.items;
1383
+ const parsedItems = typeof rawItems === 'string' ? JSON.parse(rawItems) : (rawItems || []);
1384
+ const transformedItems = transformFn ? parsedItems.map(transformFn) : parsedItems;
1385
+ return {
1386
+ ...paginatedResponse,
1387
+ items: transformedItems
1388
+ };
1389
+ }
1390
+ /**
1391
+ * Helper method for non-paginated resource retrieval
1392
+ *
1393
+ * @param params - Parameters for non-paginated resource retrieval
1394
+ * @returns Promise resolving to an object with data and totalCount
1395
+ */
1396
+ static async getAllNonPaginated(params) {
1397
+ const { serviceAccess, getAllEndpoint, getByFolderEndpoint, folderId, additionalParams, transformFn, method = HTTP_METHODS.GET, options = {} } = params;
1398
+ // Set default field names
1399
+ const itemsField = options.itemsField || DEFAULT_ITEMS_FIELD;
1400
+ const totalCountField = options.totalCountField || DEFAULT_TOTAL_COUNT_FIELD;
1401
+ // Determine endpoint and headers based on folderId
1402
+ const endpoint = folderId ? getByFolderEndpoint : getAllEndpoint;
1403
+ const headers = folderId ? createHeaders({ [FOLDER_ID]: folderId }) : {};
1404
+ // Make the API call based on method
1405
+ let response;
1406
+ if (method === HTTP_METHODS.POST) {
1407
+ response = await serviceAccess.post(endpoint, additionalParams, { headers });
1408
+ }
1409
+ else {
1410
+ response = await serviceAccess.get(endpoint, {
1411
+ params: additionalParams,
1412
+ headers
1413
+ });
1414
+ }
1415
+ // Extract and transform items from response
1416
+ const rawItems = response.data?.[itemsField];
1417
+ const totalCount = response.data?.[totalCountField];
1418
+ // Parse items - automatically handle JSON string responses
1419
+ const parsedItems = typeof rawItems === 'string' ? JSON.parse(rawItems) : (rawItems || []);
1420
+ const items = transformFn ? parsedItems.map(transformFn) : parsedItems;
1421
+ return {
1422
+ items,
1423
+ totalCount
1424
+ };
1425
+ }
1426
+ /**
1427
+ * Centralized getAll implementation that handles both paginated and non-paginated requests
1428
+ *
1429
+ * @param config - Configuration for the getAll operation
1430
+ * @param options - Request options including pagination parameters
1431
+ * @returns Promise resolving to either paginated or non-paginated response based on options
1432
+ */
1433
+ static async getAll(config, options) {
1434
+ const optionsWithDefaults = options || {};
1435
+ const { folderId, ...restOptions } = optionsWithDefaults;
1436
+ const cursor = options?.cursor;
1437
+ const pageSize = options?.pageSize;
1438
+ const jumpToPage = options?.jumpToPage;
1439
+ // Determine if pagination is requested
1440
+ const isPaginationRequested = PaginationHelpers.hasPaginationParameters(options || {});
1441
+ // Process parameters (custom processing if provided, otherwise default)
1442
+ let processedOptions = restOptions;
1443
+ if (config.processParametersFn) {
1444
+ processedOptions = config.processParametersFn(restOptions, folderId);
1445
+ }
1446
+ // Apply ODATA prefix to keys (excluding specified keys)
1447
+ const excludeKeys = config.excludeFromPrefix || [];
1448
+ const keysToPrefix = Object.keys(processedOptions).filter(k => !excludeKeys.includes(k));
1449
+ const prefixedOptions = addPrefixToKeys(processedOptions, ODATA_PREFIX, keysToPrefix);
1450
+ // Default pagination options
1451
+ const paginationOptions = {
1452
+ paginationType: PaginationType.OFFSET,
1453
+ itemsField: DEFAULT_ITEMS_FIELD,
1454
+ totalCountField: DEFAULT_TOTAL_COUNT_FIELD,
1455
+ ...config.pagination
1456
+ };
1457
+ // Paginated flow
1458
+ if (isPaginationRequested) {
1459
+ return PaginationHelpers.getAllPaginated({
1460
+ serviceAccess: config.serviceAccess,
1461
+ getEndpoint: config.getEndpoint,
1462
+ folderId,
1463
+ paginationParams: cursor ? { cursor, pageSize } : jumpToPage ? { jumpToPage, pageSize } : { pageSize },
1464
+ additionalParams: prefixedOptions,
1465
+ transformFn: config.transformFn,
1466
+ method: config.method,
1467
+ options: {
1468
+ ...paginationOptions,
1469
+ paginationParams: config.pagination?.paginationParams
1470
+ }
1471
+ }); // Type assertion needed due to conditional return
1472
+ }
1473
+ // Non-paginated flow
1474
+ const byFolderEndpoint = config.getByFolderEndpoint || config.getEndpoint(folderId);
1475
+ return PaginationHelpers.getAllNonPaginated({
1476
+ serviceAccess: config.serviceAccess,
1477
+ getAllEndpoint: config.getEndpoint(),
1478
+ getByFolderEndpoint: byFolderEndpoint,
1479
+ folderId,
1480
+ additionalParams: prefixedOptions,
1481
+ transformFn: config.transformFn,
1482
+ method: config.method,
1483
+ options: {
1484
+ itemsField: paginationOptions.itemsField,
1485
+ totalCountField: paginationOptions.totalCountField
1486
+ }
1487
+ });
1488
+ }
1489
+ }
1490
+
1491
+ /**
1492
+ * SDK Internals Registry - Internal registry for SDK instances
1493
+ *
1494
+ * This class is NOT exported in the public API.
1495
+ * It provides a secure way to share SDK internals between
1496
+ * the UiPath class and service classes without exposing them publicly.
1497
+ *
1498
+ * @internal
1499
+ */
1500
+ // Global symbol key to ensure WeakMap is shared across module instances
1501
+ // This prevents issues when core and service modules are bundled separately
1502
+ const REGISTRY_KEY = Symbol.for('@uipath/sdk-internals-registry');
1503
+ // Get or create the global WeakMap store
1504
+ const getGlobalStore = () => {
1505
+ const globalObj = globalThis;
1506
+ if (!globalObj[REGISTRY_KEY]) {
1507
+ globalObj[REGISTRY_KEY] = new WeakMap();
1508
+ }
1509
+ return globalObj[REGISTRY_KEY];
1510
+ };
1511
+ /**
1512
+ * Internal registry for SDK private components.
1513
+ * Uses WeakMap to prevent memory leaks - entries are automatically
1514
+ * garbage collected when the SDK instance is no longer referenced.
1515
+ *
1516
+ * Uses a global singleton pattern to ensure the same WeakMap is shared
1517
+ * across separately bundled modules (core, entities, tasks, etc.).
1518
+ *
1519
+ * @internal - Not exported in public API
1520
+ */
1521
+ class SDKInternalsRegistry {
1522
+ // Use global store to ensure sharing across module bundles
1523
+ static get store() {
1524
+ return getGlobalStore();
1525
+ }
1526
+ /**
1527
+ * Register SDK instance internals
1528
+ * Called by UiPath constructor
1529
+ */
1530
+ static set(instance, internals) {
1531
+ this.store.set(instance, internals);
1532
+ }
1533
+ /**
1534
+ * Retrieve SDK instance internals
1535
+ * Called by BaseService constructor
1536
+ */
1537
+ static get(instance) {
1538
+ const internals = this.store.get(instance);
1539
+ if (!internals) {
1540
+ throw new Error('Invalid SDK instance. Make sure to pass a valid UiPath instance to the service constructor.');
1541
+ }
1542
+ return internals;
1543
+ }
1544
+ }
1545
+
1546
+ var _BaseService_apiClient;
1547
+ /**
1548
+ * Base class for all UiPath SDK services.
1549
+ *
1550
+ * Provides common functionality for authentication, configuration, and API communication.
1551
+ * All service classes extend this base to inherit dependency injection and HTTP client access.
1552
+ *
1553
+ * This class implements the dependency injection pattern where services receive a configured
1554
+ * UiPath instance. The ApiClient is created internally and handles all HTTP operations
1555
+ * including authentication token management.
1556
+ *
1557
+ * @remarks
1558
+ * Service classes should extend this base and call `super(uiPath)` in their constructor.
1559
+ * Protected HTTP methods (get, post, put, patch, delete) are available to all subclasses.
1560
+ *
1561
+ */
1562
+ class BaseService {
1563
+ /**
1564
+ * Creates a base service instance with dependency injection.
1565
+ *
1566
+ * Extracts configuration, execution context, and token manager from the UiPath instance
1567
+ * to initialize an authenticated API client. The ApiClient handles all HTTP operations
1568
+ * and token management internally.
1569
+ *
1570
+ * @param instance - UiPath SDK instance providing authentication and configuration.
1571
+ * Services receive this via dependency injection in the modular pattern.
1572
+ *
1573
+ * @example
1574
+ * ```typescript
1575
+ * // Services automatically call this via super()
1576
+ * export class EntityService extends BaseService {
1577
+ * constructor(instance: IUiPath) {
1578
+ * super(instance); // Initializes the internal ApiClient
1579
+ * }
1580
+ * }
1581
+ *
1582
+ * // Usage in modular pattern
1583
+ * import { UiPath } from '@uipath/uipath-typescript/core';
1584
+ * import { Entities } from '@uipath/uipath-typescript/entities';
1585
+ *
1586
+ * const sdk = new UiPath(config);
1587
+ * await sdk.initialize();
1588
+ * const entities = new Entities(sdk);
1589
+ * ```
1590
+ */
1591
+ constructor(instance) {
1592
+ // Private field - not visible via Object.keys() or any reflection
1593
+ _BaseService_apiClient.set(this, void 0);
1594
+ const { config, context, tokenManager } = SDKInternalsRegistry.get(instance);
1595
+ __classPrivateFieldSet(this, _BaseService_apiClient, new ApiClient(config, context, tokenManager), "f");
1596
+ }
1597
+ /**
1598
+ * Gets a valid authentication token, refreshing if necessary.
1599
+ * Use this when you need to manually add Authorization headers (e.g., direct uploads).
1600
+ *
1601
+ * @returns Promise resolving to a valid access token string
1602
+ * @throws AuthenticationError if no token is available or refresh fails
1603
+ */
1604
+ async getValidAuthToken() {
1605
+ return __classPrivateFieldGet(this, _BaseService_apiClient, "f").getValidToken();
1606
+ }
1607
+ /**
1608
+ * Creates a service accessor for pagination helpers
1609
+ * This allows pagination helpers to access protected methods without making them public
1610
+ */
1611
+ createPaginationServiceAccess() {
1612
+ return {
1613
+ get: (path, options) => this.get(path, options || {}),
1614
+ post: (path, body, options) => this.post(path, body, options || {}),
1615
+ requestWithPagination: (method, path, paginationOptions, options) => this.requestWithPagination(method, path, paginationOptions, options)
1616
+ };
1617
+ }
1618
+ async request(method, path, options = {}) {
1619
+ switch (method.toUpperCase()) {
1620
+ case 'GET':
1621
+ return this.get(path, options);
1622
+ case 'POST':
1623
+ return this.post(path, options.body, options);
1624
+ case 'PUT':
1625
+ return this.put(path, options.body, options);
1626
+ case 'PATCH':
1627
+ return this.patch(path, options.body, options);
1628
+ case 'DELETE':
1629
+ return this.delete(path, options);
1630
+ default:
1631
+ throw new Error(`Unsupported HTTP method: ${method}`);
1632
+ }
1633
+ }
1634
+ async requestWithSpec(spec) {
1635
+ if (!spec.method || !spec.url) {
1636
+ throw new Error('Request spec must include method and url');
1637
+ }
1638
+ return this.request(spec.method, spec.url, spec);
1639
+ }
1640
+ async get(path, options = {}) {
1641
+ const response = await __classPrivateFieldGet(this, _BaseService_apiClient, "f").get(path, options);
1642
+ return { data: response };
1643
+ }
1644
+ async post(path, data, options = {}) {
1645
+ const response = await __classPrivateFieldGet(this, _BaseService_apiClient, "f").post(path, data, options);
1646
+ return { data: response };
1647
+ }
1648
+ async put(path, data, options = {}) {
1649
+ const response = await __classPrivateFieldGet(this, _BaseService_apiClient, "f").put(path, data, options);
1650
+ return { data: response };
1651
+ }
1652
+ async patch(path, data, options = {}) {
1653
+ const response = await __classPrivateFieldGet(this, _BaseService_apiClient, "f").patch(path, data, options);
1654
+ return { data: response };
1655
+ }
1656
+ async delete(path, options = {}) {
1657
+ const response = await __classPrivateFieldGet(this, _BaseService_apiClient, "f").delete(path, options);
1658
+ return { data: response };
1659
+ }
1660
+ /**
1661
+ * Execute a request with cursor-based pagination
1662
+ */
1663
+ async requestWithPagination(method, path, paginationOptions, options) {
1664
+ const paginationType = options.pagination.paginationType;
1665
+ // Validate and prepare pagination parameters
1666
+ const params = this.validateAndPreparePaginationParams(paginationType, paginationOptions);
1667
+ // Prepare request parameters based on pagination type
1668
+ const requestParams = this.preparePaginationRequestParams(paginationType, params, options.pagination);
1669
+ // For POST requests, merge pagination params into body; for GET, use query params
1670
+ if (method.toUpperCase() === 'POST') {
1671
+ const existingBody = (options.body && typeof options.body === 'object') ? options.body : {};
1672
+ options.body = {
1673
+ ...existingBody,
1674
+ ...options.params,
1675
+ ...requestParams
1676
+ };
1677
+ }
1678
+ else {
1679
+ // Merge pagination parameters with existing parameters
1680
+ options.params = {
1681
+ ...options.params,
1682
+ ...requestParams
1683
+ };
1684
+ }
1685
+ // Make the request
1686
+ const response = await this.request(method, path, options);
1687
+ // Extract data from the response and create page result
1688
+ return this.createPaginatedResponseFromResponse(response, params, paginationType, {
1689
+ itemsField: options.pagination.itemsField,
1690
+ totalCountField: options.pagination.totalCountField,
1691
+ continuationTokenField: options.pagination.continuationTokenField
1692
+ });
1693
+ }
1694
+ /**
1695
+ * Validates and prepares pagination parameters from options
1696
+ */
1697
+ validateAndPreparePaginationParams(paginationType, paginationOptions) {
1698
+ return PaginationHelpers.validatePaginationOptions(paginationOptions, paginationType);
1699
+ }
1700
+ /**
1701
+ * Prepares request parameters for pagination based on pagination type
1702
+ */
1703
+ preparePaginationRequestParams(paginationType, params, paginationConfig) {
1704
+ const requestParams = {};
1705
+ let limitedPageSize;
1706
+ const paginationParams = paginationConfig?.paginationParams;
1707
+ switch (paginationType) {
1708
+ case PaginationType.OFFSET:
1709
+ limitedPageSize = getLimitedPageSize(params.pageSize);
1710
+ const pageSizeParam = paginationParams?.pageSizeParam || ODATA_OFFSET_PARAMS.PAGE_SIZE_PARAM;
1711
+ const offsetParam = paginationParams?.offsetParam || ODATA_OFFSET_PARAMS.OFFSET_PARAM;
1712
+ const countParam = paginationParams?.countParam || ODATA_OFFSET_PARAMS.COUNT_PARAM;
1713
+ requestParams[pageSizeParam] = limitedPageSize;
1714
+ if (params.pageNumber && params.pageNumber > 1) {
1715
+ requestParams[offsetParam] = (params.pageNumber - 1) * limitedPageSize;
1716
+ }
1717
+ // Include total count for ODATA APIs
1718
+ {
1719
+ requestParams[countParam] = true;
1720
+ }
1721
+ break;
1722
+ case PaginationType.TOKEN:
1723
+ const tokenPageSizeParam = paginationParams?.pageSizeParam || BUCKET_TOKEN_PARAMS.PAGE_SIZE_PARAM;
1724
+ const tokenParam = paginationParams?.tokenParam || BUCKET_TOKEN_PARAMS.TOKEN_PARAM;
1725
+ if (params.pageSize) {
1726
+ requestParams[tokenPageSizeParam] = getLimitedPageSize(params.pageSize);
1727
+ }
1728
+ if (params.continuationToken) {
1729
+ requestParams[tokenParam] = params.continuationToken;
1730
+ }
1731
+ break;
1732
+ }
1733
+ return requestParams;
1734
+ }
1735
+ /**
1736
+ * Creates a paginated response from API response
1737
+ */
1738
+ createPaginatedResponseFromResponse(response, params, paginationType, fields) {
1739
+ // Extract fields from response
1740
+ const itemsField = fields.itemsField ||
1741
+ (paginationType === PaginationType.TOKEN ? 'items' : 'value');
1742
+ const totalCountField = fields.totalCountField || 'totalRecordCount';
1743
+ const continuationTokenField = fields.continuationTokenField || 'continuationToken';
1744
+ // Extract items and metadata
1745
+ const items = response.data[itemsField] || [];
1746
+ const totalCount = response.data[totalCountField];
1747
+ const continuationToken = response.data[continuationTokenField];
1748
+ // Determine if there are more pages
1749
+ const hasMore = this.determineHasMorePages(paginationType, {
1750
+ totalCount,
1751
+ pageSize: params.pageSize,
1752
+ currentPage: params.pageNumber || 1,
1753
+ itemsCount: items.length,
1754
+ continuationToken
1755
+ });
1756
+ // Create and return the page result
1757
+ return PaginationManager.createPaginatedResponse({
1758
+ pageInfo: {
1759
+ hasMore,
1760
+ totalCount,
1761
+ currentPage: params.pageNumber,
1762
+ pageSize: params.pageSize,
1763
+ continuationToken
1764
+ },
1765
+ type: paginationType,
1766
+ }, items);
1767
+ }
1768
+ /**
1769
+ * Determines if there are more pages based on pagination type and metadata
1770
+ */
1771
+ determineHasMorePages(paginationType, info) {
1772
+ switch (paginationType) {
1773
+ case PaginationType.OFFSET:
1774
+ const effectivePageSize = info.pageSize ?? DEFAULT_PAGE_SIZE;
1775
+ // If totalCount is available, use it for precise calculation
1776
+ if (info.totalCount !== undefined) {
1777
+ return (info.currentPage * effectivePageSize) < info.totalCount;
1778
+ }
1779
+ // Fallback when totalCount is not available
1780
+ // NOTE: This code path should rarely be executed as the APIs typically return totalCount
1781
+ return info.itemsCount === effectivePageSize;
1782
+ case PaginationType.TOKEN:
1783
+ return !!info.continuationToken;
1784
+ default:
1785
+ return false;
1786
+ }
1787
+ }
1788
+ }
1789
+ _BaseService_apiClient = new WeakMap();
1790
+
1791
+ /**
1792
+ * API Endpoint Constants
1793
+ * Centralized location for all API endpoints used throughout the SDK
1794
+ */
1795
+ /**
1796
+ * Base path constants for different services
1797
+ */
1798
+ const ORCHESTRATOR_BASE = 'orchestrator_';
1799
+ const PIMS_BASE = 'pims_';
1800
+ /**
1801
+ * Maestro Process Service Endpoints
1802
+ */
1803
+ const MAESTRO_ENDPOINTS = {
1804
+ PROCESSES: {
1805
+ GET_ALL: `${PIMS_BASE}/api/v1/processes/summary`,
1806
+ GET_SETTINGS: (processKey) => `${PIMS_BASE}/api/v1/processes/${processKey}/settings`,
1807
+ },
1808
+ INSTANCES: {
1809
+ GET_ALL: `${PIMS_BASE}/api/v1/instances`,
1810
+ GET_BY_ID: (instanceId) => `${PIMS_BASE}/api/v1/instances/${instanceId}`,
1811
+ GET_EXECUTION_HISTORY: (instanceId) => `${PIMS_BASE}/api/v1/spans/${instanceId}`,
1812
+ GET_BPMN: (instanceId) => `${PIMS_BASE}/api/v1/instances/${instanceId}/bpmn`,
1813
+ GET_VARIABLES: (instanceId) => `${PIMS_BASE}/api/v1/instances/${instanceId}/variables`,
1814
+ CANCEL: (instanceId) => `${PIMS_BASE}/api/v1/instances/${instanceId}/cancel`,
1815
+ PAUSE: (instanceId) => `${PIMS_BASE}/api/v1/instances/${instanceId}/pause`,
1816
+ RESUME: (instanceId) => `${PIMS_BASE}/api/v1/instances/${instanceId}/resume`,
1817
+ },
1818
+ INCIDENTS: {
1819
+ GET_ALL: `${PIMS_BASE}/api/v1/incidents/summary`,
1820
+ GET_BY_PROCESS: (processKey) => `${PIMS_BASE}/api/v1/incidents/process/${processKey}`,
1821
+ GET_BY_INSTANCE: (instanceId) => `${PIMS_BASE}/api/v1/instances/${instanceId}/incidents`,
1822
+ },
1823
+ CASES: {
1824
+ GET_CASE_JSON: (instanceId) => `${PIMS_BASE}/api/v1/cases/${instanceId}/case-json`,
1825
+ GET_ELEMENT_EXECUTIONS: (instanceId) => `${PIMS_BASE}/api/v1/element-executions/case-instances/${instanceId}`,
1826
+ REOPEN: (instanceId) => `${PIMS_BASE}/api/v1/cases/${instanceId}/reopen`,
1827
+ },
1828
+ };
1829
+ /**
1830
+ * Task Service (Action Center) Endpoints
1831
+ */
1832
+ const TASK_ENDPOINTS = {
1833
+ CREATE_GENERIC_TASK: `${ORCHESTRATOR_BASE}/tasks/GenericTasks/CreateTask`,
1834
+ GET_TASK_USERS: (folderId) => `${ORCHESTRATOR_BASE}/odata/Tasks/UiPath.Server.Configuration.OData.GetTaskUsers(organizationUnitId=${folderId})`,
1835
+ GET_TASKS_ACROSS_FOLDERS: `${ORCHESTRATOR_BASE}/odata/Tasks/UiPath.Server.Configuration.OData.GetTasksAcrossFolders`,
1836
+ GET_TASKS_ACROSS_FOLDERS_ADMIN: `${ORCHESTRATOR_BASE}/odata/Tasks/UiPath.Server.Configuration.OData.GetTasksAcrossFoldersForAdmin`,
1837
+ GET_BY_ID: (id) => `${ORCHESTRATOR_BASE}/odata/Tasks(${id})`,
1838
+ ASSIGN_TASKS: `${ORCHESTRATOR_BASE}/odata/Tasks/UiPath.Server.Configuration.OData.AssignTasks`,
1839
+ REASSIGN_TASKS: `${ORCHESTRATOR_BASE}/odata/Tasks/UiPath.Server.Configuration.OData.ReassignTasks`,
1840
+ UNASSIGN_TASKS: `${ORCHESTRATOR_BASE}/odata/Tasks/UiPath.Server.Configuration.OData.UnassignTasks`,
1841
+ COMPLETE_FORM_TASK: `${ORCHESTRATOR_BASE}/forms/TaskForms/CompleteTask`,
1842
+ COMPLETE_APP_TASK: `${ORCHESTRATOR_BASE}/tasks/AppTasks/CompleteAppTask`,
1843
+ COMPLETE_GENERIC_TASK: `${ORCHESTRATOR_BASE}/tasks/GenericTasks/CompleteTask`,
1844
+ GET_TASK_FORM_BY_ID: `${ORCHESTRATOR_BASE}/forms/TaskForms/GetTaskFormById`,
1845
+ };
1846
+
1847
+ /**
1848
+ * SDK Telemetry constants
1849
+ */
1850
+ // Connection string placeholder that will be replaced during build
1851
+ 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";
1852
+ // SDK Version placeholder
1853
+ const SDK_VERSION = "1.0.0";
1854
+ const VERSION = "Version";
1855
+ const SERVICE = "Service";
1856
+ const CLOUD_ORGANIZATION_NAME = "CloudOrganizationName";
1857
+ const CLOUD_TENANT_NAME = "CloudTenantName";
1858
+ const CLOUD_URL = "CloudUrl";
1859
+ const CLOUD_CLIENT_ID = "CloudClientId";
1860
+ const CLOUD_REDIRECT_URI = "CloudRedirectUri";
1861
+ const APP_NAME = "ApplicationName";
1862
+ const CLOUD_ROLE_NAME = "uipath-ts-sdk";
1863
+ // Service and logger names
1864
+ const SDK_SERVICE_NAME = "UiPath.TypeScript.Sdk";
1865
+ const SDK_LOGGER_NAME = "uipath-ts-sdk-telemetry";
1866
+ // Event names
1867
+ const SDK_RUN_EVENT = "Sdk.Run";
1868
+ // Default value for unknown/empty attributes
1869
+ const UNKNOWN = "";
1870
+
1871
+ /**
1872
+ * Log exporter that sends ALL logs as Application Insights custom events
1873
+ */
1874
+ class ApplicationInsightsEventExporter {
1875
+ constructor(connectionString) {
1876
+ this.connectionString = connectionString;
1877
+ }
1878
+ export(logs, resultCallback) {
1879
+ try {
1880
+ logs.forEach(logRecord => {
1881
+ this.sendAsCustomEvent(logRecord);
1882
+ });
1883
+ resultCallback({ code: 0 });
1884
+ }
1885
+ catch (error) {
1886
+ console.debug('Failed to export logs to Application Insights:', error);
1887
+ resultCallback({ code: 2, error });
1888
+ }
1889
+ }
1890
+ shutdown() {
1891
+ return Promise.resolve();
1892
+ }
1893
+ sendAsCustomEvent(logRecord) {
1894
+ // Get event name from body or attributes
1895
+ const eventName = logRecord.body || SDK_RUN_EVENT;
1896
+ const payload = {
1897
+ name: 'Microsoft.ApplicationInsights.Event',
1898
+ time: new Date().toISOString(),
1899
+ iKey: this.extractInstrumentationKey(),
1900
+ data: {
1901
+ baseType: 'EventData',
1902
+ baseData: {
1903
+ ver: 2,
1904
+ name: eventName,
1905
+ properties: this.convertAttributesToProperties(logRecord.attributes || {})
1906
+ }
1907
+ },
1908
+ tags: {
1909
+ 'ai.cloud.role': CLOUD_ROLE_NAME,
1910
+ 'ai.cloud.roleInstance': SDK_VERSION
1911
+ }
1912
+ };
1913
+ this.sendToApplicationInsights(payload);
1914
+ }
1915
+ extractInstrumentationKey() {
1916
+ const match = this.connectionString.match(/InstrumentationKey=([^;]+)/);
1917
+ return match ? match[1] : '';
1918
+ }
1919
+ convertAttributesToProperties(attributes) {
1920
+ const properties = {};
1921
+ Object.entries(attributes || {}).forEach(([key, value]) => {
1922
+ properties[key] = String(value);
1923
+ });
1924
+ return properties;
1925
+ }
1926
+ async sendToApplicationInsights(payload) {
1927
+ try {
1928
+ const ingestionEndpoint = this.extractIngestionEndpoint();
1929
+ if (!ingestionEndpoint) {
1930
+ console.debug('No ingestion endpoint found in connection string');
1931
+ return;
1932
+ }
1933
+ const url = `${ingestionEndpoint}/v2/track`;
1934
+ const response = await fetch(url, {
1935
+ method: 'POST',
1936
+ headers: {
1937
+ 'Content-Type': 'application/json',
1938
+ },
1939
+ body: JSON.stringify(payload)
1940
+ });
1941
+ if (!response.ok) {
1942
+ console.debug(`Failed to send event telemetry: ${response.status} ${response.statusText}`);
1943
+ }
1944
+ }
1945
+ catch (error) {
1946
+ console.debug('Error sending event telemetry to Application Insights:', error);
1947
+ }
1948
+ }
1949
+ extractIngestionEndpoint() {
1950
+ const match = this.connectionString.match(/IngestionEndpoint=([^;]+)/);
1951
+ return match ? match[1] : '';
1952
+ }
1953
+ }
1954
+ /**
1955
+ * Singleton telemetry client
1956
+ */
1957
+ class TelemetryClient {
1958
+ constructor() {
1959
+ this.isInitialized = false;
1960
+ }
1961
+ static getInstance() {
1962
+ if (!TelemetryClient.instance) {
1963
+ TelemetryClient.instance = new TelemetryClient();
1964
+ }
1965
+ return TelemetryClient.instance;
1966
+ }
1967
+ /**
1968
+ * Initialize telemetry
1969
+ */
1970
+ initialize(config) {
1971
+ if (this.isInitialized) {
1972
+ return;
1973
+ }
1974
+ this.isInitialized = true;
1975
+ if (config) {
1976
+ this.telemetryContext = config;
1977
+ }
1978
+ try {
1979
+ const connectionString = this.getConnectionString();
1980
+ if (!connectionString) {
1981
+ return;
1982
+ }
1983
+ this.setupTelemetryProvider(connectionString);
1984
+ }
1985
+ catch (error) {
1986
+ // Silent failure - telemetry errors shouldn't break functionality
1987
+ console.debug('Failed to initialize OpenTelemetry:', error);
1988
+ }
1989
+ }
1990
+ getConnectionString() {
1991
+ const connectionString = CONNECTION_STRING;
1992
+ return connectionString;
1993
+ }
1994
+ setupTelemetryProvider(connectionString) {
1995
+ const exporter = new ApplicationInsightsEventExporter(connectionString);
1996
+ const processor = new sdkLogs.BatchLogRecordProcessor(exporter);
1997
+ this.logProvider = new sdkLogs.LoggerProvider({
1998
+ processors: [processor]
1999
+ });
2000
+ this.logger = this.logProvider.getLogger(SDK_LOGGER_NAME);
2001
+ }
2002
+ /**
2003
+ * Track a telemetry event
2004
+ */
2005
+ track(eventName, name, extraAttributes = {}) {
2006
+ try {
2007
+ // Skip if logger not initialized
2008
+ if (!this.logger) {
2009
+ return;
2010
+ }
2011
+ const finalDisplayName = name || eventName;
2012
+ const attributes = this.getEnrichedAttributes(extraAttributes, eventName);
2013
+ // Emit as log
2014
+ this.logger.emit({
2015
+ body: finalDisplayName,
2016
+ attributes: attributes,
2017
+ timestamp: Date.now(),
2018
+ });
2019
+ }
2020
+ catch (error) {
2021
+ // Silent failure
2022
+ console.debug('Failed to track telemetry event:', error);
2023
+ }
2024
+ }
2025
+ /**
2026
+ * Get enriched attributes for telemetry events
2027
+ */
2028
+ getEnrichedAttributes(extraAttributes, eventName) {
2029
+ const attributes = {
2030
+ ...extraAttributes,
2031
+ [APP_NAME]: SDK_SERVICE_NAME,
2032
+ [VERSION]: SDK_VERSION,
2033
+ [SERVICE]: eventName,
2034
+ [CLOUD_URL]: this.createCloudUrl(),
2035
+ [CLOUD_ORGANIZATION_NAME]: this.telemetryContext?.orgName || UNKNOWN,
2036
+ [CLOUD_TENANT_NAME]: this.telemetryContext?.tenantName || UNKNOWN,
2037
+ [CLOUD_REDIRECT_URI]: this.telemetryContext?.redirectUri || UNKNOWN,
2038
+ [CLOUD_CLIENT_ID]: this.telemetryContext?.clientId || UNKNOWN,
2039
+ };
2040
+ return attributes;
2041
+ }
2042
+ /**
2043
+ * Create cloud URL from base URL, organization ID, and tenant ID
2044
+ */
2045
+ createCloudUrl() {
2046
+ const baseUrl = this.telemetryContext?.baseUrl;
2047
+ const orgId = this.telemetryContext?.orgName;
2048
+ const tenantId = this.telemetryContext?.tenantName;
2049
+ if (!baseUrl || !orgId || !tenantId) {
2050
+ return UNKNOWN;
2051
+ }
2052
+ return `${baseUrl}/${orgId}/${tenantId}`;
2053
+ }
2054
+ }
2055
+ // Export singleton instance
2056
+ const telemetryClient = TelemetryClient.getInstance();
2057
+
2058
+ /**
2059
+ * SDK Track decorator and function for telemetry
2060
+ */
2061
+ /**
2062
+ * Common tracking logic shared between method and function decorators
2063
+ */
2064
+ function createTrackedFunction(originalFunction, nameOrOptions, fallbackName, opts) {
2065
+ return function (...args) {
2066
+ // Determine if we should track this call
2067
+ let shouldTrack = true;
2068
+ if (opts.condition !== undefined) {
2069
+ if (typeof opts.condition === 'function') {
2070
+ shouldTrack = opts.condition.apply(this, args);
2071
+ }
2072
+ else {
2073
+ shouldTrack = opts.condition;
2074
+ }
2075
+ }
2076
+ // Track the event if enabled
2077
+ if (shouldTrack) {
2078
+ // Use the full name provided in the decorator (e.g., "Queue.GetAll")
2079
+ const serviceMethod = typeof nameOrOptions === 'string'
2080
+ ? nameOrOptions
2081
+ : fallbackName;
2082
+ // Use 'Sdk.Run' as the name and serviceMethod as the service
2083
+ telemetryClient.track(serviceMethod, SDK_RUN_EVENT, opts.attributes);
2084
+ }
2085
+ // Execute the original function
2086
+ return originalFunction.apply(this, args);
2087
+ };
2088
+ }
2089
+ /**
2090
+ * Track decorator that can be used to automatically track function calls
2091
+ *
2092
+ * Usage:
2093
+ * @track("Service.Method")
2094
+ * function myFunction() { ... }
2095
+ *
2096
+ * @track("Queue.GetAll")
2097
+ * async getAll() { ... }
2098
+ *
2099
+ * @track("Tasks.Create")
2100
+ * async create() { ... }
2101
+ *
2102
+ * @track("Assets.Update", { condition: false })
2103
+ * function myFunction() { ... }
2104
+ *
2105
+ * @track("Processes.Start", { attributes: { customProp: "value" } })
2106
+ * function myFunction() { ... }
2107
+ */
2108
+ function track(nameOrOptions, options) {
2109
+ return function decorator(_target, propertyKey, descriptor) {
2110
+ const opts = typeof nameOrOptions === 'object' ? nameOrOptions : {};
2111
+ if (descriptor && typeof descriptor.value === 'function') {
2112
+ // Method decorator
2113
+ descriptor.value = createTrackedFunction(descriptor.value, nameOrOptions, propertyKey || 'unknown_method', opts);
2114
+ return descriptor;
2115
+ }
2116
+ // Function decorator
2117
+ return (originalFunction) => createTrackedFunction(originalFunction, nameOrOptions, originalFunction.name || 'unknown_function', opts);
2118
+ };
2119
+ }
2120
+
2121
+ /**
2122
+ * Creates query parameters object from key-value pairs, filtering out undefined values
2123
+ * @param paramsObj - Object containing parameter key-value pairs
2124
+ * @returns Parameters object with undefined values filtered out
2125
+ *
2126
+ * @example
2127
+ * ```typescript
2128
+ * // Entity service parameters
2129
+ * const params = createParams({
2130
+ * start: 0,
2131
+ * limit: 10,
2132
+ * expansionLevel: 1
2133
+ * });
2134
+ *
2135
+ * // With optional/undefined values (automatically filtered)
2136
+ * const params = createParams({
2137
+ * start: options.start, // Could be undefined
2138
+ * limit: options.limit, // Could be undefined
2139
+ * expansionLevel: options.expansionLevel // Could be undefined
2140
+ * });
2141
+ *
2142
+ * // Empty params
2143
+ * const params = createParams();
2144
+ * ```
2145
+ */
2146
+ function createParams(paramsObj = {}) {
2147
+ const params = {};
2148
+ for (const [key, value] of Object.entries(paramsObj)) {
2149
+ if (value !== undefined && value !== null) {
2150
+ params[key] = value;
2151
+ }
2152
+ }
2153
+ return params;
2154
+ }
2155
+
2156
+ /**
2157
+ * Service for interacting with UiPath Maestro Cases
2158
+ */
2159
+ class CasesService extends BaseService {
2160
+ /**
2161
+ * Get all case management processes with their instance statistics
2162
+ * @returns Promise resolving to array of Case objects
2163
+ *
2164
+ * @example
2165
+ * ```typescript
2166
+ * import { Cases } from '@uipath/uipath-typescript/cases';
2167
+ *
2168
+ * const cases = new Cases(sdk);
2169
+ * const allCases = await cases.getAll();
2170
+ *
2171
+ * // Access case information
2172
+ * for (const caseProcess of allCases) {
2173
+ * console.log(`Case Process: ${caseProcess.processKey}`);
2174
+ * console.log(`Running instances: ${caseProcess.runningCount}`);
2175
+ * console.log(`Completed instances: ${caseProcess.completedCount}`);
2176
+ * }
2177
+ * ```
2178
+ */
2179
+ async getAll() {
2180
+ const params = createParams({
2181
+ processType: ProcessType.CaseManagement
2182
+ });
2183
+ const response = await this.get(MAESTRO_ENDPOINTS.PROCESSES.GET_ALL, { params });
2184
+ // Extract processes array from response data and add name field
2185
+ const cases = response.data?.processes || [];
2186
+ return cases.map(caseItem => ({
2187
+ ...caseItem,
2188
+ name: this.extractCaseName(caseItem.packageId)
2189
+ }));
2190
+ }
2191
+ /**
2192
+ * Extract a readable case name from the packageId
2193
+ * @param packageId - The full package identifier
2194
+ * @returns A human-readable case name
2195
+ * @private
2196
+ */
2197
+ extractCaseName(packageId) {
2198
+ // Check if packageId contains "CaseManagement."
2199
+ const caseManagementIndex = packageId.indexOf('CaseManagement.');
2200
+ if (caseManagementIndex !== -1) {
2201
+ // Extract everything after "CaseManagement."
2202
+ const afterCaseManagement = packageId.substring(caseManagementIndex + 'CaseManagement.'.length);
2203
+ // Replace hyphens with spaces for better readability
2204
+ return afterCaseManagement.replace(/-/g, ' ');
2205
+ }
2206
+ // If no "CaseManagement.", return the whole packageId
2207
+ return packageId;
2208
+ }
2209
+ }
2210
+ __decorate([
2211
+ track('Cases.GetAll')
2212
+ ], CasesService.prototype, "getAll", null);
2213
+
2214
+ /**
2215
+ * Process Incident Status
2216
+ */
2217
+ var ProcessIncidentStatus;
2218
+ (function (ProcessIncidentStatus) {
2219
+ ProcessIncidentStatus["Open"] = "Open";
2220
+ ProcessIncidentStatus["Closed"] = "Closed";
2221
+ })(ProcessIncidentStatus || (ProcessIncidentStatus = {}));
2222
+ /**
2223
+ * Process Incident Type
2224
+ */
2225
+ var ProcessIncidentType;
2226
+ (function (ProcessIncidentType) {
2227
+ ProcessIncidentType["System"] = "System";
2228
+ ProcessIncidentType["User"] = "User";
2229
+ ProcessIncidentType["Deployment"] = "Deployment";
2230
+ })(ProcessIncidentType || (ProcessIncidentType = {}));
2231
+ /**
2232
+ * Process Incident Severity
2233
+ */
2234
+ var ProcessIncidentSeverity;
2235
+ (function (ProcessIncidentSeverity) {
2236
+ ProcessIncidentSeverity["Error"] = "Error";
2237
+ ProcessIncidentSeverity["Warning"] = "Warning";
2238
+ })(ProcessIncidentSeverity || (ProcessIncidentSeverity = {}));
2239
+ /**
2240
+ * Process Incident Debug Mode
2241
+ */
2242
+ var DebugMode;
2243
+ (function (DebugMode) {
2244
+ DebugMode["None"] = "None";
2245
+ DebugMode["Default"] = "Default";
2246
+ DebugMode["StepByStep"] = "StepByStep";
2247
+ DebugMode["SingleStep"] = "SingleStep";
2248
+ })(DebugMode || (DebugMode = {}));
2249
+
2250
+ /**
2251
+ * Case Instance Types
2252
+ * Types and interfaces for Maestro case instance management
2253
+ */
2254
+ /**
2255
+ * Case stage task type
2256
+ */
2257
+ exports.StageTaskType = void 0;
2258
+ (function (StageTaskType) {
2259
+ StageTaskType["EXTERNAL_AGENT"] = "external-agent";
2260
+ StageTaskType["RPA"] = "rpa";
2261
+ StageTaskType["AGENTIC_PROCESS"] = "process";
2262
+ StageTaskType["AGENT"] = "agent";
2263
+ StageTaskType["ACTION"] = "action";
2264
+ StageTaskType["API_WORKFLOW"] = "api-workflow";
2265
+ })(exports.StageTaskType || (exports.StageTaskType = {}));
2266
+ /**
2267
+ * Escalation recipient scope
2268
+ */
2269
+ exports.EscalationRecipientScope = void 0;
2270
+ (function (EscalationRecipientScope) {
2271
+ EscalationRecipientScope["USER"] = "user";
2272
+ EscalationRecipientScope["USER_GROUP"] = "usergroup";
2273
+ })(exports.EscalationRecipientScope || (exports.EscalationRecipientScope = {}));
2274
+ /**
2275
+ * Escalation action type
2276
+ */
2277
+ exports.EscalationActionType = void 0;
2278
+ (function (EscalationActionType) {
2279
+ EscalationActionType["NOTIFICATION"] = "notification";
2280
+ })(exports.EscalationActionType || (exports.EscalationActionType = {}));
2281
+ /**
2282
+ * Escalation rule trigger type
2283
+ */
2284
+ exports.EscalationTriggerType = void 0;
2285
+ (function (EscalationTriggerType) {
2286
+ EscalationTriggerType["SLA_BREACHED"] = "sla-breached";
2287
+ EscalationTriggerType["AT_RISK"] = "at-risk";
2288
+ })(exports.EscalationTriggerType || (exports.EscalationTriggerType = {}));
2289
+ /**
2290
+ * SLA duration unit
2291
+ */
2292
+ exports.SLADurationUnit = void 0;
2293
+ (function (SLADurationUnit) {
2294
+ SLADurationUnit["HOURS"] = "h";
2295
+ SLADurationUnit["DAYS"] = "d";
2296
+ SLADurationUnit["WEEKS"] = "w";
2297
+ SLADurationUnit["MONTHS"] = "m";
2298
+ })(exports.SLADurationUnit || (exports.SLADurationUnit = {}));
2299
+
2300
+ /**
2301
+ * Creates methods for a case instance
2302
+ *
2303
+ * @param instanceData - The case instance data (response from API)
2304
+ * @param service - The case instance service instance
2305
+ * @returns Object containing case instance methods
2306
+ */
2307
+ function createCaseInstanceMethods(instanceData, service) {
2308
+ return {
2309
+ async close(options) {
2310
+ if (!instanceData.instanceId)
2311
+ throw new Error('Case instance ID is undefined');
2312
+ if (!instanceData.folderKey)
2313
+ throw new Error('Case instance folder key is undefined');
2314
+ return service.close(instanceData.instanceId, instanceData.folderKey, options);
2315
+ },
2316
+ async pause(options) {
2317
+ if (!instanceData.instanceId)
2318
+ throw new Error('Case instance ID is undefined');
2319
+ if (!instanceData.folderKey)
2320
+ throw new Error('Case instance folder key is undefined');
2321
+ return service.pause(instanceData.instanceId, instanceData.folderKey, options);
2322
+ },
2323
+ async reopen(options) {
2324
+ if (!instanceData.instanceId)
2325
+ throw new Error('Case instance ID is undefined');
2326
+ if (!instanceData.folderKey)
2327
+ throw new Error('Case instance folder key is undefined');
2328
+ return service.reopen(instanceData.instanceId, instanceData.folderKey, options);
2329
+ },
2330
+ async resume(options) {
2331
+ if (!instanceData.instanceId)
2332
+ throw new Error('Case instance ID is undefined');
2333
+ if (!instanceData.folderKey)
2334
+ throw new Error('Case instance folder key is undefined');
2335
+ return service.resume(instanceData.instanceId, instanceData.folderKey, options);
2336
+ },
2337
+ async getExecutionHistory() {
2338
+ if (!instanceData.instanceId)
2339
+ throw new Error('Case instance ID is undefined');
2340
+ if (!instanceData.folderKey)
2341
+ throw new Error('Case instance folder key is undefined');
2342
+ return service.getExecutionHistory(instanceData.instanceId, instanceData.folderKey);
2343
+ },
2344
+ async getStages() {
2345
+ if (!instanceData.instanceId)
2346
+ throw new Error('Case instance ID is undefined');
2347
+ if (!instanceData.folderKey)
2348
+ throw new Error('Case instance folder key is undefined');
2349
+ return service.getStages(instanceData.instanceId, instanceData.folderKey);
2350
+ },
2351
+ async getActionTasks(options) {
2352
+ if (!instanceData.instanceId)
2353
+ throw new Error('Case instance ID is undefined');
2354
+ return service.getActionTasks(instanceData.instanceId, options);
2355
+ }
2356
+ };
2357
+ }
2358
+ /**
2359
+ * Creates an actionable case instance by combining API case instance data with operational methods.
2360
+ *
2361
+ * @param instanceData - The case instance data from API
2362
+ * @param service - The case instance service instance
2363
+ * @returns A case instance object with added methods
2364
+ */
2365
+ function createCaseInstanceWithMethods(instanceData, service) {
2366
+ const methods = createCaseInstanceMethods(instanceData, service);
2367
+ return Object.assign({}, instanceData, methods);
2368
+ }
2369
+
2370
+ /**
2371
+ * Maps fields for Case Instance entities to ensure consistent naming
2372
+ */
2373
+ const CaseInstanceMap = {
2374
+ startedTimeUtc: 'startedTime',
2375
+ completedTimeUtc: 'completedTime',
2376
+ expiryTimeUtc: 'expiredTime',
2377
+ createdAt: 'createdTime',
2378
+ updatedAt: 'updatedTime',
2379
+ externalId: 'caseId',
2380
+ };
2381
+ /**
2382
+ * Maps fields for Case App Config
2383
+ */
2384
+ const CaseAppConfigMap = {
2385
+ sections: 'overview',
2386
+ };
2387
+ /**
2388
+ * Maps fields for Stage SLA configuration
2389
+ */
2390
+ const StageSLAMap = {
2391
+ count: 'length',
2392
+ unit: 'duration',
2393
+ };
2394
+ /**
2395
+ * Maps UTC time fields to simpler field names
2396
+ * Used for transforming execution history responses
2397
+ */
2398
+ const TimeFieldTransformMap = {
2399
+ startedTimeUtc: 'startedTime',
2400
+ completedTimeUtc: 'completedTime',
2401
+ };
2402
+ /**
2403
+ * Constants for case instance stage processing
2404
+ */
2405
+ const CASE_STAGE_CONSTANTS = {
2406
+ TRIGGER_NODE_TYPE: 'case-management:Trigger',
2407
+ UNDEFINED_VALUE: 'Undefined',
2408
+ NOT_STARTED_STATUS: 'Not Started'
2409
+ };
2410
+ /**
2411
+ * Function to generate case instance task filter by case instance ID
2412
+ */
2413
+ const CASE_INSTANCE_TASK_FILTER = (caseInstanceId) => `Tags/any(tags:tags/DisplayName eq '${caseInstanceId}') and (IsDeleted eq false)`;
2414
+ /**
2415
+ * Default expand parameters for case instance tasks
2416
+ */
2417
+ const CASE_INSTANCE_TASK_EXPAND = 'AssignedToUser,Activities';
2418
+
2419
+ var TaskType;
2420
+ (function (TaskType) {
2421
+ TaskType["Form"] = "FormTask";
2422
+ TaskType["External"] = "ExternalTask";
2423
+ TaskType["App"] = "AppTask";
2424
+ })(TaskType || (TaskType = {}));
2425
+ var TaskPriority;
2426
+ (function (TaskPriority) {
2427
+ TaskPriority["Low"] = "Low";
2428
+ TaskPriority["Medium"] = "Medium";
2429
+ TaskPriority["High"] = "High";
2430
+ TaskPriority["Critical"] = "Critical";
2431
+ })(TaskPriority || (TaskPriority = {}));
2432
+ var TaskStatus;
2433
+ (function (TaskStatus) {
2434
+ TaskStatus["Unassigned"] = "Unassigned";
2435
+ TaskStatus["Pending"] = "Pending";
2436
+ TaskStatus["Completed"] = "Completed";
2437
+ })(TaskStatus || (TaskStatus = {}));
2438
+ var TaskSlaCriteria;
2439
+ (function (TaskSlaCriteria) {
2440
+ TaskSlaCriteria["TaskCreated"] = "TaskCreated";
2441
+ TaskSlaCriteria["TaskAssigned"] = "TaskAssigned";
2442
+ TaskSlaCriteria["TaskCompleted"] = "TaskCompleted";
2443
+ })(TaskSlaCriteria || (TaskSlaCriteria = {}));
2444
+ var TaskSlaStatus;
2445
+ (function (TaskSlaStatus) {
2446
+ TaskSlaStatus["OverdueLater"] = "OverdueLater";
2447
+ TaskSlaStatus["OverdueSoon"] = "OverdueSoon";
2448
+ TaskSlaStatus["Overdue"] = "Overdue";
2449
+ TaskSlaStatus["CompletedInTime"] = "CompletedInTime";
2450
+ })(TaskSlaStatus || (TaskSlaStatus = {}));
2451
+ var TaskSourceName;
2452
+ (function (TaskSourceName) {
2453
+ TaskSourceName["Agent"] = "Agent";
2454
+ TaskSourceName["Workflow"] = "Workflow";
2455
+ TaskSourceName["Maestro"] = "Maestro";
2456
+ TaskSourceName["Default"] = "Default";
2457
+ })(TaskSourceName || (TaskSourceName = {}));
2458
+ /**
2459
+ * Task activity types
2460
+ */
2461
+ var TaskActivityType;
2462
+ (function (TaskActivityType) {
2463
+ TaskActivityType["Created"] = "Created";
2464
+ TaskActivityType["Assigned"] = "Assigned";
2465
+ TaskActivityType["Reassigned"] = "Reassigned";
2466
+ TaskActivityType["Unassigned"] = "Unassigned";
2467
+ TaskActivityType["Saved"] = "Saved";
2468
+ TaskActivityType["Forwarded"] = "Forwarded";
2469
+ TaskActivityType["Completed"] = "Completed";
2470
+ TaskActivityType["Commented"] = "Commented";
2471
+ TaskActivityType["Deleted"] = "Deleted";
2472
+ TaskActivityType["BulkSaved"] = "BulkSaved";
2473
+ TaskActivityType["BulkCompleted"] = "BulkCompleted";
2474
+ TaskActivityType["FirstOpened"] = "FirstOpened";
2475
+ })(TaskActivityType || (TaskActivityType = {}));
2476
+
2477
+ /**
2478
+ * Creates methods for a task
2479
+ *
2480
+ * @param taskData - The task data (response from API)
2481
+ * @param service - The task service instance
2482
+ * @returns Object containing task methods
2483
+ */
2484
+ function createTaskMethods(taskData, service) {
2485
+ return {
2486
+ async assign(options) {
2487
+ if (!taskData.id)
2488
+ throw new Error('Task ID is undefined');
2489
+ const assignmentOptions = 'userId' in options && options.userId !== undefined
2490
+ ? { taskId: taskData.id, userId: options.userId }
2491
+ : { taskId: taskData.id, userNameOrEmail: options.userNameOrEmail };
2492
+ return service.assign(assignmentOptions);
2493
+ },
2494
+ async reassign(options) {
2495
+ if (!taskData.id)
2496
+ throw new Error('Task ID is undefined');
2497
+ const assignmentOptions = 'userId' in options && options.userId !== undefined
2498
+ ? { taskId: taskData.id, userId: options.userId }
2499
+ : { taskId: taskData.id, userNameOrEmail: options.userNameOrEmail };
2500
+ return service.reassign(assignmentOptions);
2501
+ },
2502
+ async unassign() {
2503
+ if (!taskData.id)
2504
+ throw new Error('Task ID is undefined');
2505
+ return service.unassign(taskData.id);
2506
+ },
2507
+ async complete(options) {
2508
+ if (!taskData.id)
2509
+ throw new Error('Task ID is undefined');
2510
+ const folderId = taskData.folderId;
2511
+ if (!folderId)
2512
+ throw new Error('Folder ID is required');
2513
+ return service.complete({
2514
+ type: options.type,
2515
+ taskId: taskData.id,
2516
+ data: options.data,
2517
+ action: options.action
2518
+ }, folderId);
2519
+ }
2520
+ };
2521
+ }
2522
+ /**
2523
+ * Creates an actionable task by combining API task data with operational methods.
2524
+ *
2525
+ * @param taskData - The task data from API
2526
+ * @param service - The task service instance
2527
+ * @returns A task object with added methods
2528
+ */
2529
+ function createTaskWithMethods(taskData, service) {
2530
+ const methods = createTaskMethods(taskData, service);
2531
+ return Object.assign({}, taskData, methods);
2532
+ }
2533
+
2534
+ /**
2535
+ * Maps numeric TaskStatus values (from API) to TaskStatus enum values.
2536
+ * Extend this file with additional field mappings as needed.
2537
+ */
2538
+ const TaskStatusMap = {
2539
+ 0: TaskStatus.Unassigned,
2540
+ 1: TaskStatus.Pending,
2541
+ 2: TaskStatus.Completed,
2542
+ };
2543
+ // Field mapping for time-related fields to ensure consistent naming
2544
+ const TaskMap = {
2545
+ completionTime: 'completedTime',
2546
+ deletionTime: 'deletedTime',
2547
+ lastModificationTime: 'lastModifiedTime',
2548
+ creationTime: 'createdTime',
2549
+ organizationUnitId: 'folderId'
2550
+ };
2551
+ /**
2552
+ * Default expand parameters
2553
+ */
2554
+ const DEFAULT_TASK_EXPAND = 'AssignedToUser,CreatorUser,LastModifierUser';
2555
+
2556
+ /**
2557
+ * Service for interacting with UiPath Tasks API
2558
+ */
2559
+ class TaskService extends BaseService {
2560
+ constructor() {
2561
+ super(...arguments);
2562
+ /**
2563
+ * Process parameters for task queries with folder filtering
2564
+ * @param options - The REST API options to process
2565
+ * @param folderId - Optional folder ID to filter by
2566
+ * @returns Processed options with folder filtering applied if needed
2567
+ * @private
2568
+ */
2569
+ this.processTaskParameters = (options, folderId) => {
2570
+ // Add default expand parameters
2571
+ const processedOptions = this.addDefaultExpand(options);
2572
+ if (folderId) {
2573
+ // Create or add to existing filter for folder-specific queries
2574
+ if (processedOptions.filter) {
2575
+ processedOptions.filter = `${processedOptions.filter} and organizationUnitId eq ${folderId}`;
2576
+ }
2577
+ else {
2578
+ processedOptions.filter = `organizationUnitId eq ${folderId}`;
2579
+ }
2580
+ }
2581
+ return processedOptions;
2582
+ };
2583
+ }
2584
+ /**
2585
+ * Creates a new task
2586
+ * @param task - The task to be created
2587
+ * @param folderId - Required folder ID
2588
+ * @returns Promise resolving to the created task
2589
+ *
2590
+ * @example
2591
+ * ```typescript
2592
+ * import { Tasks } from '@uipath/uipath-typescript/tasks';
2593
+ *
2594
+ * const tasks = new Tasks(sdk);
2595
+ * const task = await tasks.create({
2596
+ * title: "My Task",
2597
+ * priority: TaskPriority.Medium,
2598
+ * data: { key: "value" }
2599
+ * }, 123); // folderId is required
2600
+ * ```
2601
+ */
2602
+ async create(task, folderId) {
2603
+ const headers = createHeaders({ [FOLDER_ID]: folderId });
2604
+ const externalTask = {
2605
+ ...task,
2606
+ type: TaskType.External //currently only external task is supported
2607
+ };
2608
+ const response = await this.post(TASK_ENDPOINTS.CREATE_GENERIC_TASK, externalTask, { headers });
2609
+ // Transform time fields for consistency
2610
+ const normalizedData = transformData(response.data, TaskMap);
2611
+ const transformedData = applyDataTransforms(normalizedData, { field: 'status', valueMap: TaskStatusMap });
2612
+ return createTaskWithMethods(transformedData, this);
2613
+ }
2614
+ /**
2615
+ * Gets users in the given folder who have Tasks.View and Tasks.Edit permissions
2616
+ *
2617
+ * The method returns either:
2618
+ * - An array of users (when no pagination parameters are provided)
2619
+ * - A paginated result with navigation cursors (when any pagination parameter is provided)
2620
+ *
2621
+ * @param folderId - The folder ID to get users from
2622
+ * @param options - Optional query and pagination parameters
2623
+ * @returns Promise resolving to an array of users or paginated result
2624
+ *
2625
+ * @example
2626
+ * ```typescript
2627
+ * import { Tasks } from '@uipath/uipath-typescript/tasks';
2628
+ *
2629
+ * const tasks = new Tasks(sdk);
2630
+ *
2631
+ * // Standard array return
2632
+ * const users = await tasks.getUsers(123);
2633
+ *
2634
+ * // Get users with filtering
2635
+ * const users = await tasks.getUsers(123, {
2636
+ * filter: "name eq 'abc'"
2637
+ * });
2638
+ *
2639
+ * // First page with pagination
2640
+ * const page1 = await tasks.getUsers(123, { pageSize: 10 });
2641
+ *
2642
+ * // Navigate using cursor
2643
+ * if (page1.hasNextPage) {
2644
+ * const page2 = await tasks.getUsers(123, { cursor: page1.nextCursor });
2645
+ * }
2646
+ *
2647
+ * // Jump to specific page
2648
+ * const page5 = await tasks.getUsers(123, {
2649
+ * jumpToPage: 5,
2650
+ * pageSize: 10
2651
+ * });
2652
+ * ```
2653
+ */
2654
+ async getUsers(folderId, options) {
2655
+ // Transformation function for users
2656
+ const transformUserResponse = (user) => pascalToCamelCaseKeys(user);
2657
+ // Add folderId to options so the centralized helper can handle it properly
2658
+ const optionsWithFolder = { ...options, folderId };
2659
+ return PaginationHelpers.getAll({
2660
+ serviceAccess: this.createPaginationServiceAccess(),
2661
+ getEndpoint: (folderId) => TASK_ENDPOINTS.GET_TASK_USERS(folderId), // Use folderId from centralized helper
2662
+ getByFolderEndpoint: TASK_ENDPOINTS.GET_TASK_USERS(folderId), // Use the passed folderId
2663
+ transformFn: transformUserResponse,
2664
+ pagination: {
2665
+ paginationType: PaginationType.OFFSET,
2666
+ itemsField: ODATA_PAGINATION.ITEMS_FIELD,
2667
+ totalCountField: ODATA_PAGINATION.TOTAL_COUNT_FIELD,
2668
+ paginationParams: {
2669
+ pageSizeParam: ODATA_OFFSET_PARAMS.PAGE_SIZE_PARAM,
2670
+ offsetParam: ODATA_OFFSET_PARAMS.OFFSET_PARAM,
2671
+ countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM
2672
+ }
2673
+ }
2674
+ }, optionsWithFolder);
2675
+ }
2676
+ /**
2677
+ * Gets tasks across folders with optional filtering and folder scoping
2678
+ *
2679
+ * The method returns either:
2680
+ * - An array of tasks (when no pagination parameters are provided)
2681
+ * - A paginated result with navigation cursors (when any pagination parameter is provided)
2682
+ *
2683
+ * @param options - Query options including optional folderId, asTaskAdmin flag and pagination options
2684
+ * @returns Promise resolving to an array of tasks or paginated result
2685
+ *
2686
+ * @example
2687
+ * ```typescript
2688
+ * import { Tasks } from '@uipath/uipath-typescript/tasks';
2689
+ *
2690
+ * const tasks = new Tasks(sdk);
2691
+ *
2692
+ * // Standard array return
2693
+ * const allTasks = await tasks.getAll();
2694
+ *
2695
+ * // Get tasks within a specific folder
2696
+ * const folderTasks = await tasks.getAll({
2697
+ * folderId: 123
2698
+ * });
2699
+ *
2700
+ * // Get tasks with admin permissions
2701
+ * const adminTasks = await tasks.getAll({
2702
+ * asTaskAdmin: true
2703
+ * });
2704
+ *
2705
+ * // First page with pagination
2706
+ * const page1 = await tasks.getAll({ pageSize: 10 });
2707
+ *
2708
+ * // Navigate using cursor
2709
+ * if (page1.hasNextPage) {
2710
+ * const page2 = await tasks.getAll({ cursor: page1.nextCursor });
2711
+ * }
2712
+ *
2713
+ * // Jump to specific page
2714
+ * const page5 = await tasks.getAll({
2715
+ * jumpToPage: 5,
2716
+ * pageSize: 10
2717
+ * });
2718
+ * ```
2719
+ */
2720
+ async getAll(options) {
2721
+ // Determine which endpoint to use based on asTaskAdmin flag
2722
+ const endpoint = options?.asTaskAdmin
2723
+ ? TASK_ENDPOINTS.GET_TASKS_ACROSS_FOLDERS_ADMIN
2724
+ : TASK_ENDPOINTS.GET_TASKS_ACROSS_FOLDERS;
2725
+ // Transformation function for tasks
2726
+ const transformTaskResponse = (task) => {
2727
+ const transformedTask = transformData(pascalToCamelCaseKeys(task), TaskMap);
2728
+ return createTaskWithMethods(applyDataTransforms(transformedTask, { field: 'status', valueMap: TaskStatusMap }), this);
2729
+ };
2730
+ return PaginationHelpers.getAll({
2731
+ serviceAccess: this.createPaginationServiceAccess(),
2732
+ getEndpoint: () => endpoint,
2733
+ transformFn: transformTaskResponse,
2734
+ processParametersFn: this.processTaskParameters,
2735
+ excludeFromPrefix: ['event'], // Exclude 'event' key from ODATA prefix transformation
2736
+ pagination: {
2737
+ paginationType: PaginationType.OFFSET,
2738
+ itemsField: ODATA_PAGINATION.ITEMS_FIELD,
2739
+ totalCountField: ODATA_PAGINATION.TOTAL_COUNT_FIELD,
2740
+ paginationParams: {
2741
+ pageSizeParam: ODATA_OFFSET_PARAMS.PAGE_SIZE_PARAM, // OData OFFSET parameter
2742
+ offsetParam: ODATA_OFFSET_PARAMS.OFFSET_PARAM, // OData OFFSET parameter
2743
+ countParam: ODATA_OFFSET_PARAMS.COUNT_PARAM // OData OFFSET parameter
2744
+ }
2745
+ }
2746
+ }, options);
2747
+ }
2748
+ /**
2749
+ * Gets a task by ID
2750
+ * IMPORTANT: For form tasks, folderId must be provided.
2751
+ *
2752
+ * @param id - The ID of the task to retrieve
2753
+ * @param options - Optional query parameters
2754
+ * @param folderId - Optional folder ID (REQUIRED for form tasks)
2755
+ * @returns Promise resolving to the task (form tasks will return form-specific data)
2756
+ *
2757
+ * @example
2758
+ * ```typescript
2759
+ * import { Tasks } from '@uipath/uipath-typescript/tasks';
2760
+ *
2761
+ * const tasks = new Tasks(sdk);
2762
+ *
2763
+ * // Get task by ID
2764
+ * const task = await tasks.getById(123);
2765
+ *
2766
+ * // If the task is a form task, it will automatically return form-specific data
2767
+ * ```
2768
+ */
2769
+ async getById(id, options = {}, folderId) {
2770
+ const headers = createHeaders({ [FOLDER_ID]: folderId });
2771
+ // Add default expand parameters
2772
+ const modifiedOptions = this.addDefaultExpand(options);
2773
+ // prefix all keys in options
2774
+ const keysToPrefix = Object.keys(modifiedOptions);
2775
+ const apiOptions = addPrefixToKeys(modifiedOptions, ODATA_PREFIX, keysToPrefix);
2776
+ const response = await this.get(TASK_ENDPOINTS.GET_BY_ID(id), {
2777
+ params: apiOptions,
2778
+ headers
2779
+ });
2780
+ // Transform response from PascalCase to camelCase and normalize time fields
2781
+ const transformedTask = transformData(pascalToCamelCaseKeys(response.data), TaskMap);
2782
+ // Check if this is a form task and get form-specific data if it is
2783
+ if (transformedTask.type === TaskType.Form) {
2784
+ const formOptions = { expandOnFormLayout: true };
2785
+ return this.getFormTaskById(id, folderId || transformedTask.folderId, formOptions);
2786
+ }
2787
+ return createTaskWithMethods(applyDataTransforms(transformedTask, { field: 'status', valueMap: TaskStatusMap }), this);
2788
+ }
2789
+ /**
2790
+ * Assigns tasks to users
2791
+ *
2792
+ * @param taskAssignments - Single task assignment or array of task assignments
2793
+ * @returns Promise resolving to array of task assignment results
2794
+ *
2795
+ * @example
2796
+ * ```typescript
2797
+ * import { Tasks } from '@uipath/uipath-typescript/tasks';
2798
+ *
2799
+ * const tasks = new Tasks(sdk);
2800
+ *
2801
+ * // Assign a single task to a user by ID
2802
+ * const result = await tasks.assign({
2803
+ * taskId: 123,
2804
+ * userId: 456
2805
+ * });
2806
+ *
2807
+ * // Assign a single task to a user by email
2808
+ * const result = await tasks.assign({
2809
+ * taskId: 123,
2810
+ * userNameOrEmail: "user@example.com"
2811
+ * });
2812
+ *
2813
+ * // Assign multiple tasks
2814
+ * const result = await tasks.assign([
2815
+ * {
2816
+ * taskId: 123,
2817
+ * userId: 456
2818
+ * },
2819
+ * {
2820
+ * taskId: 789,
2821
+ * userNameOrEmail: "user@example.com"
2822
+ * }
2823
+ * ]);
2824
+ * ```
2825
+ */
2826
+ async assign(taskAssignments) {
2827
+ // Normalize input to array
2828
+ const assignmentArray = Array.isArray(taskAssignments) ? taskAssignments : [taskAssignments];
2829
+ const options = {
2830
+ taskAssignments: assignmentArray
2831
+ };
2832
+ // Convert options to PascalCase for API
2833
+ const pascalOptions = camelToPascalCaseKeys(options);
2834
+ const response = await this.post(TASK_ENDPOINTS.ASSIGN_TASKS, pascalOptions);
2835
+ // Transform response from PascalCase to camelCase
2836
+ const transformedResponse = pascalToCamelCaseKeys(response.data);
2837
+ // Process OData array response - empty array = success, non-empty = error
2838
+ return processODataArrayResponse(transformedResponse, assignmentArray);
2839
+ }
2840
+ /**
2841
+ * Reassigns tasks to new users
2842
+ *
2843
+ * @param taskAssignments - Single task assignment or array of task assignments
2844
+ * @returns Promise resolving to array of task assignment results
2845
+ *
2846
+ * @example
2847
+ * ```typescript
2848
+ * import { Tasks } from '@uipath/uipath-typescript/tasks';
2849
+ *
2850
+ * const tasks = new Tasks(sdk);
2851
+ *
2852
+ * // Reassign a single task to a user by ID
2853
+ * const result = await tasks.reassign({
2854
+ * taskId: 123,
2855
+ * userId: 456
2856
+ * });
2857
+ *
2858
+ * // Reassign a single task to a user by email
2859
+ * const result = await tasks.reassign({
2860
+ * taskId: 123,
2861
+ * userNameOrEmail: "user@example.com"
2862
+ * });
2863
+ *
2864
+ * // Reassign multiple tasks
2865
+ * const result = await tasks.reassign([
2866
+ * {
2867
+ * taskId: 123,
2868
+ * userId: 456
2869
+ * },
2870
+ * {
2871
+ * taskId: 789,
2872
+ * userNameOrEmail: "user@example.com"
2873
+ * }
2874
+ * ]);
2875
+ * ```
2876
+ */
2877
+ async reassign(taskAssignments) {
2878
+ // Normalize input to array
2879
+ const assignmentArray = Array.isArray(taskAssignments) ? taskAssignments : [taskAssignments];
2880
+ const options = {
2881
+ taskAssignments: assignmentArray
2882
+ };
2883
+ // Convert options to PascalCase for API
2884
+ const pascalOptions = camelToPascalCaseKeys(options);
2885
+ const response = await this.post(TASK_ENDPOINTS.REASSIGN_TASKS, pascalOptions);
2886
+ // Transform response from PascalCase to camelCase
2887
+ const transformedResponse = pascalToCamelCaseKeys(response.data);
2888
+ // Process OData array response - empty array = success, non-empty = error
2889
+ return processODataArrayResponse(transformedResponse, assignmentArray);
2890
+ }
2891
+ /**
2892
+ * Unassigns tasks (removes current assignees)
2893
+ *
2894
+ * @param taskIds - Single task ID or array of task IDs to unassign
2895
+ * @returns Promise resolving to array of task assignment results
2896
+ *
2897
+ * @example
2898
+ * ```typescript
2899
+ * import { Tasks } from '@uipath/uipath-typescript/tasks';
2900
+ *
2901
+ * const tasks = new Tasks(sdk);
2902
+ *
2903
+ * // Unassign a single task
2904
+ * const result = await tasks.unassign(123);
2905
+ *
2906
+ * // Unassign multiple tasks
2907
+ * const result = await tasks.unassign([123, 456, 789]);
2908
+ * ```
2909
+ */
2910
+ async unassign(taskIds) {
2911
+ // Normalize input to array
2912
+ const taskIdArray = Array.isArray(taskIds) ? taskIds : [taskIds];
2913
+ const options = {
2914
+ taskIds: taskIdArray
2915
+ };
2916
+ const response = await this.post(TASK_ENDPOINTS.UNASSIGN_TASKS, options);
2917
+ // Transform response from PascalCase to camelCase
2918
+ const transformedResponse = pascalToCamelCaseKeys(response.data);
2919
+ // Process OData array response - empty array = success, non-empty = error
2920
+ // Return the task IDs that were unassigned
2921
+ return processODataArrayResponse(transformedResponse, taskIdArray.map(id => ({ taskId: id })));
2922
+ }
2923
+ /**
2924
+ * Completes a task with the specified type and data
2925
+ *
2926
+ * @param options - The completion options including task type, taskId, data, and action
2927
+ * @param folderId - Required folder ID
2928
+ * @returns Promise resolving to completion result
2929
+ *
2930
+ * @example
2931
+ * ```typescript
2932
+ * import { Tasks } from '@uipath/uipath-typescript/tasks';
2933
+ *
2934
+ * const tasks = new Tasks(sdk);
2935
+ *
2936
+ * // Complete an app task
2937
+ * await tasks.complete({
2938
+ * type: TaskType.App,
2939
+ * taskId: 456,
2940
+ * data: {},
2941
+ * action: "submit"
2942
+ * }, 123); // folderId is required
2943
+ *
2944
+ * // Complete an external task
2945
+ * await tasks.complete({
2946
+ * type: TaskType.External,
2947
+ * taskId: 789
2948
+ * }, 123); // folderId is required
2949
+ * ```
2950
+ */
2951
+ async complete(options, folderId) {
2952
+ const headers = createHeaders({ [FOLDER_ID]: folderId });
2953
+ let endpoint;
2954
+ switch (options.type) {
2955
+ case TaskType.Form:
2956
+ endpoint = TASK_ENDPOINTS.COMPLETE_FORM_TASK;
2957
+ break;
2958
+ case TaskType.App:
2959
+ endpoint = TASK_ENDPOINTS.COMPLETE_APP_TASK;
2960
+ break;
2961
+ default:
2962
+ endpoint = TASK_ENDPOINTS.COMPLETE_GENERIC_TASK;
2963
+ break;
2964
+ }
2965
+ // CompleteAppTask returns 204 no content
2966
+ await this.post(endpoint, options, { headers });
2967
+ // Return success with the request context data
2968
+ return {
2969
+ success: true,
2970
+ data: options
2971
+ };
2972
+ }
2973
+ /**
2974
+ * Gets a form task by ID (private method)
2975
+ *
2976
+ * @param id - The ID of the form task to retrieve
2977
+ * @param folderId - Required folder ID
2978
+ * @param options - Optional query parameters
2979
+ * @returns Promise resolving to the form task
2980
+ */
2981
+ async getFormTaskById(id, folderId, options = {}) {
2982
+ const headers = createHeaders({ [FOLDER_ID]: folderId });
2983
+ const response = await this.get(TASK_ENDPOINTS.GET_TASK_FORM_BY_ID, {
2984
+ params: {
2985
+ taskId: id,
2986
+ ...options
2987
+ },
2988
+ headers
2989
+ });
2990
+ const transformedFormTask = transformData(response.data, TaskMap);
2991
+ return createTaskWithMethods(applyDataTransforms(transformedFormTask, { field: 'status', valueMap: TaskStatusMap }), this);
2992
+ }
2993
+ /**
2994
+ * Adds default expand parameters to options
2995
+ * @param options - The options object to add default expand to
2996
+ * @returns Options with default expand parameters added
2997
+ * @private
2998
+ */
2999
+ addDefaultExpand(options) {
3000
+ const processedOptions = { ...options };
3001
+ processedOptions.expand = processedOptions.expand
3002
+ ? `${DEFAULT_TASK_EXPAND},${processedOptions.expand}`
3003
+ : DEFAULT_TASK_EXPAND;
3004
+ return processedOptions;
3005
+ }
3006
+ }
3007
+ __decorate([
3008
+ track('Tasks.Create')
3009
+ ], TaskService.prototype, "create", null);
3010
+ __decorate([
3011
+ track('Tasks.GetUsers')
3012
+ ], TaskService.prototype, "getUsers", null);
3013
+ __decorate([
3014
+ track('Tasks.GetAll')
3015
+ ], TaskService.prototype, "getAll", null);
3016
+ __decorate([
3017
+ track('Tasks.GetById')
3018
+ ], TaskService.prototype, "getById", null);
3019
+ __decorate([
3020
+ track('Tasks.Assign')
3021
+ ], TaskService.prototype, "assign", null);
3022
+ __decorate([
3023
+ track('Tasks.Reassign')
3024
+ ], TaskService.prototype, "reassign", null);
3025
+ __decorate([
3026
+ track('Tasks.Unassign')
3027
+ ], TaskService.prototype, "unassign", null);
3028
+ __decorate([
3029
+ track('Tasks.Complete')
3030
+ ], TaskService.prototype, "complete", null);
3031
+
3032
+ class CaseInstancesService extends BaseService {
3033
+ /**
3034
+ * Creates an instance of the Case Instances service.
3035
+ *
3036
+ * @param instance - UiPath SDK instance providing authentication and configuration
3037
+ */
3038
+ constructor(instance) {
3039
+ super(instance);
3040
+ this.taskService = new TaskService(instance);
3041
+ }
3042
+ /**
3043
+ * Get all case instances with optional filtering and pagination
3044
+ *
3045
+ * The method returns either:
3046
+ * - A NonPaginatedResponse with items array (when no pagination parameters are provided)
3047
+ * - A PaginatedResponse with navigation cursors (when any pagination parameter is provided)
3048
+ *
3049
+ * @param options -Query parameters for filtering instances and pagination
3050
+ * @returns Promise resolving to case instances or paginated result
3051
+ *
3052
+ * @example
3053
+ * ```typescript
3054
+ * import { CaseInstances } from '@uipath/uipath-typescript/cases';
3055
+ *
3056
+ * const caseInstances = new CaseInstances(sdk);
3057
+ *
3058
+ * // Get all case instances (non-paginated)
3059
+ * const instances = await caseInstances.getAll();
3060
+ *
3061
+ * // Close faulted instances using methods directly on instances
3062
+ * for (const instance of instances.items) {
3063
+ * if (instance.latestRunStatus === 'Faulted') {
3064
+ * await instance.close({ comment: 'Closing faulted case instance' });
3065
+ * }
3066
+ * }
3067
+ *
3068
+ * // With filtering
3069
+ * const filtered = await caseInstances.getAll({
3070
+ * processKey: 'MyCaseProcess'
3071
+ * });
3072
+ *
3073
+ * // First page with pagination
3074
+ * const page1 = await caseInstances.getAll({ pageSize: 10 });
3075
+ *
3076
+ * // Navigate using cursor
3077
+ * if (page1.hasNextPage) {
3078
+ * const page2 = await caseInstances.getAll({ cursor: page1.nextCursor });
3079
+ * }
3080
+ * ```
3081
+ */
3082
+ async getAll(options) {
3083
+ // Add processType filter to only get case management instances
3084
+ const enhancedOptions = {
3085
+ ...options,
3086
+ processType: ProcessType.CaseManagement
3087
+ };
3088
+ // Base transformation function for case instances (synchronous)
3089
+ const transformCaseInstance = (item) => {
3090
+ const rawInstance = transformData(item, CaseInstanceMap);
3091
+ return createCaseInstanceWithMethods(rawInstance, this);
3092
+ };
3093
+ // Get the paginated result with basic transformation
3094
+ const result = await PaginationHelpers.getAll({
3095
+ serviceAccess: this.createPaginationServiceAccess(),
3096
+ getEndpoint: () => MAESTRO_ENDPOINTS.INSTANCES.GET_ALL,
3097
+ transformFn: transformCaseInstance,
3098
+ pagination: {
3099
+ paginationType: PaginationType.TOKEN,
3100
+ itemsField: PROCESS_INSTANCE_PAGINATION.ITEMS_FIELD,
3101
+ continuationTokenField: PROCESS_INSTANCE_PAGINATION.CONTINUATION_TOKEN_FIELD,
3102
+ paginationParams: {
3103
+ pageSizeParam: PROCESS_INSTANCE_TOKEN_PARAMS.PAGE_SIZE_PARAM,
3104
+ tokenParam: PROCESS_INSTANCE_TOKEN_PARAMS.TOKEN_PARAM
3105
+ }
3106
+ },
3107
+ excludeFromPrefix: Object.keys(enhancedOptions || {})
3108
+ }, enhancedOptions);
3109
+ // Enhance instances with case JSON data if requested
3110
+ if (result.items && result.items.length > 0) {
3111
+ const enhancedItems = await this.enhanceInstancesWithCaseJson(result.items);
3112
+ return {
3113
+ ...result,
3114
+ items: enhancedItems
3115
+ };
3116
+ }
3117
+ return result;
3118
+ }
3119
+ /**
3120
+ * Get a case instance by ID with operation methods (close, pause, resume, reopen)
3121
+ * @param instanceId - The ID of the instance to retrieve
3122
+ * @param folderKey - Required folder key
3123
+ * @returns Promise<CaseInstanceGetResponse>
3124
+ */
3125
+ async getById(instanceId, folderKey) {
3126
+ const response = await this.get(MAESTRO_ENDPOINTS.INSTANCES.GET_BY_ID(instanceId), {
3127
+ headers: createHeaders({ [FOLDER_KEY]: folderKey })
3128
+ });
3129
+ const transformedInstance = transformData(response.data, CaseInstanceMap);
3130
+ const instanceWithMethods = createCaseInstanceWithMethods(transformedInstance, this);
3131
+ // Enhance with case JSON data
3132
+ return this.enhanceInstanceWithCaseJson(instanceWithMethods);
3133
+ }
3134
+ /**
3135
+ * Enhance a single case instance with case JSON data
3136
+ * @param instance - The case instance to enhance
3137
+ * @returns Promise resolving to enhanced instance
3138
+ * @private
3139
+ */
3140
+ async enhanceInstanceWithCaseJson(instance) {
3141
+ if (!instance.folderKey) {
3142
+ return instance;
3143
+ }
3144
+ try {
3145
+ const caseJson = await this.getCaseJson(instance.instanceId, instance.folderKey);
3146
+ if (caseJson && caseJson.root) {
3147
+ // Transform caseAppConfig
3148
+ const transformedCaseAppConfig = caseJson.root.caseAppConfig ? (() => {
3149
+ const transformed = transformData(caseJson.root.caseAppConfig, CaseAppConfigMap);
3150
+ // Remove id field from each overview item
3151
+ if (transformed.overview) {
3152
+ transformed.overview = transformed.overview.map(({ id: _, ...rest }) => rest);
3153
+ }
3154
+ return transformed;
3155
+ })() : undefined;
3156
+ return {
3157
+ ...instance,
3158
+ ...(transformedCaseAppConfig && { caseAppConfig: transformedCaseAppConfig }),
3159
+ ...(caseJson.root.name && { caseType: caseJson.root.name }),
3160
+ ...(caseJson.root.description && { caseTitle: caseJson.root.description })
3161
+ };
3162
+ }
3163
+ }
3164
+ catch (error) {
3165
+ console.debug(`Failed to fetch case JSON for instance ${instance.instanceId}:`, error);
3166
+ }
3167
+ return instance;
3168
+ }
3169
+ /**
3170
+ * Enhance multiple case instances with case JSON data
3171
+ * @param instances - Array of case instances to enhance
3172
+ * @returns Promise resolving to array of enhanced instances
3173
+ * @private
3174
+ */
3175
+ async enhanceInstancesWithCaseJson(instances) {
3176
+ return Promise.all(instances.map(instance => this.enhanceInstanceWithCaseJson(instance)));
3177
+ }
3178
+ /**
3179
+ * Get case JSON for a specific instance
3180
+ * @param instanceId - The case instance ID
3181
+ * @param folderKey - Required folder key
3182
+ * @returns Promise resolving to case JSON data
3183
+ * @private
3184
+ */
3185
+ async getCaseJson(instanceId, folderKey) {
3186
+ try {
3187
+ const response = await this.get(MAESTRO_ENDPOINTS.CASES.GET_CASE_JSON(instanceId), {
3188
+ headers: createHeaders({ [FOLDER_KEY]: folderKey })
3189
+ });
3190
+ return response.data;
3191
+ }
3192
+ catch {
3193
+ // Return null if the case JSON is not available
3194
+ return null;
3195
+ }
3196
+ }
3197
+ /**
3198
+ * Close a case instance
3199
+ * @param instanceId - The ID of the instance to cancel
3200
+ * @param folderKey - Required folder key
3201
+ * @param options - Optional cancellation options with comment
3202
+ * @returns Promise resolving to operation result with updated instance data
3203
+ */
3204
+ async close(instanceId, folderKey, options) {
3205
+ const response = await this.post(MAESTRO_ENDPOINTS.INSTANCES.CANCEL(instanceId), options || {}, {
3206
+ headers: createHeaders({ [FOLDER_KEY]: folderKey })
3207
+ });
3208
+ return {
3209
+ success: true,
3210
+ data: response.data
3211
+ };
3212
+ }
3213
+ /**
3214
+ * Pause a case instance
3215
+ * @param instanceId - The ID of the instance to pause
3216
+ * @param folderKey - Required folder key
3217
+ * @param options - Optional pause options with comment
3218
+ * @returns Promise resolving to operation result with updated instance data
3219
+ */
3220
+ async pause(instanceId, folderKey, options) {
3221
+ const response = await this.post(MAESTRO_ENDPOINTS.INSTANCES.PAUSE(instanceId), options || {}, {
3222
+ headers: createHeaders({ [FOLDER_KEY]: folderKey })
3223
+ });
3224
+ return {
3225
+ success: true,
3226
+ data: response.data
3227
+ };
3228
+ }
3229
+ /**
3230
+ * Reopen a case instance from a specified element
3231
+ * @param instanceId - The ID of the case instance to reopen
3232
+ * @param folderKey - Required folder key
3233
+ * @param options - Reopen options containing stageId (the stage ID to resume from) and an optional comment
3234
+ * @returns Promise resolving to operation result with updated instance data
3235
+ */
3236
+ async reopen(instanceId, folderKey, options) {
3237
+ // Transform SDK options to API request format
3238
+ const requestBody = {
3239
+ StartElementId: options.stageId,
3240
+ ...(options.comment && { Comment: options.comment })
3241
+ };
3242
+ const response = await this.post(MAESTRO_ENDPOINTS.CASES.REOPEN(instanceId), requestBody, {
3243
+ headers: createHeaders({ [FOLDER_KEY]: folderKey })
3244
+ });
3245
+ return {
3246
+ success: true,
3247
+ data: response.data
3248
+ };
3249
+ }
3250
+ /**
3251
+ * Resume a case instance
3252
+ * @param instanceId - The ID of the instance to resume
3253
+ * @param folderKey - Required folder key
3254
+ * @param options - Optional resume options with comment
3255
+ * @returns Promise resolving to operation result with updated instance data
3256
+ */
3257
+ async resume(instanceId, folderKey, options) {
3258
+ const response = await this.post(MAESTRO_ENDPOINTS.INSTANCES.RESUME(instanceId), options || {}, {
3259
+ headers: createHeaders({ [FOLDER_KEY]: folderKey })
3260
+ });
3261
+ return {
3262
+ success: true,
3263
+ data: response.data
3264
+ };
3265
+ }
3266
+ /**
3267
+ * Get execution history for a case instance
3268
+ * @param instanceId - The ID of the case instance
3269
+ * @param folderKey - Required folder key
3270
+ * @returns Promise resolving to instance execution history
3271
+ * @example
3272
+ * ```typescript
3273
+ * import { CaseInstances } from '@uipath/uipath-typescript/cases';
3274
+ *
3275
+ * const caseInstances = new CaseInstances(sdk);
3276
+ * const history = await caseInstances.getExecutionHistory(
3277
+ * 'instance-id',
3278
+ * 'folder-key'
3279
+ * );
3280
+ * ```
3281
+ */
3282
+ async getExecutionHistory(instanceId, folderKey) {
3283
+ const response = await this.get(MAESTRO_ENDPOINTS.CASES.GET_ELEMENT_EXECUTIONS(instanceId), {
3284
+ headers: createHeaders({ [FOLDER_KEY]: folderKey })
3285
+ });
3286
+ // Transform the main response
3287
+ const transformedResponse = transformData(response.data, TimeFieldTransformMap);
3288
+ // Transform each element execution and its nested element runs
3289
+ if (transformedResponse.elementExecutions && Array.isArray(transformedResponse.elementExecutions)) {
3290
+ transformedResponse.elementExecutions = transformedResponse.elementExecutions.map((execution) => {
3291
+ // Transform the element execution itself
3292
+ const transformedExecution = transformData(execution, TimeFieldTransformMap);
3293
+ // Transform nested element runs if they exist
3294
+ if (transformedExecution.elementRuns && Array.isArray(transformedExecution.elementRuns)) {
3295
+ transformedExecution.elementRuns = transformedExecution.elementRuns.map((run) => transformData(run, TimeFieldTransformMap));
3296
+ }
3297
+ return transformedExecution;
3298
+ });
3299
+ }
3300
+ return transformedResponse;
3301
+ }
3302
+ /**
3303
+ * Get case stages with their associated tasks and execution status
3304
+ * @param caseInstanceId - The ID of the case instance
3305
+ * @param folderKey - Required folder key
3306
+ * @returns Promise resolving to an array of case stages, each containing their tasks with execution details
3307
+ */
3308
+ async getStages(caseInstanceId, folderKey) {
3309
+ // Fetch both execution history and case JSON in parallel, but handle execution failures gracefully
3310
+ const [executionHistoryResponse, caseJsonResponse] = await Promise.allSettled([
3311
+ this.getExecutionHistory(caseInstanceId, folderKey),
3312
+ this.getCaseJson(caseInstanceId, folderKey)
3313
+ ]);
3314
+ // Extract execution history if successful, otherwise use null
3315
+ const executionHistory = executionHistoryResponse.status === 'fulfilled'
3316
+ ? executionHistoryResponse.value
3317
+ : null;
3318
+ // Extract case JSON - the null check below will handle failures
3319
+ const caseJson = caseJsonResponse.status === 'fulfilled'
3320
+ ? caseJsonResponse.value
3321
+ : null;
3322
+ if (!caseJson || !caseJson.nodes) {
3323
+ return [];
3324
+ }
3325
+ // Create lookup maps for efficient data access
3326
+ const executionMap = this.createExecutionMap(executionHistory);
3327
+ const bindingsMap = this.createBindingsMap(caseJson);
3328
+ // Process nodes to extract stages (exclude triggers)
3329
+ const stages = caseJson.nodes
3330
+ .filter((node) => node.type !== CASE_STAGE_CONSTANTS.TRIGGER_NODE_TYPE)
3331
+ .map((node) => this.createStageFromNode(node, executionMap, bindingsMap));
3332
+ return stages;
3333
+ }
3334
+ /**
3335
+ * Create a map of element ID to execution data
3336
+ * @param executionHistory - The execution history response
3337
+ * @returns Map of elementId to execution metadata
3338
+ * @private
3339
+ */
3340
+ createExecutionMap(executionHistory) {
3341
+ const executionMap = new Map();
3342
+ if (executionHistory?.elementExecutions) {
3343
+ for (const execution of executionHistory.elementExecutions) {
3344
+ executionMap.set(execution.elementId, execution);
3345
+ }
3346
+ }
3347
+ return executionMap;
3348
+ }
3349
+ /**
3350
+ * Create a map of binding IDs to their values
3351
+ * @param caseJsonResponse - The case JSON response
3352
+ * @returns Map of binding ID to binding object
3353
+ * @private
3354
+ */
3355
+ createBindingsMap(caseJsonResponse) {
3356
+ const bindingsMap = new Map();
3357
+ if (caseJsonResponse?.root?.data?.uipath?.bindings) {
3358
+ for (const binding of caseJsonResponse.root.data.uipath.bindings) {
3359
+ if (binding.id) {
3360
+ bindingsMap.set(binding.id, binding);
3361
+ }
3362
+ }
3363
+ }
3364
+ return bindingsMap;
3365
+ }
3366
+ /**
3367
+ * Resolve binding values from binding expressions
3368
+ * @param value - The value that may contain binding references
3369
+ * @param bindingsMap - Map of binding IDs to binding objects
3370
+ * @returns Resolved value
3371
+ * @private
3372
+ */
3373
+ resolveBinding(value, bindingsMap) {
3374
+ if (typeof value === 'string' && value.startsWith('=bindings.')) {
3375
+ const bindingId = value.substring('=bindings.'.length);
3376
+ const binding = bindingsMap.get(bindingId);
3377
+ return binding?.default || binding?.name || value;
3378
+ }
3379
+ return value;
3380
+ }
3381
+ /**
3382
+ * Process tasks for a stage node
3383
+ * @param node - The stage node containing tasks
3384
+ * @param executionMap - Map of element IDs to execution data
3385
+ * @param bindingsMap - Map of binding IDs to binding objects
3386
+ * @returns Processed tasks array
3387
+ * @private
3388
+ */
3389
+ processTasks(node, executionMap, bindingsMap) {
3390
+ if (!node.data?.tasks || !Array.isArray(node.data.tasks)) {
3391
+ return [];
3392
+ }
3393
+ return node.data.tasks.map((taskGroup) => {
3394
+ if (Array.isArray(taskGroup)) {
3395
+ return taskGroup.map((task) => {
3396
+ const taskId = task.id;
3397
+ // Find the execution data using the task's id
3398
+ const taskExecution = taskId ? executionMap.get(taskId) : undefined;
3399
+ // Resolve task name from bindings
3400
+ let taskName = task.displayName;
3401
+ if (!taskName && task.data?.name) {
3402
+ taskName = this.resolveBinding(task.data.name, bindingsMap);
3403
+ }
3404
+ const stageTask = {
3405
+ id: taskId || task.elementId || CASE_STAGE_CONSTANTS.UNDEFINED_VALUE,
3406
+ name: taskName || CASE_STAGE_CONSTANTS.UNDEFINED_VALUE,
3407
+ completedTime: taskExecution?.completedTime || CASE_STAGE_CONSTANTS.UNDEFINED_VALUE,
3408
+ startedTime: taskExecution?.startedTime || CASE_STAGE_CONSTANTS.UNDEFINED_VALUE,
3409
+ status: taskExecution?.status || CASE_STAGE_CONSTANTS.NOT_STARTED_STATUS,
3410
+ type: task.type || CASE_STAGE_CONSTANTS.UNDEFINED_VALUE
3411
+ };
3412
+ return stageTask;
3413
+ });
3414
+ }
3415
+ return [];
3416
+ });
3417
+ }
3418
+ /**
3419
+ * Create a stage from a case node
3420
+ * @param node - The case node to process
3421
+ * @param executionMap - Map of element IDs to execution data
3422
+ * @param bindingsMap - Map of binding IDs to binding objects
3423
+ * @returns CaseGetStageResponse object
3424
+ * @private
3425
+ */
3426
+ createStageFromNode(node, executionMap, bindingsMap) {
3427
+ const execution = executionMap.get(node.id);
3428
+ const stage = {
3429
+ id: node.id,
3430
+ name: node.data?.label || CASE_STAGE_CONSTANTS.UNDEFINED_VALUE,
3431
+ sla: node.data?.sla ? transformData(node.data.sla, StageSLAMap) : undefined,
3432
+ status: execution?.status || CASE_STAGE_CONSTANTS.NOT_STARTED_STATUS,
3433
+ tasks: this.processTasks(node, executionMap, bindingsMap)
3434
+ };
3435
+ return stage;
3436
+ }
3437
+ /**
3438
+ * Get human in the loop tasks associated with a case instance
3439
+ * @param caseInstanceId - The ID of the case instance
3440
+ * @param options - Optional filtering and pagination options
3441
+ * @returns Promise resolving to human in the loop tasks associated with the case instance
3442
+ */
3443
+ async getActionTasks(caseInstanceId, options) {
3444
+ // Build filter to match tasks by case instance ID using tags
3445
+ const tagFilter = CASE_INSTANCE_TASK_FILTER(caseInstanceId);
3446
+ // Combine with any existing filter
3447
+ const filter = options?.filter
3448
+ ? `(${tagFilter}) and (${options.filter})`
3449
+ : tagFilter;
3450
+ // Add expand to include AssignedToUser and Activities
3451
+ const expand = CASE_INSTANCE_TASK_EXPAND;
3452
+ // Prepare the enhanced options with proper typing
3453
+ const enhancedOptions = {
3454
+ ...options,
3455
+ filter,
3456
+ expand
3457
+ };
3458
+ return await this.taskService.getAll(enhancedOptions);
3459
+ }
3460
+ }
3461
+ __decorate([
3462
+ track('CaseInstances.GetAll')
3463
+ ], CaseInstancesService.prototype, "getAll", null);
3464
+ __decorate([
3465
+ track('CaseInstances.GetById')
3466
+ ], CaseInstancesService.prototype, "getById", null);
3467
+ __decorate([
3468
+ track('CaseInstances.Close')
3469
+ ], CaseInstancesService.prototype, "close", null);
3470
+ __decorate([
3471
+ track('CaseInstances.Pause')
3472
+ ], CaseInstancesService.prototype, "pause", null);
3473
+ __decorate([
3474
+ track('CaseInstances.Reopen')
3475
+ ], CaseInstancesService.prototype, "reopen", null);
3476
+ __decorate([
3477
+ track('CaseInstances.Resume')
3478
+ ], CaseInstancesService.prototype, "resume", null);
3479
+ __decorate([
3480
+ track('CaseInstances.GetExecutionHistory')
3481
+ ], CaseInstancesService.prototype, "getExecutionHistory", null);
3482
+ __decorate([
3483
+ track('CaseInstances.GetStages')
3484
+ ], CaseInstancesService.prototype, "getStages", null);
3485
+ __decorate([
3486
+ track('CaseInstances.GetActionTasks')
3487
+ ], CaseInstancesService.prototype, "getActionTasks", null);
3488
+
3489
+ exports.CaseInstances = CaseInstancesService;
3490
+ exports.CaseInstancesService = CaseInstancesService;
3491
+ exports.Cases = CasesService;
3492
+ exports.CasesService = CasesService;
3493
+ exports.createCaseInstanceWithMethods = createCaseInstanceWithMethods;