@rbaileysr/zephyr-managed-api 1.2.1 → 1.2.8
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 +199 -881
- package/dist/README.md +199 -881
- package/dist/groups/Private/PrivateAttachments.d.ts +697 -0
- package/dist/groups/Private/PrivateAttachments.d.ts.map +1 -0
- package/dist/groups/Private/PrivateAttachments.js +2109 -0
- package/dist/groups/Private/PrivateAuthentication.d.ts +29 -0
- package/dist/groups/Private/PrivateAuthentication.d.ts.map +1 -0
- package/dist/groups/Private/PrivateAuthentication.js +24 -0
- package/dist/groups/Private/PrivateBase.d.ts +32 -0
- package/dist/groups/Private/PrivateBase.d.ts.map +1 -0
- package/dist/groups/Private/PrivateBase.js +77 -0
- package/dist/groups/Private/PrivateComments.d.ts +149 -0
- package/dist/groups/Private/PrivateComments.d.ts.map +1 -0
- package/dist/groups/Private/PrivateComments.js +493 -0
- package/dist/groups/Private/PrivateCustomFields.d.ts +54 -0
- package/dist/groups/Private/PrivateCustomFields.d.ts.map +1 -0
- package/dist/groups/Private/PrivateCustomFields.js +150 -0
- package/dist/groups/Private/PrivateVersions.d.ts +38 -0
- package/dist/groups/Private/PrivateVersions.d.ts.map +1 -0
- package/dist/groups/Private/PrivateVersions.js +99 -0
- package/dist/groups/Private.d.ts +142 -180
- package/dist/groups/Private.d.ts.map +1 -1
- package/dist/groups/Private.js +178 -695
- package/dist/package.json +1 -1
- package/dist/types.d.ts +339 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright Adaptavist 2025 (c) All rights reserved
|
|
3
|
+
*/
|
|
4
|
+
import { PrivateBase } from './PrivateBase';
|
|
5
|
+
import { BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, ServerError, UnexpectedError } from '../../utils';
|
|
6
|
+
export class PrivateComments extends PrivateBase {
|
|
7
|
+
constructor(apiConnection) {
|
|
8
|
+
super(apiConnection);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Get comments for a test case using private API
|
|
12
|
+
*
|
|
13
|
+
* Retrieves all comments associated with a test case.
|
|
14
|
+
*
|
|
15
|
+
* ⚠️ WARNING: This uses a private Zephyr API endpoint that is not officially supported.
|
|
16
|
+
* The endpoint may change or be removed at any time without notice.
|
|
17
|
+
*
|
|
18
|
+
* @param credentials - Private API credentials
|
|
19
|
+
* @param request - Get comments request
|
|
20
|
+
* @param request.testCaseKey - Test case key (e.g., 'PROJ-T1'). The numeric ID will be looked up automatically if Zephyr Connector is available.
|
|
21
|
+
* @param request.projectId - Jira project ID (numeric, not the project key)
|
|
22
|
+
* @returns Array of comments
|
|
23
|
+
* @throws {BadRequestError} If the request is invalid
|
|
24
|
+
* @throws {UnauthorizedError} If authentication fails
|
|
25
|
+
* @throws {ForbiddenError} If the user doesn't have permission
|
|
26
|
+
* @throws {NotFoundError} If the test case is not found
|
|
27
|
+
* @throws {ServerError} If the server returns an error
|
|
28
|
+
* @throws {UnexpectedError} If test case ID cannot be looked up from key and Zephyr Connector is not available
|
|
29
|
+
*/
|
|
30
|
+
async getTestCaseComments(credentials, request) {
|
|
31
|
+
// Get test case ID from key if we have API connection
|
|
32
|
+
let testCaseId;
|
|
33
|
+
if (this.testCaseGroup) {
|
|
34
|
+
try {
|
|
35
|
+
const testCase = await this.testCaseGroup.getTestCase({ testCaseKey: request.testCaseKey });
|
|
36
|
+
if (!testCase) {
|
|
37
|
+
throw new NotFoundError(`Test case with key '${request.testCaseKey}' not found.`);
|
|
38
|
+
}
|
|
39
|
+
testCaseId = testCase.id;
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
if (error instanceof NotFoundError) {
|
|
43
|
+
throw new NotFoundError(`Test case with key '${request.testCaseKey}' not found.`);
|
|
44
|
+
}
|
|
45
|
+
throw new UnexpectedError(`Failed to look up test case ID from key '${request.testCaseKey}'. Ensure Zephyr Connector is configured.`, error);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
throw new UnexpectedError('Cannot look up test case ID from key. This method requires Zephyr Connector to be configured. Use createZephyrApi() with an API Connection.');
|
|
50
|
+
}
|
|
51
|
+
// Get Context JWT
|
|
52
|
+
const contextJwt = await this.getContextJwt(credentials);
|
|
53
|
+
const url = `${this.privateApiBaseUrl}/testcase/${testCaseId}/comments`;
|
|
54
|
+
const headers = {
|
|
55
|
+
'accept': 'application/json',
|
|
56
|
+
'authorization': `JWT ${contextJwt}`,
|
|
57
|
+
'jira-project-id': String(request.projectId),
|
|
58
|
+
};
|
|
59
|
+
try {
|
|
60
|
+
const response = await fetch(url, {
|
|
61
|
+
method: 'GET',
|
|
62
|
+
headers,
|
|
63
|
+
});
|
|
64
|
+
if (!response.ok) {
|
|
65
|
+
if (response.status === 400) {
|
|
66
|
+
throw new BadRequestError('Invalid request parameters for getting comments.');
|
|
67
|
+
}
|
|
68
|
+
if (response.status === 401) {
|
|
69
|
+
throw new UnauthorizedError('Failed to authenticate. Please check your credentials.');
|
|
70
|
+
}
|
|
71
|
+
if (response.status === 403) {
|
|
72
|
+
throw new ForbiddenError('Insufficient permissions to get comments.');
|
|
73
|
+
}
|
|
74
|
+
if (response.status === 404) {
|
|
75
|
+
throw new NotFoundError(`Test case with key '${request.testCaseKey}' not found.`);
|
|
76
|
+
}
|
|
77
|
+
throw new ServerError(`Failed to get comments. Status: ${response.status}`, response.status, response.statusText);
|
|
78
|
+
}
|
|
79
|
+
const comments = (await response.json());
|
|
80
|
+
return comments;
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
if (error instanceof BadRequestError ||
|
|
84
|
+
error instanceof UnauthorizedError ||
|
|
85
|
+
error instanceof ForbiddenError ||
|
|
86
|
+
error instanceof NotFoundError ||
|
|
87
|
+
error instanceof ServerError) {
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
throw new UnexpectedError('Unexpected error while getting comments', error);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get comments for a test cycle using private API
|
|
95
|
+
*
|
|
96
|
+
* Retrieves all comments associated with a test cycle (test run).
|
|
97
|
+
*
|
|
98
|
+
* ⚠️ WARNING: This uses a private Zephyr API endpoint that is not officially supported.
|
|
99
|
+
* The endpoint may change or be removed at any time without notice.
|
|
100
|
+
*
|
|
101
|
+
* @param credentials - Private API credentials
|
|
102
|
+
* @param request - Get comments request
|
|
103
|
+
* @param request.testCycleId - Test cycle ID (numeric)
|
|
104
|
+
* @param request.projectId - Jira project ID (numeric, not the project key)
|
|
105
|
+
* @returns Array of comments
|
|
106
|
+
* @throws {BadRequestError} If the request is invalid
|
|
107
|
+
* @throws {UnauthorizedError} If authentication fails
|
|
108
|
+
* @throws {ForbiddenError} If the user doesn't have permission
|
|
109
|
+
* @throws {NotFoundError} If the test cycle is not found
|
|
110
|
+
* @throws {ServerError} If the server returns an error
|
|
111
|
+
*/
|
|
112
|
+
async getTestCycleComments(credentials, request) {
|
|
113
|
+
// Get Context JWT
|
|
114
|
+
const contextJwt = await this.getContextJwt(credentials);
|
|
115
|
+
const url = `${this.privateApiBaseUrl}/testrun/${request.testCycleId}/comments`;
|
|
116
|
+
const headers = {
|
|
117
|
+
'accept': 'application/json',
|
|
118
|
+
'authorization': `JWT ${contextJwt}`,
|
|
119
|
+
'jira-project-id': String(request.projectId),
|
|
120
|
+
};
|
|
121
|
+
try {
|
|
122
|
+
const response = await fetch(url, {
|
|
123
|
+
method: 'GET',
|
|
124
|
+
headers,
|
|
125
|
+
});
|
|
126
|
+
if (!response.ok) {
|
|
127
|
+
if (response.status === 400) {
|
|
128
|
+
throw new BadRequestError('Invalid request parameters for getting comments.');
|
|
129
|
+
}
|
|
130
|
+
if (response.status === 401) {
|
|
131
|
+
throw new UnauthorizedError('Failed to authenticate. Please check your credentials.');
|
|
132
|
+
}
|
|
133
|
+
if (response.status === 403) {
|
|
134
|
+
throw new ForbiddenError('Insufficient permissions to get comments.');
|
|
135
|
+
}
|
|
136
|
+
if (response.status === 404) {
|
|
137
|
+
throw new NotFoundError(`Test cycle with ID '${request.testCycleId}' not found.`);
|
|
138
|
+
}
|
|
139
|
+
throw new ServerError(`Failed to get comments. Status: ${response.status}`, response.status, response.statusText);
|
|
140
|
+
}
|
|
141
|
+
const comments = (await response.json());
|
|
142
|
+
return comments;
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
if (error instanceof BadRequestError ||
|
|
146
|
+
error instanceof UnauthorizedError ||
|
|
147
|
+
error instanceof ForbiddenError ||
|
|
148
|
+
error instanceof NotFoundError ||
|
|
149
|
+
error instanceof ServerError) {
|
|
150
|
+
throw error;
|
|
151
|
+
}
|
|
152
|
+
throw new UnexpectedError('Unexpected error while getting comments', error);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Get comments for a test plan using private API
|
|
157
|
+
*
|
|
158
|
+
* Retrieves all comments associated with a test plan.
|
|
159
|
+
*
|
|
160
|
+
* ⚠️ WARNING: This uses a private Zephyr API endpoint that is not officially supported.
|
|
161
|
+
* The endpoint may change or be removed at any time without notice.
|
|
162
|
+
*
|
|
163
|
+
* @param credentials - Private API credentials
|
|
164
|
+
* @param request - Get comments request
|
|
165
|
+
* @param request.testPlanId - Test plan ID (numeric)
|
|
166
|
+
* @param request.projectId - Jira project ID (numeric, not the project key)
|
|
167
|
+
* @returns Array of comments
|
|
168
|
+
* @throws {BadRequestError} If the request is invalid
|
|
169
|
+
* @throws {UnauthorizedError} If authentication fails
|
|
170
|
+
* @throws {ForbiddenError} If the user doesn't have permission
|
|
171
|
+
* @throws {NotFoundError} If the test plan is not found
|
|
172
|
+
* @throws {ServerError} If the server returns an error
|
|
173
|
+
*/
|
|
174
|
+
async getTestPlanComments(credentials, request) {
|
|
175
|
+
// Get Context JWT
|
|
176
|
+
const contextJwt = await this.getContextJwt(credentials);
|
|
177
|
+
const url = `${this.privateApiBaseUrl}/testplan/${request.testPlanId}/comments`;
|
|
178
|
+
const headers = {
|
|
179
|
+
'accept': 'application/json',
|
|
180
|
+
'authorization': `JWT ${contextJwt}`,
|
|
181
|
+
'jira-project-id': String(request.projectId),
|
|
182
|
+
};
|
|
183
|
+
try {
|
|
184
|
+
const response = await fetch(url, {
|
|
185
|
+
method: 'GET',
|
|
186
|
+
headers,
|
|
187
|
+
});
|
|
188
|
+
if (!response.ok) {
|
|
189
|
+
if (response.status === 400) {
|
|
190
|
+
throw new BadRequestError('Invalid request parameters for getting comments.');
|
|
191
|
+
}
|
|
192
|
+
if (response.status === 401) {
|
|
193
|
+
throw new UnauthorizedError('Failed to authenticate. Please check your credentials.');
|
|
194
|
+
}
|
|
195
|
+
if (response.status === 403) {
|
|
196
|
+
throw new ForbiddenError('Insufficient permissions to get comments.');
|
|
197
|
+
}
|
|
198
|
+
if (response.status === 404) {
|
|
199
|
+
throw new NotFoundError(`Test plan with ID '${request.testPlanId}' not found.`);
|
|
200
|
+
}
|
|
201
|
+
throw new ServerError(`Failed to get comments. Status: ${response.status}`, response.status, response.statusText);
|
|
202
|
+
}
|
|
203
|
+
const comments = (await response.json());
|
|
204
|
+
return comments;
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
if (error instanceof BadRequestError ||
|
|
208
|
+
error instanceof UnauthorizedError ||
|
|
209
|
+
error instanceof ForbiddenError ||
|
|
210
|
+
error instanceof NotFoundError ||
|
|
211
|
+
error instanceof ServerError) {
|
|
212
|
+
throw error;
|
|
213
|
+
}
|
|
214
|
+
throw new UnexpectedError('Unexpected error while getting comments', error);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Create a comment on a test case using private API
|
|
219
|
+
*
|
|
220
|
+
* Adds a comment to an existing test case. The comment will be associated with
|
|
221
|
+
* the specified user account ID.
|
|
222
|
+
*
|
|
223
|
+
* ⚠️ WARNING: This uses a private Zephyr API endpoint that is not officially supported.
|
|
224
|
+
* The endpoint may change or be removed at any time without notice.
|
|
225
|
+
*
|
|
226
|
+
* @param credentials - Private API credentials
|
|
227
|
+
* @param request - Comment creation request
|
|
228
|
+
* @param request.testCaseKey - Test case key (e.g., 'PROJ-T1'). The numeric ID will be looked up automatically if Zephyr Connector is available.
|
|
229
|
+
* @param request.projectId - Jira project ID (numeric, not the project key)
|
|
230
|
+
* @param request.body - Comment text/body
|
|
231
|
+
* @param request.createdBy - Atlassian account ID of the user creating the comment (e.g., '5d6fdc98dc6e480dbc021aae')
|
|
232
|
+
* @returns Comment creation response
|
|
233
|
+
* @throws {BadRequestError} If the request is invalid
|
|
234
|
+
* @throws {UnauthorizedError} If authentication fails
|
|
235
|
+
* @throws {ForbiddenError} If the user doesn't have permission
|
|
236
|
+
* @throws {NotFoundError} If the test case is not found
|
|
237
|
+
* @throws {ServerError} If the server returns an error
|
|
238
|
+
* @throws {UnexpectedError} If test case ID cannot be looked up from key and Zephyr Connector is not available
|
|
239
|
+
*/
|
|
240
|
+
async createTestCaseComment(credentials, request) {
|
|
241
|
+
// Get test case ID from key if we have API connection
|
|
242
|
+
let testCaseId;
|
|
243
|
+
if (this.testCaseGroup) {
|
|
244
|
+
try {
|
|
245
|
+
const testCase = await this.testCaseGroup.getTestCase({ testCaseKey: request.testCaseKey });
|
|
246
|
+
if (!testCase) {
|
|
247
|
+
throw new NotFoundError(`Test case with key '${request.testCaseKey}' not found.`);
|
|
248
|
+
}
|
|
249
|
+
testCaseId = testCase.id;
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
if (error instanceof NotFoundError) {
|
|
253
|
+
throw new NotFoundError(`Test case with key '${request.testCaseKey}' not found.`);
|
|
254
|
+
}
|
|
255
|
+
throw new UnexpectedError(`Failed to look up test case ID from key '${request.testCaseKey}'. Ensure Zephyr Connector is configured.`, error);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
throw new UnexpectedError('Cannot look up test case ID from key. This method requires Zephyr Connector to be configured. Use createZephyrApi() with an API Connection.');
|
|
260
|
+
}
|
|
261
|
+
// Get Context JWT
|
|
262
|
+
const contextJwt = await this.getContextJwt(credentials);
|
|
263
|
+
const url = `${this.privateApiBaseUrl}/testcase/${testCaseId}/comments`;
|
|
264
|
+
const headers = {
|
|
265
|
+
'Content-Type': 'application/json',
|
|
266
|
+
'authorization': `JWT ${contextJwt}`,
|
|
267
|
+
'jira-project-id': String(request.projectId),
|
|
268
|
+
};
|
|
269
|
+
const payload = {
|
|
270
|
+
body: request.body,
|
|
271
|
+
createdBy: request.createdBy,
|
|
272
|
+
};
|
|
273
|
+
try {
|
|
274
|
+
const response = await fetch(url, {
|
|
275
|
+
method: 'POST',
|
|
276
|
+
headers,
|
|
277
|
+
body: JSON.stringify(payload),
|
|
278
|
+
});
|
|
279
|
+
if (!response.ok) {
|
|
280
|
+
if (response.status === 400) {
|
|
281
|
+
const errorText = await response.text().catch(() => 'Bad Request');
|
|
282
|
+
throw new BadRequestError(`Failed to create test case comment: ${errorText}`, response.statusText);
|
|
283
|
+
}
|
|
284
|
+
if (response.status === 401) {
|
|
285
|
+
throw new UnauthorizedError('Authentication failed. Please check your credentials.');
|
|
286
|
+
}
|
|
287
|
+
if (response.status === 403) {
|
|
288
|
+
throw new ForbiddenError('You do not have permission to create comments on this test case.');
|
|
289
|
+
}
|
|
290
|
+
if (response.status === 404) {
|
|
291
|
+
throw new NotFoundError('Test case not found.');
|
|
292
|
+
}
|
|
293
|
+
throw new ServerError(`Failed to create test case comment. Status: ${response.status}`, response.status, response.statusText);
|
|
294
|
+
}
|
|
295
|
+
return await response.json();
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
if (error instanceof BadRequestError ||
|
|
299
|
+
error instanceof UnauthorizedError ||
|
|
300
|
+
error instanceof ForbiddenError ||
|
|
301
|
+
error instanceof NotFoundError ||
|
|
302
|
+
error instanceof ServerError ||
|
|
303
|
+
error instanceof UnexpectedError) {
|
|
304
|
+
throw error;
|
|
305
|
+
}
|
|
306
|
+
throw new UnexpectedError('Unexpected error while creating test case comment', error);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Create a comment on a test cycle using private API
|
|
311
|
+
*
|
|
312
|
+
* Adds a comment to an existing test cycle (test run). The comment will be associated with
|
|
313
|
+
* the specified user account ID.
|
|
314
|
+
*
|
|
315
|
+
* ⚠️ WARNING: This uses a private Zephyr API endpoint that is not officially supported.
|
|
316
|
+
* The endpoint may change or be removed at any time without notice.
|
|
317
|
+
*
|
|
318
|
+
* @param credentials - Private API credentials
|
|
319
|
+
* @param request - Comment creation request
|
|
320
|
+
* @param request.testCycleKey - Test cycle key (e.g., 'PROJ-R1'). The numeric ID will be looked up automatically if Zephyr Connector is available.
|
|
321
|
+
* @param request.projectId - Jira project ID (numeric, not the project key)
|
|
322
|
+
* @param request.body - Comment text/body
|
|
323
|
+
* @param request.createdBy - Atlassian account ID of the user creating the comment (e.g., '5d6fdc98dc6e480dbc021aae')
|
|
324
|
+
* @returns Comment creation response
|
|
325
|
+
* @throws {BadRequestError} If the request is invalid
|
|
326
|
+
* @throws {UnauthorizedError} If authentication fails
|
|
327
|
+
* @throws {ForbiddenError} If the user doesn't have permission
|
|
328
|
+
* @throws {NotFoundError} If the test cycle is not found
|
|
329
|
+
* @throws {ServerError} If the server returns an error
|
|
330
|
+
* @throws {UnexpectedError} If test cycle ID cannot be looked up from key and Zephyr Connector is not available
|
|
331
|
+
*/
|
|
332
|
+
async createTestCycleComment(credentials, request) {
|
|
333
|
+
// Get test cycle ID from key if we have API connection
|
|
334
|
+
let testCycleId;
|
|
335
|
+
if (this.testCycleGroup) {
|
|
336
|
+
try {
|
|
337
|
+
const testCycle = await this.testCycleGroup.getTestCycle({ testCycleIdOrKey: request.testCycleKey });
|
|
338
|
+
if (!testCycle) {
|
|
339
|
+
throw new NotFoundError(`Test cycle with key '${request.testCycleKey}' not found.`);
|
|
340
|
+
}
|
|
341
|
+
testCycleId = testCycle.id;
|
|
342
|
+
}
|
|
343
|
+
catch (error) {
|
|
344
|
+
if (error instanceof NotFoundError) {
|
|
345
|
+
throw new NotFoundError(`Test cycle with key '${request.testCycleKey}' not found.`);
|
|
346
|
+
}
|
|
347
|
+
throw new UnexpectedError(`Failed to look up test cycle ID from key '${request.testCycleKey}'. Ensure Zephyr Connector is configured.`, error);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
throw new UnexpectedError('Cannot look up test cycle ID from key. This method requires Zephyr Connector to be configured. Use createZephyrApi() with an API Connection.');
|
|
352
|
+
}
|
|
353
|
+
// Get Context JWT
|
|
354
|
+
const contextJwt = await this.getContextJwt(credentials);
|
|
355
|
+
const url = `${this.privateApiBaseUrl}/testrun/${testCycleId}/comments`;
|
|
356
|
+
const headers = {
|
|
357
|
+
'Content-Type': 'application/json',
|
|
358
|
+
'authorization': `JWT ${contextJwt}`,
|
|
359
|
+
'jira-project-id': String(request.projectId),
|
|
360
|
+
};
|
|
361
|
+
const payload = {
|
|
362
|
+
body: request.body,
|
|
363
|
+
createdBy: request.createdBy,
|
|
364
|
+
};
|
|
365
|
+
try {
|
|
366
|
+
const response = await fetch(url, {
|
|
367
|
+
method: 'POST',
|
|
368
|
+
headers,
|
|
369
|
+
body: JSON.stringify(payload),
|
|
370
|
+
});
|
|
371
|
+
if (!response.ok) {
|
|
372
|
+
if (response.status === 400) {
|
|
373
|
+
const errorText = await response.text().catch(() => 'Bad Request');
|
|
374
|
+
throw new BadRequestError(`Failed to create test cycle comment: ${errorText}`, response.statusText);
|
|
375
|
+
}
|
|
376
|
+
if (response.status === 401) {
|
|
377
|
+
throw new UnauthorizedError('Authentication failed. Please check your credentials.');
|
|
378
|
+
}
|
|
379
|
+
if (response.status === 403) {
|
|
380
|
+
throw new ForbiddenError('You do not have permission to create comments on this test cycle.');
|
|
381
|
+
}
|
|
382
|
+
if (response.status === 404) {
|
|
383
|
+
throw new NotFoundError('Test cycle not found.');
|
|
384
|
+
}
|
|
385
|
+
throw new ServerError(`Failed to create test cycle comment. Status: ${response.status}`, response.status, response.statusText);
|
|
386
|
+
}
|
|
387
|
+
return await response.json();
|
|
388
|
+
}
|
|
389
|
+
catch (error) {
|
|
390
|
+
if (error instanceof BadRequestError ||
|
|
391
|
+
error instanceof UnauthorizedError ||
|
|
392
|
+
error instanceof ForbiddenError ||
|
|
393
|
+
error instanceof NotFoundError ||
|
|
394
|
+
error instanceof ServerError ||
|
|
395
|
+
error instanceof UnexpectedError) {
|
|
396
|
+
throw error;
|
|
397
|
+
}
|
|
398
|
+
throw new UnexpectedError('Unexpected error while creating test cycle comment', error);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Create a comment on a test plan using private API
|
|
403
|
+
*
|
|
404
|
+
* Adds a comment to an existing test plan. The comment will be associated with
|
|
405
|
+
* the specified user account ID.
|
|
406
|
+
*
|
|
407
|
+
* ⚠️ WARNING: This uses a private Zephyr API endpoint that is not officially supported.
|
|
408
|
+
* The endpoint may change or be removed at any time without notice.
|
|
409
|
+
*
|
|
410
|
+
* @param credentials - Private API credentials
|
|
411
|
+
* @param request - Comment creation request
|
|
412
|
+
* @param request.testPlanKey - Test plan key (e.g., 'PROJ-P1'). The numeric ID will be looked up automatically if Zephyr Connector is available.
|
|
413
|
+
* @param request.projectId - Jira project ID (numeric, not the project key)
|
|
414
|
+
* @param request.body - Comment text/body
|
|
415
|
+
* @param request.createdBy - Atlassian account ID of the user creating the comment (e.g., '5d6fdc98dc6e480dbc021aae')
|
|
416
|
+
* @returns Comment creation response
|
|
417
|
+
* @throws {BadRequestError} If the request is invalid
|
|
418
|
+
* @throws {UnauthorizedError} If authentication fails
|
|
419
|
+
* @throws {ForbiddenError} If the user doesn't have permission
|
|
420
|
+
* @throws {NotFoundError} If the test plan is not found
|
|
421
|
+
* @throws {ServerError} If the server returns an error
|
|
422
|
+
* @throws {UnexpectedError} If test plan ID cannot be looked up from key and Zephyr Connector is not available
|
|
423
|
+
*/
|
|
424
|
+
async createTestPlanComment(credentials, request) {
|
|
425
|
+
// Get test plan ID from key if we have API connection
|
|
426
|
+
let testPlanId;
|
|
427
|
+
if (this.testPlanGroup) {
|
|
428
|
+
try {
|
|
429
|
+
const testPlan = await this.testPlanGroup.getTestPlan({ testPlanIdOrKey: request.testPlanKey });
|
|
430
|
+
if (!testPlan) {
|
|
431
|
+
throw new NotFoundError(`Test plan with key '${request.testPlanKey}' not found.`);
|
|
432
|
+
}
|
|
433
|
+
testPlanId = testPlan.id;
|
|
434
|
+
}
|
|
435
|
+
catch (error) {
|
|
436
|
+
if (error instanceof NotFoundError) {
|
|
437
|
+
throw new NotFoundError(`Test plan with key '${request.testPlanKey}' not found.`);
|
|
438
|
+
}
|
|
439
|
+
throw new UnexpectedError(`Failed to look up test plan ID from key '${request.testPlanKey}'. Ensure Zephyr Connector is configured.`, error);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
throw new UnexpectedError('Cannot look up test plan ID from key. This method requires Zephyr Connector to be configured. Use createZephyrApi() with an API Connection.');
|
|
444
|
+
}
|
|
445
|
+
// Get Context JWT
|
|
446
|
+
const contextJwt = await this.getContextJwt(credentials);
|
|
447
|
+
const url = `${this.privateApiBaseUrl}/testplan/${testPlanId}/comments`;
|
|
448
|
+
const headers = {
|
|
449
|
+
'Content-Type': 'application/json',
|
|
450
|
+
'authorization': `JWT ${contextJwt}`,
|
|
451
|
+
'jira-project-id': String(request.projectId),
|
|
452
|
+
};
|
|
453
|
+
const payload = {
|
|
454
|
+
body: request.body,
|
|
455
|
+
createdBy: request.createdBy,
|
|
456
|
+
};
|
|
457
|
+
try {
|
|
458
|
+
const response = await fetch(url, {
|
|
459
|
+
method: 'POST',
|
|
460
|
+
headers,
|
|
461
|
+
body: JSON.stringify(payload),
|
|
462
|
+
});
|
|
463
|
+
if (!response.ok) {
|
|
464
|
+
if (response.status === 400) {
|
|
465
|
+
const errorText = await response.text().catch(() => 'Bad Request');
|
|
466
|
+
throw new BadRequestError(`Failed to create test plan comment: ${errorText}`, response.statusText);
|
|
467
|
+
}
|
|
468
|
+
if (response.status === 401) {
|
|
469
|
+
throw new UnauthorizedError('Authentication failed. Please check your credentials.');
|
|
470
|
+
}
|
|
471
|
+
if (response.status === 403) {
|
|
472
|
+
throw new ForbiddenError('You do not have permission to create comments on this test plan.');
|
|
473
|
+
}
|
|
474
|
+
if (response.status === 404) {
|
|
475
|
+
throw new NotFoundError('Test plan not found.');
|
|
476
|
+
}
|
|
477
|
+
throw new ServerError(`Failed to create test plan comment. Status: ${response.status}`, response.status, response.statusText);
|
|
478
|
+
}
|
|
479
|
+
return await response.json();
|
|
480
|
+
}
|
|
481
|
+
catch (error) {
|
|
482
|
+
if (error instanceof BadRequestError ||
|
|
483
|
+
error instanceof UnauthorizedError ||
|
|
484
|
+
error instanceof ForbiddenError ||
|
|
485
|
+
error instanceof NotFoundError ||
|
|
486
|
+
error instanceof ServerError ||
|
|
487
|
+
error instanceof UnexpectedError) {
|
|
488
|
+
throw error;
|
|
489
|
+
}
|
|
490
|
+
throw new UnexpectedError('Unexpected error while creating test plan comment', error);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright Adaptavist 2025 (c) All rights reserved
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Private API Custom Fields sub-group
|
|
6
|
+
* Handles custom field creation and retrieval
|
|
7
|
+
*
|
|
8
|
+
* ⚠️ WARNING: These methods use private APIs that are not officially supported.
|
|
9
|
+
*/
|
|
10
|
+
import type { PrivateApiCredentials, PrivateCustomFieldCategory, CreatePrivateCustomFieldRequest, GetCustomFieldsRequest, PrivateCustomField } from '../../types';
|
|
11
|
+
import { PrivateBase } from './PrivateBase';
|
|
12
|
+
import type { ZephyrApiConnection } from '../../index';
|
|
13
|
+
export declare class PrivateCustomFields extends PrivateBase {
|
|
14
|
+
constructor(apiConnection?: ZephyrApiConnection);
|
|
15
|
+
/**
|
|
16
|
+
* Create a custom field using private API
|
|
17
|
+
*
|
|
18
|
+
* Creates a custom field for the specified entity type (test case, test plan, test run, test step, or test execution).
|
|
19
|
+
*
|
|
20
|
+
* ⚠️ WARNING: This uses a private Zephyr API endpoint that is not officially supported.
|
|
21
|
+
* The endpoint may change or be removed at any time without notice.
|
|
22
|
+
*
|
|
23
|
+
* @param credentials - Private API credentials
|
|
24
|
+
* @param category - Entity type for the custom field (TEST_CASE, TEST_PLAN, TEST_RUN, TEST_STEP, or TEST_EXECUTION)
|
|
25
|
+
* @param request - Custom field creation request
|
|
26
|
+
* @returns The created custom field response
|
|
27
|
+
* @throws {BadRequestError} If the request is invalid
|
|
28
|
+
* @throws {UnauthorizedError} If authentication fails
|
|
29
|
+
* @throws {ForbiddenError} If the user doesn't have permission
|
|
30
|
+
* @throws {ServerError} If the server returns an error
|
|
31
|
+
*/
|
|
32
|
+
createCustomField(credentials: PrivateApiCredentials, category: PrivateCustomFieldCategory, request: CreatePrivateCustomFieldRequest): Promise<unknown>;
|
|
33
|
+
/**
|
|
34
|
+
* Get custom fields for a specific entity type using private API
|
|
35
|
+
*
|
|
36
|
+
* Retrieves all custom fields configured for the specified entity type (test case, test plan, test run, test step, or test execution) in a project.
|
|
37
|
+
*
|
|
38
|
+
* ⚠️ WARNING: This uses a private Zephyr API endpoint that is not officially supported.
|
|
39
|
+
* The endpoint may change or be removed at any time without notice.
|
|
40
|
+
*
|
|
41
|
+
* @param credentials - Private API credentials
|
|
42
|
+
* @param category - Entity type for the custom fields (TEST_CASE, TEST_PLAN, TEST_RUN, TEST_STEP, or TEST_EXECUTION)
|
|
43
|
+
* @param request - Get custom fields request
|
|
44
|
+
* @param request.projectId - Jira project ID (numeric, not the project key)
|
|
45
|
+
* @returns Array of custom field definitions
|
|
46
|
+
* @throws {BadRequestError} If the request is invalid
|
|
47
|
+
* @throws {UnauthorizedError} If authentication fails
|
|
48
|
+
* @throws {ForbiddenError} If the user doesn't have permission
|
|
49
|
+
* @throws {NotFoundError} If the project is not found
|
|
50
|
+
* @throws {ServerError} If the server returns an error
|
|
51
|
+
*/
|
|
52
|
+
getCustomFields(credentials: PrivateApiCredentials, category: PrivateCustomFieldCategory, request: GetCustomFieldsRequest): Promise<PrivateCustomField[]>;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=PrivateCustomFields.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PrivateCustomFields.d.ts","sourceRoot":"","sources":["../../../groups/Private/PrivateCustomFields.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;GAKG;AAEH,OAAO,KAAK,EACX,qBAAqB,EACrB,0BAA0B,EAC1B,+BAA+B,EAC/B,sBAAsB,EACtB,kBAAkB,EAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,qBAAa,mBAAoB,SAAQ,WAAW;gBACvC,aAAa,CAAC,EAAE,mBAAmB;IAI/C;;;;;;;;;;;;;;;;OAgBG;IACG,iBAAiB,CACtB,WAAW,EAAE,qBAAqB,EAClC,QAAQ,EAAE,0BAA0B,EACpC,OAAO,EAAE,+BAA+B,GACtC,OAAO,CAAC,OAAO,CAAC;IA+DnB;;;;;;;;;;;;;;;;;;OAkBG;IACG,eAAe,CACpB,WAAW,EAAE,qBAAqB,EAClC,QAAQ,EAAE,0BAA0B,EACpC,OAAO,EAAE,sBAAsB,GAC7B,OAAO,CAAC,kBAAkB,EAAE,CAAC;CA8DhC"}
|