@rbaileysr/zephyr-managed-api 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +132 -73
- package/dist/index.d.ts +142 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +42 -9
- package/package.json +1 -1
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
|
-
- **
|
|
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
|
-
- **
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
80
|
+
// Single import for everything
|
|
81
|
+
import Zephyr from '@rbaileysr/zephyr-managed-api';
|
|
70
82
|
import ZephyrApiConnection from '../api/zephyr';
|
|
71
83
|
|
|
72
|
-
|
|
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
|
|
88
|
+
const testCase = await api.TestCase.getTestCase({ testCaseKey: 'PROJ-T1' });
|
|
76
89
|
console.log(`Test case: ${testCase.name}`);
|
|
77
90
|
```
|
|
78
91
|
|
|
79
|
-
#### Using
|
|
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
|
+
```
|
|
83
102
|
|
|
84
|
-
|
|
85
|
-
|
|
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
|
+
);
|
|
113
|
+
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
190
|
+
const testCase = await api.TestCase.getTestCase({ testCaseKey: 'PROJ-T1' });
|
|
158
191
|
|
|
159
192
|
// Update it
|
|
160
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
346
|
+
import Zephyr from '@rbaileysr/zephyr-managed-api';
|
|
309
347
|
import ZephyrApiConnection from '../api/zephyr';
|
|
310
348
|
|
|
311
|
-
|
|
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
|
|
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
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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) =>
|
|
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
|
|
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) =>
|
|
610
|
+
const allTestCases = await Zephyr.getAllPagesCursor(
|
|
611
|
+
(startAtId, limit) => api.TestCase.listTestCasesCursorPaginated({
|
|
554
612
|
projectKey: 'PROJ',
|
|
555
613
|
startAtId,
|
|
556
614
|
limit
|
|
@@ -616,3 +674,4 @@ 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
|
+
|
package/dist/index.d.ts
CHANGED
|
@@ -80,40 +80,172 @@ export declare class ZephyrApi {
|
|
|
80
80
|
/**
|
|
81
81
|
* Create a Zephyr API instance with the provided API connection (Connector-based)
|
|
82
82
|
*
|
|
83
|
+
* The base URL is configured in the Generic Connector in ScriptRunner Connect.
|
|
84
|
+
* No region parameter is needed as the connector handles the full base URL.
|
|
85
|
+
*
|
|
83
86
|
* @param apiConnection - The API connection from scripts/api/zephyr
|
|
84
|
-
* @param region - API region ('us' or 'eu'), defaults to 'us'
|
|
85
87
|
* @returns A Zephyr API instance with all resource groups
|
|
86
88
|
*
|
|
87
89
|
* @example
|
|
88
90
|
* ```typescript
|
|
89
|
-
* import { createZephyrApi } from '
|
|
91
|
+
* import { createZephyrApi } from '@rbaileysr/zephyr-managed-api';
|
|
90
92
|
* import ZephyrApiConnection from '../api/zephyr';
|
|
91
93
|
*
|
|
92
|
-
* const Zephyr = createZephyrApi(ZephyrApiConnection
|
|
94
|
+
* const Zephyr = createZephyrApi(ZephyrApiConnection);
|
|
93
95
|
* const testCase = await Zephyr.TestCase.getTestCase({ testCaseKey: 'PROJ-T1' });
|
|
94
96
|
* ```
|
|
95
97
|
*/
|
|
96
|
-
export declare function createZephyrApi(apiConnection: ZephyrApiConnection
|
|
98
|
+
export declare function createZephyrApi(apiConnection: ZephyrApiConnection): ZephyrApi;
|
|
97
99
|
/**
|
|
98
100
|
* Create a Zephyr API instance with OAuth token
|
|
99
101
|
*
|
|
100
102
|
* @param oauthToken - The OAuth token string
|
|
101
|
-
* @param
|
|
102
|
-
* @param baseUrl - Optional custom base URL (overrides region)
|
|
103
|
+
* @param baseUrl - The full base URL for the Zephyr API (e.g., 'https://api.zephyrscale.smartbear.com/v2' or 'https://eu.api.zephyrscale.smartbear.com/v2')
|
|
103
104
|
* @returns A Zephyr API instance with all resource groups
|
|
104
105
|
*
|
|
105
106
|
* @example
|
|
106
107
|
* ```typescript
|
|
107
|
-
* import { createZephyrApi } from '
|
|
108
|
+
* import { createZephyrApi } from '@rbaileysr/zephyr-managed-api';
|
|
109
|
+
*
|
|
110
|
+
* // OAuth token authentication (US region)
|
|
111
|
+
* const Zephyr = createZephyrApi('oauth-token-string', 'https://api.zephyrscale.smartbear.com/v2');
|
|
112
|
+
*
|
|
113
|
+
* // OAuth token authentication (EU region)
|
|
114
|
+
* const ZephyrEU = createZephyrApi('oauth-token-string', 'https://eu.api.zephyrscale.smartbear.com/v2');
|
|
108
115
|
*
|
|
109
|
-
* // OAuth token authentication
|
|
110
|
-
* const Zephyr = createZephyrApi('oauth-token-string', 'us');
|
|
111
116
|
* const testCase = await Zephyr.TestCase.getTestCase({ testCaseKey: 'PROJ-T1' });
|
|
112
117
|
* ```
|
|
113
118
|
*/
|
|
114
|
-
export declare function createZephyrApi(oauthToken: string,
|
|
119
|
+
export declare function createZephyrApi(oauthToken: string, baseUrl: string): ZephyrApi;
|
|
115
120
|
export * from './types';
|
|
116
121
|
export * from './error-strategy';
|
|
117
122
|
export { getAllPages, getAllPagesCursor } from './utils';
|
|
118
123
|
export { HttpError, BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, TooManyRequestsError, ServerError, UnexpectedError, } from './utils';
|
|
124
|
+
import { getAllPages, getAllPagesCursor } from './utils';
|
|
125
|
+
import { retry, continuePropagation, ErrorStrategyBuilder } from './error-strategy';
|
|
126
|
+
/**
|
|
127
|
+
* Default export for convenient single-import usage
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```typescript
|
|
131
|
+
* import Zephyr from '@rbaileysr/zephyr-managed-api';
|
|
132
|
+
* import ZephyrApiConnection from '../api/zephyr';
|
|
133
|
+
*
|
|
134
|
+
* const api = Zephyr.createZephyrApi(ZephyrApiConnection);
|
|
135
|
+
* const pages = await Zephyr.getAllPages(...);
|
|
136
|
+
* const errorStrategy = new Zephyr.ErrorStrategyBuilder()...;
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
declare const _default: {
|
|
140
|
+
createZephyrApi: typeof createZephyrApi;
|
|
141
|
+
ZephyrApi: typeof ZephyrApi;
|
|
142
|
+
getAllPages: typeof getAllPages;
|
|
143
|
+
getAllPagesCursor: typeof getAllPagesCursor;
|
|
144
|
+
HttpError: {
|
|
145
|
+
new (message: string, status: number, statusText: string, response?: unknown | undefined): {
|
|
146
|
+
readonly status: number;
|
|
147
|
+
readonly statusText: string;
|
|
148
|
+
readonly response?: unknown | undefined;
|
|
149
|
+
name: string;
|
|
150
|
+
message: string;
|
|
151
|
+
stack?: string;
|
|
152
|
+
};
|
|
153
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
154
|
+
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
|
|
155
|
+
stackTraceLimit: number;
|
|
156
|
+
};
|
|
157
|
+
BadRequestError: {
|
|
158
|
+
new (message: string, statusText?: string, response?: unknown): {
|
|
159
|
+
readonly status: number;
|
|
160
|
+
readonly statusText: string;
|
|
161
|
+
readonly response?: unknown | undefined;
|
|
162
|
+
name: string;
|
|
163
|
+
message: string;
|
|
164
|
+
stack?: string;
|
|
165
|
+
};
|
|
166
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
167
|
+
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
|
|
168
|
+
stackTraceLimit: number;
|
|
169
|
+
};
|
|
170
|
+
UnauthorizedError: {
|
|
171
|
+
new (message: string, statusText?: string, response?: unknown): {
|
|
172
|
+
readonly status: number;
|
|
173
|
+
readonly statusText: string;
|
|
174
|
+
readonly response?: unknown | undefined;
|
|
175
|
+
name: string;
|
|
176
|
+
message: string;
|
|
177
|
+
stack?: string;
|
|
178
|
+
};
|
|
179
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
180
|
+
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
|
|
181
|
+
stackTraceLimit: number;
|
|
182
|
+
};
|
|
183
|
+
ForbiddenError: {
|
|
184
|
+
new (message: string, statusText?: string, response?: unknown): {
|
|
185
|
+
readonly status: number;
|
|
186
|
+
readonly statusText: string;
|
|
187
|
+
readonly response?: unknown | undefined;
|
|
188
|
+
name: string;
|
|
189
|
+
message: string;
|
|
190
|
+
stack?: string;
|
|
191
|
+
};
|
|
192
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
193
|
+
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
|
|
194
|
+
stackTraceLimit: number;
|
|
195
|
+
};
|
|
196
|
+
NotFoundError: {
|
|
197
|
+
new (message: string, statusText?: string, response?: unknown): {
|
|
198
|
+
readonly status: number;
|
|
199
|
+
readonly statusText: string;
|
|
200
|
+
readonly response?: unknown | undefined;
|
|
201
|
+
name: string;
|
|
202
|
+
message: string;
|
|
203
|
+
stack?: string;
|
|
204
|
+
};
|
|
205
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
206
|
+
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
|
|
207
|
+
stackTraceLimit: number;
|
|
208
|
+
};
|
|
209
|
+
TooManyRequestsError: {
|
|
210
|
+
new (message: string, statusText?: string, response?: unknown): {
|
|
211
|
+
readonly status: number;
|
|
212
|
+
readonly statusText: string;
|
|
213
|
+
readonly response?: unknown | undefined;
|
|
214
|
+
name: string;
|
|
215
|
+
message: string;
|
|
216
|
+
stack?: string;
|
|
217
|
+
};
|
|
218
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
219
|
+
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
|
|
220
|
+
stackTraceLimit: number;
|
|
221
|
+
};
|
|
222
|
+
ServerError: {
|
|
223
|
+
new (message: string, status: number, statusText?: string, response?: unknown): {
|
|
224
|
+
readonly status: number;
|
|
225
|
+
readonly statusText: string;
|
|
226
|
+
readonly response?: unknown | undefined;
|
|
227
|
+
name: string;
|
|
228
|
+
message: string;
|
|
229
|
+
stack?: string;
|
|
230
|
+
};
|
|
231
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
232
|
+
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
|
|
233
|
+
stackTraceLimit: number;
|
|
234
|
+
};
|
|
235
|
+
UnexpectedError: {
|
|
236
|
+
new (message: string, cause?: unknown | undefined): {
|
|
237
|
+
readonly cause?: unknown | undefined;
|
|
238
|
+
name: string;
|
|
239
|
+
message: string;
|
|
240
|
+
stack?: string;
|
|
241
|
+
};
|
|
242
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
243
|
+
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
|
|
244
|
+
stackTraceLimit: number;
|
|
245
|
+
};
|
|
246
|
+
retry: typeof retry;
|
|
247
|
+
continuePropagation: typeof continuePropagation;
|
|
248
|
+
ErrorStrategyBuilder: typeof ErrorStrategyBuilder;
|
|
249
|
+
};
|
|
250
|
+
export default _default;
|
|
119
251
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IACnC,KAAK,EAAE,CACN,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QACT,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QACrE,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,GAAG,WAAW,GAAG,eAAe,GAAG,IAAI,CAAC;KACvE,KACG,OAAO,CAAC;QACZ,EAAE,EAAE,OAAO,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;QACrB,OAAO,EAAE;YAAE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;SAAE,CAAC;KAC9C,CAAC,CAAC;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -67,12 +67,11 @@ class OAuthZephyrConnection {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
/**
|
|
70
|
-
* Get base URL for region
|
|
70
|
+
* Get default base URL for US region
|
|
71
|
+
* Used as fallback for OAuth token mode if baseUrl not provided
|
|
71
72
|
*/
|
|
72
|
-
function
|
|
73
|
-
return
|
|
74
|
-
? 'https://api.zephyrscale.smartbear.com/v2'
|
|
75
|
-
: 'https://eu.api.zephyrscale.smartbear.com/v2';
|
|
73
|
+
function getDefaultBaseUrl() {
|
|
74
|
+
return 'https://api.zephyrscale.smartbear.com/v2';
|
|
76
75
|
}
|
|
77
76
|
/**
|
|
78
77
|
* Main Zephyr API class
|
|
@@ -99,17 +98,17 @@ export class ZephyrApi {
|
|
|
99
98
|
}
|
|
100
99
|
}
|
|
101
100
|
// Implementation
|
|
102
|
-
export function createZephyrApi(apiConnectionOrOAuthToken,
|
|
103
|
-
const finalRegion = region ?? 'us';
|
|
101
|
+
export function createZephyrApi(apiConnectionOrOAuthToken, baseUrl) {
|
|
104
102
|
let apiConnection;
|
|
105
103
|
if (typeof apiConnectionOrOAuthToken === 'string') {
|
|
106
104
|
// OAuth mode - create OAuth connection
|
|
107
|
-
|
|
105
|
+
// baseUrl is required for OAuth token mode
|
|
106
|
+
const finalBaseUrl = baseUrl ?? getDefaultBaseUrl();
|
|
108
107
|
apiConnection = new OAuthZephyrConnection(apiConnectionOrOAuthToken, finalBaseUrl);
|
|
109
108
|
}
|
|
110
109
|
else {
|
|
111
110
|
// Connector mode - use provided connection
|
|
112
|
-
//
|
|
111
|
+
// Base URL is configured in the Generic Connector, so no parameter needed
|
|
113
112
|
apiConnection = apiConnectionOrOAuthToken;
|
|
114
113
|
}
|
|
115
114
|
return new ZephyrApi(apiConnection);
|
|
@@ -122,3 +121,37 @@ export * from './error-strategy';
|
|
|
122
121
|
export { getAllPages, getAllPagesCursor } from './utils';
|
|
123
122
|
// Export error types
|
|
124
123
|
export { HttpError, BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, TooManyRequestsError, ServerError, UnexpectedError, } from './utils';
|
|
124
|
+
// Import utilities for default export
|
|
125
|
+
import { getAllPages, getAllPagesCursor } from './utils';
|
|
126
|
+
import { HttpError, BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, TooManyRequestsError, ServerError, UnexpectedError, } from './utils';
|
|
127
|
+
import { retry, continuePropagation, ErrorStrategyBuilder } from './error-strategy';
|
|
128
|
+
/**
|
|
129
|
+
* Default export for convenient single-import usage
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```typescript
|
|
133
|
+
* import Zephyr from '@rbaileysr/zephyr-managed-api';
|
|
134
|
+
* import ZephyrApiConnection from '../api/zephyr';
|
|
135
|
+
*
|
|
136
|
+
* const api = Zephyr.createZephyrApi(ZephyrApiConnection);
|
|
137
|
+
* const pages = await Zephyr.getAllPages(...);
|
|
138
|
+
* const errorStrategy = new Zephyr.ErrorStrategyBuilder()...;
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export default {
|
|
142
|
+
createZephyrApi,
|
|
143
|
+
ZephyrApi,
|
|
144
|
+
getAllPages,
|
|
145
|
+
getAllPagesCursor,
|
|
146
|
+
HttpError,
|
|
147
|
+
BadRequestError,
|
|
148
|
+
UnauthorizedError,
|
|
149
|
+
ForbiddenError,
|
|
150
|
+
NotFoundError,
|
|
151
|
+
TooManyRequestsError,
|
|
152
|
+
ServerError,
|
|
153
|
+
UnexpectedError,
|
|
154
|
+
retry,
|
|
155
|
+
continuePropagation,
|
|
156
|
+
ErrorStrategyBuilder,
|
|
157
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rbaileysr/zephyr-managed-api",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Managed API wrapper for Zephyr Cloud REST API v2 - Comprehensive type-safe access to all Zephyr API endpoints for ScriptRunner Connect",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|