@gypsy-js/cli
Version:
786 lines (713 loc) • 18.1 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var __cli_spinner__ = require('cli-spinner');
var __chalk__ = require('chalk');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n["default"] = e;
return Object.freeze(n);
}
var __cli_spinner____namespace = /*#__PURE__*/_interopNamespace(__cli_spinner__);
var __chalk____default = /*#__PURE__*/_interopDefaultLegacy(__chalk__);
/**
* @file colors.
* @author qivmvip AT gmail DOT com
* @date 2022-03-02
*/
/**
* @type {LoggerColors}
*/
const logger$3 = {
dbg: '#aaabab',
log: '#007799',
inf: '#0099bb',
wrn: '#0088aa',
err: '#ff3333',
};
/**
* @type {IndicatorColors}
*/
const indicator$3 = {
exec: '#77ccbb',
info: '#0088aa',
warn: '#0088aa',
succ: '#00ff00',
fail: '#ff3333',
};
/**
* @type {SpinnerColors}
*/
const spinner$3 = {
spin: '#0099bb',
updt: '#0088aa',
succ: '#00ff00',
fail: '#ff8800',
};
var __colors__ = /*#__PURE__*/Object.freeze({
__proto__: null,
logger: logger$3,
indicator: indicator$3,
spinner: spinner$3
});
/**
* @file Message utilities.
* @author qivmvip AT gmail DOT com.
* @date 2021-03-01
*/
/**
* @type {Builder}
*/
class Builder {
constructor(text) {
this.__text = text;
}
text(text) {
this.__text = text;
}
color(color) {
this.__color = color;
return this;
}
bgColor(bgColor) {
this.__bgColor = bgColor;
return this;
}
bold(bold) {
this.__bold = bold;
return this;
}
italic(italic) {
this.__italic = italic;
return this;
}
underline(underline) {
this.__underline = underline;
return this;
}
/**
* Build a {@link Message} object.
* @returns {Message} a new {@link Message}.
*/
build() {
if (!this.color && !this.bgColor && !this.__bold && !this.__italic && !this.__underline) {
return {
text: this.__text
};
} else {
return {
text: this.__text,
style: {
color: this.__color,
bgColor: this.__bgColor,
bold: this.__bold,
italic: this.__italic,
underline: this.__underline
},
};
}
}
}
/**
* @type {MessagesBuilderFn}
*/
const builder = (text) => {
return new Builder(text);
};
/**
* @type {MessagesRawFn}
*/
const raw = (text) => {
return new Builder(text).build();
};
/**
* @type {MessagesColorizeFn}
*/
const colorize = (text, color) => {
return builder(text).color(color).build();
};
var __messages__ = /*#__PURE__*/Object.freeze({
__proto__: null,
builder: builder,
raw: raw,
colorize: colorize
});
/**
* @file cli library CommonJS entry point.
* @author qivmvip AT gmail DOT com
* @date 2022-02-17
*/
/**
* Get the symbol.
* @param {'logger'|'indicator'|'spinner'} instance
* @param {string} verb
* @param {SymbolsGetOptions} options
* @returns {Message}
*/
const __get__ = (instance, verb, options) => {
const { unicode, colorized, bold } = options || {
unicode: true, colorized: true, bold: true
};
const raw = {
logger: unicode ? {
dbg: 'ν',
log: 'ℹ',
wrn: '⚠',
err: '✖',
} : {
dbg: 'v',
log: 'i',
wrn: '‼',
err: '×',
},
indicator: unicode ? {
exec: '⇒',
info: 'ℹ',
succ: '✔',
fail: '✘',
} : {
exec: 'λ',
info: 'i',
succ: '√',
fail: '×',
},
spinner: unicode ? {
spin: 'æ',
updt: '…',
succ: '✔',
fail: '✘',
} : {
spin: 'æ',
updt: '…',
succ: '√',
fail: '×',
},
};
const builder$1 = builder(raw[instance][verb]);
if (colorized) {
builder$1.color(__colors__[instance][verb]);
}
if (bold) {
builder$1.bold(true);
}
return builder$1.build();
};
/**
* @type {LoggerSymbols}
*/
const logger$2 = {
get: (verb, options) => __get__('logger', verb, options),
};
/**
* @type {IndicatorSymbols}
*/
const indicator$2 = {
get: (verb, options) => __get__('indicator', verb, options),
};
/**
* @type {SpinnerSymbols}
*/
const spinner$2 = {
get: (verb, options) => __get__('spinner', verb, options),
};
var __symbols__ = /*#__PURE__*/Object.freeze({
__proto__: null,
logger: logger$2,
indicator: indicator$2,
spinner: spinner$2
});
/**
* @file Duration utilities.
* @author qivmvip AT gmail DOT com
* @date 2022-03-01
*/
const zh = {
ns: '纳秒',
us: '微秒',
ms: '毫秒',
s: '秒',
m: '分',
h: '小时',
D: '天',
M: '月',
Y: '年',
};
const en = {
ns: 'ns',
us: 'us',
ms: 'ms',
s: 's',
m: 'm',
h: 'h',
D: 'D',
M: 'M',
Y: 'Y',
};
/**
* Format duration to be a human-friendly readable string.
* @param {number} duration The options.
* @param {{i18n: {lang: string;};format: {padding: boolean;keepMilliseconds: boolean;};}} options The options.
* @returns {string} The formatted string.
*/
const readable = (duration, options) => {
// options
if (!options) {
options = {
i18n: {
lang: 'en_US.UTF-8',
},
format: {
padding: false,
keepMilliseconds: true,
},
};
}
// milliseconds per xxx
const SECOND_MS = 1000;
const MINUTE_MS = SECOND_MS * 60;
const HOUR_MS = MINUTE_MS * 60;
const DAY_MS = HOUR_MS * 24;
// unit
const texts = options.i18n && options.i18n.lang.includes('zh') ? zh : en;
const MSECS = texts.ms;
const SECS = texts.s;
const MINS = texts.m;
const HRS = texts.h;
const DAYS = texts.D;
// format, let's go...
let remainder = duration;
// days
const days = Math.trunc(remainder / DAY_MS);
remainder = remainder - (days * DAY_MS);
// hours
const hrs = Math.trunc(remainder / HOUR_MS);
remainder = remainder - (hrs * HOUR_MS);
// minutes
const mins = Math.trunc(remainder / MINUTE_MS);
remainder = remainder - (mins * MINUTE_MS);
// seconds
const secs = Math.trunc(remainder / SECOND_MS);
remainder = remainder - (secs * SECOND_MS);
// milliseconds
const msecs = remainder;
// str
const padding = options && options.format && options.format.padding;
const msecsStr = padding ? msecs.toString().padStart(3, '0') : msecs.toString();
const secsStr = padding ? secs.toString().padStart(2, '0') : secs.toString();
const minsStr = padding ? mins.toString().padStart(2, '0') : mins.toString();
const hrsStr = hrs.toString();
const daysStr = days.toString();
const keepMilliseconds = options && options.format && options.format.keepMilliseconds;
const msStr = keepMilliseconds ? `${msecsStr}${MSECS}` : '';
if (days > 0) {
return `${daysStr}${DAYS}${hrsStr}${HRS}${minsStr}${MINS}${secsStr}${SECS}${msStr}`;
}
if (hrs > 0) {
return `${hrsStr}${HRS}${minsStr}${MINS}${secsStr}${SECS}${msStr}`;
}
if (mins > 0) {
return `${minsStr}${MINS}${secsStr}${SECS}${msStr}`;
}
return `${secsStr}${SECS}${msStr}`;
};
/**
* @file The console.
* @author qivmvip AT gmail DOT com
* @date 2022-03-02
*/
/**
* @typedef {import("./types/index").messages.Message} Message
* @typedef {import("./types/index").Output} Output
*/
const __ctx__ = () => context$1.get();
const __dev__ = () => (
__ctx__() && __ctx__().env && '1' === __ctx__().env.GYPSY_CLI_DEV
);
const __ts__ = () => ((__ctx__() && __ctx__().args) && (
__ctx__().args.options && __ctx__().args.options['gypsy-cli-ts']
));
const __symbol__ = () => ((__ctx__() && __ctx__().args) && (
__ctx__().args.options && __ctx__().args.options['gypsy-cli-symbol']
));
/**
* Stylify message to as a stylish text.
* @param {Message} message
* @returns {string} stylish text.
*/
const __stylify__ = (message) => {
if (message && message.text) {
if (message.style) {
let stylish = __chalk____default["default"];
if (message.style.color) {
stylish = __chalk____default["default"].hex(message.style.color);
}
if (message.style.bgColor) {
stylish = stylish.bgHex(message.style.bgColor);
}
if (message.style.bold) {
stylish = stylish.bold;
}
if (message.style.italic) {
stylish = stylish.italic;
}
if (message.style.underline) {
stylish = stylish.underline;
}
return stylish(message.text);
} else {
return message.text;
}
}
else {
return '';
}
};
const __dbg__ = (output) => (
__dev__() && (console.log(__chalk____default["default"].gray(`[DEV] output => ${JSON.stringify(output)}`)))
);
/**
* format prefix.
* @param {Output} output
* @returns
*/
const __prefix__ = (output) => (
''.concat(
__symbol__() ? `${__stylify__(output.symbol)} ` : ''
).concat(
__ts__() ? `${__stylify__(colorize(output.date.toISOString(), __colors__[output.instance][output.verb]))} ` : ''
)
);
/////////////////////////////////// SPINNER ////////////////////////////////////
let __spinner_ts__ = Date.now();
let __spinner_tag__ = '';
let __logger_idle__ = false;
const __spinner__ = new __cli_spinner____namespace.Spinner({
onTick: (msg) => {
__logger_idle__ = true;
__spinner__.clearLine(__spinner__.stream);
const cost = Date.now() - __spinner_ts__;
__spinner__.stream.write(`${msg} 耗时 ${readable(cost)}`);
}
});
__spinner__.setSpinnerString(Math.floor(Math.random() * 30));
__spinner__.setSpinnerDelay(Math.floor(Math.random() * 23.333 + 66.666));
/////////////////////////////////// SPINNER ////////////////////////////////////
/**
* @type {Sink[]}
*/
const logger$1 = [
{
/**
* Pour out into console.
* @param {Output} output the output.
*/
pour: (output) => {
if (__spinner__.isSpinning() && __logger_idle__) {
console.log('\r');
}
__dbg__(output);
const prefix = __prefix__(output);
const text = prefix.concat(...output.messages.map(x => __stylify__(x)));
if ('dbg' === output.verb) {
console.debug(text);
} else if ('log' === output.verb) {
console.log(text);
} else if ('inf' === output.verb) {
console.info(text);
} else if ('wrn' === output.verb) {
console.warn(text);
} else if ('err' === output.verb) {
console.error(text);
} else {
console.log(
__chalk____default["default"].yellow(`Unknown logger verb => ${JSON.stringify(output)}`)
);
}
__logger_idle__ = false;
}
}
];
/**
* @type {Sink[]}
*/
const indicator$1 = [
{
/**
* Pour out into console.
* @param {Output} output the output.
*/
pour: (output) => {
if (__spinner__.isSpinning() && __logger_idle__) {
console.log('\r');
}
__dbg__(output);
const prefix = __prefix__(output);
const text = prefix.concat(...output.messages.map(x => __stylify__(x)));
if ('exec' === output.verb) {
console.info(text);
} else if ('info' === output.verb) {
console.info(text);
} else if ('warn' === output.verb) {
console.warn(text);
} else if ('succ' === output.verb) {
console.info(text);
} else if ('fail' === output.verb) {
console.error(text);
} else {
console.log(
__chalk____default["default"].yellow(`Unknown indicator verb => ${JSON.stringify(output)}`)
);
}
__logger_idle__ = false;
}
}
];
/**
* @type {Sink[]}
*/
const spinner$1 = [
{
/**
*
* @param {Output} output
*/
pour: (output) => {
__dbg__(output);
const text = ''.concat(
...output.messages.map(x => __stylify__(x))
);
if ('spin' === output.verb) {
__logger_idle__ = true;
__spinner_ts__ = Date.now();
__spinner_tag__ = `${text} …`;
const prefix = `${__stylify__(output.symbol)} 执行 => `;
__spinner__.setSpinnerTitle(
__chalk____default["default"].bgGray(
`${__chalk____default["default"].bold.yellowBright(prefix)} ${__spinner_tag__}`
)
);
__spinner__.start();
} else if ('updt' === output.verb) {
const prefix = `${__stylify__(output.symbol)} 执行 => `;
__spinner__.setSpinnerTitle(
__chalk____default["default"].bgGray(
`${__chalk____default["default"].bold.yellowBright(prefix)} ${__spinner_tag__} ${text}`
)
);
} else if ('succ' === output.verb) {
__spinner__.stop(true);
const prefix = `${__stylify__(output.symbol)} 完成 => `;
const finalText = text ? `${__spinner_tag__} ${text}` : __spinner_tag__;
__spinner__.stream.write(' ' +
__chalk____default["default"].bgGray(
`${__chalk____default["default"].bold.greenBright(prefix)} ${finalText}`
) + ` 耗时 ${readable(Date.now() - __spinner_ts__)}\n`
);
__spinner_tag__ = undefined;
__logger_idle__ = false;
} else if ('fail' === output.verb) {
__spinner__.stop(true);
const prefix = `${__stylify__(output.symbol)} 失败 => `;
const finalText = text ? `${__spinner_tag__} ${text}` : __spinner_tag__;
__spinner__.stream.write(' ' +
__chalk____default["default"].bgGray(
`${__chalk____default["default"].bold.redBright(prefix)} ${finalText}`
+ ` 耗时 ${readable(Date.now() - __spinner_ts__)}\n`
)
);
__spinner_tag__ = undefined;
__logger_idle__ = false;
} else {
console.log(
__chalk____default["default"].yellow(`Unknown spinner verb => ${JSON.stringify(output)}`)
);
}
}
}
];
var __console__ = /*#__PURE__*/Object.freeze({
__proto__: null,
logger: logger$1,
indicator: indicator$1,
spinner: spinner$1
});
/**
* @file The data.
* @author qivmvip AT gmail DOT com
* @date 2022-03-02
*/
/**
* @type {Context}
*/
let __context__ = {};
/**
* @type {Sinks}
*/
let __sinks__ = __console__;
const context$1 = {
set: (context) => {
__context__ = context;
},
get: () => {
return __context__;
}
};
const sinks$1 = {
set: (sinks) => {
__sinks__ = sinks;
},
get: () => {
return __sinks__;
}
};
/**
* @file The defaults.
* @author qivmvip AT gmail DOT com
* @date 2022-03-02
*/
/**
* @type {Context}
*/
const context = Object.freeze({});
/**
* @type {DefaultSinks}
*/
const sinks = Object.freeze({
console: __console__,
devtools: Object.freeze({
common: __console__,
chrome: __console__,
firefox: __console__,
}),
html: __console__,
});
var __defaults__ = /*#__PURE__*/Object.freeze({
__proto__: null,
context: context,
sinks: sinks
});
/**
* @file The config.
* @author qivmvip AT gmail DOT com
* @date 2022-03-02
*/
/**
* Configure the context and sinks
* @param {Context} context The context.
* @param {Sink} sink The sink.
*/
const configure = (context, sink) => {
context$1.set(context);
sinks$1.set(sink);
};
var __configs__ = /*#__PURE__*/Object.freeze({
__proto__: null,
configure: configure
});
/**
* @file cli library CommonJS entry point.
* @author qivmvip AT gmail DOT com
* @date 2022-02-17
*/
/**
* @type {Message}
*/
const messages = __messages__;
/**
* @type {Colors}
*/
const colors = __colors__;
/**
* @type {Symbols}
*/
const symbols = __symbols__;
/**
* Wrap {@link CliMessages} to {@link Output} objects
* @param {'logger'|'indicator'|'spinner'} instance
* @param {string} verb
* @param {...any} msgs
* @returns {Output} An output object.
*/
const __wrap__ = (instance, verb, ...msgs) => ({
date: new Date(),
instance: instance,
verb: verb,
symbol: __symbols__[instance].get(verb),
messages: msgs.map(msg => {
if ('string' === (typeof msg)) {
return colorize(msg, colors[instance][verb]);
} else {
return msg;
}
}),
});
/**
* Common verb helper function.
* @param {'logger'|'indicator'|'spinner'} instance
* @param {string} verb
* @param {CliMessages} messages
*/
const __verb__ = (instance, verb, ...messages) => {
const chains = sinks$1.get() && sinks$1.get()[instance];
chains && chains.forEach((sink) => {
sink.pour(__wrap__(instance, verb, ...messages));
});
};
/**
* @type {Defaults}
*/
const defaults = __defaults__;
/**
* @type {Configs}
*/
const configs = __configs__;
/**
* @type {Logger}
*/
const logger = {
dbg: (...messages) => __verb__('logger', 'dbg', ...messages),
log: (...messages) => __verb__('logger', 'log', ...messages),
inf: (...messages) => __verb__('logger', 'inf', ...messages),
wrn: (...messages) => __verb__('logger', 'wrn', ...messages),
err: (...messages) => __verb__('logger', 'err', ...messages),
};
/**
* @type {Indicator}
*/
const indicator = {
exec: (...messages) => __verb__('indicator', 'exec', ...messages),
info: (...messages) => __verb__('indicator', 'info', ...messages),
warn: (...messages) => __verb__('indicator', 'warn', ...messages),
succ: (...messages) => __verb__('indicator', 'succ', ...messages),
fail: (...messages) => __verb__('indicator', 'fail', ...messages),
};
/**
* @type {Spinner}
*/
const spinner = {
spin: (...messages) => __verb__('spinner', 'spin', ...messages),
updt: (...messages) => __verb__('spinner', 'updt', ...messages),
succ: (...messages) => __verb__('spinner', 'succ', ...messages),
fail: (...messages) => __verb__('spinner', 'fail', ...messages),
};
exports.colors = colors;
exports.configs = configs;
exports.defaults = defaults;
exports.indicator = indicator;
exports.logger = logger;
exports.messages = messages;
exports.spinner = spinner;
exports.symbols = symbols;
//# sourceMappingURL=index.cjs.map