diff --git a/.eslintrc.js b/.eslintrc.js
index 148b0fa619..8191939429 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -52,6 +52,7 @@ module.exports = {
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-inferrable-types': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
+ '@typescript-eslint/triple-slash-reference': 'off',
// TODO: enable those rules?
'no-empty': 'off',
diff --git a/@commitlint/prompt-cli/cli.js b/@commitlint/prompt-cli/cli.js
index 16f957e07a..716bb4dde7 100755
--- a/@commitlint/prompt-cli/cli.js
+++ b/@commitlint/prompt-cli/cli.js
@@ -1,10 +1,8 @@
#!/usr/bin/env node
const execa = require('execa');
+const inquirer = require('inquirer');
const {prompter} = require('@commitlint/prompt');
-const _ = undefined;
-const prompt = () => prompter(_, commit);
-
main().catch((err) => {
setTimeout(() => {
throw err;
@@ -21,7 +19,7 @@ function main() {
process.exit(1);
}
})
- .then(() => prompt());
+ .then(() => prompter(inquirer, commit));
}
function isStageEmpty() {
diff --git a/@commitlint/prompt-cli/package.json b/@commitlint/prompt-cli/package.json
index deedb393a5..329eb125f8 100644
--- a/@commitlint/prompt-cli/package.json
+++ b/@commitlint/prompt-cli/package.json
@@ -37,6 +37,7 @@
},
"dependencies": {
"@commitlint/prompt": "^14.1.0",
+ "inquirer": "^6.5.2",
"execa": "^5.0.0"
},
"gitHead": "70f7f4688b51774e7ac5e40e896cdaa3f132b2bc"
diff --git a/@commitlint/prompt/package.json b/@commitlint/prompt/package.json
index 04ed72c757..c421069da7 100644
--- a/@commitlint/prompt/package.json
+++ b/@commitlint/prompt/package.json
@@ -38,15 +38,19 @@
},
"devDependencies": {
"@commitlint/utils": "^14.0.0",
- "commitizen": "4.2.4"
+ "@commitlint/types": "^13.2.0",
+ "@commitlint/config-angular": "^13.2.0",
+ "@types/inquirer": "^6.5.0",
+ "inquirer": "^6.5.2",
+ "commitizen": "^4.2.4"
},
"dependencies": {
"@commitlint/ensure": "^14.1.0",
"@commitlint/load": "^14.1.0",
"@commitlint/types": "^14.0.0",
"chalk": "^4.0.0",
- "throat": "^6.0.0",
- "vorpal": "^1.12.0"
+ "lodash": "^4.17.19",
+ "inquirer": "^6.5.2"
},
"gitHead": "70f7f4688b51774e7ac5e40e896cdaa3f132b2bc"
}
diff --git a/@commitlint/prompt/src/index.ts b/@commitlint/prompt/src/index.ts
index 134c621e59..ca85678b1a 100644
--- a/@commitlint/prompt/src/index.ts
+++ b/@commitlint/prompt/src/index.ts
@@ -1,18 +1,10 @@
-// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
-import vorpal from 'vorpal';
-import input from './input';
+import inquirer from 'inquirer';
+import {input} from './input';
type Commit = (input: string) => void;
-/**
- * Entry point for commitizen
- * @param _ inquirer instance passed by commitizen, unused
- * @param commit callback to execute with complete commit message
- * @return {void}
- */
-export function prompter(_: unknown, commit: Commit): void {
- input(vorpal).then((message) => {
+export function prompter(cz: typeof inquirer, commit: Commit): void {
+ input(cz.prompt).then((message) => {
commit(message);
});
}
diff --git a/@commitlint/prompt/src/input.test.ts b/@commitlint/prompt/src/input.test.ts
new file mode 100644
index 0000000000..cde2a5efb2
--- /dev/null
+++ b/@commitlint/prompt/src/input.test.ts
@@ -0,0 +1,96 @@
+import {Answers, PromptModule, QuestionCollection} from 'inquirer';
+///
+import {input} from './input';
+import chalk from 'chalk';
+
+jest.mock(
+ '@commitlint/load',
+ () => {
+ return () => require('@commitlint/config-angular');
+ },
+ {
+ virtual: true,
+ }
+);
+
+test('should work with all fields filled', async () => {
+ const prompt = stub({
+ 'input-custom': {
+ type: 'fix',
+ scope: 'test',
+ subject: 'subject',
+ body: 'body',
+ footer: 'footer',
+ },
+ });
+ const message = await input(prompt);
+ expect(message).toEqual('fix(test): subject\n' + 'body\n' + 'footer');
+});
+
+test('should work without scope', async () => {
+ const prompt = stub({
+ 'input-custom': {
+ type: 'fix',
+ scope: '',
+ subject: 'subject',
+ body: 'body',
+ footer: 'footer',
+ },
+ });
+ const message = await input(prompt);
+ expect(message).toEqual('fix: subject\n' + 'body\n' + 'footer');
+});
+
+test('should fail without type', async () => {
+ const spy = jest.spyOn(console, 'error').mockImplementation();
+ const prompt = stub({
+ 'input-custom': {
+ type: '',
+ scope: '',
+ subject: '',
+ body: '',
+ footer: '',
+ },
+ });
+ const message = await input(prompt);
+ expect(message).toEqual('');
+ expect(console.error).toHaveBeenCalledTimes(1);
+ expect(console.error).toHaveBeenLastCalledWith(
+ new Error(`⚠ ${chalk.bold('type')} may not be empty.`)
+ );
+ spy.mockRestore();
+});
+
+function stub(config: Record>): PromptModule {
+ const prompt = async (questions: QuestionCollection): Promise => {
+ const result: Answers = {};
+ const resolvedConfig = Array.isArray(questions) ? questions : [questions];
+ for (const promptConfig of resolvedConfig) {
+ const configType = promptConfig.type || 'input';
+ const questions = config[configType];
+ if (!questions) {
+ throw new Error(`Unexpected config type: ${configType}`);
+ }
+ const answer = questions[promptConfig.name!];
+ if (answer == null) {
+ throw new Error(`Unexpected config name: ${promptConfig.name}`);
+ }
+ const validate = promptConfig.validate;
+ if (validate) {
+ const validationResult = validate(answer, result);
+ if (validationResult !== true) {
+ throw new Error(validationResult || undefined);
+ }
+ }
+
+ result[promptConfig.name!] = answer;
+ }
+ return result;
+ };
+ prompt.registerPrompt = () => {
+ return prompt;
+ };
+ prompt.restoreDefaultPrompts = () => true;
+ prompt.prompts = {};
+ return prompt as any as PromptModule;
+}
diff --git a/@commitlint/prompt/src/input.ts b/@commitlint/prompt/src/input.ts
index bb34fcf62f..ff7db40901 100644
--- a/@commitlint/prompt/src/input.ts
+++ b/@commitlint/prompt/src/input.ts
@@ -1,13 +1,13 @@
import load from '@commitlint/load';
-import throat from 'throat';
+import {DistinctQuestion, PromptModule} from 'inquirer';
import format from './library/format';
import getPrompt from './library/get-prompt';
import settings from './settings';
-import {InputSetting, Prompter, Result} from './library/types';
-import {getHasName, getMaxLength, getRules} from './library/utils';
+import type {InputSetting, Result} from './library/types';
-export default input;
+import {getHasName, getMaxLength, getRules} from './library/utils';
+import InputCustomPrompt from './inquirer/InputCustomPrompt';
/**
* Get user input by interactive prompt based on
@@ -15,15 +15,7 @@ export default input;
* @param prompter
* @return commit message
*/
-async function input(prompter: () => Prompter): Promise {
- const results: Result = {
- type: null,
- scope: null,
- subject: null,
- body: null,
- footer: null,
- };
-
+export async function input(prompter: PromptModule): Promise {
const {rules} = await load();
const parts = ['type', 'scope', 'subject', 'body', 'footer'] as const;
const headerParts = ['type', 'scope', 'subject'];
@@ -33,31 +25,28 @@ async function input(prompter: () => Prompter): Promise {
);
const maxLength = getMaxLength(headerLengthRule);
- await Promise.all(
- parts.map(
- throat(1, async (input) => {
- const inputRules = getRules(input, rules);
- const inputSettings: InputSetting = settings[input];
-
- if (headerParts.includes(input) && maxLength < Infinity) {
- inputSettings.header = {
- length: maxLength,
- };
- }
-
- results[input] = await getPrompt(input, {
- rules: inputRules,
- settings: inputSettings,
- results,
- prompter,
- });
- })
- )
- ).catch((err) => {
+ try {
+ const questions: DistinctQuestion[] = [];
+ prompter.registerPrompt('input-custom', InputCustomPrompt);
+
+ for (const input of parts) {
+ const inputSetting: InputSetting = settings[input];
+ const inputRules = getRules(input, rules);
+ if (headerParts.includes(input) && maxLength < Infinity) {
+ inputSetting.header = {
+ length: maxLength,
+ };
+ }
+ const question = getPrompt(input, inputRules, inputSetting);
+ if (question) {
+ questions.push(question);
+ }
+ }
+
+ const results = await prompter(questions);
+ return format(results);
+ } catch (err) {
console.error(err);
return '';
- });
-
- // Return the results
- return format(results);
+ }
}
diff --git a/@commitlint/prompt/src/inquirer/InputCustomPrompt.ts b/@commitlint/prompt/src/inquirer/InputCustomPrompt.ts
new file mode 100644
index 0000000000..036bb78cc3
--- /dev/null
+++ b/@commitlint/prompt/src/inquirer/InputCustomPrompt.ts
@@ -0,0 +1,117 @@
+///
+import chalk from 'chalk';
+import inquirer from 'inquirer';
+import InputPrompt from 'inquirer/lib/prompts/input';
+import observe from 'inquirer/lib/utils/events';
+import {Interface as ReadlineInterface, Key} from 'readline';
+import type {Subscription} from 'rxjs/internal/Subscription';
+
+import Answers = inquirer.Answers;
+import InputCustomOptions = inquirer.InputCustomOptions;
+import SuccessfulPromptStateData = inquirer.prompts.SuccessfulPromptStateData;
+
+interface KeyDescriptor {
+ value: string;
+ key: Key;
+}
+
+export default class InputCustomPrompt<
+ TQuestion extends InputCustomOptions = InputCustomOptions
+> extends InputPrompt {
+ private lineSubscription: Subscription;
+ private readonly tabCompletion: string[];
+
+ constructor(
+ question: TQuestion,
+ readLine: ReadlineInterface,
+ answers: Answers
+ ) {
+ super(question, readLine, answers);
+
+ if (this.opt.log) {
+ this.rl.write(this.opt.log(answers));
+ }
+
+ if (!this.opt.maxLength) {
+ this.throwParamError('maxLength');
+ }
+
+ const events = observe(this.rl);
+ this.lineSubscription = events.keypress.subscribe(
+ this.onKeyPress2.bind(this)
+ );
+ this.tabCompletion = (this.opt.tabCompletion || [])
+ .map((item) => item.value)
+ .sort((a, b) => a.localeCompare(b));
+ }
+
+ onEnd(state: SuccessfulPromptStateData): void {
+ this.lineSubscription.unsubscribe();
+ super.onEnd(state);
+ }
+
+ /**
+ * @see https://nodejs.org/api/readline.html#readline_rl_write_data_key
+ * @see https://nodejs.org/api/readline.html#readline_rl_line
+ */
+ updateLine(line: string): void {
+ this.rl.write(null as any, {ctrl: true, name: 'b'});
+ this.rl.write(null as any, {ctrl: true, name: 'd'});
+ this.rl.write(line.substr(this.rl.line.length));
+ }
+
+ onKeyPress2(e: KeyDescriptor): void {
+ if (e.key.name === 'tab' && this.tabCompletion.length > 0) {
+ let line = this.rl.line.trim();
+ if (line.length > 0) {
+ for (const item of this.tabCompletion) {
+ if (item.startsWith(line) && item !== line) {
+ line = item;
+ break;
+ }
+ }
+ }
+ this.updateLine(line);
+ }
+ }
+
+ measureInput(input: string): number {
+ if (this.opt.filter) {
+ return this.opt.filter(input).length;
+ }
+ return input.length;
+ }
+
+ render(error?: string): void {
+ const answered = this.status === 'answered';
+
+ let message = this.getQuestion();
+ const length = this.measureInput(this.rl.line);
+
+ if (answered) {
+ message += chalk.cyan(this.answer);
+ } else if (this.opt.transformer) {
+ message += this.opt.transformer(this.rl.line, this.answers, {});
+ }
+
+ let bottomContent = '';
+
+ if (error) {
+ bottomContent = chalk.red('>> ') + error;
+ } else if (!answered) {
+ const maxLength = this.opt.maxLength(this.answers);
+ if (maxLength < Infinity) {
+ const lengthRemaining = maxLength - length;
+ const color =
+ lengthRemaining <= 5
+ ? chalk.red
+ : lengthRemaining <= 10
+ ? chalk.yellow
+ : chalk.grey;
+ bottomContent = color(`${lengthRemaining} characters left`);
+ }
+ }
+
+ this.screen.render(message, bottomContent);
+ }
+}
diff --git a/@commitlint/prompt/src/inquirer/inquirer.d.ts b/@commitlint/prompt/src/inquirer/inquirer.d.ts
new file mode 100644
index 0000000000..06d2304ab2
--- /dev/null
+++ b/@commitlint/prompt/src/inquirer/inquirer.d.ts
@@ -0,0 +1,23 @@
+import {Answers, InputQuestionOptions} from 'inquirer';
+
+declare module 'inquirer' {
+ interface InputCustomCompletionOption {
+ value: string;
+ description?: string;
+ }
+
+ export interface InputCustomOptions
+ extends InputQuestionOptions {
+ /**
+ * @inheritdoc
+ */
+ type?: 'input-custom';
+ log?(answers?: T): string;
+ tabCompletion?: InputCustomCompletionOption[];
+ maxLength(answers?: T): number;
+ }
+
+ interface QuestionMap {
+ 'input-custom': InputCustomOptions;
+ }
+}
diff --git a/@commitlint/prompt/src/library/format.test.ts b/@commitlint/prompt/src/library/format.test.ts
new file mode 100644
index 0000000000..ae20b3b1ab
--- /dev/null
+++ b/@commitlint/prompt/src/library/format.test.ts
@@ -0,0 +1,55 @@
+import {Result} from './types';
+import format from './format';
+
+test('should return empty string', () => {
+ const result: Result = {};
+ expect(format(result)).toBe(' ');
+});
+
+test('should omit scope', () => {
+ const result: Result = {
+ type: 'fix',
+ subject: 'test',
+ };
+ expect(format(result)).toBe('fix: test');
+});
+
+test('should include scope', () => {
+ const result: Result = {
+ type: 'fix',
+ scope: 'prompt',
+ subject: 'test',
+ };
+ expect(format(result)).toBe('fix(prompt): test');
+});
+
+test('should include body', () => {
+ const result: Result = {
+ type: 'fix',
+ scope: 'prompt',
+ subject: 'test',
+ body: 'some body',
+ };
+ expect(format(result)).toBe('fix(prompt): test\nsome body');
+});
+
+test('should include footer', () => {
+ const result: Result = {
+ type: 'fix',
+ scope: 'prompt',
+ subject: 'test',
+ footer: 'some footer',
+ };
+ expect(format(result)).toBe('fix(prompt): test\nsome footer');
+});
+
+test('should include body and footer', () => {
+ const result: Result = {
+ type: 'fix',
+ scope: 'prompt',
+ subject: 'test',
+ body: 'some body',
+ footer: 'some footer',
+ };
+ expect(format(result)).toBe('fix(prompt): test\nsome body\nsome footer');
+});
diff --git a/@commitlint/prompt/src/library/format.ts b/@commitlint/prompt/src/library/format.ts
index 54f7cf9355..e2d3076b9b 100644
--- a/@commitlint/prompt/src/library/format.ts
+++ b/@commitlint/prompt/src/library/format.ts
@@ -1,7 +1,5 @@
import chalk from 'chalk';
-import {Result} from './types';
-
-export default format;
+import {Result, ResultPart} from './types';
/**
* Get formatted commit message
@@ -9,21 +7,29 @@ export default format;
* @param debug show debug information in commit message
* @return formatted debug message
*/
-function format(input: Result, debug = false): string {
+export default function format(input: Result, debug = false): string {
+ const defaultInput = {
+ type: undefined,
+ scope: undefined,
+ subject: undefined,
+ body: undefined,
+ footer: undefined,
+ ...input,
+ };
const results = debug
- ? Object.entries(input).reduce((registry, [name, value]) => {
- registry[name as 'type' | 'scope' | 'subject' | 'body' | 'footer'] =
- value === null ? chalk.grey(`<${name}>`) : chalk.bold(value);
+ ? Object.entries(defaultInput).reduce((registry, [name, value]) => {
+ registry[name as ResultPart] =
+ value === undefined ? chalk.grey(`<${name}>`) : chalk.bold(value);
return registry;
}, {})
- : input;
+ : defaultInput;
// Return formatted string
const {type, scope, subject, body, footer} = results;
return [
- `${type}${scope ? '(' : ''}${scope}${scope ? ')' : ''}${
- type || scope ? ':' : ''
- } ${subject}`,
+ `${type || ''}${scope ? `(${scope})` : ''}${type || scope ? ':' : ''} ${
+ subject || ''
+ }`,
body,
footer,
]
diff --git a/@commitlint/prompt/src/library/get-prompt.test.ts b/@commitlint/prompt/src/library/get-prompt.test.ts
deleted file mode 100644
index 831fbcab8a..0000000000
--- a/@commitlint/prompt/src/library/get-prompt.test.ts
+++ /dev/null
@@ -1,100 +0,0 @@
-import getPrompt from './get-prompt';
-import {Prompter, PrompterCommand} from './types';
-
-test('throws without params', () => {
- expect(() => (getPrompt as any)()).toThrow('Missing prompter function');
-});
-
-test('throws with incompatible prompter', () => {
- expect(() =>
- getPrompt('type', {
- prompter: (() => ({})) as any,
- })
- ).toThrow('prompt.removeAllListeners');
-});
-
-test('returns input unaltered without rules', async () => {
- const message = await getPrompt('type', {
- prompter: stub('foobar'),
- });
-
- expect(message).toEqual('foobar');
-});
-
-function stub(input = '') {
- return function stubPrompter(): Prompter {
- const called: any[] = [];
- const actions: any[] = [];
-
- const instanceCommand: PrompterCommand = {
- description(...args) {
- called.push([instanceCommand.description, args]);
- return instanceCommand;
- },
- action(...args) {
- actions.push(args[0]);
- called.push([instanceCommand.action, args]);
- return instanceCommand;
- },
- };
-
- function redraw(...args: any[]): void {
- called.push([instance.log, args]);
- }
- redraw.done = function (...args: any[]) {
- called.push([instance.ui.redraw.done, args]);
- };
-
- const instance: Prompter & {called: any[]} = {
- called,
- addListener(...args): void {
- called.push([instance.addListener, args]);
- },
- catch(...args) {
- called.push([instance.catch, args]);
- return instanceCommand;
- },
- command(...args) {
- called.push([instance.command, args]);
- return instanceCommand;
- },
- exec(...args) {
- called.push([instance.command, args]);
- return Promise.resolve();
- },
- delimiter(...args) {
- called.push([instance.delimiter, args]);
- return instance;
- },
- log(...args) {
- called.push([instance.log, args]);
- return instance;
- },
- removeAllListeners(...args) {
- called.push([instance.removeAllListeners, args]);
- },
- show(...args) {
- called.push([instance.show, args]);
- return instance;
- },
- ui: {
- log(...args) {
- called.push([instance.log, args]);
- },
- input(...args) {
- called.push([instance.log, args]);
- return args[0]!;
- },
- redraw,
- },
- };
-
- setTimeout(() => {
- actions[0]({
- text: Array.isArray(input) ? input : [input],
- });
- }, 0);
-
- return instance;
- };
-}
diff --git a/@commitlint/prompt/src/library/get-prompt.ts b/@commitlint/prompt/src/library/get-prompt.ts
index 73a9cb7f15..81abe7fc73 100644
--- a/@commitlint/prompt/src/library/get-prompt.ts
+++ b/@commitlint/prompt/src/library/get-prompt.ts
@@ -1,6 +1,7 @@
import chalk from 'chalk';
+import {InputCustomOptions} from 'inquirer';
-import type {InputSetting, Prompter, Result, RuleEntry} from './types';
+import type {InputSetting, RuleEntry, Result, ResultPart} from './types';
import format from './format';
import getForcedCaseFn from './get-forced-case-fn';
@@ -8,232 +9,115 @@ import getForcedLeadingFn from './get-forced-leading-fn';
import meta from './meta';
import {
enumRuleIsActive,
- ruleIsNotApplicable,
- ruleIsApplicable,
- ruleIsActive,
getHasName,
getMaxLength,
+ ruleIsActive,
+ ruleIsApplicable,
+ ruleIsNotApplicable,
} from './utils';
+const EOL = '\n';
+
/**
* Get a cli prompt based on rule configuration
* @param type type of the data to gather
- * @param context rules to parse
+ * @param rules
+ * @param settings
* @return prompt instance
*/
export default function getPrompt(
- type: string,
- context: {
- rules?: RuleEntry[];
- settings?: InputSetting;
- results?: Result;
- prompter?: () => Prompter;
- } = {}
-): Promise {
- const {rules = [], settings = {}, results = {}, prompter} = context;
-
- if (typeof prompter !== 'function') {
- throw new TypeError('Missing prompter function in getPrompt context');
- }
-
- const prompt = prompter();
-
- if (typeof prompt.removeAllListeners !== 'function') {
- throw new TypeError(
- 'getPrompt: prompt.removeAllListeners is not a function'
- );
- }
-
- if (typeof prompt.command !== 'function') {
- throw new TypeError('getPrompt: prompt.command is not a function');
- }
-
- if (typeof prompt.catch !== 'function') {
- throw new TypeError('getPrompt: prompt.catch is not a function');
- }
-
- if (typeof prompt.addListener !== 'function') {
- throw new TypeError('getPrompt: prompt.addListener is not a function');
- }
-
- if (typeof prompt.log !== 'function') {
- throw new TypeError('getPrompt: prompt.log is not a function');
- }
-
- if (typeof prompt.delimiter !== 'function') {
- throw new TypeError('getPrompt: prompt.delimiter is not a function');
- }
-
- if (typeof prompt.show !== 'function') {
- throw new TypeError('getPrompt: prompt.show is not a function');
- }
-
- const enumRule = rules.filter(getHasName('enum')).find(enumRuleIsActive);
-
- const emptyRule = rules.find(getHasName('empty'));
-
- const mustBeEmpty =
- emptyRule && ruleIsActive(emptyRule) && ruleIsApplicable(emptyRule);
+ type: ResultPart,
+ rules: RuleEntry[] = [],
+ settings: InputSetting = {}
+): InputCustomOptions | null {
+ const emptyRule = rules.filter(getHasName('empty')).find(ruleIsActive);
- const mayNotBeEmpty =
- emptyRule && ruleIsActive(emptyRule) && ruleIsNotApplicable(emptyRule);
-
- const mayBeEmpty = !mayNotBeEmpty;
+ const mustBeEmpty = emptyRule ? ruleIsApplicable(emptyRule) : false;
if (mustBeEmpty) {
- prompt.removeAllListeners('keypress');
- prompt.removeAllListeners('client_prompt_submit');
- prompt.ui.redraw.done();
- return Promise.resolve(undefined);
+ return null;
}
- const caseRule = rules.find(getHasName('case'));
-
- const forceCaseFn = getForcedCaseFn(caseRule);
+ const required = emptyRule ? ruleIsNotApplicable(emptyRule) : false;
- const leadingBlankRule = rules.find(getHasName('leading-blank'));
-
- const forceLeadingBlankFn = getForcedLeadingFn(leadingBlankRule);
+ const forceCaseFn = getForcedCaseFn(rules.find(getHasName('case')));
+ const forceLeadingBlankFn = getForcedLeadingFn(
+ rules.find(getHasName('leading-blank'))
+ );
const maxLengthRule = rules.find(getHasName('max-length'));
const inputMaxLength = getMaxLength(maxLengthRule);
- const headerLength = settings.header ? settings.header.length : Infinity;
-
- const remainingHeaderLength = headerLength
- ? headerLength -
- [
- results.type,
- results.scope,
- results.scope ? '()' : '',
- results.type && results.scope ? ':' : '',
- results.subject,
- ].join('').length
- : Infinity;
-
- const maxLength = Math.min(inputMaxLength, remainingHeaderLength);
-
- return new Promise((resolve) => {
- // Add the defined enums as sub commands if applicable
- if (enumRule) {
- const [, [, , enums]] = enumRule;
+ const enumRule = rules.filter(getHasName('enum')).find(enumRuleIsActive);
- enums.forEach((enumerable) => {
+ const tabCompletion = enumRule
+ ? enumRule[1][2].map((enumerable) => {
const enumSettings = (settings.enumerables || {})[enumerable] || {};
- prompt
- .command(enumerable)
- .description(enumSettings.description || '')
- .action(() => {
- prompt.removeAllListeners();
- prompt.ui.redraw.done();
- return resolve(forceLeadingBlankFn(forceCaseFn(enumerable)));
- });
+ return {
+ value: forceLeadingBlankFn(forceCaseFn(enumerable)),
+ description: enumSettings.description || '',
+ };
+ })
+ : [];
+
+ const maxLength = (res: Result) => {
+ let remainingHeaderLength = Infinity;
+ if (settings.header && settings.header.length) {
+ const header = format({
+ type: res.type,
+ scope: res.scope,
+ subject: res.subject,
});
- } else {
- prompt.catch('[text...]').action((parameters) => {
- const {text = ''} = parameters;
- prompt.removeAllListeners();
- prompt.ui.redraw.done();
- return resolve(forceLeadingBlankFn(forceCaseFn(text.join(' '))));
- });
- }
-
- if (mayBeEmpty) {
- // Add an easy exit command
- prompt
- .command(':skip')
- .description('Skip the input if possible.')
- .action(() => {
- prompt.removeAllListeners();
- prompt.ui.redraw.done();
- resolve('');
- });
+ remainingHeaderLength = settings.header.length - header.length;
}
-
- // Handle empty input
- const onSubmit = (input: string) => {
- if (input.length > 0) {
- return;
+ return Math.min(inputMaxLength, remainingHeaderLength);
+ };
+
+ return {
+ type: 'input-custom',
+ name: type,
+ message: `${type}:`,
+ validate(input, answers) {
+ if (input.length > maxLength(answers || {})) {
+ return 'Input contains too many characters!';
}
-
- // Show help if enum is defined and input may not be empty
- if (mayNotBeEmpty) {
- prompt.ui.log(chalk.yellow(`⚠ ${chalk.bold(type)} may not be empty.`));
+ if (required && input.trim().length === 0) {
+ // Show help if enum is defined and input may not be empty
+ return `⚠ ${chalk.bold(type)} may not be empty.`;
}
- if (mayBeEmpty) {
- prompt.ui.log(
- chalk.blue(
- `ℹ Enter ${chalk.bold(':skip')} to omit ${chalk.bold(type)}.`
- )
- );
+ const tabValues = tabCompletion.map((item) => item.value);
+ if (
+ input.length > 0 &&
+ tabValues.length > 0 &&
+ !tabValues.includes(input)
+ ) {
+ return `⚠ ${chalk.bold(type)} must be one of ${tabValues.join(', ')}.`;
}
-
- if (enumRule) {
- prompt.exec('help');
+ return true;
+ },
+ tabCompletion,
+ log(answers?: Result) {
+ let prefix =
+ `${chalk.white('Please enter a')} ${chalk.bold(type)}: ${meta({
+ optional: !required,
+ required: required,
+ 'tab-completion': typeof enumRule !== 'undefined',
+ header: typeof settings.header !== 'undefined',
+ 'multi-line': settings.multiline,
+ })}` + EOL;
+
+ if (settings.description) {
+ prefix += chalk.grey(`${settings.description}`) + EOL;
}
- };
-
- const drawRemaining = (length: number) => {
- if (length < Infinity) {
- const colors = [
- {
- threshold: 5,
- color: chalk.red,
- },
- {
- threshold: 10,
- color: chalk.yellow,
- },
- {
- threshold: Infinity,
- color: chalk.grey,
- },
- ];
-
- const el = colors.find((item) => item.threshold >= length);
- const color = el ? el.color : chalk.grey;
- prompt.ui.redraw(color(`${length} characters left`));
+ if (answers) {
+ prefix += EOL + `${format(answers, true)}` + EOL;
}
- };
-
- const onKey = (event: {value: string}) => {
- const sanitized = forceCaseFn(event.value);
- const cropped = sanitized.slice(0, maxLength);
-
- // We **could** do live editing, but there are some quirks to solve
- /* const live = merge({}, results, {
- [type]: cropped
- });
- prompt.ui.redraw(`\n\n${format(live, true)}\n\n`); */
-
- if (maxLength) {
- drawRemaining(maxLength - cropped.length);
- }
- prompt.ui.input(cropped);
- };
-
- prompt.addListener('keypress', onKey);
- prompt.addListener('client_prompt_submit', onSubmit);
-
- prompt.log(
- `\n\nPlease enter a ${chalk.bold(type)}: ${meta({
- optional: !mayNotBeEmpty,
- required: mayNotBeEmpty,
- 'tab-completion': typeof enumRule !== 'undefined',
- header: typeof settings.header !== 'undefined',
- 'multi-line': settings.multiline,
- })}`
- );
-
- if (settings.description) {
- prompt.log(chalk.grey(`${settings.description}\n`));
- }
-
- prompt.log(`\n\n${format(results, true)}\n\n`);
-
- drawRemaining(maxLength);
-
- prompt.delimiter(`❯ ${type}:`).show();
- });
+ return prefix + EOL;
+ },
+ maxLength,
+ transformer(value: string) {
+ return forceCaseFn(value);
+ },
+ };
}
diff --git a/@commitlint/prompt/src/library/types.ts b/@commitlint/prompt/src/library/types.ts
index 0f05c3cd6f..e873e4a36a 100644
--- a/@commitlint/prompt/src/library/types.ts
+++ b/@commitlint/prompt/src/library/types.ts
@@ -19,37 +19,6 @@ export type InputSetting = {
};
};
-export type Result = Partial<
- Record<'type' | 'scope' | 'subject' | 'body' | 'footer', null | string>
->;
+export type ResultPart = 'type' | 'scope' | 'subject' | 'body' | 'footer';
-export interface PrompterCommand {
- description(value: string): this;
- action(
- action: (args: {
- [key: string]: any;
- options: {
- [key: string]: any;
- };
- }) => Promise | void
- ): this;
-}
-
-export interface Prompter {
- delimiter(value: string): this;
- show(): this;
- exec(command: string): Promise;
- log(text?: string): void;
- catch(command: string, description?: string): PrompterCommand;
- command(command: string, description?: string): PrompterCommand;
- removeAllListeners(input?: string): void;
- addListener(input: string, cb: (event: any) => void): void;
- ui: {
- log(text?: string): void;
- input(text?: string): string;
- redraw: {
- (text: string, ...texts: string[]): void;
- done(): void;
- };
- };
-}
+export type Result = Partial>;
diff --git a/@commitlint/prompt/tsconfig.json b/@commitlint/prompt/tsconfig.json
index 2a6d93a0fa..76dd5e38cb 100644
--- a/@commitlint/prompt/tsconfig.json
+++ b/@commitlint/prompt/tsconfig.json
@@ -7,5 +7,5 @@
},
"include": ["./src"],
"exclude": ["./src/**/*.test.ts", "./lib/**/*"],
- "references": [{"path": "../cli"}]
+ "references": [{"path": "../types"}, {"path": "../load"}]
}
diff --git a/yarn.lock b/yarn.lock
index 67775c4cb5..800e6c5643 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1398,6 +1398,18 @@
resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
+"@commitlint/config-angular-type-enum@^13.2.0":
+ version "13.2.0"
+ resolved "https://registry.npmjs.org/@commitlint/config-angular-type-enum/-/config-angular-type-enum-13.2.0.tgz#e3f9b8a07118ed8e060b0b1d04a549f74957634d"
+ integrity sha512-HSP9lzCoHC9+bjJquvByiSUpo0GbAipbjcT6l3Jl6XOzkCjhnUkYcQ2b/O5nXv3mf8Vv/n5k2Sk4nbCYEVpSGQ==
+
+"@commitlint/config-angular@^13.2.0":
+ version "13.2.0"
+ resolved "https://registry.npmjs.org/@commitlint/config-angular/-/config-angular-13.2.0.tgz#78c62551279bdf7ed3a9bf993751f346c42b2944"
+ integrity sha512-mfytI8ZrPt7kuxjZo0ZfFw0bg1zEa2kI6/prVaYJ0FJgOE8EP1Co9Y4DJZEegohfYFeRcFK3radog7WOr2pzdw==
+ dependencies:
+ "@commitlint/config-angular-type-enum" "^13.2.0"
+
"@endemolshinegroup/cosmiconfig-typescript-loader@^3.0.2":
version "3.0.2"
resolved "https://registry.npmjs.org/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz#eea4635828dde372838b0909693ebd9aafeec22d"
@@ -2623,6 +2635,14 @@
dependencies:
"@types/node" "*"
+"@types/inquirer@^6.5.0":
+ version "6.5.0"
+ resolved "https://registry.npmjs.org/@types/inquirer/-/inquirer-6.5.0.tgz#b83b0bf30b88b8be7246d40e51d32fe9d10e09be"
+ integrity sha512-rjaYQ9b9y/VFGOpqBEXRavc3jh0a+e6evAbI31tMda8VlPaSy0AZJfXsvmIe3wklc7W6C3zCSfleuMXR7NOyXw==
+ dependencies:
+ "@types/through" "*"
+ rxjs "^6.4.0"
+
"@types/inquirer@^8.0.0":
version "8.1.0"
resolved "https://registry.npmjs.org/@types/inquirer/-/inquirer-8.1.0.tgz#99fab20fd6fb3ee2b0352042082fe8dbec76bf55"
@@ -3002,11 +3022,6 @@ ansi-colors@^4.1.1:
resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
-ansi-escapes@^1.0.0, ansi-escapes@^1.1.0:
- version "1.4.0"
- resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
- integrity sha1-06ioOzGapneTZisT52HHkRQiMG4=
-
ansi-escapes@^3.2.0:
version "3.2.0"
resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b"
@@ -3294,15 +3309,6 @@ babel-plugin-polyfill-regenerator@^0.2.3:
dependencies:
"@babel/helper-define-polyfill-provider" "^0.2.4"
-babel-polyfill@^6.3.14:
- version "6.26.0"
- resolved "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153"
- integrity sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=
- dependencies:
- babel-runtime "^6.26.0"
- core-js "^2.5.0"
- regenerator-runtime "^0.10.5"
-
babel-preset-current-node-syntax@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b"
@@ -3329,14 +3335,6 @@ babel-preset-jest@^27.2.0:
babel-plugin-jest-hoist "^27.2.0"
babel-preset-current-node-syntax "^1.0.0"
-babel-runtime@^6.26.0:
- version "6.26.0"
- resolved "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
- integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4=
- dependencies:
- core-js "^2.4.0"
- regenerator-runtime "^0.11.0"
-
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
@@ -3614,7 +3612,7 @@ caseless@~0.12.0:
resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
-chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1:
+chalk@^1.1.1:
version "1.1.3"
resolved "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=
@@ -3728,13 +3726,6 @@ cli-boxes@^2.2.0:
resolved "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f"
integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==
-cli-cursor@^1.0.1, cli-cursor@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
- integrity sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=
- dependencies:
- restore-cursor "^1.0.1"
-
cli-cursor@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
@@ -3757,11 +3748,6 @@ cli-truncate@2.1.0, cli-truncate@^2.1.0:
slice-ansi "^3.0.0"
string-width "^4.2.0"
-cli-width@^1.0.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/cli-width/-/cli-width-1.1.1.tgz#a4d293ef67ebb7b88d4a4d42c0ccf00c4d1e366d"
- integrity sha1-pNKT72frt7iNSk1CwMzwDE0eNm0=
-
cli-width@^2.0.0:
version "2.2.1"
resolved "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48"
@@ -3895,42 +3881,42 @@ commander@~2.20.3:
resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
-commitizen@4.2.4, commitizen@^4.2.4:
- version "4.2.4"
- resolved "https://registry.npmjs.org/commitizen/-/commitizen-4.2.4.tgz#a3e5b36bd7575f6bf6e7aa19dbbf06b0d8f37165"
- integrity sha512-LlZChbDzg3Ir3O2S7jSo/cgWp5/QwylQVr59K4xayVq8S4/RdKzSyJkghAiZZHfhh5t4pxunUoyeg0ml1q/7aw==
+commitizen@^4.0.3:
+ version "4.1.2"
+ resolved "https://registry.npmjs.org/commitizen/-/commitizen-4.1.2.tgz#6095eb825fd3f0d3611df88e6803c69b23307e9a"
+ integrity sha512-LBxTQKHbVgroMz9ohpm86N+GfJobonGyvDc3zBGdZazbwCLz2tqLa48Rf2TnAdKx7/06W1i1R3SXUt5QW97qVQ==
dependencies:
cachedir "2.2.0"
cz-conventional-changelog "3.2.0"
dedent "0.7.0"
detect-indent "6.0.0"
- find-node-modules "^2.1.2"
+ find-node-modules "2.0.0"
find-root "1.1.0"
fs-extra "8.1.0"
glob "7.1.4"
- inquirer "6.5.2"
+ inquirer "6.5.0"
is-utf8 "^0.2.1"
- lodash "^4.17.20"
+ lodash "4.17.15"
minimist "1.2.5"
strip-bom "4.0.0"
strip-json-comments "3.0.1"
-commitizen@^4.0.3:
- version "4.1.2"
- resolved "https://registry.npmjs.org/commitizen/-/commitizen-4.1.2.tgz#6095eb825fd3f0d3611df88e6803c69b23307e9a"
- integrity sha512-LBxTQKHbVgroMz9ohpm86N+GfJobonGyvDc3zBGdZazbwCLz2tqLa48Rf2TnAdKx7/06W1i1R3SXUt5QW97qVQ==
+commitizen@^4.2.4:
+ version "4.2.4"
+ resolved "https://registry.npmjs.org/commitizen/-/commitizen-4.2.4.tgz#a3e5b36bd7575f6bf6e7aa19dbbf06b0d8f37165"
+ integrity sha512-LlZChbDzg3Ir3O2S7jSo/cgWp5/QwylQVr59K4xayVq8S4/RdKzSyJkghAiZZHfhh5t4pxunUoyeg0ml1q/7aw==
dependencies:
cachedir "2.2.0"
cz-conventional-changelog "3.2.0"
dedent "0.7.0"
detect-indent "6.0.0"
- find-node-modules "2.0.0"
+ find-node-modules "^2.1.2"
find-root "1.1.0"
fs-extra "8.1.0"
glob "7.1.4"
- inquirer "6.5.0"
+ inquirer "6.5.2"
is-utf8 "^0.2.1"
- lodash "4.17.15"
+ lodash "^4.17.20"
minimist "1.2.5"
strip-bom "4.0.0"
strip-json-comments "3.0.1"
@@ -4156,11 +4142,6 @@ core-js-compat@^3.18.0, core-js-compat@^3.19.0:
browserslist "^4.17.5"
semver "7.0.0"
-core-js@^2.4.0, core-js@^2.5.0:
- version "2.6.12"
- resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
- integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
-
core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
@@ -4984,11 +4965,6 @@ execa@^5.1.1:
signal-exit "^3.0.3"
strip-final-newline "^2.0.0"
-exit-hook@^1.0.0:
- version "1.1.1"
- resolved "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
- integrity sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=
-
exit@^0.1.2:
version "0.1.2"
resolved "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
@@ -5124,14 +5100,6 @@ figlet@^1.1.1:
resolved "https://registry.npmjs.org/figlet/-/figlet-1.5.0.tgz#2db4d00a584e5155a96080632db919213c3e003c"
integrity sha512-ZQJM4aifMpz6H19AW1VqvZ7l4pOE9p7i/3LyxgO2kp+PO/VcDYNqIHEMtkccqIhTXMKci4kjueJr/iCQEaT/Ww==
-figures@^1.3.5:
- version "1.7.0"
- resolved "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
- integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=
- dependencies:
- escape-string-regexp "^1.0.5"
- object-assign "^4.1.0"
-
figures@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
@@ -5993,11 +5961,6 @@ imurmurhash@^0.1.4:
resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
-in-publish@^2.0.0:
- version "2.0.1"
- resolved "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz#948b1a535c8030561cea522f73f78f4be357e00c"
- integrity sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==
-
indent-string@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80"
@@ -6057,24 +6020,6 @@ init-package-json@^2.0.2:
validate-npm-package-license "^3.0.4"
validate-npm-package-name "^3.0.0"
-inquirer@0.11.0:
- version "0.11.0"
- resolved "https://registry.npmjs.org/inquirer/-/inquirer-0.11.0.tgz#7448bfa924092af311d47173bbab990cae2bb027"
- integrity sha1-dEi/qSQJKvMR1HFzu6uZDK4rsCc=
- dependencies:
- ansi-escapes "^1.1.0"
- ansi-regex "^2.0.0"
- chalk "^1.0.0"
- cli-cursor "^1.0.1"
- cli-width "^1.0.1"
- figures "^1.3.5"
- lodash "^3.3.1"
- readline2 "^1.0.1"
- run-async "^0.1.0"
- rx-lite "^3.1.2"
- strip-ansi "^3.0.0"
- through "^2.3.6"
-
inquirer@6.5.0:
version "6.5.0"
resolved "https://registry.npmjs.org/inquirer/-/inquirer-6.5.0.tgz#2303317efc9a4ea7ec2e2df6f86569b734accf42"
@@ -6094,7 +6039,7 @@ inquirer@6.5.0:
strip-ansi "^5.1.0"
through "^2.3.6"
-inquirer@6.5.2:
+inquirer@6.5.2, inquirer@^6.5.2:
version "6.5.2"
resolved "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca"
integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==
@@ -7493,19 +7438,11 @@ lodash.templatesettings@^4.0.0:
dependencies:
lodash._reinterpolate "^3.0.0"
-lodash@4.17.15, lodash@^3.3.1, lodash@^4.17.12, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.5.1, lodash@^4.7.0:
+lodash@4.17.15, lodash@^4.17.12, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0:
version "4.17.21"
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
-log-update@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1"
- integrity sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=
- dependencies:
- ansi-escapes "^1.0.0"
- cli-cursor "^1.0.2"
-
log-update@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1"
@@ -7951,11 +7888,6 @@ multimatch@^5.0.0:
arrify "^2.0.1"
minimatch "^3.0.4"
-mute-stream@0.0.5:
- version "0.0.5"
- resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0"
- integrity sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=
-
mute-stream@0.0.7:
version "0.0.7"
resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
@@ -8041,11 +7973,6 @@ node-int64@^0.4.0:
resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=
-node-localstorage@^0.6.0:
- version "0.6.0"
- resolved "https://registry.npmjs.org/node-localstorage/-/node-localstorage-0.6.0.tgz#45a0601c6932dfde6644a23361f1be173c75d3af"
- integrity sha1-RaBgHGky395mRKIzYfG+Fzx1068=
-
node-modules-regexp@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40"
@@ -8311,11 +8238,6 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0:
dependencies:
wrappy "1"
-onetime@^1.0.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789"
- integrity sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=
-
onetime@^2.0.0:
version "2.0.1"
resolved "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
@@ -9134,15 +9056,6 @@ readdirp@~3.5.0:
dependencies:
picomatch "^2.2.1"
-readline2@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35"
- integrity sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=
- dependencies:
- code-point-at "^1.0.0"
- is-fullwidth-code-point "^1.0.0"
- mute-stream "0.0.5"
-
rechoir@^0.6.2:
version "0.6.2"
resolved "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
@@ -9186,16 +9099,6 @@ regenerate@^1.4.2:
resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a"
integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==
-regenerator-runtime@^0.10.5:
- version "0.10.5"
- resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
- integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=
-
-regenerator-runtime@^0.11.0:
- version "0.11.1"
- resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
- integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
-
regenerator-runtime@^0.13.4:
version "0.13.9"
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
@@ -9412,14 +9315,6 @@ responselike@^1.0.2:
dependencies:
lowercase-keys "^1.0.0"
-restore-cursor@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
- integrity sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=
- dependencies:
- exit-hook "^1.0.0"
- onetime "^1.0.0"
-
restore-cursor@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
@@ -9472,13 +9367,6 @@ rimraf@^3.0.2:
dependencies:
glob "^7.1.3"
-run-async@^0.1.0:
- version "0.1.0"
- resolved "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389"
- integrity sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=
- dependencies:
- once "^1.3.0"
-
run-async@^2.2.0, run-async@^2.4.0:
version "2.4.1"
resolved "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455"
@@ -9491,11 +9379,6 @@ run-parallel@^1.1.9:
dependencies:
queue-microtask "^1.2.2"
-rx-lite@^3.1.2:
- version "3.1.2"
- resolved "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102"
- integrity sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=
-
rxjs@^6.4.0:
version "6.5.4"
resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c"
@@ -10245,7 +10128,7 @@ text-table@^0.2.0:
resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
-throat@^6.0.0, throat@^6.0.1:
+throat@^6.0.1:
version "6.0.1"
resolved "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375"
integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==
@@ -10774,22 +10657,6 @@ verror@1.10.0:
core-util-is "1.0.2"
extsprintf "^1.2.0"
-vorpal@^1.12.0:
- version "1.12.0"
- resolved "https://registry.npmjs.org/vorpal/-/vorpal-1.12.0.tgz#4be7b2a4e48f8fcfc9cf3648c419d311c522159d"
- integrity sha1-S+eypOSPj8/JzzZIxBnTEcUiFZ0=
- dependencies:
- babel-polyfill "^6.3.14"
- chalk "^1.1.0"
- in-publish "^2.0.0"
- inquirer "0.11.0"
- lodash "^4.5.1"
- log-update "^1.0.2"
- minimist "^1.2.0"
- node-localstorage "^0.6.0"
- strip-ansi "^3.0.0"
- wrap-ansi "^2.0.0"
-
w3c-hr-time@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"
@@ -10921,14 +10788,6 @@ wordwrap@^1.0.0:
resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
-wrap-ansi@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
- integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=
- dependencies:
- string-width "^1.0.1"
- strip-ansi "^3.0.1"
-
wrap-ansi@^5.1.0:
version "5.1.0"
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09"