UNPKG

@platformos/pos-cli

Version:

Manage your platformOS application

1,932 lines (1,675 loc) 144 kB
'use strict'; function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var fs$1 = _interopDefault(require('fs')); var path$1 = _interopDefault(require('path')); var index = require('./index-26d8486e.js'); require('events'); require('stream'); require('string_decoder'); require('assert'); require('buffer'); require('zlib'); require('util'); require('crypto'); require('os'); require('tty'); require('constants'); require('https'); require('child_process'); require('url'); require('net'); require('tls'); var readline = _interopDefault(require('readline')); function toArr(any) { return any == null ? [] : Array.isArray(any) ? any : [any]; } function toVal(out, key, val, opts) { var x, old=out[key], nxt=( !!~opts.string.indexOf(key) ? (val == null || val === true ? '' : String(val)) : typeof val === 'boolean' ? val : !!~opts.boolean.indexOf(key) ? (val === 'false' ? false : val === 'true' || (out._.push((x = +val,x * 0 === 0) ? x : val),!!val)) : (x = +val,x * 0 === 0) ? x : val ); out[key] = old == null ? nxt : (Array.isArray(old) ? old.concat(nxt) : [old, nxt]); } var lib = function (args, opts) { args = args || []; opts = opts || {}; var k, arr, arg, name, val, out={ _:[] }; var i=0, j=0, idx=0, len=args.length; const alibi = opts.alias !== void 0; const strict = opts.unknown !== void 0; const defaults = opts.default !== void 0; opts.alias = opts.alias || {}; opts.string = toArr(opts.string); opts.boolean = toArr(opts.boolean); if (alibi) { for (k in opts.alias) { arr = opts.alias[k] = toArr(opts.alias[k]); for (i=0; i < arr.length; i++) { (opts.alias[arr[i]] = arr.concat(k)).splice(i, 1); } } } opts.boolean.forEach(key => { opts.boolean = opts.boolean.concat(opts.alias[key] = opts.alias[key] || []); }); opts.string.forEach(key => { opts.string = opts.string.concat(opts.alias[key] = opts.alias[key] || []); }); if (defaults) { for (k in opts.default) { opts.alias[k] = opts.alias[k] || []; (opts[typeof opts.default[k]] || []).push(k); } } const keys = strict ? Object.keys(opts.alias) : []; for (i=0; i < len; i++) { arg = args[i]; if (arg === '--') { out._ = out._.concat(args.slice(++i)); break; } for (j=0; j < arg.length; j++) { if (arg.charCodeAt(j) !== 45) break; // "-" } if (j === 0) { out._.push(arg); } else if (arg.substring(j, j + 3) === 'no-') { name = arg.substring(j + 3); if (strict && !~keys.indexOf(name)) { return opts.unknown(arg); } out[name] = false; } else { for (idx=j+1; idx < arg.length; idx++) { if (arg.charCodeAt(idx) === 61) break; // "=" } name = arg.substring(j, idx); val = arg.substring(++idx) || (i+1 === len || (''+args[i+1]).charCodeAt(0) === 45 || args[++i]); arr = (j === 2 ? [name] : name); for (idx=0; idx < arr.length; idx++) { name = arr[idx]; if (strict && !~keys.indexOf(name)) return opts.unknown('-'.repeat(j) + name); toVal(out, name, (idx + 1 < arr.length) || val, opts); } } } if (defaults) { for (k in opts.default) { if (out[k] === void 0) { out[k] = opts.default[k]; } } } if (alibi) { for (k in out) { arr = opts.alias[k] || []; while (arr.length > 0) { out[arr.shift()] = out[k]; } } } return out; }; const isWin = process.platform === 'win32'; const SEP = isWin ? `\\\\+` : `\\/`; const SEP_ESC = isWin ? `\\\\` : `/`; const GLOBSTAR = `((?:[^/]*(?:/|$))*)`; const WILDCARD = `([^/]*)`; const GLOBSTAR_SEGMENT = `((?:[^${SEP_ESC}]*(?:${SEP_ESC}|$))*)`; const WILDCARD_SEGMENT = `([^${SEP_ESC}]*)`; /** * Convert any glob pattern to a JavaScript Regexp object * @param {String} glob Glob pattern to convert * @param {Object} opts Configuration object * @param {Boolean} [opts.extended=false] Support advanced ext globbing * @param {Boolean} [opts.globstar=false] Support globstar * @param {Boolean} [opts.strict=true] be laissez faire about mutiple slashes * @param {Boolean} [opts.filepath=''] Parse as filepath for extra path related features * @param {String} [opts.flags=''] RegExp globs * @returns {Object} converted object with string, segments and RegExp object */ function globrex(glob, {extended = false, globstar = false, strict = false, filepath = false, flags = ''} = {}) { let regex = ''; let segment = ''; let path = { regex: '', segments: [] }; // If we are doing extended matching, this boolean is true when we are inside // a group (eg {*.html,*.js}), and false otherwise. let inGroup = false; let inRange = false; // extglob stack. Keep track of scope const ext = []; // Helper function to build string and segments function add(str, {split, last, only}={}) { if (only !== 'path') regex += str; if (filepath && only !== 'regex') { path.regex += (str === '\\/' ? SEP : str); if (split) { if (last) segment += str; if (segment !== '') { if (!flags.includes('g')) segment = `^${segment}$`; // change it 'includes' path.segments.push(new RegExp(segment, flags)); } segment = ''; } else { segment += str; } } } let c, n; for (let i = 0; i < glob.length; i++) { c = glob[i]; n = glob[i + 1]; if (['\\', '$', '^', '.', '='].includes(c)) { add(`\\${c}`); continue; } if (c === '/') { add(`\\${c}`, {split: true}); if (n === '/' && !strict) regex += '?'; continue; } if (c === '(') { if (ext.length) { add(c); continue; } add(`\\${c}`); continue; } if (c === ')') { if (ext.length) { add(c); let type = ext.pop(); if (type === '@') { add('{1}'); } else if (type === '!') { add('([^\/]*)'); } else { add(type); } continue; } add(`\\${c}`); continue; } if (c === '|') { if (ext.length) { add(c); continue; } add(`\\${c}`); continue; } if (c === '+') { if (n === '(' && extended) { ext.push(c); continue; } add(`\\${c}`); continue; } if (c === '@' && extended) { if (n === '(') { ext.push(c); continue; } } if (c === '!') { if (extended) { if (inRange) { add('^'); continue } if (n === '(') { ext.push(c); add('(?!'); i++; continue; } add(`\\${c}`); continue; } add(`\\${c}`); continue; } if (c === '?') { if (extended) { if (n === '(') { ext.push(c); } else { add('.'); } continue; } add(`\\${c}`); continue; } if (c === '[') { if (inRange && n === ':') { i++; // skip [ let value = ''; while(glob[++i] !== ':') value += glob[i]; if (value === 'alnum') add('(\\w|\\d)'); else if (value === 'space') add('\\s'); else if (value === 'digit') add('\\d'); i++; // skip last ] continue; } if (extended) { inRange = true; add(c); continue; } add(`\\${c}`); continue; } if (c === ']') { if (extended) { inRange = false; add(c); continue; } add(`\\${c}`); continue; } if (c === '{') { if (extended) { inGroup = true; add('('); continue; } add(`\\${c}`); continue; } if (c === '}') { if (extended) { inGroup = false; add(')'); continue; } add(`\\${c}`); continue; } if (c === ',') { if (inGroup) { add('|'); continue; } add(`\\${c}`); continue; } if (c === '*') { if (n === '(' && extended) { ext.push(c); continue; } // Move over all consecutive "*"'s. // Also store the previous and next characters let prevChar = glob[i - 1]; let starCount = 1; while (glob[i + 1] === '*') { starCount++; i++; } let nextChar = glob[i + 1]; if (!globstar) { // globstar is disabled, so treat any number of "*" as one add('.*'); } else { // globstar is enabled, so determine if this is a globstar segment let isGlobstar = starCount > 1 && // multiple "*"'s (prevChar === '/' || prevChar === undefined) && // from the start of the segment (nextChar === '/' || nextChar === undefined); // to the end of the segment if (isGlobstar) { // it's a globstar, so match zero or more path segments add(GLOBSTAR, {only:'regex'}); add(GLOBSTAR_SEGMENT, {only:'path', last:true, split:true}); i++; // move over the "/" } else { // it's not a globstar, so only match one path segment add(WILDCARD, {only:'regex'}); add(WILDCARD_SEGMENT, {only:'path'}); } } continue; } add(c); } // When regexp 'g' flag is specified don't // constrain the regular expression with ^ & $ if (!flags.includes('g')) { regex = `^${regex}$`; segment = `^${segment}$`; if (filepath) path.regex = `^${path.regex}$`; } const result = {regex: new RegExp(regex, flags)}; // Push the last segment if (filepath) { path.segments.push(new RegExp(segment, flags)); path.regex = new RegExp(path.regex, flags); path.globstar = new RegExp(!flags.includes('g') ? `^${GLOBSTAR_SEGMENT}$` : GLOBSTAR_SEGMENT, flags); result.path = path; } return result; } var globrex_1 = globrex; const CHARS = { '{': '}', '(': ')', '[': ']'}; const STRICT = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\)|(\\).|([@?!+*]\(.*\)))/; const RELAXED = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; /** * Detect if a string cointains glob * @param {String} str Input string * @param {Object} [options] Configuration object * @param {Boolean} [options.strict=true] Use relaxed regex if true * @returns {Boolean} true if string contains glob */ function isglob(str, { strict = true } = {}) { if (str === '') return false; let match, rgx = strict ? STRICT : RELAXED; while ((match = rgx.exec(str))) { if (match[2]) return true; let idx = match.index + match[0].length; // if an open bracket/brace/paren is escaped, // set the index to the next closing character let open = match[1]; let close = open ? CHARS[open] : null; if (open && close) { let n = str.indexOf(close, idx); if (n !== -1) idx = n + 1; } str = str.slice(idx); } return false; } /** * Find the static part of a glob-path, * split path and return path part * @param {String} str Path/glob string * @returns {String} static path section of glob */ function parent(str, { strict = false } = {}) { str = path$1.normalize(str).replace(/\/|\\/, '/'); // special case for strings ending in enclosure containing path separator if (/[\{\[].*[\/]*.*[\}\]]$/.test(str)) str += '/'; // preserves full path in case of trailing path separator str += 'a'; do {str = path$1.dirname(str);} while (isglob(str, {strict}) || /(^|[^\\])([\{\[]|\([^\)]+$)/.test(str)); // remove escape chars and return result return str.replace(/\\([\*\?\|\[\]\(\)\{\}])/g, '$1'); } /** * Parse a glob path, and split it by static/glob part * @param {String} pattern String path * @param {Object} [opts] Options * @param {Object} [opts.strict=false] Use strict parsing * @returns {Object} object with parsed path */ function globalyzer(pattern, opts = {}) { let base = parent(pattern, opts); let isGlob = isglob(pattern, opts); let glob; if (base != '.') { glob = pattern.substr(base.length); if (glob.startsWith('/')) glob = glob.substr(1); } else { glob = pattern; } if (!isGlob) { base = path$1.dirname(pattern); glob = base !== '.' ? pattern.substr(base.length) : pattern; } if (glob.startsWith('./')) glob = glob.substr(2); if (glob.startsWith('/')) glob = glob.substr(1); return { base, glob, isGlob }; } var src = globalyzer; const { join, resolve, relative } = path$1; const isHidden = /(^|[\\\/])\.[^\\\/\.]/g; let CACHE = {}; function walk(output, prefix, lexer, opts, dirname='', level=0) { const rgx = lexer.segments[level]; const dir = join(opts.cwd, prefix, dirname); const files = fs$1.readdirSync(dir); const { dot, filesOnly } = opts; let i=0, len=files.length, file; let fullpath, relpath, stats, isMatch; for (; i < len; i++) { fullpath = join(dir, file=files[i]); relpath = dirname ? join(dirname, file) : file; if (!dot && isHidden.test(relpath)) continue; isMatch = lexer.regex.test(relpath); if ((stats=CACHE[relpath]) === void 0) { CACHE[relpath] = stats = fs$1.lstatSync(fullpath); } if (!stats.isDirectory()) { isMatch && output.push(relative(opts.cwd, fullpath)); continue; } if (rgx && !rgx.test(file)) continue; !filesOnly && isMatch && output.push(join(prefix, relpath)); walk(output, prefix, lexer, opts, relpath, rgx && rgx.toString() !== lexer.globstar && ++level); } } /** * Find files using bash-like globbing. * All paths are normalized compared to node-glob. * @param {String} str Glob string * @param {String} [options.cwd='.'] Current working directory * @param {Boolean} [options.dot=false] Include dotfile matches * @param {Boolean} [options.absolute=false] Return absolute paths * @param {Boolean} [options.filesOnly=false] Do not include folders if true * @param {Boolean} [options.flush=false] Reset cache object * @returns {Array} array containing matching files */ var sync = function (str, opts={}) { if (!str) return []; let glob = src(str); opts.cwd = opts.cwd || '.'; if (!glob.isGlob) { try { let resolved = resolve(opts.cwd, str); let dirent = fs$1.statSync(resolved); if (opts.filesOnly && !dirent.isFile()) return [] return opts.absolute ? [resolved] : [str]; } catch (err) { if (err.code != 'ENOENT') throw err; return []; } } if (opts.flush) CACHE = {}; let matches = []; const { path } = globrex_1(glob.glob, { filepath:true, globstar:true, extended:true }); path.globstar = path.globstar.toString(); walk(matches, glob.base, path, opts, '.', 0); return opts.absolute ? matches.map(x => resolve(opts.cwd, x)) : matches; }; function fuzzysearch (needle, haystack) { var tlen = haystack.length; var qlen = needle.length; if (qlen > tlen) { return false; } if (qlen === tlen) { return needle === haystack; } outer: for (var i = 0, j = 0; i < qlen; i++) { var nch = needle.charCodeAt(i); while (j < tlen) { if (haystack.charCodeAt(j++) === nch) { continue outer; } } return false; } return true; } var fuzzysearch_1 = fuzzysearch; var symbols = index.createCommonjsModule(function (module) { const isWindows = process.platform === 'win32'; const isLinux = process.platform === 'linux'; const windows = { bullet: '•', check: '√', cross: '×', ellipsis: '...', heart: '❤', info: 'i', line: '─', middot: '·', minus: '-', plus: '+', question: '?', questionSmall: '﹖', pointer: '>', pointerSmall: '»', warning: '‼' }; const other = { ballotCross: '✘', bullet: '•', check: '✔', cross: '✖', ellipsis: '…', heart: '❤', info: 'ℹ', line: '─', middot: '·', minus: '-', plus: '+', question: '?', questionFull: '?', questionSmall: '﹖', pointer: isLinux ? '▸' : '❯', pointerSmall: isLinux ? '‣' : '›', warning: '⚠' }; module.exports = isWindows ? windows : other; Reflect.defineProperty(module.exports, 'windows', { enumerable: false, value: windows }); Reflect.defineProperty(module.exports, 'other', { enumerable: false, value: other }); }); const colors = { enabled: true, visible: true, styles: {}, keys: {} }; if ('FORCE_COLOR' in process.env) { colors.enabled = process.env.FORCE_COLOR !== '0'; } const ansi = style => { style.open = `\u001b[${style.codes[0]}m`; style.close = `\u001b[${style.codes[1]}m`; style.regex = new RegExp(`\\u001b\\[${style.codes[1]}m`, 'g'); return style; }; const wrap = (style, str, nl) => { let { open, close, regex } = style; str = open + (str.includes(close) ? str.replace(regex, close + open) : str) + close; // see https://github.com/chalk/chalk/pull/92, thanks to the // chalk contributors for this fix. However, we've confirmed that // this issue is also present in Windows terminals return nl ? str.replace(/\r?\n/g, `${close}$&${open}`) : str; }; const style = (input, stack) => { if (input === '' || input == null) return ''; if (colors.enabled === false) return input; if (colors.visible === false) return ''; let str = '' + input; let nl = str.includes('\n'); let n = stack.length; while (n-- > 0) str = wrap(colors.styles[stack[n]], str, nl); return str; }; const define = (name, codes, type) => { colors.styles[name] = ansi({ name, codes }); let t = colors.keys[type] || (colors.keys[type] = []); t.push(name); Reflect.defineProperty(colors, name, { get() { let color = input => style(input, color.stack); Reflect.setPrototypeOf(color, colors); color.stack = this.stack ? this.stack.concat(name) : [name]; return color; } }); }; define('reset', [0, 0], 'modifier'); define('bold', [1, 22], 'modifier'); define('dim', [2, 22], 'modifier'); define('italic', [3, 23], 'modifier'); define('underline', [4, 24], 'modifier'); define('inverse', [7, 27], 'modifier'); define('hidden', [8, 28], 'modifier'); define('strikethrough', [9, 29], 'modifier'); define('black', [30, 39], 'color'); define('red', [31, 39], 'color'); define('green', [32, 39], 'color'); define('yellow', [33, 39], 'color'); define('blue', [34, 39], 'color'); define('magenta', [35, 39], 'color'); define('cyan', [36, 39], 'color'); define('white', [37, 39], 'color'); define('gray', [90, 39], 'color'); define('grey', [90, 39], 'color'); define('bgBlack', [40, 49], 'bg'); define('bgRed', [41, 49], 'bg'); define('bgGreen', [42, 49], 'bg'); define('bgYellow', [43, 49], 'bg'); define('bgBlue', [44, 49], 'bg'); define('bgMagenta', [45, 49], 'bg'); define('bgCyan', [46, 49], 'bg'); define('bgWhite', [47, 49], 'bg'); define('blackBright', [90, 39], 'bright'); define('redBright', [91, 39], 'bright'); define('greenBright', [92, 39], 'bright'); define('yellowBright', [93, 39], 'bright'); define('blueBright', [94, 39], 'bright'); define('magentaBright', [95, 39], 'bright'); define('cyanBright', [96, 39], 'bright'); define('whiteBright', [97, 39], 'bright'); define('bgBlackBright', [100, 49], 'bgBright'); define('bgRedBright', [101, 49], 'bgBright'); define('bgGreenBright', [102, 49], 'bgBright'); define('bgYellowBright', [103, 49], 'bgBright'); define('bgBlueBright', [104, 49], 'bgBright'); define('bgMagentaBright', [105, 49], 'bgBright'); define('bgCyanBright', [106, 49], 'bgBright'); define('bgWhiteBright', [107, 49], 'bgBright'); /* eslint-disable no-control-regex */ const re = colors.ansiRegex = /\u001b\[\d+m/gm; colors.hasColor = colors.hasAnsi = str => { re.lastIndex = 0; return !!str && typeof str === 'string' && re.test(str); }; colors.unstyle = str => { re.lastIndex = 0; return typeof str === 'string' ? str.replace(re, '') : str; }; colors.none = colors.clear = colors.noop = str => str; // no-op, for programmatic usage colors.stripColor = colors.unstyle; colors.symbols = symbols; colors.define = define; var ansiColors = colors; var utils = index.createCommonjsModule(function (module, exports) { const toString = Object.prototype.toString; let called = false; let fns = []; const complements = { 'yellow': 'blue', 'cyan': 'red', 'green': 'magenta', 'black': 'white', 'blue': 'yellow', 'red': 'cyan', 'magenta': 'green', 'white': 'black' }; exports.longest = (arr, prop) => { return arr.reduce((a, v) => Math.max(a, prop ? v[prop].length : v.length), 0); }; exports.hasColor = str => !!str && ansiColors.hasColor(str); const isObject = exports.isObject = val => { return val !== null && typeof val === 'object' && !Array.isArray(val); }; exports.nativeType = val => { return toString.call(val).slice(8, -1).toLowerCase().replace(/\s/g, ''); }; exports.isAsyncFn = val => { return exports.nativeType(val) === 'asyncfunction'; }; exports.isPrimitive = val => { return val != null && typeof val !== 'object' && typeof val !== 'function'; }; exports.resolve = (context, value, ...rest) => { if (typeof value === 'function') { return value.call(context, ...rest); } return value; }; exports.scrollDown = (choices = []) => [...choices.slice(1), choices[0]]; exports.scrollUp = (choices = []) => [choices.pop(), ...choices]; exports.reorder = (arr = []) => { let res = arr.slice(); res.sort((a, b) => { if (a.index > b.index) return 1; if (a.index < b.index) return -1; return 0; }); return res; }; exports.swap = (arr, index, pos) => { let len = arr.length; let idx = pos === len ? 0 : pos < 0 ? len - 1 : pos; let choice = arr[index]; arr[index] = arr[idx]; arr[idx] = choice; }; exports.width = (stream, fallback = 80) => { let columns = (stream && stream.columns) ? stream.columns : fallback; if (stream && typeof stream.getWindowSize === 'function') { columns = stream.getWindowSize()[0]; } if (process.platform === 'win32') { return columns - 1; } return columns; }; exports.height = (stream, fallback = 20) => { let rows = (stream && stream.rows) ? stream.rows : fallback; if (stream && typeof stream.getWindowSize === 'function') { rows = stream.getWindowSize()[1]; } return rows; }; exports.wordWrap = (str, options = {}) => { if (!str) return str; if (typeof options === 'number') { options = { width: options }; } let { indent = '', newline = ('\n' + indent), width = 80 } = options; let spaces = (newline + indent).match(/[^\S\n]/g) || []; width -= spaces.length; let source = `.{1,${width}}([\\s\\u200B]+|$)|[^\\s\\u200B]+?([\\s\\u200B]+|$)`; let output = str.trim(); let regex = new RegExp(source, 'g'); let lines = output.match(regex) || []; lines = lines.map(line => line.replace(/\n$/, '')); if (options.padEnd) lines = lines.map(line => line.padEnd(width, ' ')); if (options.padStart) lines = lines.map(line => line.padStart(width, ' ')); return indent + lines.join(newline); }; exports.unmute = color => { let name = color.stack.find(n => ansiColors.keys.color.includes(n)); if (name) { return ansiColors[name]; } let bg = color.stack.find(n => n.slice(2) === 'bg'); if (bg) { return ansiColors[name.slice(2)]; } return str => str; }; exports.pascal = str => str ? str[0].toUpperCase() + str.slice(1) : ''; exports.inverse = color => { if (!color || !color.stack) return color; let name = color.stack.find(n => ansiColors.keys.color.includes(n)); if (name) { let col = ansiColors['bg' + exports.pascal(name)]; return col ? col.black : color; } let bg = color.stack.find(n => n.slice(0, 2) === 'bg'); if (bg) { return ansiColors[bg.slice(2).toLowerCase()] || color; } return ansiColors.none; }; exports.complement = color => { if (!color || !color.stack) return color; let name = color.stack.find(n => ansiColors.keys.color.includes(n)); let bg = color.stack.find(n => n.slice(0, 2) === 'bg'); if (name && !bg) { return ansiColors[complements[name] || name]; } if (bg) { let lower = bg.slice(2).toLowerCase(); let comp = complements[lower]; if (!comp) return color; return ansiColors['bg' + exports.pascal(comp)] || color; } return ansiColors.none; }; exports.meridiem = date => { let hours = date.getHours(); let minutes = date.getMinutes(); let ampm = hours >= 12 ? 'pm' : 'am'; hours = hours % 12; let hrs = hours === 0 ? 12 : hours; let min = minutes < 10 ? '0' + minutes : minutes; return hrs + ':' + min + ' ' + ampm; }; /** * Set a value on the given object. * @param {Object} obj * @param {String} prop * @param {any} value */ exports.set = (obj = {}, prop = '', val) => { return prop.split('.').reduce((acc, k, i, arr) => { let value = arr.length - 1 > i ? (acc[k] || {}) : val; if (!exports.isObject(value) && i < arr.length - 1) value = {}; return (acc[k] = value); }, obj); }; /** * Get a value from the given object. * @param {Object} obj * @param {String} prop */ exports.get = (obj = {}, prop = '', fallback) => { let value = obj[prop] == null ? prop.split('.').reduce((acc, k) => acc && acc[k], obj) : obj[prop]; return value == null ? fallback : value; }; exports.mixin = (target, b) => { if (!isObject(target)) return b; if (!isObject(b)) return target; for (let key of Object.keys(b)) { let desc = Object.getOwnPropertyDescriptor(b, key); if (desc.hasOwnProperty('value')) { if (target.hasOwnProperty(key) && isObject(desc.value)) { let existing = Object.getOwnPropertyDescriptor(target, key); if (isObject(existing.value)) { target[key] = exports.merge({}, target[key], b[key]); } else { Reflect.defineProperty(target, key, desc); } } else { Reflect.defineProperty(target, key, desc); } } else { Reflect.defineProperty(target, key, desc); } } return target; }; exports.merge = (...args) => { let target = {}; for (let ele of args) exports.mixin(target, ele); return target; }; exports.mixinEmitter = (obj, emitter) => { let proto = emitter.constructor.prototype; for (let key of Object.keys(proto)) { let val = proto[key]; if (typeof val === 'function') { exports.define(obj, key, val.bind(emitter)); } else { exports.define(obj, key, val); } } }; exports.onExit = callback => { const onExit = (quit, code) => { if (called) return; called = true; fns.forEach(fn => fn()); if (quit === true) { process.exit(128 + code); } }; if (fns.length === 0) { process.once('SIGTERM', onExit.bind(null, true, 15)); process.once('SIGINT', onExit.bind(null, true, 2)); process.once('exit', onExit); } fns.push(callback); }; exports.define = (obj, key, value) => { Reflect.defineProperty(obj, key, { value }); }; exports.defineExport = (obj, key, fn) => { let custom; Reflect.defineProperty(obj, key, { enumerable: true, configurable: true, set(val) { custom = val; }, get() { return custom ? custom() : fn(); } }); }; }); var utils_1 = utils.longest; var utils_2 = utils.hasColor; var utils_3 = utils.isObject; var utils_4 = utils.nativeType; var utils_5 = utils.isAsyncFn; var utils_6 = utils.isPrimitive; var utils_7 = utils.resolve; var utils_8 = utils.scrollDown; var utils_9 = utils.scrollUp; var utils_10 = utils.reorder; var utils_11 = utils.swap; var utils_12 = utils.width; var utils_13 = utils.height; var utils_14 = utils.wordWrap; var utils_15 = utils.unmute; var utils_16 = utils.pascal; var utils_17 = utils.inverse; var utils_18 = utils.complement; var utils_19 = utils.meridiem; var utils_20 = utils.set; var utils_21 = utils.get; var utils_22 = utils.mixin; var utils_23 = utils.merge; var utils_24 = utils.mixinEmitter; var utils_25 = utils.onExit; var utils_26 = utils.define; var utils_27 = utils.defineExport; /** * Actions are mappings from keypress event names to method names * in the prompts. */ var ctrl = { a: 'first', b: 'backward', c: 'cancel', d: 'deleteForward', e: 'last', f: 'forward', g: 'reset', i: 'tab', k: 'cutForward', l: 'reset', n: 'newItem', m: 'cancel', j: 'submit', p: 'search', r: 'remove', s: 'save', u: 'undo', w: 'cutLeft', x: 'toggleCursor', v: 'paste' }; var shift = { up: 'shiftUp', down: 'shiftDown', left: 'shiftLeft', right: 'shiftRight', tab: 'prev' }; var fn = { up: 'pageUp', down: 'pageDown', left: 'pageLeft', right: 'pageRight', delete: 'deleteForward' }; // <alt> on Windows var option = { b: 'backward', f: 'forward', d: 'cutRight', left: 'cutLeft', up: 'altUp', down: 'altDown' }; var keys = { pageup: 'pageUp', // <fn>+<up> (mac), <Page Up> (windows) pagedown: 'pageDown', // <fn>+<down> (mac), <Page Down> (windows) home: 'home', // <fn>+<left> (mac), <home> (windows) end: 'end', // <fn>+<right> (mac), <end> (windows) cancel: 'cancel', delete: 'deleteForward', backspace: 'delete', down: 'down', enter: 'submit', escape: 'cancel', left: 'left', space: 'space', number: 'number', return: 'submit', right: 'right', tab: 'next', up: 'up' }; var combos = { ctrl: ctrl, shift: shift, fn: fn, option: option, keys: keys }; /* eslint-disable no-control-regex */ const metaKeyCodeRe = /^(?:\x1b)([a-zA-Z0-9])$/; const fnKeyRe = /^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/; const keyName = { /* xterm/gnome ESC O letter */ 'OP': 'f1', 'OQ': 'f2', 'OR': 'f3', 'OS': 'f4', /* xterm/rxvt ESC [ number ~ */ '[11~': 'f1', '[12~': 'f2', '[13~': 'f3', '[14~': 'f4', /* from Cygwin and used in libuv */ '[[A': 'f1', '[[B': 'f2', '[[C': 'f3', '[[D': 'f4', '[[E': 'f5', /* common */ '[15~': 'f5', '[17~': 'f6', '[18~': 'f7', '[19~': 'f8', '[20~': 'f9', '[21~': 'f10', '[23~': 'f11', '[24~': 'f12', /* xterm ESC [ letter */ '[A': 'up', '[B': 'down', '[C': 'right', '[D': 'left', '[E': 'clear', '[F': 'end', '[H': 'home', /* xterm/gnome ESC O letter */ 'OA': 'up', 'OB': 'down', 'OC': 'right', 'OD': 'left', 'OE': 'clear', 'OF': 'end', 'OH': 'home', /* xterm/rxvt ESC [ number ~ */ '[1~': 'home', '[2~': 'insert', '[3~': 'delete', '[4~': 'end', '[5~': 'pageup', '[6~': 'pagedown', /* putty */ '[[5~': 'pageup', '[[6~': 'pagedown', /* rxvt */ '[7~': 'home', '[8~': 'end', /* rxvt keys with modifiers */ '[a': 'up', '[b': 'down', '[c': 'right', '[d': 'left', '[e': 'clear', '[2$': 'insert', '[3$': 'delete', '[5$': 'pageup', '[6$': 'pagedown', '[7$': 'home', '[8$': 'end', 'Oa': 'up', 'Ob': 'down', 'Oc': 'right', 'Od': 'left', 'Oe': 'clear', '[2^': 'insert', '[3^': 'delete', '[5^': 'pageup', '[6^': 'pagedown', '[7^': 'home', '[8^': 'end', /* misc. */ '[Z': 'tab', }; function isShiftKey(code) { return ['[a', '[b', '[c', '[d', '[e', '[2$', '[3$', '[5$', '[6$', '[7$', '[8$', '[Z'].includes(code) } function isCtrlKey(code) { return [ 'Oa', 'Ob', 'Oc', 'Od', 'Oe', '[2^', '[3^', '[5^', '[6^', '[7^', '[8^'].includes(code) } const keypress = (s = '', event = {}) => { let parts; let key = { name: event.name, ctrl: false, meta: false, shift: false, option: false, sequence: s, raw: s, ...event }; if (Buffer.isBuffer(s)) { if (s[0] > 127 && s[1] === void 0) { s[0] -= 128; s = '\x1b' + String(s); } else { s = String(s); } } else if (s !== void 0 && typeof s !== 'string') { s = String(s); } else if (!s) { s = key.sequence || ''; } key.sequence = key.sequence || s || key.name; if (s === '\r') { // carriage return key.raw = void 0; key.name = 'return'; } else if (s === '\n') { // enter, should have been called linefeed key.name = 'enter'; } else if (s === '\t') { // tab key.name = 'tab'; } else if (s === '\b' || s === '\x7f' || s === '\x1b\x7f' || s === '\x1b\b') { // backspace or ctrl+h key.name = 'backspace'; key.meta = s.charAt(0) === '\x1b'; } else if (s === '\x1b' || s === '\x1b\x1b') { // escape key key.name = 'escape'; key.meta = s.length === 2; } else if (s === ' ' || s === '\x1b ') { key.name = 'space'; key.meta = s.length === 2; } else if (s <= '\x1a') { // ctrl+letter key.name = String.fromCharCode(s.charCodeAt(0) + 'a'.charCodeAt(0) - 1); key.ctrl = true; } else if (s.length === 1 && s >= '0' && s <= '9') { // number key.name = 'number'; } else if (s.length === 1 && s >= 'a' && s <= 'z') { // lowercase letter key.name = s; } else if (s.length === 1 && s >= 'A' && s <= 'Z') { // shift+letter key.name = s.toLowerCase(); key.shift = true; } else if ((parts = metaKeyCodeRe.exec(s))) { // meta+character key key.meta = true; key.shift = /^[A-Z]$/.test(parts[1]); } else if ((parts = fnKeyRe.exec(s))) { let segs = [...s]; if (segs[0] === '\u001b' && segs[1] === '\u001b') { key.option = true; } // ansi escape sequence // reassemble the key code leaving out leading \x1b's, // the modifier key bitflag and any meaningless "1;" sequence let code = [parts[1], parts[2], parts[4], parts[6]].filter(Boolean).join(''); let modifier = (parts[3] || parts[5] || 1) - 1; // Parse the key modifier key.ctrl = !!(modifier & 4); key.meta = !!(modifier & 10); key.shift = !!(modifier & 1); key.code = code; key.name = keyName[code]; key.shift = isShiftKey(code) || key.shift; key.ctrl = isCtrlKey(code) || key.ctrl; } return key; }; keypress.listen = (options = {}, onKeypress) => { let { stdin } = options; if (!stdin || (stdin !== process.stdin && !stdin.isTTY)) { throw new Error('Invalid stream passed'); } let rl = readline.createInterface({ terminal: true, input: stdin }); readline.emitKeypressEvents(stdin, rl); let on = (buf, key) => onKeypress(buf, keypress(buf, key), rl); let isRaw = stdin.isRaw; if (stdin.isTTY) stdin.setRawMode(true); stdin.on('keypress', on); rl.resume(); let off = () => { if (stdin.isTTY) stdin.setRawMode(isRaw); stdin.removeListener('keypress', on); rl.pause(); rl.close(); }; return off; }; keypress.action = (buf, key, customActions) => { let obj = { ...combos, ...customActions }; if (key.ctrl) { key.action = obj.ctrl[key.name]; return key; } if (key.option && obj.option) { key.action = obj.option[key.name]; return key; } if (key.shift) { key.action = obj.shift[key.name]; return key; } key.action = obj.keys[key.name]; return key; }; var keypress_1 = keypress; var timer = prompt => { prompt.timers = prompt.timers || {}; let timers = prompt.options.timers; if (!timers) return; for (let key of Object.keys(timers)) { let opts = timers[key]; if (typeof opts === 'number') { opts = { interval: opts }; } create(prompt, key, opts); } }; function create(prompt, name, options = {}) { let timer = prompt.timers[name] = { name, start: Date.now(), ms: 0, tick: 0 }; let ms = options.interval || 120; timer.frames = options.frames || []; timer.loading = true; let interval = setInterval(() => { timer.ms = Date.now() - timer.start; timer.tick++; prompt.render(); }, ms); timer.stop = () => { timer.loading = false; clearInterval(interval); }; Reflect.defineProperty(timer, 'interval', { value: interval }); prompt.once('close', () => timer.stop()); return timer.stop; } const { define: define$1, width } = utils; class State { constructor(prompt) { let options = prompt.options; define$1(this, '_prompt', prompt); this.type = prompt.type; this.name = prompt.name; this.message = ''; this.header = ''; this.footer = ''; this.error = ''; this.hint = ''; this.input = ''; this.cursor = 0; this.index = 0; this.lines = 0; this.tick = 0; this.prompt = ''; this.buffer = ''; this.width = width(options.stdout || process.stdout); Object.assign(this, options); this.name = this.name || this.message; this.message = this.message || this.name; this.symbols = prompt.symbols; this.styles = prompt.styles; this.required = new Set(); this.cancelled = false; this.submitted = false; } clone() { let state = { ...this }; state.status = this.status; state.buffer = Buffer.from(state.buffer); delete state.clone; return state; } set color(val) { this._color = val; } get color() { let styles = this.prompt.styles; if (this.cancelled) return styles.cancelled; if (this.submitted) return styles.submitted; let color = this._color || styles[this.status]; return typeof color === 'function' ? color : styles.pending; } set loading(value) { this._loading = value; } get loading() { if (typeof this._loading === 'boolean') return this._loading; if (this.loadingChoices) return 'choices'; return false; } get status() { if (this.cancelled) return 'cancelled'; if (this.submitted) return 'submitted'; return 'pending'; } } var state = State; const styles = { default: ansiColors.noop, noop: ansiColors.noop, /** * Modifiers */ set inverse(custom) { this._inverse = custom; }, get inverse() { return this._inverse || utils.inverse(this.primary); }, set complement(custom) { this._complement = custom; }, get complement() { return this._complement || utils.complement(this.primary); }, /** * Main color */ primary: ansiColors.cyan, /** * Main palette */ success: ansiColors.green, danger: ansiColors.magenta, strong: ansiColors.bold, warning: ansiColors.yellow, muted: ansiColors.dim, disabled: ansiColors.gray, dark: ansiColors.dim.gray, underline: ansiColors.underline, set info(custom) { this._info = custom; }, get info() { return this._info || this.primary; }, set em(custom) { this._em = custom; }, get em() { return this._em || this.primary.underline; }, set heading(custom) { this._heading = custom; }, get heading() { return this._heading || this.muted.underline; }, /** * Statuses */ set pending(custom) { this._pending = custom; }, get pending() { return this._pending || this.primary; }, set submitted(custom) { this._submitted = custom; }, get submitted() { return this._submitted || this.success; }, set cancelled(custom) { this._cancelled = custom; }, get cancelled() { return this._cancelled || this.danger; }, /** * Special styling */ set typing(custom) { this._typing = custom; }, get typing() { return this._typing || this.dim; }, set placeholder(custom) { this._placeholder = custom; }, get placeholder() { return this._placeholder || this.primary.dim; }, set highlight(custom) { this._highlight = custom; }, get highlight() { return this._highlight || this.inverse; } }; styles.merge = (options = {}) => { if (options.styles && typeof options.styles.enabled === 'boolean') { ansiColors.enabled = options.styles.enabled; } if (options.styles && typeof options.styles.visible === 'boolean') { ansiColors.visible = options.styles.visible; } let result = utils.merge({}, styles, options.styles); delete result.merge; for (let key of Object.keys(ansiColors)) { if (!result.hasOwnProperty(key)) { Reflect.defineProperty(result, key, { get: () => ansiColors[key] }); } } for (let key of Object.keys(ansiColors.styles)) { if (!result.hasOwnProperty(key)) { Reflect.defineProperty(result, key, { get: () => ansiColors[key] }); } } return result; }; var styles_1 = styles; const isWindows = process.platform === 'win32'; const symbols$1 = { ...ansiColors.symbols, upDownDoubleArrow: '⇕', upDownDoubleArrow2: '⬍', upDownArrow: '↕', asterisk: '*', asterism: '⁂', bulletWhite: '◦', electricArrow: '⌁', ellipsisLarge: '⋯', ellipsisSmall: '…', fullBlock: '█', identicalTo: '≡', indicator: ansiColors.symbols.check, leftAngle: '‹', mark: '※', minus: '−', multiplication: '×', obelus: '÷', percent: '%', pilcrow: '¶', pilcrow2: '❡', pencilUpRight: '✐', pencilDownRight: '✎', pencilRight: '✏', plus: '+', plusMinus: '±', pointRight: '☞', rightAngle: '›', section: '§', hexagon: { off: '⬡', on: '⬢', disabled: '⬢' }, ballot: { on: '☑', off: '☐', disabled: '☒' }, stars: { on: '★', off: '☆', disabled: '☆' }, folder: { on: '▼', off: '▶', disabled: '▶' }, prefix: { pending: ansiColors.symbols.question, submitted: ansiColors.symbols.check, cancelled: ansiColors.symbols.cross }, separator: { pending: ansiColors.symbols.pointerSmall, submitted: ansiColors.symbols.middot, cancelled: ansiColors.symbols.middot }, radio: { off: isWindows ? '( )' : '◯', on: isWindows ? '(*)' : '◉', disabled: isWindows ? '(|)' : 'Ⓘ' }, numbers: ['⓪', '①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨', '⑩', '⑪', '⑫', '⑬', '⑭', '⑮', '⑯', '⑰', '⑱', '⑲', '⑳', '㉑', '㉒', '㉓', '㉔', '㉕', '㉖', '㉗', '㉘', '㉙', '㉚', '㉛', '㉜', '㉝', '㉞', '㉟', '㊱', '㊲', '㊳', '㊴', '㊵', '㊶', '㊷', '㊸', '㊹', '㊺', '㊻', '㊼', '㊽', '㊾', '㊿'] }; symbols$1.merge = options => { let result = utils.merge({}, ansiColors.symbols, symbols$1, options.symbols); delete result.merge; return result; }; var symbols_1 = symbols$1; var theme = prompt => { prompt.options = utils.merge({}, prompt.options.theme, prompt.options); prompt.symbols = symbols_1.merge(prompt.options); prompt.styles = styles_1.merge(prompt.options); }; var ansi_1 = index.createCommonjsModule(function (module, exports) { const isTerm = process.env.TERM_PROGRAM === 'Apple_Terminal'; const ansi = module.exports = exports; const ESC = '\u001b['; const BEL = '\u0007'; let hidden = false; const code = ansi.code = { bell: BEL, beep: BEL, beginning: `${ESC}G`, down: `${ESC}J`, esc: ESC, getPosition: `${ESC}6n`, hide: `${ESC}?25l`, line: `${ESC}2K`, lineEnd: `${ESC}K`, lineStart: `${ESC}1K`, restorePosition: ESC + (isTerm ? '8' : 'u'), savePosition: ESC + (isTerm ? '7' : 's'), screen: `${ESC}2J`, show: `${ESC}?25h`, up: `${ESC}1J` }; const cursor = ansi.cursor = { get hidden() { return hidden; }, hide() { hidden = true; return code.hide; }, show() { hidden = false; return code.show; }, forward: (count = 1) => `${ESC}${count}C`, backward: (count = 1) => `${ESC}${count}D`, nextLine: (count = 1) => `${ESC}E`.repeat(count), prevLine: (count = 1) => `${ESC}F`.repeat(count), up: (count = 1) => count ? `${ESC}${count}A` : '', down: (count = 1) => count ? `${ESC}${count}B` : '', right: (count = 1) => count ? `${ESC}${count}C` : '', left: (count = 1) => count ? `${ESC}${count}D` : '', to(x, y) { return y ? `${ESC}${y + 1};${x + 1}H` : `${ESC}${x + 1}G`; }, move(x = 0, y = 0) { let res = ''; res += (x < 0) ? cursor.left(-x) : (x > 0) ? cursor.right(x) : ''; res += (y < 0) ? cursor.up(-y) : (y > 0) ? cursor.down(y) : ''; return res; }, restore(state = {}) { let { after, cursor, initial, input, prompt, size, value } = state; initial = utils.isPrimitive(initial) ? String(initial) : ''; input = utils.isPrimitive(input) ? String(input) : ''; value = utils.isPrimitive(value) ? String(value) : ''; if (size) { let codes = ansi.cursor.up(size) + ansi.cursor.to(prompt.length); let diff = input.length - cursor; if (diff > 0) { codes += ansi.cursor.left(diff); } return codes; } if (value || after) { let pos = (!input && !!initial) ? -initial.length : -input.length + cursor; if (after) pos -= after.length; if (input === '' && initial && !prompt.includes(initial)) { pos += initial.length; } return ansi.cursor.move(pos); } } }; const erase = ansi.erase = { screen: code.screen, up: code.up, down: code.down, line: code.line, lineEnd: code.lineEnd, lineStart: code.lineStart, lines(n) { let str = ''; for (let i = 0; i < n; i++) { str += ansi.erase.line + (i < n - 1 ? ansi.cursor.up(1) : ''); } if (n) str += ansi.code.beginning; return str; } }; ansi.clear = (input = '', columns = process.stdout.columns) => { if (!columns) return erase.line + cursor.to(0); let width = str => [...ansiColors.unstyle(str)].length; let lines = input.split(/\r?\n/); let rows = 0; for (let line of lines) { rows += 1 + Math.floor(Math.max(width(line) - 1, 0) / columns); } return (erase.line + cursor.prevLine()).repeat(rows - 1) + erase.line + cursor.to(0); }; }); /** * Base class for creating a new Prompt. * @param {Object} `options` Question object. */ class Prompt extends index.Events { constructor(options = {}) { super(); this.name = options.name; this.type = options.type; this.options = options; theme(this); timer(this); this.state = new state(this); this.initial = [options.initial, options.default].find(v => v != null); this.stdout = options.stdout || process.stdout; this.stdin = options.stdin || process.stdin; this.scale = options.scale || 1; this.term = this.options.term || process.env.TERM_PROGRAM; this.margin = margin(this.options.margin); this.setMaxListeners(0); setOptions(this); } async keypress(input, event = {}) { this.keypressed = true; let key = keypress_1.action(input, keypress_1(input, event), this.options.actions); this.state.keypress = key; this.emit('keypress', input, key); this.emit('state', this.state.clone()); let fn = this.options[key.action] || this[key.action] || this.dispatch; if (typeof fn === 'function') { return await fn.call(this, input, key); } this.alert(); } alert() { delete this.state.alert; if (this.options.show === false) { this.emit('alert'); } else { this.stdout.write(ansi_1.code.beep); } } cursorHide() { this.stdout.write(ansi_1.cursor.hide()); utils.onExit(() => this.cursorShow()); } cursorShow() { this.stdout.write(ansi_1.cursor.show()); } write(str) { if (!str) return; if (this.stdout && this.state.show !== false) { this.stdout.write(str); } this.state.buffer += str; } clear(lines = 0) { let buffer = this.state.buffer; this.state.buffer = ''; if ((!buffer && !lines) || this.options.show === false) return; this.stdout.write(ansi_1.cursor.down(lines) + ansi_1.clear(buffer, this.width)); } restore() { if (this.state.closed || this.options.show === false) return; let { prompt, after, rest } = this.sections(); let { cursor, initial = '', input = '', value = '' } = this; let size = this.state.size = rest.length; let state = { after, cursor, initial, input, prompt, size, value }; let codes = ansi_1.cursor.restore(state); if (codes) { this.stdout.write(codes); } } sections() { let { buffer, input, prompt } = this.state; prompt = ansiColors.unstyle(prompt); let buf = ansiColors.unstyle(buffer); let idx = buf.indexOf(prompt); let header = buf.slice(0, idx); let rest = buf.slice(idx); let lines = rest.split('\n'); let first = lines[0]; let last = lines[lines.length - 1]; let promptLine = prompt + (input ? ' ' + input : ''); let len = promptLine.length; let after = len < first.length ? first.slice(len + 1) : ''; return { header, prompt: first, after, rest: lines.slice(1), last }; } async submit() { this.state.submitted = true; this.state.validating = true; // this will only be called when the prompt is directly submitted // without initializing, i.e. when the prompt is skipped, etc. Otherwize, // "options.onSubmit" is will be handled by the "initialize()" method. if (this.options.onSubmit) { await this.options.onSubmit.call(this, this.name, this.value, this); } let result = this.state.error || await this.validate(this.value, this.state); if (result !== true) { let error = '\n' + this.symbols.pointer + ' '; if (typeof result === 'string') { error += result.trim(); } else { error += 'Invalid input'; }