211 lines
4.7 KiB
TypeScript
211 lines
4.7 KiB
TypeScript
import * as chalk from 'chalk';
|
|
/*
|
|
* Because we don't want to depend on @nrwl/workspace (to speed up the workspace creation)
|
|
* we duplicate the helper functions from @nrwl/workspace in this file.
|
|
*/
|
|
export interface CLIErrorMessageConfig {
|
|
title: string;
|
|
bodyLines?: string[];
|
|
slug?: string;
|
|
}
|
|
|
|
export interface CLIWarnMessageConfig {
|
|
title: string;
|
|
bodyLines?: string[];
|
|
slug?: string;
|
|
}
|
|
|
|
export interface CLINoteMessageConfig {
|
|
title: string;
|
|
bodyLines?: string[];
|
|
}
|
|
|
|
export interface CLISuccessMessageConfig {
|
|
title: string;
|
|
bodyLines?: string[];
|
|
}
|
|
|
|
/**
|
|
* Automatically disable styling applied by chalk if CI=true
|
|
*/
|
|
if (process.env.CI === 'true') {
|
|
(chalk as any).level = 0;
|
|
}
|
|
|
|
class CLIOutput {
|
|
private readonly NX_PREFIX = `${chalk.cyan(
|
|
'>'
|
|
)} ${chalk.reset.inverse.bold.cyan(' NX ')}`;
|
|
/**
|
|
* Longer dash character which forms more of a continuous line when place side to side
|
|
* with itself, unlike the standard dash character
|
|
*/
|
|
private readonly VERTICAL_SEPARATOR =
|
|
'———————————————————————————————————————————————';
|
|
|
|
/**
|
|
* Expose some color and other utility functions so that other parts of the codebase that need
|
|
* more fine-grained control of message bodies are still using a centralized
|
|
* implementation.
|
|
*/
|
|
colors = {
|
|
gray: chalk.gray,
|
|
};
|
|
bold = chalk.bold;
|
|
underline = chalk.underline;
|
|
|
|
private writeToStdOut(str: string) {
|
|
process.stdout.write(str);
|
|
}
|
|
|
|
private writeOutputTitle({
|
|
label,
|
|
title,
|
|
}: {
|
|
label?: string;
|
|
title: string;
|
|
}): void {
|
|
let outputTitle: string;
|
|
if (label) {
|
|
outputTitle = `${this.NX_PREFIX} ${label} ${title}\n`;
|
|
} else {
|
|
outputTitle = `${this.NX_PREFIX} ${title}\n`;
|
|
}
|
|
this.writeToStdOut(outputTitle);
|
|
}
|
|
|
|
private writeOptionalOutputBody(bodyLines?: string[]): void {
|
|
if (!bodyLines) {
|
|
return;
|
|
}
|
|
this.addNewline();
|
|
bodyLines.forEach((bodyLine) => this.writeToStdOut(' ' + bodyLine + '\n'));
|
|
}
|
|
|
|
addNewline() {
|
|
this.writeToStdOut('\n');
|
|
}
|
|
|
|
addVerticalSeparator() {
|
|
this.writeToStdOut(`\n${chalk.gray(this.VERTICAL_SEPARATOR)}\n\n`);
|
|
}
|
|
|
|
addVerticalSeparatorWithoutNewLines() {
|
|
this.writeToStdOut(`${chalk.gray(this.VERTICAL_SEPARATOR)}\n`);
|
|
}
|
|
|
|
error({ title, slug, bodyLines }: CLIErrorMessageConfig) {
|
|
this.addNewline();
|
|
|
|
this.writeOutputTitle({
|
|
label: chalk.reset.inverse.bold.red(' ERROR '),
|
|
title: chalk.bold.red(title),
|
|
});
|
|
|
|
this.writeOptionalOutputBody(bodyLines);
|
|
|
|
/**
|
|
* Optional slug to be used in an Nx error message redirect URL
|
|
*/
|
|
if (slug && typeof slug === 'string') {
|
|
this.addNewline();
|
|
this.writeToStdOut(
|
|
chalk.grey(' ' + 'Learn more about this error: ') +
|
|
'https://errors.nx.dev/' +
|
|
slug +
|
|
'\n'
|
|
);
|
|
}
|
|
|
|
this.addNewline();
|
|
}
|
|
|
|
warn({ title, slug, bodyLines }: CLIWarnMessageConfig) {
|
|
this.addNewline();
|
|
|
|
this.writeOutputTitle({
|
|
label: chalk.reset.inverse.bold.yellow(' WARNING '),
|
|
title: chalk.bold.yellow(title),
|
|
});
|
|
|
|
this.writeOptionalOutputBody(bodyLines);
|
|
|
|
/**
|
|
* Optional slug to be used in an Nx warning message redirect URL
|
|
*/
|
|
if (slug && typeof slug === 'string') {
|
|
this.addNewline();
|
|
this.writeToStdOut(
|
|
chalk.grey(' ' + 'Learn more about this warning: ') +
|
|
'https://errors.nx.dev/' +
|
|
slug +
|
|
'\n'
|
|
);
|
|
}
|
|
|
|
this.addNewline();
|
|
}
|
|
|
|
note({ title, bodyLines }: CLINoteMessageConfig) {
|
|
this.addNewline();
|
|
|
|
this.writeOutputTitle({
|
|
label: chalk.reset.inverse.bold.keyword('orange')(' NOTE '),
|
|
title: chalk.bold.keyword('orange')(title),
|
|
});
|
|
|
|
this.writeOptionalOutputBody(bodyLines);
|
|
|
|
this.addNewline();
|
|
}
|
|
|
|
success({ title, bodyLines }: CLISuccessMessageConfig) {
|
|
this.addNewline();
|
|
|
|
this.writeOutputTitle({
|
|
label: chalk.reset.inverse.bold.green(' SUCCESS '),
|
|
title: chalk.bold.green(title),
|
|
});
|
|
|
|
this.writeOptionalOutputBody(bodyLines);
|
|
|
|
this.addNewline();
|
|
}
|
|
|
|
logSingleLine(message: string) {
|
|
this.addNewline();
|
|
|
|
this.writeOutputTitle({
|
|
title: message,
|
|
});
|
|
|
|
this.addNewline();
|
|
}
|
|
|
|
logCommand(message: string, isCached: boolean = false) {
|
|
this.addNewline();
|
|
|
|
this.writeToStdOut(chalk.bold(`> ${message} `));
|
|
|
|
if (isCached) {
|
|
this.writeToStdOut(chalk.bold.grey(`[retrieved from cache]`));
|
|
}
|
|
|
|
this.addNewline();
|
|
}
|
|
|
|
log({ title, bodyLines }: CLIWarnMessageConfig) {
|
|
this.addNewline();
|
|
|
|
this.writeOutputTitle({
|
|
title: chalk.white(title),
|
|
});
|
|
|
|
this.writeOptionalOutputBody(bodyLines);
|
|
|
|
this.addNewline();
|
|
}
|
|
}
|
|
|
|
export const output = new CLIOutput();
|