@rbaileysr/zephyr-managed-api 1.0.0 → 1.0.2

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 (58) hide show
  1. package/README.md +155 -74
  2. package/dist/README.md +699 -0
  3. package/dist/error-strategy.d.ts +3 -0
  4. package/dist/error-strategy.d.ts.map +1 -1
  5. package/dist/error-strategy.js +3 -0
  6. package/dist/groups/All.d.ts +3 -0
  7. package/dist/groups/All.d.ts.map +1 -1
  8. package/dist/groups/All.js +2 -6
  9. package/dist/groups/Automation.d.ts +3 -0
  10. package/dist/groups/Automation.d.ts.map +1 -1
  11. package/dist/groups/Automation.js +2 -3
  12. package/dist/groups/Environment.d.ts +3 -0
  13. package/dist/groups/Environment.d.ts.map +1 -1
  14. package/dist/groups/Environment.js +2 -3
  15. package/dist/groups/Folder.d.ts +3 -0
  16. package/dist/groups/Folder.d.ts.map +1 -1
  17. package/dist/groups/Folder.js +2 -3
  18. package/dist/groups/IssueLink.d.ts +3 -0
  19. package/dist/groups/IssueLink.d.ts.map +1 -1
  20. package/dist/groups/IssueLink.js +2 -3
  21. package/dist/groups/Link.d.ts +3 -0
  22. package/dist/groups/Link.d.ts.map +1 -1
  23. package/dist/groups/Link.js +2 -3
  24. package/dist/groups/Priority.d.ts +3 -0
  25. package/dist/groups/Priority.d.ts.map +1 -1
  26. package/dist/groups/Priority.js +2 -3
  27. package/dist/groups/Project.d.ts +3 -0
  28. package/dist/groups/Project.d.ts.map +1 -1
  29. package/dist/groups/Project.js +2 -3
  30. package/dist/groups/Status.d.ts +3 -0
  31. package/dist/groups/Status.d.ts.map +1 -1
  32. package/dist/groups/Status.js +2 -3
  33. package/dist/groups/TestCase.d.ts +3 -0
  34. package/dist/groups/TestCase.d.ts.map +1 -1
  35. package/dist/groups/TestCase.js +2 -3
  36. package/dist/groups/TestCycle.d.ts +3 -0
  37. package/dist/groups/TestCycle.d.ts.map +1 -1
  38. package/dist/groups/TestCycle.js +2 -3
  39. package/dist/groups/TestExecution.d.ts +3 -0
  40. package/dist/groups/TestExecution.d.ts.map +1 -1
  41. package/dist/groups/TestExecution.js +2 -3
  42. package/dist/groups/TestPlan.d.ts +3 -0
  43. package/dist/groups/TestPlan.d.ts.map +1 -1
  44. package/dist/groups/TestPlan.js +2 -3
  45. package/dist/index.d.ts +147 -12
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +47 -11
  48. package/dist/package.json +54 -0
  49. package/dist/types.d.ts +3 -0
  50. package/dist/types.d.ts.map +1 -1
  51. package/dist/types.js +3 -0
  52. package/dist/utils-api-call.d.ts +3 -0
  53. package/dist/utils-api-call.d.ts.map +1 -1
  54. package/dist/utils-api-call.js +3 -0
  55. package/dist/utils.d.ts +3 -0
  56. package/dist/utils.d.ts.map +1 -1
  57. package/dist/utils.js +3 -0
  58. package/package.json +4 -4
package/README.md CHANGED
@@ -17,11 +17,10 @@ This Managed API wrapper provides a clean, type-safe interface to interact with
17
17
  - **Comprehensive Coverage**: Supports all Zephyr Cloud REST API v2 endpoints
18
18
  - **Error Handling**: Built-in error parsing and handling using Commons Core error types
19
19
  - **Pagination Support**: Both offset-based and cursor-based pagination
20
- - **Region Support**: Configurable US and EU regions
21
- - **Flexible Authentication**: Supports OAuth tokens and ScriptRunner Connect API Connections
20
+ - **Flexible Authentication**: Supports OAuth tokens and ScriptRunner Connect API Connections (base URL configured in Generic Connector)
22
21
  - **Custom Fields**: Full support for dynamic custom fields
23
22
  - **Web App Compatible**: Works seamlessly in ScriptRunner Connect web app
