Skip to content

Commit

Permalink
perf: use prompts instead of inquirer (#5443)
Browse files Browse the repository at this point in the history
  • Loading branch information
janoshrubos authored Dec 18, 2020
1 parent 6de0c3e commit ab24ece
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 105 deletions.
6 changes: 3 additions & 3 deletions lib/common/commands/proxy/proxy-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import { ProxyCommandBase } from "./proxy-base";
import { HttpProtocolToPort } from "../../constants";
import { parse } from "url";
import { platform, EOL } from "os";
import * as prompt from "inquirer";
import { IOptions } from "../../../declarations";
import {
IErrors,
IHostInfo,
IAnalyticsService,
IProxyService,
IProxyLibSettings,
IPrompterQuestion,
} from "../../declarations";
import { IInjector } from "../../definitions/yok";
import { injector } from "../../yok";
Expand Down Expand Up @@ -165,9 +165,9 @@ export class ProxySetCommand extends ProxyCommandBase {

private async getPortFromUserInput(): Promise<number> {
const schemaName = "port";
const schema: prompt.Question = {
const schema: IPrompterQuestion = {
message: "Port",
type: "input",
type: "text",
name: schemaName,
validate: (value: any) => {
return !value || !this.isValidPort(value)
Expand Down
17 changes: 17 additions & 0 deletions lib/common/declarations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
IGoogleAnalyticsData,
} from "./definitions/google-analytics";
import * as child_process from "child_process";
import { Answers } from "prompts";

// tslint:disable-next-line:interface-name
interface Object {
Expand Down Expand Up @@ -829,6 +830,22 @@ interface IPrompterOptions extends IAllowEmpty {
defaultAction?: () => string;
}

interface IPrompterAnswers extends Record<string, any> {}

interface IPrompterQuestion<T extends Answers<any> = Answers<any>> {
type?: string;
name?: string;
message?: string;
default?: any;
prefix?: string;
suffix?: string;
filter?(input: any, answers: T): any;
validate?(
input: any,
answers?: T
): boolean | string | Promise<boolean | string>;
}

interface IAnalyticsSettingsService {
canDoRequest(): Promise<boolean>;
getUserId(): Promise<string>;
Expand Down
39 changes: 17 additions & 22 deletions lib/common/prompter.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import * as prompt from "inquirer";
import * as prompt from "prompts";
import * as helpers from "./helpers";
import * as readline from "readline";
import { ReadStream } from "tty";
import { IAllowEmpty, IPrompterOptions } from "./declarations";
import {
IAllowEmpty,
IPrompterAnswers,
IPrompterOptions,
IPrompterQuestion,
} from "./declarations";
import { injector } from "./yok";
const MuteStream = require("mute-stream");
import * as _ from "lodash";

export class Prompter implements IPrompter {
private descriptionSeparator = "|";
private ctrlcReader: readline.ReadLine;
private muteStreamInstance: any = null;

Expand All @@ -18,12 +22,7 @@ export class Prompter implements IPrompter {
}
}

public async get(questions: prompt.Question[]): Promise<any> {
_.each(questions, (q) => {
q.filter = (selection: string) => {
return selection.split(this.descriptionSeparator)[0].trim();
};
});
public async get(questions: IPrompterQuestion[]): Promise<any> {
try {
this.muteStdout();

Expand Down Expand Up @@ -55,7 +54,7 @@ export class Prompter implements IPrompter {
message: string,
options?: IAllowEmpty
): Promise<string> {
const schema: prompt.Question = {
const schema: IPrompterQuestion = {
message,
type: "password",
name: "password",
Expand All @@ -73,9 +72,9 @@ export class Prompter implements IPrompter {
message: string,
options?: IPrompterOptions
): Promise<string> {
const schema: prompt.Question = {
const schema: IPrompterQuestion = {
message,
type: "input",
type: "text",
name: "inputString",
validate: (value: any) => {
const doesNotAllowEmpty =
Expand All @@ -95,9 +94,9 @@ export class Prompter implements IPrompter {
promptMessage: string,
choices: string[]
): Promise<string> {
const schema: prompt.Answers = {
const schema: IPrompterAnswers = {
message: promptMessage,
type: "list",
type: "select",
name: "userAnswer",
choices,
};
Expand All @@ -110,21 +109,17 @@ export class Prompter implements IPrompter {
promptMessage: string,
choices: { key: string; description: string }[]
): Promise<string> {
const longestKeyLength = choices.concat().sort(function (a, b) {
return b.key.length - a.key.length;
})[0].key.length;
const inquirerChoices = choices.map((choice) => {
return {
name: `${_.padEnd(choice.key, longestKeyLength)} ${
choice.description ? this.descriptionSeparator : ""
} ${choice.description}`,
short: choice.key,
title: choice.key,
value: choice.key,
description: choice.description,
};
});

const schema: any = {
message: promptMessage,
type: "list",
type: "select",
name: "userAnswer",
choices: inquirerChoices,
};
Expand Down
4 changes: 2 additions & 2 deletions lib/definitions/prompter.d.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import * as prompt from "inquirer";
import {
IPrompterOptions,
IAllowEmpty,
IDisposable,
IPrompterQuestion,
} from "../common/declarations";

declare global {
interface IPrompter extends IDisposable {
get(schemas: prompt.Question[]): Promise<any>;
get(schemas: IPrompterQuestion[]): Promise<any>;
getPassword(prompt: string, options?: IAllowEmpty): Promise<string>;
getString(prompt: string, options?: IPrompterOptions): Promise<string>;
promptForChoice(promptMessage: string, choices: string[]): Promise<string>;
Expand Down
109 changes: 35 additions & 74 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit ab24ece

Please sign in to comment.