bugzilla
Version:
A NodeJS module to access Bugzilla instances through the REST API.
125 lines • 4.37 kB
JavaScript
import { URLSearchParams, URL } from 'url';
import axios from 'axios';
import { object } from './validators';
import { LoginResponseSpec } from './types';
export function params(search) {
if (search instanceof URLSearchParams) {
return search;
}
return new URLSearchParams(search);
}
function isError(payload) {
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return payload && typeof payload == 'object' && payload.error;
}
async function performRequest(config, validator) {
var _a;
try {
let response = await axios.request(Object.assign(Object.assign({}, config), { headers: Object.assign({ Accept: 'application/json' }, ((_a = config.headers) !== null && _a !== void 0 ? _a : {})) }));
if (isError(response.data)) {
throw new Error(response.data.message);
}
return validator(response.data);
}
catch (e) {
if (axios.isAxiosError(e)) {
throw new Error(e.message);
}
else {
throw e;
}
}
}
/**
* Responsible for requesting data from the bugzilla instance handling any
* necessary authentication and error handling that must happen. The chief
* access is through the `get`, `post` and `put` methods.
*/
export class BugzillaLink {
constructor(instance) {
this.instance = new URL('rest/', instance);
}
buildURL(path, query) {
let url = new URL(path, this.instance);
if (query) {
url.search = params(query).toString();
}
return url;
}
async get(path, validator, searchParams) {
return this.request({
url: this.buildURL(path, searchParams).toString(),
}, validator);
}
async post(path, validator, content, searchParams) {
return this.request({
url: this.buildURL(path, searchParams).toString(),
method: 'POST',
data: JSON.stringify(content),
headers: {
'Content-Type': 'application/json',
},
}, validator);
}
async put(path, validator, content, searchParams) {
return this.request({
url: this.buildURL(path, searchParams).toString(),
method: 'PUT',
data: JSON.stringify(content),
headers: {
'Content-Type': 'application/json',
},
}, validator);
}
}
export class PublicLink extends BugzillaLink {
async request(config, validator) {
return performRequest(config, validator);
}
}
/**
* Handles authentication using an API key.
*/
export class ApiKeyLink extends BugzillaLink {
constructor(instance, apiKey) {
super(instance);
this.apiKey = apiKey;
}
async request(config, validator) {
var _a;
return performRequest(Object.assign(Object.assign({}, config), { headers: Object.assign(Object.assign({}, ((_a = config.headers) !== null && _a !== void 0 ? _a : {})), { 'X-BUGZILLA-API-KEY': this.apiKey,
// Red Hat Bugzilla uses Authorization header - https://bugzilla.redhat.com/docs/en/html/api/core/v1/general.html#authentication
Authorization: `Bearer ${this.apiKey}` }) }), validator);
}
}
/**
* Handles authentication using a username and password.
*/
export class PasswordLink extends BugzillaLink {
constructor(instance, username, password, restrictLogin) {
super(instance);
this.username = username;
this.password = password;
this.restrictLogin = restrictLogin;
this.token = null;
}
async login() {
let loginInfo = await performRequest({
url: this.buildURL('login', {
login: this.username,
password: this.password,
restrict_login: String(this.restrictLogin),
}).toString(),
}, object(LoginResponseSpec));
return loginInfo.token;
}
async request(config, validator) {
var _a;
if (!this.token) {
this.token = await this.login();
}
return performRequest(Object.assign(Object.assign({}, config), { headers: Object.assign(Object.assign({}, ((_a = config.headers) !== null && _a !== void 0 ? _a : {})), { 'X-BUGZILLA-TOKEN': this.token }) }), validator);
}
}
//# sourceMappingURL=link.js.map