24
- - **JSDoc Documentation**: All methods include descriptions and links to official API documentation
23
+ - **Single Import**: Convenient default export for all utilities and types
25
24
 
26
25
  ## Installation
27
26
 
@@ -52,40 +51,74 @@ npm install @rbaileysr/zephyr-managed-api
52
51
 
53
52
  4. **Use in Scripts:**
54
53
  ```typescript
55
- import { createZephyrApi } from '@rbaileysr/zephyr-managed-api';
54
+ // Single import (recommended) - everything in one import
55
+ import Zephyr from '@rbaileysr/zephyr-managed-api';
56
56
  import ZephyrApiConnection from '../api/zephyr';
57
57
 
58
58
  // Using API Connection (recommended for ScriptRunner Connect)
59
- const Zephyr = createZephyrApi(ZephyrApiConnection, 'us');
59
+ // Base URL is configured in the Generic Connector
60
+ const api = Zephyr.createZephyrApi(ZephyrApiConnection);
61
+
62
+ // Access utilities and error types from the same import
63
+ const pages = await Zephyr.getAllPages(...);
64
+ const errorStrategy = new Zephyr.ErrorStrategyBuilder()...;
65
+ ```
66
+
67
+ **Alternative - Named Imports:**
68
+ ```typescript
69
+ // Named imports (if you prefer)
70
+ import { createZephyrApi, getAllPages, ErrorStrategyBuilder } from '@rbaileysr/zephyr-managed-api';
60
71
  ```
61
72
 
62
73
  ## Usage
63
74
 
64
75
  ### Basic Examples
65
76
 
66
- #### Using API Connection (ScriptRunner Connect)
77
+ #### Using API Connection (ScriptRunner Connect) - Single Import
67
78
 
68
79
  ```typescript
69
- import { createZephyrApi } from '@rbaileysr/zephyr-managed-api';
80
+ // Single import for everything
81
+ import Zephyr from '@rbaileysr/zephyr-managed-api';
70
82
  import ZephyrApiConnection from '../api/zephyr';
71
83
 
72
- const Zephyr = createZephyrApi(ZephyrApiConnection, 'us');
84
+ // Create API instance (base URL configured in Generic Connector)
85
+ const api = Zephyr.createZephyrApi(ZephyrApiConnection);
73
86
 
74
87
  // Get a test case
75
- const testCase = await Zephyr.TestCase.getTestCase({ testCaseKey: 'PROJ-T1' });
88
+ const testCase = await api.TestCase.getTestCase({ testCaseKey: 'PROJ-T1' });
76
89
  console.log(`Test case: ${testCase.name}`);
77
90
  ```
78
91
 
79
- #### Using OAuth Token
92
+ #### Using API Connection - Named Imports
80
93
 
81
94
  ```typescript
95
+ // Named imports (alternative)
82
96
  import { createZephyrApi } from '@rbaileysr/zephyr-managed-api';
97
+ import ZephyrApiConnection from '../api/zephyr';
98
+
99
+ const api = createZephyrApi(ZephyrApiConnection);
100
+ const testCase = await api.TestCase.getTestCase({ testCaseKey: 'PROJ-T1' });
101
+ ```
102
+
103
+ #### Using OAuth Token
104
+
105
+ ```typescript
106
+ import Zephyr from '@rbaileysr/zephyr-managed-api';
107
+
108
+ // OAuth token with full base URL (US region)
109
+ const api = Zephyr.createZephyrApi(
110
+ 'your-oauth-token-here',
111
+ 'https://api.zephyrscale.smartbear.com/v2'
112
+ );
83
113
 
84
- const oauthToken = 'your-oauth-token-here';
85
- const Zephyr = createZephyrApi(oauthToken, 'us');
114
+ // OAuth token with full base URL (EU region)
115
+ const apiEU = Zephyr.createZephyrApi(
116
+ 'your-oauth-token-here',
117
+ 'https://eu.api.zephyrscale.smartbear.com/v2'
118
+ );
86
119
 
87
120
  // List test cases
88
- const testCases = await Zephyr.TestCase.listTestCases({
121
+ const testCases = await api.TestCase.listTestCases({
89
122
  projectKey: 'PROJ',
90
123
  maxResults: 10,
91
124
  startAt: 0
@@ -96,7 +129,7 @@ console.log(`Found ${testCases.values.length} test cases`);
96
129
  #### Create a Test Case
97
130
 
98
131
  ```typescript
