UNPKG

@gypsy-js/cli

Version:
786 lines (713 loc) 18.1 kB
'use strict'; 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