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