99
- const testCase = await Zephyr.TestCase.createTestCase({
132
+ const testCase = await api.TestCase.createTestCase({
100
133
  body: {
101
134
  projectKey: 'PROJ',
102
135
  name: 'Login Test Case',
@@ -117,7 +150,7 @@ console.log(`Created test case: ${testCase.key}`);
117
150
  #### Create a Test Cycle
118
151
 
119
152
  ```typescript
120
- const testCycle = await Zephyr.TestCycle.createTestCycle({
153
+ const testCycle = await api.TestCycle.createTestCycle({
121
154
  body: {
122
155
  projectKey: 'PROJ',
123
156
  name: 'Sprint 1 Regression',
@@ -136,7 +169,7 @@ console.log(`Created test cycle: ${testCycle.key}`);
136
169
  #### Create a Test Execution
137
170
 
138
171
  ```typescript
139
- const testExecution = await Zephyr.TestExecution.createTestExecution({
172
+ const testExecution = await api.TestExecution.createTestExecution({
140
173
  body: {
141
174
  projectKey: 'PROJ',
142
175
  testCaseKey: 'PROJ-T1',
@@ -154,16 +187,16 @@ console.log(`Created test execution: ${testExecution.key || testExecution.id}`);
154
187
 
155
188
  ```typescript
156
189
  // First, get the test case
157
- const testCase = await Zephyr.TestCase.getTestCase({ testCaseKey: 'PROJ-T1' });
190
+ const testCase = await api.TestCase.getTestCase({ testCaseKey: 'PROJ-T1' });
158
191
 
159
192
  // Update it
160
- await Zephyr.TestCase.updateTestCase({
193
+ testCase.name = 'Updated Test Case Name';
194
+ testCase.objective = 'Updated objective';
195
+ testCase.labels = [...(testCase.labels || []), 'updated'];
196
+
197
+ await api.TestCase.updateTestCase({
161
198
  testCaseKey: 'PROJ-T1',
162
- body: {
163
- name: 'Updated Test Case Name',
164
- objective: 'Updated objective',
165
- labels: [...(testCase.labels || []), 'updated']
166
- }
199
+ body: testCase
167
200
  });
168
201
  ```
169
202
 
@@ -171,7 +204,7 @@ await Zephyr.TestCase.updateTestCase({
171
204
 
172
205
  ```typescript
173
206
  // Offset-based pagination
174
- const testCases = await Zephyr.TestCase.listTestCases({
207
+ const testCases = await api.TestCase.listTestCases({
175
208
  projectKey: 'PROJ',
176
209
  folderId: 12345,
177
210
  maxResults: 50,
@@ -179,7 +212,7 @@ const testCases = await Zephyr.TestCase.listTestCases({
179
212
  });
180
213
 
181
214
  // Cursor-based pagination (for large datasets)
182
- const testCasesCursor = await Zephyr.TestCase.listTestCasesCursorPaginated({
215
+ const testCasesCursor = await api.TestCase.listTestCasesCursorPaginated({
183
216
  projectKey: 'PROJ',
184
217
  limit: 100,
185
218
  startAtId: 0
@@ -190,7 +223,7 @@ const testCasesCursor = await Zephyr.TestCase.listTestCasesCursorPaginated({
190
223
 
191
224
  ```typescript
192
225
  // Link test case to Jira issue
193
- const issueLink = await Zephyr.TestCase.createTestCaseIssueLink({
226
+ const issueLink = await api.TestCase.createTestCaseIssueLink({
194
227
  testCaseKey: 'PROJ-T1',
195
228
  body: {
196
229
  issueId: 12345
@@ -198,7 +231,7 @@ const issueLink = await Zephyr.TestCase.createTestCaseIssueLink({
198
231
  });
199
232
 
200
233
  // Link test case to web URL
201
- const webLink = await Zephyr.TestCase.createTestCaseWebLink({
234
+ const webLink = await api.TestCase.createTestCaseWebLink({
202
235
  testCaseKey: 'PROJ-T1',
203
236
  body: {
204
237
  url: 'https://example.com/test-resource',
@@ -302,35 +335,39 @@ The Managed API is organized into the following groups:
302
335
 
303
336
  ### Using ScriptRunner Connect API Connection (Recommended)
304
337
 
305
- When using in ScriptRunner Connect, configure an API Connection in the web UI and use it:
338
+ When using in ScriptRunner Connect, configure a Generic Connector with the full base URL in the web UI:
339
+
340
+ **For US region:** `https://api.zephyrscale.smartbear.com/v2`
341
+ **For EU region:** `https://eu.api.zephyrscale.smartbear.com/v2`
342
+
343
+ Then use it in your script:
306
344
 
307
345
  ```typescript
308
- import { createZephyrApi } from '@rbaileysr/zephyr-managed-api';
346
+ import Zephyr from '@rbaileysr/zephyr-managed-api';
309
347
  import ZephyrApiConnection from '../api/zephyr';
310
348
 
311
- const Zephyr = createZephyrApi(ZephyrApiConnection, 'us');
349
+ // Base URL is configured in the Generic Connector
350
+ const api = Zephyr.createZephyrApi(ZephyrApiConnection);
312
351
  ```
313
352
 
314
353
  ### Using OAuth Token
315
354
 
316
- For local testing or when using OAuth tokens directly:
355
+ For local testing or when using OAuth tokens directly, provide the full base URL:
317
356
 
318
357
  ```typescript
319
- import { createZephyrApi } from '@rbaileysr/zephyr-managed-api';
320
-
321
- const Zephyr = createZephyrApi('your-oauth-token', 'us');
322
- ```
323
-
324
- ## Region Support
358
+ import Zephyr from '@rbaileysr/zephyr-managed-api';
325
359
 
326
- The API supports both US and EU regions:
327
-
328
- ```typescript
329
- // US region (default)
330
- const ZephyrUS = createZephyrApi(apiConnection, 'us');
360
+ // US region
361
+ const api = Zephyr.createZephyrApi(
362
+ 'your-oauth-token',
363
+ 'https://api.zephyrscale.smartbear.com/v2'
364
+ );
331
365
 
332
366
  // EU region
333
- const ZephyrEU = createZephyrApi(apiConnection, 'eu');
367
+ const apiEU = Zephyr.createZephyrApi(
368
+ 'your-oauth-token',
369
+ 'https://eu.api.zephyrscale.smartbear.com/v2'
370
+ );
334
371
  ```
335
372
 
336
373
  ## Custom Fields
@@ -347,7 +384,7 @@ const customFields = {
347
384
  'Tester': 'user-account-id-here'
348
385
  };
349
386
 
350
- await Zephyr.TestCase.createTestCase({
387
+ await api.TestCase.createTestCase({
351
388
  body: {
352
389
  projectKey: 'PROJ',
353
390
  name: 'Test Case',
@@ -368,8 +405,32 @@ The API uses Commons Core-compatible error types for consistent error handling.
368
405
 
369
406
  ### Error Types
370
407
 
408
+ ```typescript
409
+ // Single import for everything
410
+ import Zephyr from '@rbaileysr/zephyr-managed-api';
411
+ import ZephyrApiConnection from '../api/zephyr';
412
+
413
+ const api = Zephyr.createZephyrApi(ZephyrApiConnection);
414
+
415
+ try {
416
+ const testCase = await api.TestCase.getTestCase({ testCaseKey: 'INVALID-T1' });
417
+ } catch (error) {
418
+ if (error instanceof Zephyr.NotFoundError) {
419
+ console.log('Test case not found');
420
+ } else if (error instanceof Zephyr.BadRequestError) {
421
+ console.log('Invalid request');
422
+ } else if (error instanceof Zephyr.TooManyRequestsError) {
423
+ console.log('Rate limited - this should have been retried automatically');
424
+ } else if (error instanceof Zephyr.HttpError) {
425
+ console.log(`HTTP error: ${error.message}`);
426
+ }
427
+ }
428
+ ```
429
+
430
+ **Alternative - Named Imports:**
371
431
  ```typescript
372
432
  import {
433
+ createZephyrApi,
373
434
  BadRequestError,
374
435
  UnauthorizedError,
375
436
  ForbiddenError,
@@ -380,19 +441,7 @@ import {
380
441
  UnexpectedError
381
442
  } from '@rbaileysr/zephyr-managed-api';
382
443
 
383
- try {
384
- const testCase = await Zephyr.TestCase.getTestCase({ testCaseKey: 'INVALID-T1' });
385
- } catch (error) {
386
- if (error instanceof NotFoundError) {
387
- console.log('Test case not found');
388
- } else if (error instanceof BadRequestError) {
389
- console.log('Invalid request');
390
- } else if (error instanceof TooManyRequestsError) {
391
- console.log('Rate limited - this should have been retried automatically');
392
- } else if (error instanceof HttpError) {
393
- console.log(`HTTP error: ${error.message}`);
394
- }
395
- }
444
+ // Use named imports as before
396
445
  ```
397
446
 
398
447
  ### Automatic Rate Limiting Handling
@@ -414,7 +463,7 @@ All API methods automatically handle rate limiting (HTTP 429) with:
414
463
  ```typescript
415
464
  // This call will automatically retry on 429 errors
416
465
  // You don't need to handle rate limiting manually
417
- const testCases = await Zephyr.TestCase.listTestCases({ projectKey: 'PROJ' });
466
+ const testCases = await api.TestCase.listTestCases({ projectKey: 'PROJ' });
418
467
  ```
419
468
 
420
469
  If rate limiting occurs:
@@ -428,10 +477,13 @@ If rate limiting occurs:
428
477
  For advanced error handling, you can provide an `errorStrategy` parameter to customize how errors are handled:
429
478
 
430
479
  ```typescript
431
- import { retry, ErrorStrategyBuilder } from '@rbaileysr/zephyr-managed-api';
480
+ import Zephyr from '@rbaileysr/zephyr-managed-api';
481
+ import ZephyrApiConnection from '../api/zephyr';
482
+
483
+ const api = Zephyr.createZephyrApi(ZephyrApiConnection);
432
484
 
433
485
  // Return null instead of throwing on 404
434
- const testCase = await Zephyr.TestCase.getTestCase(
486
+ const testCase = await api.TestCase.getTestCase(
435
487
  { testCaseKey: 'PROJ-T1' },
436
488
  {
437
489
  handleHttp404Error: () => ({ type: 'return', value: null })
@@ -439,13 +491,13 @@ const testCase = await Zephyr.TestCase.getTestCase(
439
491
  );
440
492
 
441
493
  // Using ErrorStrategyBuilder for cleaner syntax
442
- const errorStrategy = new ErrorStrategyBuilder<TestCase | null>()
494
+ const errorStrategy = new Zephyr.ErrorStrategyBuilder<TestCase | null>()
443
495
  .http404Error(() => ({ type: 'return', value: null }))
444
496
  .retryOnRateLimiting(10) // Retry up to 10 times on rate limiting
445
- .http500Error(() => retry(5000)) // Retry server errors with 5s delay
497
+ .http500Error(() => Zephyr.retry(5000)) // Retry server errors with 5s delay
446
498
  .build();
447
499
 
448
- const testCase2 = await Zephyr.TestCase.getTestCase(
500
+ const testCase2 = await api.TestCase.getTestCase(
449
501
  { testCaseKey: 'PROJ-T2' },
450
502
  errorStrategy
451
503
  );
@@ -485,7 +537,7 @@ const testCase2 = await Zephyr.TestCase.getTestCase(
485
537
  #### Offset-Based Pagination
486
538
 
487
539
  ```typescript
488
- const testCases = await Zephyr.TestCase.listTestCases({
540
+ const testCases = await api.TestCase.listTestCases({
489
541
  projectKey: 'PROJ',
490
542
  maxResults: 50,
491
543
  startAt: 0
@@ -493,7 +545,7 @@ const testCases = await Zephyr.TestCase.listTestCases({
493
545
 
494
546
  // Check if more results available
495
547
  if (!testCases.isLast) {
496
- const nextPage = await Zephyr.TestCase.listTestCases({
548
+ const nextPage = await api.TestCase.listTestCases({
497
549
  projectKey: 'PROJ',
498
550
  maxResults: 50,
499
551
  startAt: testCases.startAt + testCases.maxResults
@@ -504,7 +556,7 @@ if (!testCases.isLast) {
504
556
  #### Cursor-Based Pagination
505
557
 
506
558
  ```typescript
507
- const testCases = await Zephyr.TestCase.listTestCasesCursorPaginated({
559
+ const testCases = await api.TestCase.listTestCasesCursorPaginated({
508
560
  projectKey: 'PROJ',
509
561
  limit: 100,
510
562
  startAtId: 0
@@ -512,7 +564,7 @@ const testCases = await Zephyr.TestCase.listTestCasesCursorPaginated({
512
564
 
513
565
  // Get next page
514
566
  if (testCases.nextStartAtId !== null) {
515
- const nextPage = await Zephyr.TestCase.listTestCasesCursorPaginated({
567
+ const nextPage = await api.TestCase.listTestCasesCursorPaginated({
516
568
  projectKey: 'PROJ',
517
569
  limit: 100,
518
570
  startAtId: testCases.nextStartAtId
@@ -527,11 +579,14 @@ For convenience, use `getAllPages()` to automatically fetch all pages:
527
579
  #### Offset-Based Pagination
528
580
 
529
581
  ```typescript
530
- import { getAllPages } from '@rbaileysr/zephyr-managed-api';
582
+ import Zephyr from '@rbaileysr/zephyr-managed-api';
583
+ import ZephyrApiConnection from '../api/zephyr';
584
+
585
+ const api = Zephyr.createZephyrApi(ZephyrApiConnection);
531
586
 
532
587
  // Automatically fetches all pages
533
- const allTestCases = await getAllPages(
534
- (startAt, maxResults) => Zephyr.TestCase.listTestCases({
588
+ const allTestCases = await Zephyr.getAllPages(
589
+ (startAt, maxResults) => api.TestCase.listTestCases({
535
590
  projectKey: 'PROJ',
536
591
  startAt,
537
592
  maxResults
@@ -546,11 +601,14 @@ console.log(`Found ${allTestCases.length} test cases`);
546
601
  #### Cursor-Based Pagination
547
602
 
548
603
  ```typescript
549
- import { getAllPagesCursor } from '@rbaileysr/zephyr-managed-api';
604
+ import Zephyr from '@rbaileysr/zephyr-managed-api';
605
+ import ZephyrApiConnection from '../api/zephyr';
606
+
607
+ const api = Zephyr.createZephyrApi(ZephyrApiConnection);
550
608
 
551
609
  // Automatically fetches all pages
552
- const allTestCases = await getAllPagesCursor(
553
- (startAtId, limit) => Zephyr.TestCase.listTestCasesCursorPaginated({
610
+ const allTestCases = await Zephyr.getAllPagesCursor(
611
+ (startAtId, limit) => api.TestCase.listTestCasesCursorPaginated({
554
612
  projectKey: 'PROJ',
555
613
  startAtId,
556
614
  limit
@@ -605,7 +663,7 @@ The `All` group provides a single point of access to all API methods across all
605
663
 
606
664
  ## License
607
665
 
608
- MIT
666
+ UNLICENSED - Copyright Adaptavist 2025 (c) All rights reserved
609
667
 
610
668
  ## Support
611
669
 
@@ -616,3 +674,26 @@ For issues, questions, or contributions, please refer to the project repository
616
674
  - **NPM Package**: https://www.npmjs.com/package/@rbaileysr/zephyr-managed-api
617
675
  - **Zephyr API Documentation**: https://support.smartbear.com/zephyr-scale-cloud/api-docs/v2/
618
676
  - **ScriptRunner Connect Documentation**: https://docs.adaptavist.com/src/latest/
677
+
678
+ ## Changelog
679
+
680
+ ### 1.0.1
681
+
682
+ - **Added**: Comprehensive JSDoc comments with API endpoint descriptions and links to official documentation
683
+ - **Added**: Single import option via default export for convenient usage
684
+ - **Changed**: Removed `region` parameter from `createZephyrApi` - base URL now configured in Generic Connector
685
+ - **Improved**: Error handling to support both `BadRequestError` and `NotFoundError` in test examples
686
+ - **Improved**: Type safety and IntelliSense support throughout the API
687
+
688
+ ### 1.0.0
689
+
690
+ - **Initial Release**: Complete Managed API wrapper for Zephyr Cloud REST API v2
691
+ - **Added**: Full support for all Zephyr API endpoints (Test Cases, Test Cycles, Test Plans, Test Executions, etc.)
692
+ - **Added**: Type-safe TypeScript definitions for all API operations
693
+ - **Added**: Hierarchical API structure matching ScriptRunner Connect conventions
694
+ - **Added**: Automatic rate limiting retry with exponential backoff
695
+ - **Added**: Support for both API Connection and OAuth token authentication
696
+ - **Added**: Pagination helpers (`getAllPages`, `getAllPagesCursor`)
697
+ - **Added**: Error strategy builder for advanced error handling
698
+ - **Added**: Comprehensive error types compatible with Commons Core
699
+