@credal/actions 0.2.147 → 0.2.149
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/dist/actions/actionMapper.js +1 -0
- package/dist/actions/autogen/templates.d.ts +11 -0
- package/dist/actions/autogen/templates.js +775 -47
- package/dist/actions/autogen/types.d.ts +726 -12
- package/dist/actions/autogen/types.js +213 -4
- package/dist/actions/invoke.js +1 -1
- package/dist/actions/providers/google-oauth/getDriveFileContentById.js +24 -27
- package/dist/actions/providers/googlemail/searchGmailMessages.d.ts +14 -0
- package/dist/actions/providers/googlemail/searchGmailMessages.js +42 -24
- package/dist/actions/providers/jira/assignJiraTicket.js +16 -12
- package/dist/actions/providers/jira/commentJiraTicket.js +10 -22
- package/dist/actions/providers/jira/createJiraTicket.js +39 -49
- package/dist/actions/providers/jira/getJiraIssuesByQuery.js +37 -36
- package/dist/actions/providers/jira/getJiraTicketDetails.js +7 -5
- package/dist/actions/providers/jira/getJiraTicketHistory.js +10 -8
- package/dist/actions/providers/jira/updateJiraTicketDetails.js +16 -37
- package/dist/actions/providers/jira/updateJiraTicketStatus.js +8 -6
- package/dist/actions/providers/jira/utils.d.ts +55 -2
- package/dist/actions/providers/jira/utils.js +129 -9
- package/dist/actions/providers/slackUser/searchSlack.js +59 -32
- package/package.json +1 -1
|
@@ -8,61 +8,51 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { axiosClient } from "../../util/axiosClient.js";
|
|
11
|
-
import {
|
|
11
|
+
import { resolveAccountIdIfEmail, resolveRequestTypeField, getJiraApiConfig, getErrorMessage } from "./utils.js";
|
|
12
12
|
const createJiraTicket = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
|
|
13
|
-
const { authToken
|
|
14
|
-
const apiUrl =
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
const { authToken } = authParams;
|
|
14
|
+
const { apiUrl, browseUrl, strategy } = getJiraApiConfig(authParams);
|
|
15
|
+
// authToken is guaranteed to exist after getJiraApiConfig succeeds
|
|
16
|
+
if (!authToken) {
|
|
17
|
+
throw new Error("Auth token is required");
|
|
17
18
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (params.assignee && typeof params.assignee === "string" && params.assignee.includes("@") && authToken) {
|
|
26
|
-
assigneeId = yield getUserAccountIdFromEmail(params.assignee, apiUrl, authToken);
|
|
27
|
-
}
|
|
28
|
-
// If request type is provided, find the custom field ID and prepare the value
|
|
29
|
-
const requestTypeField = {};
|
|
30
|
-
if (params.requestTypeId && authToken) {
|
|
31
|
-
const requestTypeFieldId = yield getRequestTypeCustomFieldId(params.projectKey, apiUrl, authToken);
|
|
32
|
-
if (requestTypeFieldId) {
|
|
33
|
-
requestTypeField[requestTypeFieldId] = params.requestTypeId;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
const description = {
|
|
37
|
-
type: "doc",
|
|
38
|
-
version: 1,
|
|
39
|
-
content: [
|
|
40
|
-
{
|
|
41
|
-
type: "paragraph",
|
|
42
|
-
content: [
|
|
43
|
-
{
|
|
44
|
-
type: "text",
|
|
45
|
-
text: params.description,
|
|
46
|
-
},
|
|
47
|
-
],
|
|
48
|
-
},
|
|
49
|
-
],
|
|
50
|
-
};
|
|
19
|
+
const [reporterId, assigneeId] = yield Promise.all([
|
|
20
|
+
resolveAccountIdIfEmail(params.reporter, apiUrl, authToken, strategy),
|
|
21
|
+
resolveAccountIdIfEmail(params.assignee, apiUrl, authToken, strategy),
|
|
22
|
+
]);
|
|
23
|
+
const { field: requestTypeField, message: partialUpdateMessage } = yield resolveRequestTypeField(params.requestTypeId, params.projectKey, apiUrl, authToken);
|
|
24
|
+
const reporterAssignment = strategy.formatUserAssignment(reporterId);
|
|
25
|
+
const assigneeAssignment = strategy.formatUserAssignment(assigneeId);
|
|
51
26
|
const payload = {
|
|
52
27
|
fields: Object.assign(Object.assign(Object.assign(Object.assign({ project: {
|
|
53
28
|
key: params.projectKey,
|
|
54
|
-
}, summary: params.summary, description: description, issuetype: {
|
|
29
|
+
}, summary: params.summary, description: strategy.formatText(params.description), issuetype: {
|
|
55
30
|
name: params.issueType,
|
|
56
|
-
} }, (
|
|
57
|
-
};
|
|
58
|
-
const response = yield axiosClient.post(`${apiUrl}/issue`, payload, {
|
|
59
|
-
headers: {
|
|
60
|
-
Authorization: `Bearer ${authToken}`,
|
|
61
|
-
Accept: "application/json",
|
|
62
|
-
},
|
|
63
|
-
});
|
|
64
|
-
return {
|
|
65
|
-
ticketUrl: `${baseUrl}/browse/${response.data.key}`,
|
|
31
|
+
} }, (reporterAssignment && { reporter: reporterAssignment })), (assigneeAssignment && { assignee: assigneeAssignment })), (Object.keys(requestTypeField).length > 0 && requestTypeField)), (params.customFields && params.customFields)),
|
|
66
32
|
};
|
|
33
|
+
try {
|
|
34
|
+
const response = yield axiosClient.post(`${apiUrl}/issue`, payload, {
|
|
35
|
+
headers: {
|
|
36
|
+
Authorization: `Bearer ${authToken}`,
|
|
37
|
+
Accept: "application/json",
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
const ticketKey = response.data.key;
|
|
41
|
+
if (!ticketKey) {
|
|
42
|
+
// Check if we got HTML instead of JSON (common when auth fails)
|
|
43
|
+
if (typeof response.data === "string" && response.data.includes("<!DOCTYPE html>")) {
|
|
44
|
+
throw new Error("Received HTML response instead of JSON - this usually indicates authentication failed or the server redirected to a login page");
|
|
45
|
+
}
|
|
46
|
+
console.error("No ticket key in response:", JSON.stringify(response.data, null, 2));
|
|
47
|
+
throw new Error("Failed to get ticket key from Jira response");
|
|
48
|
+
}
|
|
49
|
+
return Object.assign({ success: true, ticketUrl: `${browseUrl}/browse/${ticketKey}` }, (partialUpdateMessage && { error: partialUpdateMessage }));
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
return {
|
|
53
|
+
success: false,
|
|
54
|
+
error: getErrorMessage(error),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
67
57
|
});
|
|
68
58
|
export default createJiraTicket;
|
|
@@ -7,13 +7,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import {
|
|
10
|
+
import { axiosClient } from "../../util/axiosClient.js";
|
|
11
|
+
import { getJiraApiConfig, getErrorMessage } from "./utils.js";
|
|
11
12
|
const DEFAULT_LIMIT = 100;
|
|
12
13
|
const getJiraIssuesByQuery = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
|
|
13
|
-
const { authToken
|
|
14
|
+
const { authToken } = authParams;
|
|
14
15
|
const { query, limit } = params;
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
const { apiUrl, browseUrl, strategy } = getJiraApiConfig(authParams);
|
|
17
|
+
if (!authToken) {
|
|
18
|
+
throw new Error("Auth token is required");
|
|
17
19
|
}
|
|
18
20
|
const queryParams = new URLSearchParams();
|
|
19
21
|
queryParams.set("jql", query);
|
|
@@ -38,9 +40,10 @@ const getJiraIssuesByQuery = (_a) => __awaiter(void 0, [_a], void 0, function* (
|
|
|
38
40
|
"aggregatetimeoriginalestimate",
|
|
39
41
|
];
|
|
40
42
|
queryParams.set("fields", fields.join(","));
|
|
41
|
-
const
|
|
43
|
+
const searchEndpoint = strategy.getSearchEndpoint();
|
|
44
|
+
const fullApiUrl = `${apiUrl}${searchEndpoint}?${queryParams.toString()}`;
|
|
42
45
|
try {
|
|
43
|
-
const response = yield axiosClient.get(
|
|
46
|
+
const response = yield axiosClient.get(fullApiUrl, {
|
|
44
47
|
headers: {
|
|
45
48
|
Authorization: `Bearer ${authToken}`,
|
|
46
49
|
Accept: "application/json",
|
|
@@ -49,39 +52,41 @@ const getJiraIssuesByQuery = (_a) => __awaiter(void 0, [_a], void 0, function* (
|
|
|
49
52
|
return {
|
|
50
53
|
success: true,
|
|
51
54
|
results: response.data.issues.map(issue => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
const { id, key, fields } = issue;
|
|
56
|
+
const { summary, description, project, issuetype, status, assignee, reporter, creator, created, updated, resolution, duedate, } = fields;
|
|
57
|
+
const ticketUrl = `${browseUrl}/browse/${key}`;
|
|
58
|
+
return {
|
|
59
|
+
name: key,
|
|
60
|
+
url: ticketUrl,
|
|
56
61
|
contents: {
|
|
57
|
-
id
|
|
58
|
-
key
|
|
59
|
-
summary
|
|
60
|
-
description: extractPlainText(
|
|
62
|
+
id,
|
|
63
|
+
key,
|
|
64
|
+
summary,
|
|
65
|
+
description: extractPlainText(description),
|
|
61
66
|
project: {
|
|
62
|
-
id:
|
|
63
|
-
key:
|
|
64
|
-
name:
|
|
67
|
+
id: project.id,
|
|
68
|
+
key: project.key,
|
|
69
|
+
name: project.name,
|
|
65
70
|
},
|
|
66
71
|
issueType: {
|
|
67
|
-
id:
|
|
68
|
-
name:
|
|
72
|
+
id: issuetype.id,
|
|
73
|
+
name: issuetype.name,
|
|
69
74
|
},
|
|
70
75
|
status: {
|
|
71
|
-
id:
|
|
72
|
-
name:
|
|
73
|
-
category:
|
|
76
|
+
id: status.id,
|
|
77
|
+
name: status.name,
|
|
78
|
+
category: status.statusCategory.name,
|
|
74
79
|
},
|
|
75
|
-
assignee: (
|
|
76
|
-
reporter: (
|
|
77
|
-
creator: (
|
|
78
|
-
created
|
|
79
|
-
updated
|
|
80
|
-
resolution: (
|
|
81
|
-
dueDate:
|
|
82
|
-
url:
|
|
80
|
+
assignee: (assignee === null || assignee === void 0 ? void 0 : assignee.emailAddress) || null,
|
|
81
|
+
reporter: (reporter === null || reporter === void 0 ? void 0 : reporter.emailAddress) || null,
|
|
82
|
+
creator: (creator === null || creator === void 0 ? void 0 : creator.emailAddress) || null,
|
|
83
|
+
created,
|
|
84
|
+
updated,
|
|
85
|
+
resolution: (resolution === null || resolution === void 0 ? void 0 : resolution.name) || null,
|
|
86
|
+
dueDate: duedate || null,
|
|
87
|
+
url: ticketUrl,
|
|
83
88
|
},
|
|
84
|
-
}
|
|
89
|
+
};
|
|
85
90
|
}),
|
|
86
91
|
};
|
|
87
92
|
}
|
|
@@ -89,11 +94,7 @@ const getJiraIssuesByQuery = (_a) => __awaiter(void 0, [_a], void 0, function* (
|
|
|
89
94
|
console.error("Error retrieving Jira issues:", error);
|
|
90
95
|
return {
|
|
91
96
|
success: false,
|
|
92
|
-
error: error
|
|
93
|
-
? error.data.length > 0
|
|
94
|
-
? error.data[0].message
|
|
95
|
-
: error.message
|
|
96
|
-
: "An unknown error occurred",
|
|
97
|
+
error: getErrorMessage(error),
|
|
97
98
|
};
|
|
98
99
|
}
|
|
99
100
|
});
|
|
@@ -8,16 +8,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { axiosClient } from "../../util/axiosClient.js";
|
|
11
|
+
import { getJiraApiConfig, getErrorMessage } from "./utils.js";
|
|
11
12
|
// https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issues/#api-rest-api-2-issue-issueidorkey-get
|
|
12
13
|
const getJiraTicketDetails = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
|
|
13
|
-
const { authToken,
|
|
14
|
+
const { authToken, baseUrl } = authParams;
|
|
14
15
|
const { issueId } = params;
|
|
15
|
-
|
|
16
|
+
const { apiUrl } = getJiraApiConfig(authParams);
|
|
17
|
+
if (!authToken || !baseUrl) {
|
|
16
18
|
throw new Error("Valid Cloud ID, base URL, and auth token are required to get Jira ticket details");
|
|
17
19
|
}
|
|
18
|
-
const
|
|
20
|
+
const fullApiUrl = `${apiUrl}/issue/${issueId}`;
|
|
19
21
|
try {
|
|
20
|
-
const response = yield axiosClient.get(
|
|
22
|
+
const response = yield axiosClient.get(fullApiUrl, {
|
|
21
23
|
headers: {
|
|
22
24
|
Authorization: `Bearer ${authToken}`,
|
|
23
25
|
Accept: "application/json",
|
|
@@ -38,7 +40,7 @@ const getJiraTicketDetails = (_a) => __awaiter(void 0, [_a], void 0, function* (
|
|
|
38
40
|
console.error("Error retrieving Jira ticket details: ", error);
|
|
39
41
|
return {
|
|
40
42
|
success: false,
|
|
41
|
-
error: error
|
|
43
|
+
error: getErrorMessage(error),
|
|
42
44
|
};
|
|
43
45
|
}
|
|
44
46
|
});
|
|
@@ -8,31 +8,33 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { axiosClient } from "../../util/axiosClient.js";
|
|
11
|
+
import { getJiraApiConfig, getErrorMessage } from "./utils.js";
|
|
11
12
|
const getJiraTicketHistory = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
|
|
12
|
-
|
|
13
|
-
const { authToken, cloudId } = authParams;
|
|
13
|
+
const { authToken } = authParams;
|
|
14
14
|
const { issueId } = params;
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
const { apiUrl, strategy } = getJiraApiConfig(authParams);
|
|
16
|
+
if (!authToken) {
|
|
17
|
+
throw new Error("Auth token is required");
|
|
17
18
|
}
|
|
18
|
-
const
|
|
19
|
+
const fullApiUrl = `${apiUrl}${strategy.getHistoryEndpoint(issueId)}`;
|
|
19
20
|
try {
|
|
20
|
-
const response = yield axiosClient.get(
|
|
21
|
+
const response = yield axiosClient.get(fullApiUrl, {
|
|
21
22
|
headers: {
|
|
22
23
|
Authorization: `Bearer ${authToken}`,
|
|
23
24
|
Accept: "application/json",
|
|
24
25
|
},
|
|
25
26
|
});
|
|
27
|
+
const historyData = strategy.parseHistoryResponse(response);
|
|
26
28
|
return {
|
|
27
29
|
success: true,
|
|
28
|
-
history:
|
|
30
|
+
history: historyData,
|
|
29
31
|
};
|
|
30
32
|
}
|
|
31
33
|
catch (error) {
|
|
32
34
|
console.error("Error retrieving Jira ticket history: ", error);
|
|
33
35
|
return {
|
|
34
36
|
success: false,
|
|
35
|
-
error: error
|
|
37
|
+
error: getErrorMessage(error),
|
|
36
38
|
};
|
|
37
39
|
}
|
|
38
40
|
});
|
|
@@ -8,56 +8,35 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { axiosClient } from "../../util/axiosClient.js";
|
|
11
|
-
import {
|
|
11
|
+
import { resolveRequestTypeField, getJiraApiConfig, getErrorMessage } from "./utils.js";
|
|
12
12
|
const updateJiraTicketDetails = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
|
|
13
|
-
const { authToken
|
|
14
|
-
const { issueId, summary, description, customFields, requestTypeId } = params;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const apiUrl = `https://api.atlassian.com/ex/jira/${cloudId}/rest/api/3/issue/${issueId}`;
|
|
19
|
-
const formattedDescription = description
|
|
20
|
-
? {
|
|
21
|
-
type: "doc",
|
|
22
|
-
version: 1,
|
|
23
|
-
content: [
|
|
24
|
-
{
|
|
25
|
-
type: "paragraph",
|
|
26
|
-
content: [
|
|
27
|
-
{
|
|
28
|
-
type: "text",
|
|
29
|
-
text: description,
|
|
30
|
-
},
|
|
31
|
-
],
|
|
32
|
-
},
|
|
33
|
-
],
|
|
34
|
-
}
|
|
35
|
-
: undefined;
|
|
36
|
-
// If request type is provided, find the custom field ID and prepare the value
|
|
37
|
-
const requestTypeField = {};
|
|
38
|
-
if (requestTypeId && authToken) {
|
|
39
|
-
const requestTypeFieldId = yield getRequestTypeCustomFieldId(params.projectKey, `https://api.atlassian.com/ex/jira/${cloudId}/rest/api/3`, authToken);
|
|
40
|
-
if (requestTypeFieldId) {
|
|
41
|
-
requestTypeField[requestTypeFieldId] = requestTypeId;
|
|
42
|
-
}
|
|
13
|
+
const { authToken } = authParams;
|
|
14
|
+
const { issueId, summary, description, customFields, requestTypeId, projectKey } = params;
|
|
15
|
+
const { apiUrl, browseUrl, strategy } = getJiraApiConfig(authParams);
|
|
16
|
+
if (!authToken) {
|
|
17
|
+
throw new Error("Auth token is required");
|
|
43
18
|
}
|
|
19
|
+
const fullApiUrl = `${apiUrl}/issue/${issueId}`;
|
|
20
|
+
const formattedDescription = description ? strategy.formatText(description) : undefined;
|
|
21
|
+
const { field: requestTypeField, message: partialUpdateMessage } = yield resolveRequestTypeField(requestTypeId, projectKey, apiUrl, authToken);
|
|
44
22
|
const payload = {
|
|
45
|
-
fields: Object.assign(Object.assign(Object.assign(Object.assign({}, (summary && { summary })), (formattedDescription && { description: formattedDescription })), requestTypeField), (customFields &&
|
|
23
|
+
fields: Object.assign(Object.assign(Object.assign(Object.assign({}, (summary && { summary })), (formattedDescription && { description: formattedDescription })), (Object.keys(requestTypeField).length > 0 && requestTypeField)), (customFields && customFields)),
|
|
46
24
|
};
|
|
47
25
|
try {
|
|
48
|
-
yield axiosClient.put(
|
|
26
|
+
yield axiosClient.put(fullApiUrl, payload, {
|
|
49
27
|
headers: {
|
|
50
28
|
Authorization: `Bearer ${authToken}`,
|
|
51
29
|
Accept: "application/json",
|
|
52
30
|
},
|
|
53
31
|
});
|
|
54
|
-
return {
|
|
55
|
-
ticketUrl: `${baseUrl}/browse/${issueId}`,
|
|
56
|
-
};
|
|
32
|
+
return Object.assign({ success: true, ticketUrl: `${browseUrl}/browse/${issueId}` }, (partialUpdateMessage && { error: partialUpdateMessage }));
|
|
57
33
|
}
|
|
58
34
|
catch (error) {
|
|
59
35
|
console.error("Error updating Jira ticket:", error);
|
|
60
|
-
|
|
36
|
+
return {
|
|
37
|
+
success: false,
|
|
38
|
+
error: getErrorMessage(error),
|
|
39
|
+
};
|
|
61
40
|
}
|
|
62
41
|
});
|
|
63
42
|
export default updateJiraTicketDetails;
|
|
@@ -8,13 +8,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { axiosClient } from "../../util/axiosClient.js";
|
|
11
|
+
import { getJiraApiConfig, getErrorMessage } from "./utils.js";
|
|
11
12
|
const updateJiraTicketStatus = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
|
|
12
|
-
const { authToken
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const { authToken } = authParams;
|
|
14
|
+
const { apiUrl, browseUrl } = getJiraApiConfig(authParams);
|
|
15
|
+
if (!authToken) {
|
|
16
|
+
throw new Error("Auth token is required");
|
|
15
17
|
}
|
|
16
18
|
const { issueId, status } = params;
|
|
17
|
-
const transitionsUrl =
|
|
19
|
+
const transitionsUrl = `${apiUrl}/issue/${issueId}/transitions`;
|
|
18
20
|
try {
|
|
19
21
|
// API takes transition ID, so fetch available transitions the find ID of transition that matches given status name
|
|
20
22
|
const transitionsResponse = yield axiosClient.get(transitionsUrl, {
|
|
@@ -41,14 +43,14 @@ const updateJiraTicketStatus = (_a) => __awaiter(void 0, [_a], void 0, function*
|
|
|
41
43
|
});
|
|
42
44
|
return {
|
|
43
45
|
success: true,
|
|
44
|
-
ticketUrl: `${
|
|
46
|
+
ticketUrl: `${browseUrl}/browse/${issueId}`,
|
|
45
47
|
};
|
|
46
48
|
}
|
|
47
49
|
catch (error) {
|
|
48
50
|
console.error("Error updating Jira ticket status: ", error);
|
|
49
51
|
return {
|
|
50
52
|
success: false,
|
|
51
|
-
error: error
|
|
53
|
+
error: getErrorMessage(error),
|
|
52
54
|
};
|
|
53
55
|
}
|
|
54
56
|
});
|
|
@@ -1,2 +1,55 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
1
|
+
export interface JiraApiConfig {
|
|
2
|
+
apiUrl: string;
|
|
3
|
+
browseUrl: string;
|
|
4
|
+
isDataCenter: boolean;
|
|
5
|
+
strategy: JiraPlatformStrategy;
|
|
6
|
+
}
|
|
7
|
+
export interface JiraServiceDeskApiConfig {
|
|
8
|
+
serviceDeskApiUrl: string;
|
|
9
|
+
browseUrl: string;
|
|
10
|
+
isDataCenter: boolean;
|
|
11
|
+
}
|
|
12
|
+
interface JiraHistoryResponse {
|
|
13
|
+
data?: {
|
|
14
|
+
values?: unknown[];
|
|
15
|
+
changelog?: {
|
|
16
|
+
histories?: unknown[];
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export interface JiraPlatformStrategy {
|
|
21
|
+
formatText(text: string): string | object;
|
|
22
|
+
formatUser(userId: string | null): {
|
|
23
|
+
[key: string]: string;
|
|
24
|
+
} | null;
|
|
25
|
+
formatUserAssignment(userId: string | null): {
|
|
26
|
+
id?: string;
|
|
27
|
+
name?: string;
|
|
28
|
+
} | null;
|
|
29
|
+
getUserSearchParam(): string;
|
|
30
|
+
getSearchEndpoint(): string;
|
|
31
|
+
getHistoryEndpoint(issueId: string): string;
|
|
32
|
+
parseHistoryResponse(response: JiraHistoryResponse): unknown[] | undefined;
|
|
33
|
+
}
|
|
34
|
+
export declare function getPlatformStrategy(isDataCenter: boolean): JiraPlatformStrategy;
|
|
35
|
+
export declare function getJiraApiConfig(authParams: {
|
|
36
|
+
cloudId?: string;
|
|
37
|
+
baseUrl?: string;
|
|
38
|
+
authToken?: string;
|
|
39
|
+
provider?: string;
|
|
40
|
+
}): JiraApiConfig;
|
|
41
|
+
export declare function isEmail(value: string | undefined): value is string;
|
|
42
|
+
export declare function resolveAccountIdIfEmail(value: string | undefined, apiUrl: string, authToken: string, strategy: JiraPlatformStrategy): Promise<string | null>;
|
|
43
|
+
export declare function getUserAccountIdFromEmail(email: string, apiUrl: string, authToken: string, strategy: JiraPlatformStrategy): Promise<string | null>;
|
|
44
|
+
export declare function getErrorMessage(error: unknown): string;
|
|
45
|
+
export declare function resolveRequestTypeField(requestTypeId: string | undefined, projectKey: string | undefined, apiUrl: string, authToken: string): Promise<{
|
|
46
|
+
field: {
|
|
47
|
+
[key: string]: string;
|
|
48
|
+
};
|
|
49
|
+
message?: string;
|
|
50
|
+
}>;
|
|
51
|
+
export declare function getRequestTypeCustomFieldId(projectKey: string, apiUrl: string, authToken: string): Promise<{
|
|
52
|
+
fieldId: string | null;
|
|
53
|
+
message?: string;
|
|
54
|
+
}>;
|
|
55
|
+
export {};
|
|
@@ -8,17 +8,111 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { axiosClient } from "../../util/axiosClient.js";
|
|
11
|
-
|
|
11
|
+
const cloudStrategy = {
|
|
12
|
+
formatText: (text) => ({
|
|
13
|
+
type: "doc",
|
|
14
|
+
version: 1,
|
|
15
|
+
content: [
|
|
16
|
+
{
|
|
17
|
+
type: "paragraph",
|
|
18
|
+
content: [
|
|
19
|
+
{
|
|
20
|
+
type: "text",
|
|
21
|
+
text: text,
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
}),
|
|
27
|
+
formatUser: (userId) => {
|
|
28
|
+
if (!userId)
|
|
29
|
+
return null;
|
|
30
|
+
return { accountId: userId };
|
|
31
|
+
},
|
|
32
|
+
formatUserAssignment: (userId) => {
|
|
33
|
+
if (!userId)
|
|
34
|
+
return null;
|
|
35
|
+
return { id: userId };
|
|
36
|
+
},
|
|
37
|
+
getUserSearchParam: () => "query",
|
|
38
|
+
getSearchEndpoint: () => "/search/jql",
|
|
39
|
+
getHistoryEndpoint: (issueId) => `/issue/${issueId}/changelog`,
|
|
40
|
+
parseHistoryResponse: (response) => { var _a; return (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.values; },
|
|
41
|
+
};
|
|
42
|
+
const dataCenterStrategy = {
|
|
43
|
+
formatText: (text) => text,
|
|
44
|
+
formatUser: (userId) => {
|
|
45
|
+
if (!userId)
|
|
46
|
+
return null;
|
|
47
|
+
return { name: userId };
|
|
48
|
+
},
|
|
49
|
+
formatUserAssignment: (userId) => {
|
|
50
|
+
if (!userId)
|
|
51
|
+
return null;
|
|
52
|
+
return { name: userId };
|
|
53
|
+
},
|
|
54
|
+
getUserSearchParam: () => "username",
|
|
55
|
+
getSearchEndpoint: () => "/search",
|
|
56
|
+
getHistoryEndpoint: (issueId) => `/issue/${issueId}?expand=changelog`,
|
|
57
|
+
parseHistoryResponse: (response) => { var _a, _b; return (_b = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.changelog) === null || _b === void 0 ? void 0 : _b.histories; },
|
|
58
|
+
};
|
|
59
|
+
export function getPlatformStrategy(isDataCenter) {
|
|
60
|
+
return isDataCenter ? dataCenterStrategy : cloudStrategy;
|
|
61
|
+
}
|
|
62
|
+
export function getJiraApiConfig(authParams) {
|
|
63
|
+
const { cloudId, baseUrl, authToken, provider } = authParams;
|
|
64
|
+
if (!authToken) {
|
|
65
|
+
throw new Error("Valid auth token is required");
|
|
66
|
+
}
|
|
67
|
+
const isDataCenter = provider === "jiraDataCenter";
|
|
68
|
+
const strategy = getPlatformStrategy(isDataCenter);
|
|
69
|
+
if (isDataCenter) {
|
|
70
|
+
if (!baseUrl) {
|
|
71
|
+
throw new Error("Valid base URL is required for Jira Data Center");
|
|
72
|
+
}
|
|
73
|
+
const trimmedUrl = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
|
|
74
|
+
return {
|
|
75
|
+
apiUrl: `${trimmedUrl}/rest/api/2`,
|
|
76
|
+
browseUrl: trimmedUrl,
|
|
77
|
+
isDataCenter: true,
|
|
78
|
+
strategy,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (!cloudId) {
|
|
82
|
+
throw new Error("Valid Cloud ID is required for Jira Cloud");
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
apiUrl: `https://api.atlassian.com/ex/jira/${cloudId}/rest/api/3`,
|
|
86
|
+
browseUrl: baseUrl || `https://${cloudId}.atlassian.net`,
|
|
87
|
+
isDataCenter: false,
|
|
88
|
+
strategy,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
export function isEmail(value) {
|
|
92
|
+
return typeof value === "string" && value.includes("@");
|
|
93
|
+
}
|
|
94
|
+
export function resolveAccountIdIfEmail(value, apiUrl, authToken, strategy) {
|
|
95
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
96
|
+
return isEmail(value) ? getUserAccountIdFromEmail(value, apiUrl, authToken, strategy) : null;
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
export function getUserAccountIdFromEmail(email, apiUrl, authToken, strategy) {
|
|
12
100
|
return __awaiter(this, void 0, void 0, function* () {
|
|
13
101
|
try {
|
|
14
|
-
const
|
|
102
|
+
const searchParam = strategy.getUserSearchParam();
|
|
103
|
+
const response = yield axiosClient.get(`${apiUrl}/user/search?${searchParam}=${encodeURIComponent(email)}`, {
|
|
15
104
|
headers: {
|
|
16
105
|
Authorization: `Bearer ${authToken}`,
|
|
17
106
|
Accept: "application/json",
|
|
18
107
|
},
|
|
19
108
|
});
|
|
20
109
|
if (response.data && response.data.length > 0) {
|
|
21
|
-
|
|
110
|
+
const user = response.data[0];
|
|
111
|
+
// Use strategy to determine which field to use
|
|
112
|
+
const userId = strategy === dataCenterStrategy ? user.name || user.key : user.accountId;
|
|
113
|
+
if (!userId)
|
|
114
|
+
return null;
|
|
115
|
+
return userId;
|
|
22
116
|
}
|
|
23
117
|
return null;
|
|
24
118
|
}
|
|
@@ -29,8 +123,30 @@ export function getUserAccountIdFromEmail(email, apiUrl, authToken) {
|
|
|
29
123
|
}
|
|
30
124
|
});
|
|
31
125
|
}
|
|
126
|
+
export function getErrorMessage(error) {
|
|
127
|
+
if (error instanceof Error)
|
|
128
|
+
return error.message;
|
|
129
|
+
return String(error);
|
|
130
|
+
}
|
|
131
|
+
export function resolveRequestTypeField(requestTypeId, projectKey, apiUrl, authToken) {
|
|
132
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
133
|
+
if (!requestTypeId || !projectKey) {
|
|
134
|
+
return { field: {} };
|
|
135
|
+
}
|
|
136
|
+
const result = yield getRequestTypeCustomFieldId(projectKey, apiUrl, authToken);
|
|
137
|
+
const field = {};
|
|
138
|
+
if (result.fieldId) {
|
|
139
|
+
field[result.fieldId] = requestTypeId;
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
field,
|
|
143
|
+
message: result.message,
|
|
144
|
+
};
|
|
145
|
+
});
|
|
146
|
+
}
|
|
32
147
|
export function getRequestTypeCustomFieldId(projectKey, apiUrl, authToken) {
|
|
33
148
|
return __awaiter(this, void 0, void 0, function* () {
|
|
149
|
+
var _a;
|
|
34
150
|
try {
|
|
35
151
|
const response = yield axiosClient.get(`${apiUrl}/issue/createmeta?projectKeys=${projectKey}&expand=projects.issuetypes.fields`, {
|
|
36
152
|
headers: {
|
|
@@ -40,12 +156,12 @@ export function getRequestTypeCustomFieldId(projectKey, apiUrl, authToken) {
|
|
|
40
156
|
});
|
|
41
157
|
const projects = response.data.projects;
|
|
42
158
|
if (!projects || projects.length === 0) {
|
|
43
|
-
return null;
|
|
159
|
+
return { fieldId: null };
|
|
44
160
|
}
|
|
45
161
|
const project = projects[0];
|
|
46
162
|
const issueTypes = project.issuetypes;
|
|
47
163
|
if (!issueTypes || issueTypes.length === 0) {
|
|
48
|
-
return null;
|
|
164
|
+
return { fieldId: null };
|
|
49
165
|
}
|
|
50
166
|
for (const issueType of issueTypes) {
|
|
51
167
|
const fields = issueType.fields;
|
|
@@ -54,18 +170,22 @@ export function getRequestTypeCustomFieldId(projectKey, apiUrl, authToken) {
|
|
|
54
170
|
if (fieldData && typeof fieldData === "object" && "name" in fieldData) {
|
|
55
171
|
const fieldInfo = fieldData;
|
|
56
172
|
if (fieldInfo.name === "Request Type") {
|
|
57
|
-
return fieldId;
|
|
173
|
+
return { fieldId };
|
|
58
174
|
}
|
|
59
175
|
}
|
|
60
176
|
}
|
|
61
177
|
}
|
|
62
178
|
}
|
|
63
|
-
return null;
|
|
179
|
+
return { fieldId: null };
|
|
64
180
|
}
|
|
65
181
|
catch (error) {
|
|
66
182
|
const axiosError = error;
|
|
67
|
-
|
|
68
|
-
|
|
183
|
+
if (((_a = axiosError.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
|
|
184
|
+
return { fieldId: null, message: "Request Type field not found (optional for Service Desk), skipping..." };
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
return { fieldId: null, message: `Error finding Request Type custom field: ${axiosError.message}` };
|
|
188
|
+
}
|
|
69
189
|
}
|
|
70
190
|
});
|
|
71
191
|
}
|