pivotal-flow
Version:
🔀 A command-line tool that helps you manage & automate your workflow to use with PivotalTracker.
174 lines (173 loc) • 6.69 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const axios_1 = __importDefault(require("axios"));
const serialize_javascript_1 = __importDefault(require("serialize-javascript"));
const ora = require("ora");
const console_1 = require("../console");
/**
* An http-client-ish class acting as an interface to the Pivotal REST APIs.
*/
class PivotalClient {
constructor(options) {
this.SERIALIZE_ERROR_OPTIONS = {
space: 2,
};
this.API_TOKEN = options.apiToken;
this.PROJECT_ID = options.projectId;
this.debug = options.debug || false;
this.restClient = axios_1.default.create({
baseURL: 'https://www.pivotaltracker.com/services/v5',
timeout: 10000,
headers: { 'X-TrackerToken': this.API_TOKEN },
});
}
getSpinner(label) {
return ora({
color: 'cyan',
text: label,
});
}
/**
* Logs the error (with help-text, if any) based on debug/no-debug mode.
* Logs response JSON when debug mode is true.
*/
logErrorMessage(axiosError) {
const { response, request } = axiosError;
if (response) {
// non-2xx response
const { status, data, statusText } = response;
const { possible_fix: helpText } = data || {};
if (helpText === 'string') {
// when pivotal provides a 'possible_fix' for their error code
console_1.warning(helpText);
}
this.debug && console_1.error(`Error - ${serialize_javascript_1.default({ status, data, statusText }, this.SERIALIZE_ERROR_OPTIONS)}`);
}
else if (request) {
// network error
console_1.warning(`NetworkError: Please check your internet connection & try again.`);
this.debug && console_1.error(`${serialize_javascript_1.default(request, this.SERIALIZE_ERROR_OPTIONS)})}`);
}
else {
// Something happened in setting up the request that triggered an Error
console_1.warning(`An unknown error occurred. Use the --debug option to get more details.`);
this.debug && console_1.error(`Unknown Error - ${axiosError.message}`);
}
}
/**
* Run an axios, with some common wrappers:
* - log error messages, with help if applicable
* - add a spinner to indicate progress
*/
request(
/** Axios config is transparently passed `to axios.request()` */
config,
/** Labels for the spinner. */
spinnerConfig) {
return __awaiter(this, void 0, void 0, function* () {
const spinner = spinnerConfig && this.getSpinner(spinnerConfig.progress);
const { success: onSuccess, error: onError } = spinnerConfig || {};
try {
spinner && spinner.start();
const { data } = yield this.restClient.request(config);
spinner && spinner.succeed(onSuccess);
return data;
}
catch (errorResponse) {
spinner && spinner.fail(onError);
this.logErrorMessage(errorResponse);
throw new Error('Failed to fetch/update details from/to Pivotal.');
}
});
}
/**
* Get the details about the current user
*/
getProfile() {
return __awaiter(this, void 0, void 0, function* () {
return this.request({
method: 'GET',
url: '/me',
}, {
progress: 'Fetching your profile',
success: 'Profile information received',
error: 'Error fetching profile',
});
});
}
/**
* Fetch stories based on project and pivotal query
* @param {string} query - pivotal search query-string
*/
getStories(query) {
return __awaiter(this, void 0, void 0, function* () {
return this.request({
method: 'GET',
url: `/projects/${this.PROJECT_ID}/search?query=${query}`,
}, { progress: 'Fetching stories' });
});
}
/**
* Fetch a project details for a specified projectId
*/
getProject() {
return __awaiter(this, void 0, void 0, function* () {
return this.request({
method: 'GET',
url: `/projects/${this.PROJECT_ID}`,
}, { progress: `Fetching project details` });
});
}
/**
* Get a single story's details.
* @param id {number} Story id
*/
getStory(id) {
return __awaiter(this, void 0, void 0, function* () {
return this.request({
method: 'GET',
url: `/projects/${this.PROJECT_ID}/stories/${id}`,
}, { progress: `Fetching story [${id}]` });
});
}
/**
* Create a story in the current project.
* @param {PivotalStory} story
*/
createStory(story) {
return __awaiter(this, void 0, void 0, function* () {
return this.request({
method: 'POST',
url: `/projects/${this.PROJECT_ID}/stories`,
data: story,
}, { progress: 'Creating story', success: 'Story created successfully', error: 'Failed to create a story' });
});
}
/**
* Update a single story's details.
* @param id {number} story id
* @param story {PivotalStory} story details to be updated
*/
updateStory(id, story) {
return __awaiter(this, void 0, void 0, function* () {
return this.request({
method: 'PUT',
url: `/projects/${this.PROJECT_ID}/stories/${id}`,
data: story,
}, false);
});
}
}
exports.default = PivotalClient;