liferay-npm-bundler-preset-reactjs
Version:
liferay npm bundler preset react
228 lines (203 loc) • 5.38 kB
text/typescript
/**
* SPDX-FileCopyrightText: © 2020 Liferay, Inc. <https://liferay.com>
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
import chalk from 'chalk';
/**
* Formatting options may be added by setting the `LR_FORMAT_OPTS` environment
* variable. It is supposed to be a comma separated list of options.
*
* Valid formatting options are:
*
* * `no-colors`: don't use colors for texts
* * `no-decorations`: don't use font decorations or emojis
*
*/
const lrFormatOpts = (process.env['LR_FORMAT_OPTS'] || '').split(',');
/** Unrolled formatting options */
const opts = {
noColors: lrFormatOpts.indexOf('no-colors') !== -1,
noDecorations: lrFormatOpts.indexOf('no-decorations') !== -1,
};
const verbatim = (...args) => args.join(' ');
/** Chalk formats table */
const fmt = {
bold: opts.noDecorations ? verbatim : chalk.bold,
error: opts.noColors ? verbatim : chalk.hex('#F44'),
info: opts.noColors ? verbatim : chalk.hex('#888'),
question: opts.noColors ? verbatim : chalk.hex('#55F'),
success: opts.noColors ? verbatim : chalk.hex('#0A0'),
title: opts.noColors ? verbatim : chalk.bold.hex('#55F'),
underline: opts.noDecorations ? verbatim : chalk.underline,
warn: opts.noColors ? verbatim : chalk.hex('#CA0'),
};
/**
* Tagged template processor for error messages.
*
* Example of use:
*
* ```ts
* error`
* This is an error message with some ${argument} to show
* `
* ```
*
* @remarks
* Error messages are prepended with a '❌' emoji.
*/
export function error(literals, ...values) {
return fmt.error(format('❌', literals, values));
}
/**
* Tagged template processor for information messages.
*
* Example of use:
*
* ```ts
* info`
* This is an information message with some ${argument} to show
* `
* ```
*
* @remarks
* Error messages are prepended with a 'ℹ️' emoji.
*/
export function info(literals, ...values) {
return fmt.info(format('ℹ️', literals, values));
}
/**
* Print an array of lines separating them with CRs or a single line.
*
* It takes care of removing:
*
* * Words inside `||` if `no-decorations` option is set
*
* And also decorates (unless `no-decorations` is provided):
*
* * URLs starting with `http(s)://` with underline
* * Words inside `{}` with bold
*
* Each passed line is processed by the {@link removeJsFormatWhitespace}
* function.
*/
export function print(lines: string | string[], ...rest: string[]): void {
if (!Array.isArray(lines)) {
lines = [lines];
}
if (rest !== undefined) {
lines.push(...rest);
}
lines = lines.map((line) => {
line = removeJsFormatWhitespace(line);
line = line.replace(/(https?:\/\/[^\s]+)/gm, fmt.underline('$1'));
line = line.replace(/{([^}]*)}/gm, fmt.bold('$1'));
line = line.replace(/\|([^|]*)\|/g, opts.noDecorations ? '' : '$1');
return line;
});
console.log(lines.join('\n'));
}
/**
* Tagged template processor for success messages.
*
* Example of use:
*
* ```ts
* success`
* This is a success message with some ${argument} to show
* `
* ```
*
* @remarks
* Error messages are prepended with a '✔️' emoji.
*/
export function success(literals, ...values) {
return fmt.success(format('✔️', literals, values));
}
/**
* Tagged template processor for question messages.
*
* Example of use:
*
* ```ts
* question`
* Is this a question message with some ${argument} to show?
* `
* ```
*
* @remarks
* Error messages are prepended with a '❓' emoji.
*/
export function question(literals, ...values) {
return fmt.question(format('❓', literals, values));
}
/**
* Tagged template processor for titles.
*
* Example of use:
*
* ```ts
* title`
* This is a title with some ${argument} to show
* `
* ```
*/
export function title(literals, ...values) {
return fmt.title(format('', literals, values));
}
/**
* Tagged template processor for warning messages.
*
* Example of use:
*
* ```ts
* warn`
* This is an warning message with some ${argument} to show
* `
* ```
*
* @remarks
* Error messages are prepended with a '⚠️' emoji.
*/
export function warn(literals, ...values) {
return fmt.warn(format('⚠️', literals, values));
}
/**
* This is an ES6 template unrolling function that optionally prefixes the final
* string with an emoji.
*
* The emoji is treated as a decoration and thus removed if the `no-decorations`
* option is set.
*
* The resulting string is processed by the `removeJsFormatWhitespace` function.
*
* @param emoji an emoji or empty string to prefix the text
*/
function format(emoji: string, literals: string[], values: any[]): string {
let ret: string = literals[0];
for (let i = 0; i < values.length; i++) {
ret += values[i];
if (i + 1 < literals.length) {
ret += literals[i + 1];
}
}
ret = removeJsFormatWhitespace(ret);
ret = (emoji ? `|${emoji} |` : '') + ret;
return ret;
}
/**
* This function removes:
*
* * A leading CR in the first line if it exists
* * Two tabs at the begining of each line
*
* This is to enhance legibility of JS code when it is formatted according to
* the project's rules.
*
* This function is (and must always be) idempotent because it may need to be
* applied several times to the same line.
*/
function removeJsFormatWhitespace(line: string): string {
line = line.replace(/^\n/, '');
line = line.replace(/^\t*/gm, '');
return line;
}