@noravel/command 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +569 -0
  3. package/dist/Command.d.ts +27 -0
  4. package/dist/Command.js +86 -0
  5. package/dist/Contracts/Command.d.ts +10 -0
  6. package/dist/Contracts/Command.js +2 -0
  7. package/dist/Contracts/CommandDefinition.d.ts +7 -0
  8. package/dist/Contracts/CommandDefinition.js +2 -0
  9. package/dist/Contracts/InputArgument.d.ts +12 -0
  10. package/dist/Contracts/InputArgument.js +9 -0
  11. package/dist/Contracts/InputOption.d.ts +15 -0
  12. package/dist/Contracts/InputOption.js +10 -0
  13. package/dist/Detector.d.ts +4 -0
  14. package/dist/Detector.js +73 -0
  15. package/dist/Executor.d.ts +4 -0
  16. package/dist/Executor.js +9 -0
  17. package/dist/Inputs/InputArgument.d.ts +13 -0
  18. package/dist/Inputs/InputArgument.js +39 -0
  19. package/dist/Inputs/InputDefinition.d.ts +11 -0
  20. package/dist/Inputs/InputDefinition.js +25 -0
  21. package/dist/Inputs/InputOption.d.ts +18 -0
  22. package/dist/Inputs/InputOption.js +84 -0
  23. package/dist/Inputs/Prompt.d.ts +5 -0
  24. package/dist/Inputs/Prompt.js +178 -0
  25. package/dist/Kernel.d.ts +15 -0
  26. package/dist/Kernel.js +88 -0
  27. package/dist/MakerCommand.d.ts +27 -0
  28. package/dist/MakerCommand.js +68 -0
  29. package/dist/Outputs/Helper.d.ts +7 -0
  30. package/dist/Outputs/Helper.js +61 -0
  31. package/dist/Outputs/OutputColor.d.ts +18 -0
  32. package/dist/Outputs/OutputColor.js +53 -0
  33. package/dist/Outputs/OutputMessage.d.ts +11 -0
  34. package/dist/Outputs/OutputMessage.js +70 -0
  35. package/dist/Outputs/ProgressBar/ProgressBar.d.ts +22 -0
  36. package/dist/Outputs/ProgressBar/ProgressBar.js +98 -0
  37. package/dist/Outputs/ProgressBar/StatusBar.d.ts +11 -0
  38. package/dist/Outputs/ProgressBar/StatusBar.js +10 -0
  39. package/dist/Outputs/ProgressBar/StatusBarFactory.d.ts +5 -0
  40. package/dist/Outputs/ProgressBar/StatusBarFactory.js +20 -0
  41. package/dist/Outputs/ProgressBar/StatusBarNormal.d.ts +6 -0
  42. package/dist/Outputs/ProgressBar/StatusBarNormal.js +19 -0
  43. package/dist/Outputs/ProgressBar/StatusBarVerbose.d.ts +6 -0
  44. package/dist/Outputs/ProgressBar/StatusBarVerbose.js +20 -0
  45. package/dist/Outputs/ProgressBar.d.ts +22 -0
  46. package/dist/Outputs/ProgressBar.js +123 -0
  47. package/dist/Parser.d.ts +9 -0
  48. package/dist/Parser.js +79 -0
  49. package/dist/index.d.ts +5 -0
  50. package/dist/index.js +14 -0
  51. package/dist/src/Command.d.ts +23 -0
  52. package/dist/src/Command.js +61 -0
  53. package/dist/src/Contracts/Command.d.ts +9 -0
  54. package/dist/src/Contracts/Command.js +2 -0
  55. package/dist/src/Contracts/InputArgument.d.ts +11 -0
  56. package/dist/src/Contracts/InputArgument.js +9 -0
  57. package/dist/src/Contracts/InputOption.d.ts +12 -0
  58. package/dist/src/Contracts/InputOption.js +10 -0
  59. package/dist/src/Detector.d.ts +4 -0
  60. package/dist/src/Detector.js +50 -0
  61. package/dist/src/Inputs/InputArgument.d.ts +12 -0
  62. package/dist/src/Inputs/InputArgument.js +36 -0
  63. package/dist/src/Inputs/InputDefinition.d.ts +11 -0
  64. package/dist/src/Inputs/InputDefinition.js +25 -0
  65. package/dist/src/Inputs/InputOption.d.ts +18 -0
  66. package/dist/src/Inputs/InputOption.js +84 -0
  67. package/dist/src/Kernel.d.ts +15 -0
  68. package/dist/src/Kernel.js +87 -0
  69. package/dist/src/MakerCommand.d.ts +27 -0
  70. package/dist/src/MakerCommand.js +68 -0
  71. package/dist/src/Outputs/Helper.d.ts +7 -0
  72. package/dist/src/Outputs/Helper.js +61 -0
  73. package/dist/src/Outputs/OutputColor.d.ts +18 -0
  74. package/dist/src/Outputs/OutputColor.js +53 -0
  75. package/dist/src/Outputs/OutputMessage.d.ts +11 -0
  76. package/dist/src/Outputs/OutputMessage.js +144 -0
  77. package/dist/src/Parser.d.ts +9 -0
  78. package/dist/src/Parser.js +79 -0
  79. package/dist/src/index.d.ts +4 -0
  80. package/dist/src/index.js +12 -0
  81. package/dist/tsconfig.tsbuildinfo +1 -0
  82. package/package.json +35 -0
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_path_1 = __importDefault(require("node:path"));
7
+ const node_fs_1 = __importDefault(require("node:fs"));
8
+ const Command_1 = __importDefault(require("./Command"));
9
+ class MakerCommand extends Command_1.default {
10
+ basePath(dirPath) {
11
+ const basePath = process.cwd();
12
+ if (!dirPath) {
13
+ return basePath;
14
+ }
15
+ dirPath = node_path_1.default.join(basePath, dirPath);
16
+ if (!node_fs_1.default.existsSync(dirPath)) {
17
+ node_fs_1.default.mkdirSync(dirPath, { recursive: true });
18
+ }
19
+ return dirPath;
20
+ }
21
+ async fileName(question = 'What should the file be named?') {
22
+ let name = this.getArgument('name');
23
+ if (!name) {
24
+ name = await this.prompt.ask(question);
25
+ }
26
+ return name;
27
+ }
28
+ makeFile(fileName, dirPath) {
29
+ const filePath = node_path_1.default.join(this.basePath(dirPath), `${fileName}.js`);
30
+ if (node_fs_1.default.existsSync(filePath) && !this.getOption('force')) {
31
+ this.output.error(this.fileAlreadyExists(filePath));
32
+ return;
33
+ }
34
+ node_fs_1.default.mkdirSync(node_path_1.default.dirname(filePath), { recursive: true });
35
+ node_fs_1.default.writeFileSync(filePath, this.contentFile(fileName), 'utf8');
36
+ this.output.success(this.fileCreatedSuccessfully(filePath));
37
+ }
38
+ /**
39
+ * Get the message that the file already exists.
40
+ *
41
+ * @returns {string}
42
+ */
43
+ fileAlreadyExists(filePath) {
44
+ return `File [${filePath}] already exists.`;
45
+ }
46
+ /**
47
+ * Get the message that the file created successfully.
48
+ *
49
+ * @param {string} filePath
50
+ * @returns {string}
51
+ */
52
+ fileCreatedSuccessfully(filePath) {
53
+ return `File [${filePath}] created successfully.`;
54
+ }
55
+ /**
56
+ * Get the content of the file.
57
+ *
58
+ * @param {string} fileName
59
+ * @returns {string}
60
+ */
61
+ contentFile(fileName) {
62
+ return '';
63
+ }
64
+ async handle() {
65
+ //
66
+ }
67
+ }
68
+ exports.default = MakerCommand;
@@ -0,0 +1,7 @@
1
+ import Command from '../Contracts/Command';
2
+ import InputDefinition from '../Inputs/InputDefinition';
3
+ export default class Helper {
4
+ showHelp(name: string, description: string, definition: InputDefinition): void;
5
+ showHelpForMain(commands: Command[]): void;
6
+ showExplanation(command: string, explanation: string): string;
7
+ }
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const OutputColor_1 = __importDefault(require("./OutputColor"));
7
+ const MAX_LENGTH = 25;
8
+ class Helper {
9
+ showHelp(name, description, definition) {
10
+ console.log(OutputColor_1.default.yellow('Description:'));
11
+ console.log(` ${description}`);
12
+ console.log('');
13
+ const argumentDefinition = definition.getArguments();
14
+ console.log(OutputColor_1.default.yellow('Usage:'));
15
+ console.log(` ${name} [options] [--] ${argumentDefinition.map((argument) => `<${argument.getName()}>`).join(' ')}`);
16
+ console.log('');
17
+ if (argumentDefinition.length) {
18
+ console.log(OutputColor_1.default.yellow('Arguments:'));
19
+ argumentDefinition.forEach((argument) => {
20
+ console.log(OutputColor_1.default.green(` ${argument.getName()} `) +
21
+ `${' '.repeat(MAX_LENGTH - argument.getName().length - 2)}${argument.getDescription()}`);
22
+ });
23
+ console.log('');
24
+ }
25
+ const optionDefinition = definition.getOptions();
26
+ if (optionDefinition.length) {
27
+ console.log(OutputColor_1.default.yellow('Options:'));
28
+ optionDefinition.forEach((option) => {
29
+ let shortcut = option.getShortcut();
30
+ if (Array.isArray(shortcut)) {
31
+ shortcut = shortcut.map((item) => `-${item}`).join(', ') + ',';
32
+ }
33
+ else if (shortcut) {
34
+ shortcut = `-${shortcut},`;
35
+ }
36
+ else {
37
+ shortcut = ' ';
38
+ }
39
+ console.log(OutputColor_1.default.green(this.showExplanation(`${shortcut} --${option.getName()}`, option.getDescription())));
40
+ });
41
+ console.log('');
42
+ }
43
+ }
44
+ showHelpForMain(commands) {
45
+ console.log(OutputColor_1.default.yellow('Usage:'));
46
+ console.log(OutputColor_1.default.green(' command [arguments] [--options]'));
47
+ console.log('');
48
+ console.log(OutputColor_1.default.yellow('Available commands:'));
49
+ commands.forEach((command) => {
50
+ console.log(OutputColor_1.default.green(this.showExplanation(command.getName(), command.getDescription())));
51
+ });
52
+ console.log('');
53
+ console.log(OutputColor_1.default.yellow('Options:'));
54
+ console.log(OutputColor_1.default.green(this.showExplanation('-h, --help', 'Show this help message')));
55
+ console.log(OutputColor_1.default.green(this.showExplanation('-v, --version', 'Display the version of Noravel Command')));
56
+ }
57
+ showExplanation(command, explanation) {
58
+ return ` ${command}${' '.repeat(MAX_LENGTH - command.length - 2)}${explanation}`;
59
+ }
60
+ }
61
+ exports.default = Helper;
@@ -0,0 +1,18 @@
1
+ export default class OutputColor {
2
+ static black(message: string): string;
3
+ static red(message: string): string;
4
+ static green(message: string): string;
5
+ static yellow(message: string): string;
6
+ static blue(message: string): string;
7
+ static magenta(message: string): string;
8
+ static cyan(message: string): string;
9
+ static white(message: string): string;
10
+ static bgBlack(message: string): string;
11
+ static bgRed(message: string): string;
12
+ static bgGreen(message: string): string;
13
+ static bgYellow(message: string): string;
14
+ static bgBlue(message: string): string;
15
+ static bgMagenta(message: string): string;
16
+ static bgCyan(message: string): string;
17
+ static bgWhite(message: string): string;
18
+ }
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class OutputColor {
4
+ static black(message) {
5
+ return `\x1b[30m${message}\x1b[0m`;
6
+ }
7
+ static red(message) {
8
+ return `\x1b[31m${message}\x1b[0m`;
9
+ }
10
+ static green(message) {
11
+ return `\x1b[32m${message}\x1b[0m`;
12
+ }
13
+ static yellow(message) {
14
+ return `\x1b[33m${message}\x1b[0m`;
15
+ }
16
+ static blue(message) {
17
+ return `\x1b[34m${message}\x1b[0m`;
18
+ }
19
+ static magenta(message) {
20
+ return `\x1b[35m${message}\x1b[0m`;
21
+ }
22
+ static cyan(message) {
23
+ return `\x1b[36m${message}\x1b[0m`;
24
+ }
25
+ static white(message) {
26
+ return `\x1b[37m${message}\x1b[0m`;
27
+ }
28
+ static bgBlack(message) {
29
+ return `\x1b[40m${message}\x1b[0m`;
30
+ }
31
+ static bgRed(message) {
32
+ return `\x1b[41m${message}\x1b[0m`;
33
+ }
34
+ static bgGreen(message) {
35
+ return `\x1b[42m${message}\x1b[0m`;
36
+ }
37
+ static bgYellow(message) {
38
+ return `\x1b[43m${message}\x1b[0m`;
39
+ }
40
+ static bgBlue(message) {
41
+ return `\x1b[44m${message}\x1b[0m`;
42
+ }
43
+ static bgMagenta(message) {
44
+ return `\x1b[45m${message}\x1b[0m`;
45
+ }
46
+ static bgCyan(message) {
47
+ return `\x1b[46m${message}\x1b[0m`;
48
+ }
49
+ static bgWhite(message) {
50
+ return `\x1b[47m${message}\x1b[0m`;
51
+ }
52
+ }
53
+ exports.default = OutputColor;
@@ -0,0 +1,11 @@
1
+ import ProgressBar from './ProgressBar/ProgressBar';
2
+ export default class OutputMessage {
3
+ info(message: string): void;
4
+ error(message: string): void;
5
+ warning(message: string): void;
6
+ success(message: string): void;
7
+ comment(message: string): void;
8
+ line(message: string, type?: 'line' | 'info' | 'error' | 'warning' | 'success' | 'comment'): void;
9
+ table(heading: string[], rows: string[][]): void;
10
+ createProgressBar(total: number, size?: number | null): ProgressBar;
11
+ }
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const OutputColor_1 = __importDefault(require("./OutputColor"));
7
+ const ProgressBar_1 = __importDefault(require("./ProgressBar/ProgressBar"));
8
+ class OutputMessage {
9
+ info(message) {
10
+ this.line(message, 'info');
11
+ }
12
+ error(message) {
13
+ this.line(message, 'error');
14
+ }
15
+ warning(message) {
16
+ this.line(message, 'warning');
17
+ }
18
+ success(message) {
19
+ this.line(message, 'success');
20
+ }
21
+ comment(message) {
22
+ this.line(message, 'comment');
23
+ }
24
+ line(message, type = 'line') {
25
+ console.log({
26
+ line: (message) => message,
27
+ info: OutputColor_1.default.cyan,
28
+ error: OutputColor_1.default.red,
29
+ warning: OutputColor_1.default.yellow,
30
+ success: OutputColor_1.default.green,
31
+ comment: OutputColor_1.default.white,
32
+ }[type](message));
33
+ }
34
+ table(heading, rows) {
35
+ const terminalWidth = process.stdout.columns;
36
+ const widthColumns = heading.map(h => h.length + 3);
37
+ for (const row of rows) {
38
+ for (let i = 0; i < row.length; i++) {
39
+ if (row[i].length + 3 > widthColumns[i]) {
40
+ widthColumns[i] = row[i].length + 3;
41
+ }
42
+ }
43
+ }
44
+ let totalWidthColumns = widthColumns.reduce((total, width) => total + width, 1);
45
+ if (terminalWidth < totalWidthColumns) {
46
+ totalWidthColumns = terminalWidth;
47
+ }
48
+ let line = '+';
49
+ let th = '|';
50
+ for (let i = 0; i < heading.length; i++) {
51
+ line += '-'.repeat(widthColumns[i] - 1) + '+';
52
+ th += ' ' + OutputColor_1.default.green(`${heading[i]}`.padEnd(widthColumns[i] - 3)) + ' |';
53
+ }
54
+ console.log(line);
55
+ console.log(th);
56
+ console.log(line);
57
+ for (const row of rows) {
58
+ let tr = '|';
59
+ for (let i = 0; i < row.length; i++) {
60
+ tr += ' ' + `${row[i]}`.padEnd(widthColumns[i] - 3) + ' |';
61
+ }
62
+ console.log(tr);
63
+ }
64
+ console.log(line);
65
+ }
66
+ createProgressBar(total, size = null) {
67
+ return new ProgressBar_1.default(total, size);
68
+ }
69
+ }
70
+ exports.default = OutputMessage;
@@ -0,0 +1,22 @@
1
+ export type ProgressBarFormat = 'normal' | 'verbose' | 'minimal';
2
+ export default class ProgressBar {
3
+ private total;
4
+ current: number;
5
+ startTime: number | null;
6
+ private size;
7
+ private progressStyle;
8
+ private format;
9
+ constructor(total: number, size?: number | null);
10
+ setTotal(total: number): void;
11
+ getTotal(): number;
12
+ setFormat(format: 'normal' | 'verbose' | 'minimal'): void;
13
+ setSize(size: number): void;
14
+ getSize(): number;
15
+ start(message?: string): void;
16
+ advance(): null | undefined;
17
+ finish(message?: string): void;
18
+ private getStatusBar;
19
+ useShapeProgress(): void;
20
+ useArrowProgress(): void;
21
+ useBlockProgress(): void;
22
+ }
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const StatusBarFactory_1 = require("./StatusBarFactory");
4
+ const ARROW_PROGRESS_STYLE = {
5
+ complete: '=',
6
+ incomplete: '-',
7
+ head: '>',
8
+ };
9
+ const SHAPE_PROGRESS_STYLE = {
10
+ complete: '#',
11
+ incomplete: '_',
12
+ head: '#',
13
+ };
14
+ const BLOCK_PROGRESS_STYLE = {
15
+ complete: '█',
16
+ incomplete: '░',
17
+ head: '█',
18
+ };
19
+ class ProgressBar {
20
+ total;
21
+ current = 0;
22
+ startTime = null;
23
+ size;
24
+ progressStyle = ARROW_PROGRESS_STYLE;
25
+ format = 'normal';
26
+ constructor(total, size = null) {
27
+ this.total = total;
28
+ this.size = size === null ? process.stdout.columns : size;
29
+ }
30
+ setTotal(total) {
31
+ this.total = total;
32
+ }
33
+ getTotal() {
34
+ return this.total;
35
+ }
36
+ setFormat(format) {
37
+ if (!['normal', 'verbose', 'minimal'].includes(format)) {
38
+ return;
39
+ }
40
+ this.format = format;
41
+ }
42
+ setSize(size) {
43
+ const terminalWidth = process.stdout.columns;
44
+ if (terminalWidth < size) {
45
+ this.size = terminalWidth;
46
+ }
47
+ else {
48
+ this.size = size;
49
+ }
50
+ }
51
+ getSize() {
52
+ return this.size;
53
+ }
54
+ start(message = '') {
55
+ this.current = 0;
56
+ this.startTime = new Date().getTime() / 1000;
57
+ console.log(message);
58
+ }
59
+ advance() {
60
+ this.current++;
61
+ if (this.total < this.current || this.startTime === null) {
62
+ return null;
63
+ }
64
+ process.stdout.write(this.getStatusBar());
65
+ if (this.current === this.total) {
66
+ process.stdout.write('\n');
67
+ }
68
+ }
69
+ finish(message = '') {
70
+ this.current = this.total;
71
+ console.log(message);
72
+ }
73
+ getStatusBar() {
74
+ const perc = this.current / this.total;
75
+ if (this.format === 'minimal') {
76
+ return '\rProgress: ' + (perc * 100).toFixed(1) + '%';
77
+ }
78
+ let statusBarInfo = StatusBarFactory_1.StatusBarFactory.create(this.format, this).getInfo(perc);
79
+ let bar = Math.floor(perc * statusBarInfo.size);
80
+ let statusBar = statusBarInfo.prefix + this.progressStyle.complete.repeat(bar);
81
+ if (bar < statusBarInfo.size) {
82
+ statusBar += this.progressStyle.head;
83
+ statusBar += this.progressStyle.incomplete.repeat(statusBarInfo.size - bar - 1);
84
+ }
85
+ statusBar += statusBarInfo.suffix;
86
+ return statusBar;
87
+ }
88
+ useShapeProgress() {
89
+ this.progressStyle = SHAPE_PROGRESS_STYLE;
90
+ }
91
+ useArrowProgress() {
92
+ this.progressStyle = ARROW_PROGRESS_STYLE;
93
+ }
94
+ useBlockProgress() {
95
+ this.progressStyle = BLOCK_PROGRESS_STYLE;
96
+ }
97
+ }
98
+ exports.default = ProgressBar;
@@ -0,0 +1,11 @@
1
+ import ProgressBar from './ProgressBar';
2
+ export type StatusBarInfo = {
3
+ prefix: string;
4
+ suffix: string;
5
+ size: number;
6
+ };
7
+ export declare abstract class StatusBar {
8
+ protected progressbar: ProgressBar;
9
+ constructor(progressbar: ProgressBar);
10
+ abstract getInfo(perc: number): StatusBarInfo;
11
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StatusBar = void 0;
4
+ class StatusBar {
5
+ progressbar;
6
+ constructor(progressbar) {
7
+ this.progressbar = progressbar;
8
+ }
9
+ }
10
+ exports.StatusBar = StatusBar;
@@ -0,0 +1,5 @@
1
+ import ProgressBar, { ProgressBarFormat } from "./ProgressBar";
2
+ import { StatusBar } from "./StatusBar";
3
+ export declare class StatusBarFactory {
4
+ static create(type: ProgressBarFormat, progressbar: ProgressBar): StatusBar;
5
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.StatusBarFactory = void 0;
7
+ const StatusBarNormal_1 = __importDefault(require("./StatusBarNormal"));
8
+ const StatusBarVerbose_1 = __importDefault(require("./StatusBarVerbose"));
9
+ class StatusBarFactory {
10
+ static create(type, progressbar) {
11
+ switch (type) {
12
+ case 'verbose':
13
+ return new StatusBarVerbose_1.default(progressbar);
14
+ case 'normal':
15
+ default:
16
+ return new StatusBarNormal_1.default(progressbar);
17
+ }
18
+ }
19
+ }
20
+ exports.StatusBarFactory = StatusBarFactory;
@@ -0,0 +1,6 @@
1
+ import { StatusBar, StatusBarInfo } from './StatusBar';
2
+ import ProgressBar from './ProgressBar';
3
+ export default class StatusBarNormal extends StatusBar {
4
+ constructor(progressbar: ProgressBar);
5
+ getInfo(perc: number): StatusBarInfo;
6
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const StatusBar_1 = require("./StatusBar");
4
+ class StatusBarNormal extends StatusBar_1.StatusBar {
5
+ constructor(progressbar) {
6
+ super(progressbar);
7
+ }
8
+ getInfo(perc) {
9
+ const currentStr = this.progressbar.current.toString();
10
+ const totalStr = this.progressbar.getTotal().toString();
11
+ const padding = totalStr.length * 2 + 2 - (totalStr.length + currentStr.length + 1);
12
+ const prefix = '\r' + `${currentStr}/${totalStr}` + ' '.repeat(padding) + '[';
13
+ const disp = `${(perc * 100).toFixed(1)}%`;
14
+ const suffix = ']' + ' '.repeat(6 - disp.length) + `${disp}%`;
15
+ const size = this.progressbar.getSize() - prefix.length - suffix.length - 2;
16
+ return { prefix, suffix, size };
17
+ }
18
+ }
19
+ exports.default = StatusBarNormal;
@@ -0,0 +1,6 @@
1
+ import { StatusBar, StatusBarInfo } from './StatusBar';
2
+ import ProgressBar from './ProgressBar';
3
+ export default class StatusBarVerbose extends StatusBar {
4
+ constructor(progressbar: ProgressBar);
5
+ getInfo(perc: number): StatusBarInfo;
6
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const StatusBar_1 = require("./StatusBar");
4
+ class StatusBarVerbose extends StatusBar_1.StatusBar {
5
+ constructor(progressbar) {
6
+ super(progressbar);
7
+ }
8
+ getInfo(perc) {
9
+ const elapsed = (new Date().getTime() / 1000) - this.progressbar.startTime;
10
+ const rate = this.progressbar.current > 0 ? elapsed / this.progressbar.current : 0;
11
+ const left = this.progressbar.getTotal() - this.progressbar.current;
12
+ const eta = (rate * left).toFixed(1);
13
+ const disp = (perc * 100).toFixed(1);
14
+ const prefix = '\r[';
15
+ const suffix = `] ${disp}% ${this.progressbar.current}/${this.progressbar.getTotal()} remaining: ${eta}s. elapsed: ${elapsed.toFixed(1)}s.`;
16
+ const size = this.progressbar.getSize() - suffix.length - 1;
17
+ return { prefix, suffix, size };
18
+ }
19
+ }
20
+ exports.default = StatusBarVerbose;
@@ -0,0 +1,22 @@
1
+ export default class ProgressBar {
2
+ private total;
3
+ current: number;
4
+ startTime: number | null;
5
+ private size;
6
+ private progressStyle;
7
+ private format;
8
+ constructor(total: number, size?: number | null);
9
+ setTotal(total: number): void;
10
+ getTotal(): number;
11
+ setFormat(format: 'normal' | 'verbose' | 'minimal'): void;
12
+ setSize(size: number): void;
13
+ getSize(): number;
14
+ start(message?: string): void;
15
+ advance(): null | undefined;
16
+ finish(message?: string): void;
17
+ private getStatusBarNormal;
18
+ private getStatusBarVerbose;
19
+ private getStatusBarMinimal;
20
+ useShapeProgress(): void;
21
+ useArrowProgress(): void;
22
+ }
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ARROW_PROGRESS_STYLE = {
4
+ complete: '=',
5
+ incomplete: '-',
6
+ head: '>',
7
+ };
8
+ const SHAPE_PROGRESS_STYLE = {
9
+ complete: '#',
10
+ incomplete: '_',
11
+ head: '#',
12
+ };
13
+ class ProgressBar {
14
+ total;
15
+ current = 0;
16
+ startTime = null;
17
+ size;
18
+ progressStyle = ARROW_PROGRESS_STYLE;
19
+ format = 'normal';
20
+ constructor(total, size = null) {
21
+ this.total = total;
22
+ this.size = size === null ? process.stdout.columns : size;
23
+ }
24
+ setTotal(total) {
25
+ this.total = total;
26
+ }
27
+ getTotal() {
28
+ return this.total;
29
+ }
30
+ setFormat(format) {
31
+ this.format = format;
32
+ }
33
+ setSize(size) {
34
+ const terminalWidth = process.stdout.columns;
35
+ if (terminalWidth < size) {
36
+ this.size = terminalWidth;
37
+ }
38
+ else {
39
+ this.size = size;
40
+ }
41
+ }
42
+ getSize() {
43
+ return this.size;
44
+ }
45
+ start(message = '') {
46
+ this.current = 0;
47
+ this.startTime = new Date().getTime() / 1000;
48
+ console.log(message);
49
+ }
50
+ advance() {
51
+ this.current++;
52
+ if (this.total < this.current || this.startTime === null) {
53
+ return null;
54
+ }
55
+ let now = new Date().getTime() / 1000;
56
+ let perc = this.current / this.total;
57
+ let statusBar = '';
58
+ switch (this.format) {
59
+ case 'verbose':
60
+ statusBar = this.getStatusBarVerbose(now, perc);
61
+ break;
62
+ case 'minimal':
63
+ statusBar = this.getStatusBarMinimal(now, perc);
64
+ break;
65
+ case 'normal':
66
+ default:
67
+ statusBar = this.getStatusBarNormal(now, perc);
68
+ break;
69
+ }
70
+ process.stdout.write(statusBar);
71
+ if (this.current === this.total) {
72
+ process.stdout.write('\n');
73
+ }
74
+ }
75
+ finish(message = '') {
76
+ this.current = this.total;
77
+ console.log(message);
78
+ }
79
+ getStatusBarNormal(now, perc) {
80
+ const size = this.getSize() - 60;
81
+ let bar = Math.floor(perc * size);
82
+ const currentStr = this.current.toString();
83
+ const totalStr = this.total.toString();
84
+ const padding = (totalStr.length * 2 + 2) - (totalStr.length + currentStr.length + 1);
85
+ let statusBar = '\r' + `${this.current}/${this.total}` + ' '.repeat(padding) + '[';
86
+ statusBar += this.progressStyle.complete.repeat(bar);
87
+ if (bar < size) {
88
+ statusBar += this.progressStyle.head;
89
+ statusBar += this.progressStyle.incomplete.repeat(size - bar - 1);
90
+ }
91
+ let disp = (perc * 100).toFixed(1);
92
+ statusBar += `] ${disp}%`;
93
+ return statusBar;
94
+ }
95
+ getStatusBarVerbose(now, perc) {
96
+ const size = this.getSize() - 60;
97
+ let bar = Math.floor(perc * size);
98
+ let statusBar = '\r[';
99
+ statusBar += this.progressStyle.complete.repeat(bar);
100
+ if (bar < size) {
101
+ statusBar += this.progressStyle.head;
102
+ statusBar += this.progressStyle.incomplete.repeat(size - bar - 1);
103
+ }
104
+ let disp = (perc * 100).toFixed(1);
105
+ statusBar += `] ${disp}% ${this.current}/${this.total}`;
106
+ let elapsed = now - this.startTime;
107
+ let rate = this.current > 0 ? elapsed / this.current : 0;
108
+ let left = this.total - this.current;
109
+ let eta = (rate * left).toFixed(1);
110
+ statusBar += ` remaining: ${eta}s. elapsed: ${elapsed.toFixed(1)}s.`;
111
+ return statusBar;
112
+ }
113
+ getStatusBarMinimal(now, perc) {
114
+ return '\rProgress: ' + (perc * 100).toFixed(1) + '%';
115
+ }
116
+ useShapeProgress() {
117
+ this.progressStyle = SHAPE_PROGRESS_STYLE;
118
+ }
119
+ useArrowProgress() {
120
+ this.progressStyle = ARROW_PROGRESS_STYLE;
121
+ }
122
+ }
123
+ exports.default = ProgressBar;