import { PostBulkFetchIssuesRequestBody, PostBulkFetchIssuesResponse, GetIssueResponse, GetIssueTransitionsResponse, GetIssueTypesResponse, PostAddCommentResponse, PostBulkCreateIssueRequestBody, PostBulkCreateIssueResponse, PostCreateIssueRequestBody, PostCreateIssueResponse, PostTransitionIssueRequestBody, PutEditIssueRequestBody, PostBulkTransitionIssuesRequestBody } from "@business-logic/types/JiraApi"; import axios, { request } from "axios"; import axiosRetry from "axios-retry"; const jiraUrl = process.env.JIRA_SERVER!; const jiraUsername = process.env.JIRA_USERNAME!; const jiraApiKey = process.env.JIRA_API_KEY!; const encodedAuthKey = Buffer.from(`${jiraUsername}:${jiraApiKey}`).toString('base64'); export default class JiraApiUtil { readonly baseUrl: string; readonly issueUrl: string; readonly bulkIssueCreateUrl: string; readonly bulkIssueFetchUrl: string; readonly bulkTransitionIssuesUrl: string; readonly axiosClient: axios.AxiosInstance; constructor() { this.baseUrl = jiraUrl; this.issueUrl = `${this.baseUrl}/rest/api/3/issue`; this.bulkIssueCreateUrl = `${this.issueUrl}/bulk`; this.bulkIssueFetchUrl = `${this.issueUrl}/bulkfetch`; this.bulkTransitionIssuesUrl = `${this.baseUrl}/rest/api/3/bulk/issues/transition` this.axiosClient = axios.create(); // interceptor to log error message from api this.axiosClient.interceptors.response.use( response => response, error => { console.error('Axios Error:', error?.response?.data || error.message); return Promise.reject(error); } ); // Set up retries if requests are made too quickly axiosRetry(this.axiosClient, { retries: 4, retryDelay: (retryCount) => { return Math.pow(2, retryCount) * 1000; }, // Exponential backoff retryCondition: (error) => { return error.response?.status === 429 } // If rate-limit error }); } getIssue(issueKey: string) { const url = `${this.issueUrl}/${issueKey}`; return this.axiosClient.get(url, { headers: { Authorization: `Basic ${encodedAuthKey}`, Accept: 'application/json' } }); } postBulkFetchIssues(requestBody: PostBulkFetchIssuesRequestBody) { return this.axiosClient.post(this.bulkIssueFetchUrl, requestBody, { headers: { Authorization: `Basic ${encodedAuthKey}`, 'Accept': 'application/json', 'Content-Type': 'application/json' } }); } getIssueTransitions(issueKey: string) { const url = `${this.issueUrl}/${issueKey}/transitions` return this.axiosClient.get(url, { headers: { Authorization: `Basic ${encodedAuthKey}`, Accept: 'application/json' } }); } getIssueTypes(projectKey: string) { const url = `${this.baseUrl}/rest/api/3/issue/createmeta/${projectKey}/issuetypes`; return this.axiosClient.get(url, { headers: { Authorization: `Basic ${encodedAuthKey}`, Accept: 'application/json' } }); } postAddComment(issueKey: string, commentBody: PostAddCommentResponse) { const url = `${this.issueUrl}/${issueKey}/comment`; return this.axiosClient.post(url, commentBody, { headers: { Authorization: `Basic ${encodedAuthKey}`, 'Accept': 'application/json', 'Content-Type': 'application/json' } }); } postTransitionIssue(issueKey: string, requestBody: PostTransitionIssueRequestBody) { const transitionUrl = `${this.issueUrl}/${issueKey}/transitions` return this.axiosClient.post(transitionUrl, requestBody, { headers: { Authorization: `Basic ${encodedAuthKey}`, 'Accept': 'application/json', 'Content-Type': 'application/json' }, }); } putEditIssue(issueKey: string, requestBody: PutEditIssueRequestBody) { const editIssueUrl = `${this.issueUrl}/${issueKey}` return this.axiosClient.put(editIssueUrl, requestBody, { headers: { Authorization: `Basic ${encodedAuthKey}`, 'Accept': 'application/json', 'Content-Type': 'application/json' } }); } postBulkTransitionIssues(requestBody: PostBulkTransitionIssuesRequestBody) { return this.axiosClient.post(this.bulkTransitionIssuesUrl, requestBody, { headers: { Authorization: `Basic ${encodedAuthKey}`, 'Accept': 'application/json', 'Content-Type': 'application/json' }, }); } postCreateIssue(requestBody: PostCreateIssueRequestBody) { return this.axiosClient.post(this.issueUrl, requestBody, { headers: { Authorization: `Basic ${encodedAuthKey}`, 'Accept': 'application/json', 'Content-Type': 'application/json' }, }); } postBulkCreateIssue(requestBody: PostBulkCreateIssueRequestBody) { return this.axiosClient.post(this.bulkIssueCreateUrl, requestBody, { headers: { Authorization: `Basic ${encodedAuthKey}`, 'Accept': 'application/json', 'Content-Type': 'application/json' }, }); } }