@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.
@@ -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 { getUserAccountIdFromEmail, getRequestTypeCustomFieldId } from "./utils.js";
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, cloudId, baseUrl } = authParams;
14
- const apiUrl = `https://api.atlassian.com/ex/jira/${cloudId}/rest/api/3/`;
15
- if (!cloudId || !authToken) {
16
- throw new Error("Valid Cloud ID and auth token are required to comment on Jira ticket");
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
- // If assignee is an email, look up the account ID
19
- let reporterId = null;
20
- if (params.reporter && typeof params.reporter === "string" && params.reporter.includes("@") && authToken) {
21
- reporterId = yield getUserAccountIdFromEmail(params.reporter, apiUrl, authToken);
22
- }
23
- // If assignee is an email, look up the account ID
24
- let assigneeId = null;
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
- } }, (reporterId ? { reporter: { id: reporterId } } : {})), (assigneeId ? { assignee: { id: assigneeId } } : {})), requestTypeField), (params.customFields ? params.customFields : {})),
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 { ApiError, axiosClient } from "../../util/axiosClient.js";
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, cloudId, baseUrl } = authParams;
14
+ const { authToken } = authParams;
14
15
  const { query, limit } = params;
15
- if (!cloudId || !authToken || !baseUrl) {
16
- throw new Error("Valid Cloud ID, base URL, and auth token are required to comment on Jira ticket");
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 apiUrl = `https://api.atlassian.com/ex/jira/${cloudId}/rest/api/3/search/jql?${queryParams.toString()}`;
43
+ const searchEndpoint = strategy.getSearchEndpoint();
44
+ const fullApiUrl = `${apiUrl}${searchEndpoint}?${queryParams.toString()}`;
42
45
  try {
43
- const response = yield axiosClient.get(apiUrl, {
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
- var _a, _b, _c, _d;
53
- return ({
54
- name: issue.key,
55
- url: `${baseUrl}/browse/${issue.key}`,
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: issue.id,
58
- key: issue.key,
59
- summary: issue.fields.summary,
60
- description: extractPlainText(issue.fields.description),
62
+ id,
63
+ key,
64
+ summary,
65
+ description: extractPlainText(description),
61
66
  project: {
62
- id: issue.fields.project.id,
63
- key: issue.fields.project.key,
64
- name: issue.fields.project.name,
67
+ id: project.id,
68
+ key: project.key,
69
+ name: project.name,
65
70
  },
66
71
  issueType: {
67
- id: issue.fields.issuetype.id,
68
- name: issue.fields.issuetype.name,
72
+ id: issuetype.id,
73
+ name: issuetype.name,
69
74
  },
70
75
  status: {
71
- id: issue.fields.status.id,
72
- name: issue.fields.status.name,
73
- category: issue.fields.status.statusCategory.name,
76
+ id: status.id,
77
+ name: status.name,
78
+ category: status.statusCategory.name,
74
79
  },
75
- assignee: ((_a = issue.fields.assignee) === null || _a === void 0 ? void 0 : _a.emailAddress) || null,
76
- reporter: ((_b = issue.fields.reporter) === null || _b === void 0 ? void 0 : _b.emailAddress) || null,
77
- creator: ((_c = issue.fields.creator) === null || _c === void 0 ? void 0 : _c.emailAddress) || null,
78
- created: issue.fields.created,
79
- updated: issue.fields.updated,
80
- resolution: ((_d = issue.fields.resolution) === null || _d === void 0 ? void 0 : _d.name) || null,
81
- dueDate: issue.fields.duedate || null,
82
- url: `${baseUrl}/browse/${issue.key}`,
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 instanceof ApiError
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, cloudId, baseUrl } = authParams;
14
+ const { authToken, baseUrl } = authParams;
14
15
  const { issueId } = params;
15
- if (!cloudId || !authToken || !baseUrl) {
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 apiUrl = `https://api.atlassian.com/ex/jira/${cloudId}/rest/api/3/issue/${issueId}`;
20
+ const fullApiUrl = `${apiUrl}/issue/${issueId}`;
19
21
  try {
20
- const response = yield axiosClient.get(apiUrl, {
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 instanceof Error ? error.message : "Unknown 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
- var _b;
13
- const { authToken, cloudId } = authParams;
13
+ const { authToken } = authParams;
14
14
  const { issueId } = params;
15
- if (!cloudId || !authToken) {
16
- throw new Error("Valid Cloud ID and auth token are required to comment on Jira ticket");
15
+ const { apiUrl, strategy } = getJiraApiConfig(authParams);
16
+ if (!authToken) {
17
+ throw new Error("Auth token is required");
17
18
  }
18
- const apiUrl = `https://api.atlassian.com/ex/jira/${cloudId}/rest/api/3/issue/${issueId}/changelog`;
19
+ const fullApiUrl = `${apiUrl}${strategy.getHistoryEndpoint(issueId)}`;
19
20
  try {
20
- const response = yield axiosClient.get(apiUrl, {
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: (_b = response === null || response === void 0 ? void 0 : response.data) === null || _b === void 0 ? void 0 : _b.values,
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 instanceof Error ? error.message : "Unknown 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 { getRequestTypeCustomFieldId } from "./utils.js";
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, cloudId, baseUrl } = authParams;
14
- const { issueId, summary, description, customFields, requestTypeId } = params;
15
- if (!cloudId || !authToken) {
16
- throw new Error("Valid Cloud ID and auth token are required to comment on Jira ticket");
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 && Object.assign({}, 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(apiUrl, payload, {
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
- throw new Error(error instanceof Error ? error.message : "Unknown error");
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, cloudId, baseUrl } = authParams;
13
- if (!cloudId || !authToken) {
14
- throw new Error("Valid Cloud ID and auth token are required to comment on Jira ticket");
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 = `https://api.atlassian.com/ex/jira/${cloudId}/rest/api/3/issue/${issueId}/transitions`;
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: `${baseUrl}/browse/${issueId}`,
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 instanceof Error ? error.message : "Unknown error",
53
+ error: getErrorMessage(error),
52
54
  };
53
55
  }
54
56
  });
@@ -1,2 +1,55 @@
1
- export declare function getUserAccountIdFromEmail(email: string, apiUrl: string, authToken: string): Promise<string | null>;
2
- export declare function getRequestTypeCustomFieldId(projectKey: string, apiUrl: string, authToken: string): Promise<string | null>;
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
- export function getUserAccountIdFromEmail(email, apiUrl, authToken) {
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 response = yield axiosClient.get(`${apiUrl}/user/search?query=${encodeURIComponent(email)}`, {
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
- return response.data[0].accountId;
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
- console.error("Error finding Request Type custom field:", axiosError.message);
68
- return null;
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
  }