UNPKG

@intuitionrobotics/jira

Version:
174 lines 7.03 kB
import { BadImplementationException, ImplementationMissingException, Module } from "@intuitionrobotics/ts-common"; import { ApiException, promisifyRequest } from "@intuitionrobotics/thunderstorm/backend"; import { HttpMethod } from "@intuitionrobotics/thunderstorm"; import { buildJQL, createFormData, createText } from "./utils.js"; import {} from "../../shared/version.js"; import {} from "axios"; export class JiraModule_Class extends Module { projects; versions = {}; constructor() { super("JiraModule"); } getHeadersJson() { if (!this.config.auth || !this.config.auth.apiKey || !this.config.auth.email) throw new ImplementationMissingException('Missing auth config variables for JiraModule'); return this.buildHeaders(this.config.auth, true); } getHeadersForm() { if (!this.config.auth || !this.config.auth.apiKey || !this.config.auth.email) throw new ImplementationMissingException('Missing auth config variables for JiraModule'); return this.buildHeaders(this.config.auth, false); } getRestUrl() { if (!this.config.baseUrl) throw new ImplementationMissingException("Missing Jira baseUrl for JiraModule, please add the key baseUrl to the config"); return this.config.baseUrl + '/rest/api/3'; } buildHeaders = ({ apiKey, email }, check) => { const headers = { Authorization: `Basic ${Buffer.from(email + ':' + apiKey).toString('base64')}` }; if (!check) { headers['X-Atlassian-Token'] = 'no-check'; headers['Content-Type'] = 'multipart/form-data'; } else { headers.Accept = 'application/json'; headers['Content-Type'] = 'application/json'; } return headers; }; project = { query: async (projectKey) => { if (!this.projects) this.projects = await this.executeGetRequest(`/project`); const project = this.projects.find(_project => _project.key === projectKey); if (!project) throw new BadImplementationException(`Could not find project: ${projectKey}`); return project; } }; version = { query: async (projectId, versionName) => { if (!this.versions[projectId]) this.versions[projectId] = await this.executeGetRequest(`/project/${projectId}/versions`); return this.versions[projectId].find(v => v.name === versionName); }, create: async (projectId, versionName) => { const version = await this.executePostRequest(`/version`, { projectId, name: versionName }); this.versions[projectId].push(version); return version; } }; comment = { add: async (issueKey, comment) => { return this.executePostRequest(`/issue/${issueKey}/comment`, createText(comment)); } }; issue = { query: async (query) => { return (await this.executeGetRequest(`/search`, { jql: buildJQL(query) })).issues; }, get: async (issueId) => { return this.executeGetRequest(`/issue/${issueId}`); }, comment: this.comment, create: async (project, issueType, summary, descriptions, label, extraFields) => { const issue = await this.executePostRequest('/issue', { fields: { project, issuetype: issueType, description: createText(...descriptions), summary, labels: label || [], assignee: { accountId: this.config.defaultAssignee.accountId }, ...extraFields } }); issue.url = `${this.config.baseUrl}/browse/${issue.key}`; return issue; }, update: async (issueKey, fields) => { return this.executePutRequest(`/issue/${issueKey}`, { fields }); }, resolve: async (issueKey, projectKey, versionName, _status) => { const project = await JiraModule.project.query(projectKey); let version = await JiraModule.version.query(projectKey, versionName); if (!version) version = await JiraModule.version.create(project.id, versionName); return this.executePutRequest(`/issue/${issueKey}`, { fields: { fixVersions: [{ id: version.id }] } }); } }; getIssueTypes = async (id) => { return this.executeGetRequest('/issue/createmetadata', { projectKeys: id }); }; query = async (query) => { return (await this.executeGetRequest(`/search`, { jql: buildJQL(query) })).issues; }; getIssueRequest = async (issueId) => { return this.executeGetRequest(`/issue/${issueId}`); }; addIssueAttachment = async (issue, file) => { return this.executeFormRequest(`/issue/${issue}/attachments`, file); }; executeFormRequest = async (url, buffer) => { const request = { headers: this.getHeadersForm(), url: `${this.getRestUrl()}${url}`, data: createFormData('logs.zip', buffer), method: HttpMethod.POST }; return this.executeRequest(request); }; async executePostRequest(url, body, _label) { const request = { headers: this.getHeadersJson(), url: `${this.getRestUrl()}${url}`, data: body, method: HttpMethod.POST, responseType: 'json' }; return this.executeRequest(request); } async executePutRequest(url, body) { const request = { headers: this.getHeadersJson(), url: `${this.getRestUrl()}${url}`, data: body, method: HttpMethod.PUT, responseType: 'json' }; return this.executeRequest(request); } async executeGetRequest(url, _params) { const params = _params && Object.keys(_params).map((key) => { return `${key}=${_params[key]}`; }); let urlParams = ""; if (params && params.length > 0) urlParams = `?${params.join("&")}`; const request = { headers: this.getHeadersJson(), url: `${this.getRestUrl()}${url}${urlParams}`, method: HttpMethod.GET, responseType: "json" }; return this.executeRequest(request); } async executeRequest(request) { const response = await promisifyRequest(request); const statusCode = response.status; // TODO: need to handle 1XX and 3XX if (statusCode < 200 || statusCode >= 300) throw new ApiException(statusCode, response.data); return response.data; } } export const JiraModule = new JiraModule_Class(); //# sourceMappingURL=JiraModule.js.map