@intuitionrobotics/jira
Version:
174 lines • 7.03 kB
JavaScript
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