evergreen.js
Version:
JavaScript/TypeScript library for the Evergreen REST API
297 lines (271 loc) • 8.52 kB
text/typescript
import Axios, { AxiosPromise, AxiosRequestConfig, Method } from "axios";
import * as models from "./models";
export class client {
public username: string;
public key: string;
public apiURL: string;
public uiURL: string;
constructor(
serverURL: string,
webURL: string,
username?: string,
key?: string
) {
this.apiURL = serverURL;
this.uiURL = webURL;
this.username = username;
this.key = key;
}
/**
* General function to send a HTTP GET to the Evergreen API
*
* @param resource - resource to GET, can be a path
* @param params - query params to append to the request URL, in the format {"param": "value"}
* @returns a promise for the caller to handle responses
*/
public getAPIResource(resource: string, params?: object): AxiosPromise {
const url = this.apiURL + "/" + resource + queryString(params);
return Axios(this.formRequest("GET", url, true));
}
/**
* General function to send a HTTP GET to the Evergreen UI
*
* @param resource - resource to GET, can be a path
* @param params - query params to append to the request URL, in the format {"param": "value"}
* @returns a promise for the caller to handle responses
*/
public getUIResource(resource: string, params?: object): AxiosPromise {
const url = this.uiURL + "/" + resource + queryString(params);
return Axios(this.formRequest("GET", url, false));
}
/**
* General function to send a HTTP POST to Evergreen
*
* @param resource - resource to POST to, can be a path
* @param body - body of the request, usually as an object
* @returns a promise for the caller to handle responses
*/
public postAPIResource(resource: string, body: any): AxiosPromise {
const url = this.apiURL + "/" + resource;
return Axios(this.formRequest("POST", url, true, body));
}
/**
* General function to send a HTTP POST to the Evergreen UI
*
* @param resource - resource to POST to, can be a path
* @param body - body of the request, usually as an object
* @returns a promise for the caller to handle responses
*/
public postUIResource(resource: string, body: any): AxiosPromise {
const url = this.uiURL + "/" + resource;
return Axios(this.formRequest("POST", url, false, body));
}
// routes are below
/**
* Gets all distros
*
* @returns a promise for the caller to handle responses
*/
public getDistros(): AxiosPromise<any> {
// TODO: add type of resp
return this.getAPIResource(apiV2Resource("distros"));
}
/**
* Gets aggregated or detailed stats for tasks that have finished recently
*
* @param verbose - returns task details rather than aggregated stats
* @param lookbackMins - look for tasks that ended at most this many minutes before now
* @param status - task statuses (can be comma-separated list) to filter on
* @returns a promise for the caller to handle responses
*/
public getRecentTasks(
verbose?: boolean,
lookbackMins?: number,
status?: string
): AxiosPromise<any> {
// TODO: add type of resp
const params = {
verbose: verbose,
minutes: lookbackMins,
status: status,
};
return this.getAPIResource(apiV2Resource("status/recent_tasks"), params);
}
/**
* Updates header cookies when given login credentials
*
* @param username - Evergreen user's username
* @param password - Evergreen user's password
* @returns a promise for the caller to handle responses
*/
public getToken(username?: string, password?: string): AxiosPromise<any> {
// TODO: add type of resp
const params = {
username: username,
password: password,
};
return this.postUIResource("login", params);
}
/**
* Gets patches for a particular user
* @param username - Evergreen user's username
* @returns a promise for the caller to handle responses
*/
public getPatches(
username?: string,
page?: number
): AxiosPromise<models.Patches> {
const resource = "json/patches/user/" + username;
const params = {
page: page,
};
return this.getUIResource(resource, params);
}
/**
* Gets patches for a particular project
* @param projectName - Evergreen project name
* @returns a promise for the caller to handle responses
*/
public getProjectPatches(
projectName?: string,
page?: number
): AxiosPromise<models.Patches> {
const resource = `json/patches/project/${projectName}`;
const params = {
page,
};
return this.getUIResource(resource, params);
}
/**
* Gets logs of a particular type for a particular task/
* @param taskId - identifier for the task whose logs we want
* @param type - type of log to return
* @returns a promise for the caller to handle responses
*/
public getLogs(
taskId: string,
type: string,
executionNumber: number
): AxiosPromise<string> {
const params = {
type: type,
text: true,
};
const resource =
"task_log_raw/" + taskId + "/" + executionNumber + queryString(params);
return this.getUIResource(resource);
}
/**
* Gets build for a given build ID
* @param id - build ID whose tasks we want
* @returns a promise for the caller to handle responses
*/
public getBuild(id: string): AxiosPromise<models.Build> {
const resource = "builds/" + id;
return this.getAPIResource(apiV2Resource(resource));
}
/**
* Gets tasks for a given build ID
* @param buildId - build ID whose tasks we want
* @returns a promise for the caller to handle responses
*/
public getTasksForBuild(buildId: string): AxiosPromise<models.APITask[]> {
const resource = "builds/" + buildId + "/tasks";
return this.getAPIResource(apiV2Resource(resource));
}
/**
* Gets tests for a given task ID
* @param taskId - task ID whose tests we want
* @returns a promise for the caller to handle responses
*/
public getTestsForTask(taskId: string): AxiosPromise<models.APITest[]> {
const resource = "tasks/" + taskId + "/tests";
return this.getAPIResource(apiV2Resource(resource));
}
/**
* Gets the admin settings
*
* @param callback - function to process the response
* @returns a promise for the caller to handle responses
*/
public getAdminConfig(): AxiosPromise<models.AdminSettings> {
return this.getAPIResource(apiV2Resource("admin/settings"));
}
/**
* Sets the admin settings
*
* @param callback - function to process the response
* @param settings - settings object to set in the db
* @returns a promise for the caller to handle responses
*/
public setAdminConfig(
settings: models.AdminSettings
): AxiosPromise<models.AdminSettings> {
return this.postAPIResource(apiV2Resource("admin/settings"), settings);
}
/**
* Gets the Evergreen banner message
*
* @param callback - function to process the response
* @returns a promise for the caller to handle responses
*/
public getBanner(): AxiosPromise<any> {
// TODO: add type of resp
return this.getAPIResource(apiV2Resource("admin/banner"));
}
/**
* Sets the Evergreen banner message
*
* @param message - text to set in the banner
* @param theme - color theme to use
* @returns a promise for the caller to handle responses
*/
public setBanner(message: string, theme: string): AxiosPromise<any> {
// TODO: add type of resp
const body = {
banner: message,
theme: theme,
};
return this.postAPIResource(apiV2Resource("admin/settings"), body);
}
// end routes
private formRequest(
method: Method,
url: string,
requireHeaders: boolean,
body?: any
): AxiosRequestConfig {
let headers = {};
if (requireHeaders) {
headers = {
"Api-User": this.username,
"Api-Key": this.key,
};
}
const opts: AxiosRequestConfig = {
headers: headers,
url: url,
withCredentials: true,
method: method,
};
if (body) {
opts.data = body;
}
return opts;
}
}
export function apiV2Resource(resource: string): string {
return "rest/v2/" + resource;
}
export function queryString(params?: object): string {
if (!params || params === {}) {
return "";
}
let queryStr = "?";
for (const key in params) {
if (params[key] !== undefined && params[key] !== null) {
queryStr += key + "=" + params[key] + "&";
}
}
return queryStr.slice(0, -1);
}