@rbaileysr/zephyr-managed-api 1.2.0 → 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.
@@ -0,0 +1,150 @@
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 PrivateCustomFields extends PrivateBase {
7
+ constructor(apiConnection) {
8
+ super(apiConnection);
9
+ }
10
+ /**
11
+ * Create a custom field using private API
12
+ *
13
+ * Creates a custom field for the specified entity type (test case, test plan, test run, test step, or test execution).
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 category - Entity type for the custom field (TEST_CASE, TEST_PLAN, TEST_RUN, TEST_STEP, or TEST_EXECUTION)
20
+ * @param request - Custom field creation request
21
+ * @returns The created custom field response
22
+ * @throws {BadRequestError} If the request is invalid
23
+ * @throws {UnauthorizedError} If authentication fails
24
+ * @throws {ForbiddenError} If the user doesn't have permission
25
+ * @throws {ServerError} If the server returns an error
26
+ */
27
+ async createCustomField(credentials, category, request) {
28
+ // Get Context JWT
29
+ const contextJwt = await this.getContextJwt(credentials);
30
+ // Determine endpoint based on category
31
+ const endpointMap = {
32
+ TEST_CASE: 'customfield/testcase',
33
+ TEST_PLAN: 'customfield/testplan',
34
+ TEST_RUN: 'customfield/testrun',
35
+ TEST_STEP: 'customfield/teststep',
36
+ TEST_EXECUTION: 'customfield/testexecution',
37
+ };
38
+ const url = `${this.privateApiBaseUrl}/${endpointMap[category]}`;
39
+ const headers = {
40
+ 'Content-Type': 'application/json',
41
+ 'authorization': `JWT ${contextJwt}`,
42
+ 'jira-project-id': String(request.projectId),
43
+ };
44
+ try {
45
+ const response = await fetch(url, {
46
+ method: 'POST',
47
+ headers,
48
+ body: JSON.stringify(request),
49
+ });
50
+ if (!response.ok) {
51
+ if (response.status === 400) {
52
+ const errorText = await response.text().catch(() => 'Bad Request');
53
+ throw new BadRequestError(`Failed to create custom field: ${errorText}`, response.statusText);
54
+ }
55
+ if (response.status === 401) {
56
+ throw new UnauthorizedError('Authentication failed. Please check your credentials.');
57
+ }
58
+ if (response.status === 403) {
59
+ throw new ForbiddenError('You do not have permission to create custom fields in this project.');
60
+ }
61
+ if (response.status === 404) {
62
+ throw new NotFoundError('Project or resource not found.');
63
+ }
64
+ throw new ServerError(`Failed to create custom field. Status: ${response.status}`, response.status, response.statusText);
65
+ }
66
+ return await response.json();
67
+ }
68
+ catch (error) {
69
+ if (error instanceof BadRequestError ||
70
+ error instanceof UnauthorizedError ||
71
+ error instanceof ForbiddenError ||
72
+ error instanceof NotFoundError ||
73
+ error instanceof ServerError) {
74
+ throw error;
75
+ }
76
+ throw new UnexpectedError('Unexpected error while creating custom field', error);
77
+ }
78
+ }
79
+ /**
80
+ * Get custom fields for a specific entity type using private API
81
+ *
82
+ * Retrieves all custom fields configured for the specified entity type (test case, test plan, test run, test step, or test execution) in a project.
83
+ *
84
+ * ⚠️ WARNING: This uses a private Zephyr API endpoint that is not officially supported.
85
+ * The endpoint may change or be removed at any time without notice.
86
+ *
87
+ * @param credentials - Private API credentials
88
+ * @param category - Entity type for the custom fields (TEST_CASE, TEST_PLAN, TEST_RUN, TEST_STEP, or TEST_EXECUTION)
89
+ * @param request - Get custom fields request
90
+ * @param request.projectId - Jira project ID (numeric, not the project key)
91
+ * @returns Array of custom field definitions
92
+ * @throws {BadRequestError} If the request is invalid
93
+ * @throws {UnauthorizedError} If authentication fails
94
+ * @throws {ForbiddenError} If the user doesn't have permission
95
+ * @throws {NotFoundError} If the project is not found
96
+ * @throws {ServerError} If the server returns an error
97
+ */
98
+ async getCustomFields(credentials, category, request) {
99
+ // Get Context JWT
100
+ const contextJwt = await this.getContextJwt(credentials);
101
+ // Determine endpoint based on category
102
+ // Note: API uses "testrun" in URL even though category is "TEST_RUN"
103
+ const endpointMap = {
104
+ TEST_CASE: 'testcase',
105
+ TEST_PLAN: 'testplan',
106
+ TEST_RUN: 'testrun', // API uses "testrun" in URL
107
+ TEST_STEP: 'teststep',
108
+ TEST_EXECUTION: 'testexecution',
109
+ };
110
+ const url = `${this.privateApiBaseUrl}/project/${request.projectId}/customfields/${endpointMap[category]}?projectId=${request.projectId}`;
111
+ const headers = {
112
+ 'accept': 'application/json',
113
+ 'authorization': `JWT ${contextJwt}`,
114
+ 'jira-project-id': String(request.projectId),
115
+ };
116
+ try {
117
+ const response = await fetch(url, {
118
+ method: 'GET',
119
+ headers,
120
+ });
121
+ if (!response.ok) {
122
+ if (response.status === 400) {
123
+ const errorText = await response.text().catch(() => 'Bad Request');
124
+ throw new BadRequestError(`Failed to get custom fields: ${errorText}`, response.statusText);
125
+ }
126
+ if (response.status === 401) {
127
+ throw new UnauthorizedError('Authentication failed. Please check your credentials.');
128
+ }
129
+ if (response.status === 403) {
130
+ throw new ForbiddenError('You do not have permission to view custom fields in this project.');
131
+ }
132
+ if (response.status === 404) {
133
+ throw new NotFoundError('Project not found.');
134
+ }
135
+ throw new ServerError(`Failed to get custom fields. Status: ${response.status}`, response.status, response.statusText);
136
+ }
137
+ return await response.json();
138
+ }
139
+ catch (error) {
140
+ if (error instanceof BadRequestError ||
141
+ error instanceof UnauthorizedError ||
142
+ error instanceof ForbiddenError ||
143
+ error instanceof NotFoundError ||
144
+ error instanceof ServerError) {
145
+ throw error;
146
+ }
147
+ throw new UnexpectedError('Unexpected error while getting custom fields', error);
148
+ }
149
+ }
150
+ }
@@ -0,0 +1,38 @@
1
+ /*!
2
+ * Copyright Adaptavist 2025 (c) All rights reserved
3
+ */
4
+ /**
5
+ * Private API Versions sub-group
6
+ * Handles test case version creation
7
+ *
8
+ * ⚠️ WARNING: These methods use private APIs that are not officially supported.
9
+ */
10
+ import type { PrivateApiCredentials, CreateTestCaseVersionRequest, CreateTestCaseVersionResponse } from '../../types';
11
+ import { PrivateBase } from './PrivateBase';
12
+ import type { ZephyrApiConnection } from '../../index';
13
+ export declare class PrivateVersions extends PrivateBase {
14
+ constructor(apiConnection?: ZephyrApiConnection);
15
+ /**
16
+ * Create a new test case version using private API
17
+ *
18
+ * Creates a new version of an existing test case. Note that when a new version
19
+ * is created, the testCaseId changes for that test case.
20
+ *
21
+ * ⚠️ WARNING: This uses a private Zephyr API endpoint that is not officially supported.
22
+ * The endpoint may change or be removed at any time without notice.
23
+ *
24
+ * @param credentials - Private API credentials
25
+ * @param request - Test case version creation request
26
+ * @param request.testCaseKey - Test case key (e.g., 'PROJ-T1'). The numeric ID will be looked up automatically if Zephyr Connector is available.
27
+ * @param request.projectId - Jira project ID (numeric, not the project key)
28
+ * @returns The created version response with id and key
29
+ * @throws {BadRequestError} If the request is invalid
30
+ * @throws {UnauthorizedError} If authentication fails
31
+ * @throws {ForbiddenError} If the user doesn't have permission
32
+ * @throws {NotFoundError} If the test case is not found
33
+ * @throws {ServerError} If the server returns an error (including 409 Conflict if version already exists)
34
+ * @throws {UnexpectedError} If test case ID cannot be looked up from key and Zephyr Connector is not available
35
+ */
36
+ createTestCaseVersion(credentials: PrivateApiCredentials, request: CreateTestCaseVersionRequest): Promise<CreateTestCaseVersionResponse>;
37
+ }
38
+ //# sourceMappingURL=PrivateVersions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PrivateVersions.d.ts","sourceRoot":"","sources":["../../../groups/Private/PrivateVersions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;GAKG;AAEH,OAAO,KAAK,EACX,qBAAqB,EACrB,4BAA4B,EAC5B,6BAA6B,EAC7B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,qBAAa,eAAgB,SAAQ,WAAW;gBACnC,aAAa,CAAC,EAAE,mBAAmB;IAI/C;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,qBAAqB,CAC1B,WAAW,EAAE,qBAAqB,EAClC,OAAO,EAAE,4BAA4B,GACnC,OAAO,CAAC,6BAA6B,CAAC;CAqFzC"}
@@ -0,0 +1,99 @@
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 PrivateVersions extends PrivateBase {
7
+ constructor(apiConnection) {
8
+ super(apiConnection);
9
+ }
10
+ /**
11
+ * Create a new test case version using private API
12
+ *
13
+ * Creates a new version of an existing test case. Note that when a new version
14
+ * is created, the testCaseId changes for that test case.
15
+ *
16
+ * ⚠️ WARNING: This uses a private Zephyr API endpoint that is not officially supported.
17
+ * The endpoint may change or be removed at any time without notice.
18
+ *
19
+ * @param credentials - Private API credentials
20
+ * @param request - Test case version creation request
21
+ * @param request.testCaseKey - Test case key (e.g., 'PROJ-T1'). The numeric ID will be looked up automatically if Zephyr Connector is available.
22
+ * @param request.projectId - Jira project ID (numeric, not the project key)
23
+ * @returns The created version response with id and key
24
+ * @throws {BadRequestError} If the request is invalid
25
+ * @throws {UnauthorizedError} If authentication fails
26
+ * @throws {ForbiddenError} If the user doesn't have permission
27
+ * @throws {NotFoundError} If the test case is not found
28
+ * @throws {ServerError} If the server returns an error (including 409 Conflict if version already exists)
29
+ * @throws {UnexpectedError} If test case ID cannot be looked up from key and Zephyr Connector is not available
30
+ */
31
+ async createTestCaseVersion(credentials, request) {
32
+ // Get test case ID from key if we have API connection
33
+ let testCaseId;
34
+ if (this.testCaseGroup) {
35
+ try {
36
+ const testCase = await this.testCaseGroup.getTestCase({ testCaseKey: request.testCaseKey });
37
+ if (!testCase) {
38
+ throw new NotFoundError(`Test case with key '${request.testCaseKey}' not found.`);
39
+ }
40
+ testCaseId = testCase.id;
41
+ }
42
+ catch (error) {
43
+ if (error instanceof NotFoundError) {
44
+ throw new NotFoundError(`Test case with key '${request.testCaseKey}' not found.`);
45
+ }
46
+ throw new UnexpectedError(`Failed to look up test case ID from key '${request.testCaseKey}'. Ensure Zephyr Connector is configured.`, error);
47
+ }
48
+ }
49
+ else {
50
+ 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.');
51
+ }
52
+ // Get Context JWT
53
+ const contextJwt = await this.getContextJwt(credentials);
54
+ const url = `${this.privateApiBaseUrl}/testcase/${testCaseId}/newversion`;
55
+ const headers = {
56
+ 'Content-Type': 'application/json',
57
+ 'authorization': `JWT ${contextJwt}`,
58
+ 'jira-project-id': String(request.projectId),
59
+ };
60
+ try {
61
+ const response = await fetch(url, {
62
+ method: 'POST',
63
+ headers,
64
+ body: JSON.stringify({}), // Empty body as per documentation
65
+ });
66
+ if (!response.ok) {
67
+ if (response.status === 400) {
68
+ const errorText = await response.text().catch(() => 'Bad Request');
69
+ throw new BadRequestError(`Failed to create test case version: ${errorText}`, response.statusText);
70
+ }
71
+ if (response.status === 401) {
72
+ throw new UnauthorizedError('Authentication failed. Please check your credentials.');
73
+ }
74
+ if (response.status === 403) {
75
+ throw new ForbiddenError('You do not have permission to create test case versions in this project.');
76
+ }
77
+ if (response.status === 404) {
78
+ throw new NotFoundError('Test case not found.');
79
+ }
80
+ if (response.status === 409) {
81
+ throw new ServerError('Conflict: A new version already exists for this test case.', response.status, response.statusText);
82
+ }
83
+ throw new ServerError(`Failed to create test case version. Status: ${response.status}`, response.status, response.statusText);
84
+ }
85
+ return await response.json();
86
+ }
87
+ catch (error) {
88
+ if (error instanceof BadRequestError ||
89
+ error instanceof UnauthorizedError ||
90
+ error instanceof ForbiddenError ||
91
+ error instanceof NotFoundError ||
92
+ error instanceof ServerError ||
93
+ error instanceof UnexpectedError) {
94
+ throw error;
95
+ }
96
+ throw new UnexpectedError('Unexpected error while creating test case version', error);
97
+ }
98
+ }
99
+ }