-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
executable file
·123 lines (114 loc) · 3.5 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import ora from 'ora'
// import yargs from 'yargs';
import chalk from 'chalk';
import clear from 'clear';
import figlet from 'figlet';
import inquirer from 'inquirer';
import { DefaultActions } from './defaultActions.js'
const defaults = {
font: 'ANSI Shadow',
color: '#FFFFFF', // purple
title: 'CLI Wizard',
caption: '',
errorMessage: 'Unknown Error!',
restartMessage: 'Would you like to perform another action?',
exitMessage: '👋 Venture forth and be awesome! 👋',
// TODO: redefine CLI args
args: {}, // yargs.option('verbose', { alias: 'v', default: false }).argv,
actions: DefaultActions,
};
export class CLI {
constructor(options = {}) {
this.spinner = new ora();
this.args = options.argv || defaults.args;
this.font = options.font || defaults.font;
this.title = options.title || defaults.title;
this.color = options.color || defaults.color;
this.actions = options.actions || defaults.actions;
this.caption = options.caption || defaults.caption;
this.endOnError = options.endOnError || defaults.endOnError;
this.verbose = this.args.verbose || options.verbose || false;
this.mode = (this.verbose ? `Mode: ${chalk.blue('VERBOSE')} |`: '');
this.messages = {
onError: options.errorMessage || defaults.errorMessage,
onExit: options.exitMessage || defaults.exitMessage,
onRestart: options.restartMessage || defaults.restartMessage
};
this.header = chalk
.hex(this.color)
.bold(figlet.textSync(this.title, { font: this.font }).trimEnd());
this.log = {
verbose: (message) => this.verbose && console.info(chalk.blue('VERBOSE:'), message),
info: (message) => console.info(chalk.blue('INFO:'), message),
warning: (message) => console.warn(chalk.yellow('WARNING:'), message),
error: (message) => console.error(chalk.bgRed.black('ERROR:'), chalk.red(message || this.messages.onError)),
success: (message) => console.log(chalk.green('SUCCESS:'), message)
};
this.print = {
separator: (length = 80) => '─'.repeat(length),
header: () => {
console.log('\n');
console.log(this.header);
console.log(this.print.separator());
console.log(this.mode, this.caption);
console.log(this.print.separator());
},
actions: () => {
return this.select(
'Select an action:',
Object.keys(this.actions)
).then((response) => this.actions[response.action](this));
}
};
}
register(action) {
this.actions[action.name] = action.handler;
}
clear() {
return clear();
}
error(e) {
this.log.error(e.message);
if(this.verbose) {
console.error(e.stack);
}
return this.restart();
}
input(message, validate) {
return inquirer.prompt({
type: 'input',
name: 'action',
message,
validate
}).catch(this.error);
}
confirm(message) {
return inquirer.prompt({
type: 'confirm',
name: 'confirm',
message
}).catch(this.error);
}
select(message, choices) {
return inquirer.prompt({
type: 'rawlist',
name: 'action',
message,
choices
}).catch(this.error);
}
start() {
this.clear();
this.print.header();
this.print.actions();
}
async restart(message) {
const input = await this.confirm(message || this.messages.onRestart)
return input.confirm? this.start() : this.quit();
}
quit(message) {
this.log.success(message || this.messages.onExit);
process.exitCode = 0;
}
}
export default CLI;