Skip to content

Commit

Permalink
feat: Refactoring, Add tslint
Browse files Browse the repository at this point in the history
  • Loading branch information
HazAT committed Nov 8, 2017
1 parent 8a8ea89 commit 4ababb9
Show file tree
Hide file tree
Showing 23 changed files with 299 additions and 160 deletions.
3 changes: 2 additions & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"esbenp.prettier-vscode"
"esbenp.prettier-vscode",
"eg2.tslint"
]
}
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"**/node_modules": true,
"**/bower_components": true,
"**/dist/**": true
}
},
"tslint.autoFixOnSave": true
}
16 changes: 10 additions & 6 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { ProjectType } from './lib/steps';
import { IArgs, ProjectType } from './lib/Constants';
import { run } from './lib/Setup';

const argv = require('yargs')
.boolean('debug')
.option('projectType', {
alias: 'pt',
describe: 'Choose a project type',
choices: Object.keys(ProjectType)
.option('type', {
choices: Object.keys(ProjectType),
describe: 'Choose a project type'
})
.option('url', {
alias: 'u',
default: 'https://sentry.io/'
}).argv;

run(argv);
run(argv as IArgs);
13 changes: 13 additions & 0 deletions lib/Constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export enum ProjectType {
reactNative = 'react-native',
browser = 'browser',
node = 'node'
}

export interface IArgs {
url: string;
debug: boolean;
type: ProjectType;
}

export enum WizardProperties {}
36 changes: 20 additions & 16 deletions lib/Helper.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Chalk from 'chalk';
import { Answers, ui } from 'inquirer';
import { Step, BaseStep } from './steps/Step';
import { IArgs } from './Constants';
import { BaseStep, IStep } from './steps/Step';

function prepareMessage(msg: any) {
if (typeof msg === 'string') {
Expand All @@ -10,6 +11,7 @@ function prepareMessage(msg: any) {
}

export function l(msg: string) {
// tslint:disable-next-line
console.log(msg);
}

Expand All @@ -34,45 +36,47 @@ export function debug(msg: any) {
}

export class BottomBar {
static bar: any;
static interval: NodeJS.Timer;
public static bar: any;
public static interval: NodeJS.Timer;

static show(msg: any) {
let loader = ['/', '|', '\\', '-'];
public static show(msg: any) {
const loader = ['/', '|', '\\', '-'];
let i = 4;
BottomBar.bar = new ui.BottomBar({ bottomBar: loader[i % 4] });
BottomBar.interval = setInterval(() => {
BottomBar.bar.updateBottomBar(`${loader[i++ % 4]} ${msg}`);
}, 100);
}

static hide() {
public static hide() {
clearInterval(BottomBar.interval);
BottomBar.bar.updateBottomBar('');
nl();
BottomBar.bar.close();
}
}

function sanitizeArgs(argv: any) {
let baseUrl = argv.sentryUrl || 'https://sentry.io/';
function sanitizeArgs(argv: IArgs) {
let baseUrl = argv.url;
baseUrl += baseUrl.endsWith('/') ? '' : '/';
argv.sentryUrl = baseUrl;
argv.url = baseUrl;
}

export async function startWizard<M extends Step>(
argv: any,
...steps: { new (debug: boolean): M }[]
export async function startWizard<M extends IStep>(
argv: IArgs,
...steps: Array<{ new (debug: IArgs): M }>
) {
sanitizeArgs(argv);
if (argv.debug) debug(argv);
if (argv.debug) {
debug(argv);
}

try {
await steps.map(step => new step(argv)).reduce(async (answer, step) => {
let prevAnswer = await answer;
const prevAnswer = await answer;

let answers = await step.emit(prevAnswer);
return Object.assign({}, prevAnswer, answers);
const answers = await step.emit(prevAnswer);
return { ...prevAnswer, ...answers };
}, Promise.resolve({}));
} catch (e) {
BottomBar.hide();
Expand Down
5 changes: 3 additions & 2 deletions lib/Setup.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { IArgs } from './Constants';
import { green, red, startWizard } from './Helper';
import * as Step from './steps';
import { startWizard, green, red } from './Helper';

export function run(argv: any) {
export function run(argv: IArgs) {
startWizard(
argv,
Step.Initial,
Expand Down
10 changes: 5 additions & 5 deletions lib/steps/ConfigureProject.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import * as _ from 'lodash';
import { Answers } from 'inquirer';
import { ReactNative } from './configure/ReactNative';
import * as _ from 'lodash';
import { ProjectType } from '../Constants';
import { GenericJavascript } from './configure/GenericJavascript';
import { ProjectType } from './DetectProjectType';
import { ReactNative } from './configure/ReactNative';
import { BaseStep } from './Step';

export class ConfigureProject extends BaseStep {
emit(answers: Answers) {
let projectType: ProjectType = _.get(answers, 'projectType', ProjectType.browser);
public emit(answers: Answers) {
const projectType: ProjectType = _.get(answers, 'projectType', ProjectType.browser);
switch (projectType) {
case ProjectType.reactNative:
return new ReactNative(this.argv).emit(answers);
Expand Down
33 changes: 14 additions & 19 deletions lib/steps/DetectProjectType.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { prompt, Question, Answers } from 'inquirer';
import { BaseStep } from './Step';
import { green } from '../Helper';
import { Answers, prompt, Question } from 'inquirer';
import * as _ from 'lodash';
import { ProjectType } from '../Constants';
import { green } from '../Helper';
import { BaseStep } from './Step';

let projectPackage: any = {};

Expand All @@ -12,25 +13,15 @@ try {
projectPackage = require(`${process.cwd()}/package.json`);
}

export enum ProjectType {
reactNative = 'react-native',
browser = 'browser',
node = 'node'
}

export class DetectProjectType extends BaseStep {
async emit(answers: Answers) {
public async emit(answers: Answers) {
// If we receive project type as an arg we skip asking
if (this.argv.projectType) {
return { projectType: this.argv.projectType };
if (this.argv.type) {
return { projectType: this.argv.type };
}
let projectType = this.tryDetectingProjectType();
const projectType = this.tryDetectingProjectType();
return prompt([
{
type: 'list',
name: 'projectType',
default: projectType,
message: 'What kind of project are you running:',
choices: [
{
name: `Generic Node.js`,
Expand All @@ -44,12 +35,16 @@ export class DetectProjectType extends BaseStep {
name: `React Native`,
value: ProjectType.reactNative
}
]
],
default: projectType,
message: 'What kind of project are you running:',
name: 'projectType',
type: 'list'
}
]);
}

tryDetectingProjectType(): ProjectType | undefined {
public tryDetectingProjectType(): ProjectType | undefined {
if (_.has(projectPackage, 'dependencies.react-native')) {
return ProjectType.reactNative;
}
Expand Down
6 changes: 3 additions & 3 deletions lib/steps/Initial.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Answers } from 'inquirer';
import { BaseStep } from './Step';
import { dim } from '../Helper';
import { BaseStep } from './Step';

let wizardPackage: any = {};
let projectPackage: any = {};
Expand All @@ -14,10 +14,10 @@ try {
}

export class Initial extends BaseStep {
async emit(answers: Answers) {
public async emit(answers: Answers) {
dim('Running Sentry Setup Wizard...');
// TODO: get sentry cli version
let sentryCliVersion = 'TODO';
const sentryCliVersion = 'TODO';
dim(`version: ${wizardPackage.version} | sentry-cli version: ${sentryCliVersion}`);
return {};
}
Expand Down
16 changes: 8 additions & 8 deletions lib/steps/OpenSentry.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import { Answers } from 'inquirer';
import { BaseStep } from './Step';
import { l, green, dim, nl, BottomBar } from '../Helper';
import * as request from 'request-promise';
let open = require('open');
import { BottomBar, dim, green, l, nl } from '../Helper';
import { BaseStep } from './Step';
const open = require('open');

export class OpenSentry extends BaseStep {
async emit(answers: Answers) {
let baseUrl = this.argv.sentryUrl;
public async emit(answers: Answers) {
const baseUrl = this.argv.url;

BottomBar.show('Loading wizard...');
this.debug(`Loading wizard for ${baseUrl}`);

try {
let data = JSON.parse(await request.get(`${baseUrl}api/0/wizard`));
const data = JSON.parse(await request.get(`${baseUrl}api/0/wizard`));

BottomBar.hide();

let urlToOpen = `${baseUrl}account/settings/wizard/${data.hash}/`;
const urlToOpen = `${baseUrl}account/settings/wizard/${data.hash}/`;

open(urlToOpen);
nl();
Expand All @@ -27,7 +27,7 @@ export class OpenSentry extends BaseStep {

return { hash: data.hash };
} catch (e) {
throw `Could not connect to wizard @ ${baseUrl}`;
throw new Error(`Could not connect to wizard @ ${baseUrl}`);
}
}
}
4 changes: 2 additions & 2 deletions lib/steps/Result.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Answers } from 'inquirer';
import { BaseStep } from './Step';
import { green } from '../Helper';
import { BaseStep } from './Step';

export class Result extends BaseStep {
async emit(answers: Answers) {
public async emit(answers: Answers) {
this.debug(JSON.stringify(answers, null, '\t'));
green('🎉 Successfully setup Sentry for your project 🎉');
return {};
Expand Down
16 changes: 8 additions & 8 deletions lib/steps/SentryProjectSelector.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Answers, prompt, Question } from 'inquirer';
import * as _ from 'lodash';
import { prompt, Question, Answers } from 'inquirer';
import { BaseStep } from './Step';
import { dim } from '../Helper';
import { BaseStep } from './Step';

export class SentryProjectSelector extends BaseStep {
async emit(answers: Answers) {
public async emit(answers: Answers) {
this.debug(answers);

if (_.has(answers, 'wizard.projects') && answers.wizard.projects.length === 0) {
throw 'no projects';
throw new Error('no projects');
}

if (answers.wizard.projects.length === 1) {
Expand All @@ -17,15 +17,15 @@ export class SentryProjectSelector extends BaseStep {

return prompt([
{
type: 'list',
name: 'selectedProject',
message: 'Please select your project in Sentry:',
choices: answers.wizard.projects.map((project: any) => {
return {
name: `${project.organization.name} / ${project.name}`,
value: project
};
})
}),
message: 'Please select your project in Sentry:',
name: 'selectedProject',
type: 'list'
}
]);
}
Expand Down
11 changes: 6 additions & 5 deletions lib/steps/Step.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Answers } from 'inquirer';
import { IArgs } from '../Constants';
import { debug, nl } from '../Helper';

export abstract class BaseStep implements Step {
export abstract class BaseStep implements IStep {
protected isDebug: boolean = false;
constructor(protected argv: any = {}) {
constructor(protected argv: IArgs) {
this.isDebug = argv.debug;
}
abstract emit(answers: Answers): Promise<Answers>;
debug(msg: any) {
public abstract emit(answers: Answers): Promise<Answers>;
public debug(msg: any) {
if (this.isDebug) {
nl();
debug(msg);
Expand All @@ -16,6 +17,6 @@ export abstract class BaseStep implements Step {
}
}

export interface Step {
export interface IStep {
emit(answers?: Answers): Promise<Answers>;
}
17 changes: 6 additions & 11 deletions lib/steps/WaitForSentry.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import { Answers } from 'inquirer';
import { BaseStep } from './Step';
import { l, green, dim, nl, BottomBar } from '../Helper';
import * as request from 'request-promise';
import { BottomBar, dim, green, l, nl } from '../Helper';
import { BaseStep } from './Step';

export class WaitForSentry extends BaseStep {
async emit(answers: Answers) {
public async emit(answers: Answers) {
return new Promise(async (resolve, reject) => {
this.debug(answers);

BottomBar.show('Waiting for Sentry...');
let baseUrl = this.argv.sentryUrl;
const baseUrl = this.argv.url;

let that = this;
function poll() {
that
.makeRequest(baseUrl, answers.hash)
request
.get(`${baseUrl}api/0/wizard/${answers.hash}/`)
.then(async (data: any) => {
// Delete the wizard hash since we were able to fetch the data
await request.delete(`${baseUrl}api/0/wizard/${answers.hash}/`);
Expand All @@ -28,8 +27,4 @@ export class WaitForSentry extends BaseStep {
poll();
});
}

makeRequest(url: string, hash: string) {
return request.get(`${url}api/0/wizard/${hash}/`);
}
}
Loading

0 comments on commit 4ababb9

Please sign in to comment.