5417 lines
147 KiB
JavaScript
5417 lines
147 KiB
JavaScript
'use strict';
|
||
|
||
const path = require('node:path');
|
||
const process$1 = require('node:process');
|
||
const require$$0 = require('readline');
|
||
const require$$2 = require('events');
|
||
const node_module = require('node:module');
|
||
const child_process = require('child_process');
|
||
const require$$1$1 = require('path');
|
||
const process$2 = require('process');
|
||
const stream = require('stream');
|
||
const fs = require('node:fs');
|
||
const require$$0$1 = require('os');
|
||
const require$$1 = require('tty');
|
||
const os = require('node:os');
|
||
const require$$0$2 = require('fs');
|
||
const require$$1$2 = require('fs/promises');
|
||
const fsPromises = require('node:fs/promises');
|
||
|
||
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
||
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
||
|
||
const path__default = /*#__PURE__*/_interopDefaultCompat(path);
|
||
const process__default = /*#__PURE__*/_interopDefaultCompat(process$1);
|
||
const require$$0__default = /*#__PURE__*/_interopDefaultCompat(require$$0);
|
||
const require$$2__default = /*#__PURE__*/_interopDefaultCompat(require$$2);
|
||
const require$$1__default$2 = /*#__PURE__*/_interopDefaultCompat(require$$1$1);
|
||
const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
||
const require$$0__default$1 = /*#__PURE__*/_interopDefaultCompat(require$$0$1);
|
||
const require$$1__default = /*#__PURE__*/_interopDefaultCompat(require$$1);
|
||
const os__default = /*#__PURE__*/_interopDefaultCompat(os);
|
||
const require$$0__default$2 = /*#__PURE__*/_interopDefaultCompat(require$$0$2);
|
||
const require$$1__default$1 = /*#__PURE__*/_interopDefaultCompat(require$$1$2);
|
||
const fsPromises__default = /*#__PURE__*/_interopDefaultCompat(fsPromises);
|
||
|
||
function getDefaultExportFromCjs (x) {
|
||
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
||
}
|
||
|
||
var ini$1;
|
||
var hasRequiredIni;
|
||
|
||
function requireIni () {
|
||
if (hasRequiredIni) return ini$1;
|
||
hasRequiredIni = 1;
|
||
const { hasOwnProperty } = Object.prototype;
|
||
|
||
const encode = (obj, opt = {}) => {
|
||
if (typeof opt === 'string') {
|
||
opt = { section: opt };
|
||
}
|
||
opt.align = opt.align === true;
|
||
opt.newline = opt.newline === true;
|
||
opt.sort = opt.sort === true;
|
||
opt.whitespace = opt.whitespace === true || opt.align === true;
|
||
// The `typeof` check is required because accessing the `process` directly fails on browsers.
|
||
/* istanbul ignore next */
|
||
opt.platform = opt.platform || (typeof process !== 'undefined' && process.platform);
|
||
opt.bracketedArray = opt.bracketedArray !== false;
|
||
|
||
/* istanbul ignore next */
|
||
const eol = opt.platform === 'win32' ? '\r\n' : '\n';
|
||
const separator = opt.whitespace ? ' = ' : '=';
|
||
const children = [];
|
||
|
||
const keys = opt.sort ? Object.keys(obj).sort() : Object.keys(obj);
|
||
|
||
let padToChars = 0;
|
||
// If aligning on the separator, then padToChars is determined as follows:
|
||
// 1. Get the keys
|
||
// 2. Exclude keys pointing to objects unless the value is null or an array
|
||
// 3. Add `[]` to array keys
|
||
// 4. Ensure non empty set of keys
|
||
// 5. Reduce the set to the longest `safe` key
|
||
// 6. Get the `safe` length
|
||
if (opt.align) {
|
||
padToChars = safe(
|
||
(
|
||
keys
|
||
.filter(k => obj[k] === null || Array.isArray(obj[k]) || typeof obj[k] !== 'object')
|
||
.map(k => Array.isArray(obj[k]) ? `${k}[]` : k)
|
||
)
|
||
.concat([''])
|
||
.reduce((a, b) => safe(a).length >= safe(b).length ? a : b)
|
||
).length;
|
||
}
|
||
|
||
let out = '';
|
||
const arraySuffix = opt.bracketedArray ? '[]' : '';
|
||
|
||
for (const k of keys) {
|
||
const val = obj[k];
|
||
if (val && Array.isArray(val)) {
|
||
for (const item of val) {
|
||
out += safe(`${k}${arraySuffix}`).padEnd(padToChars, ' ') + separator + safe(item) + eol;
|
||
}
|
||
} else if (val && typeof val === 'object') {
|
||
children.push(k);
|
||
} else {
|
||
out += safe(k).padEnd(padToChars, ' ') + separator + safe(val) + eol;
|
||
}
|
||
}
|
||
|
||
if (opt.section && out.length) {
|
||
out = '[' + safe(opt.section) + ']' + (opt.newline ? eol + eol : eol) + out;
|
||
}
|
||
|
||
for (const k of children) {
|
||
const nk = splitSections(k, '.').join('\\.');
|
||
const section = (opt.section ? opt.section + '.' : '') + nk;
|
||
const child = encode(obj[k], {
|
||
...opt,
|
||
section,
|
||
});
|
||
if (out.length && child.length) {
|
||
out += eol;
|
||
}
|
||
|
||
out += child;
|
||
}
|
||
|
||
return out
|
||
};
|
||
|
||
function splitSections (str, separator) {
|
||
var lastMatchIndex = 0;
|
||
var lastSeparatorIndex = 0;
|
||
var nextIndex = 0;
|
||
var sections = [];
|
||
|
||
do {
|
||
nextIndex = str.indexOf(separator, lastMatchIndex);
|
||
|
||
if (nextIndex !== -1) {
|
||
lastMatchIndex = nextIndex + separator.length;
|
||
|
||
if (nextIndex > 0 && str[nextIndex - 1] === '\\') {
|
||
continue
|
||
}
|
||
|
||
sections.push(str.slice(lastSeparatorIndex, nextIndex));
|
||
lastSeparatorIndex = nextIndex + separator.length;
|
||
}
|
||
} while (nextIndex !== -1)
|
||
|
||
sections.push(str.slice(lastSeparatorIndex));
|
||
|
||
return sections
|
||
}
|
||
|
||
const decode = (str, opt = {}) => {
|
||
opt.bracketedArray = opt.bracketedArray !== false;
|
||
const out = Object.create(null);
|
||
let p = out;
|
||
let section = null;
|
||
// section |key = value
|
||
const re = /^\[([^\]]*)\]\s*$|^([^=]+)(=(.*))?$/i;
|
||
const lines = str.split(/[\r\n]+/g);
|
||
const duplicates = {};
|
||
|
||
for (const line of lines) {
|
||
if (!line || line.match(/^\s*[;#]/) || line.match(/^\s*$/)) {
|
||
continue
|
||
}
|
||
const match = line.match(re);
|
||
if (!match) {
|
||
continue
|
||
}
|
||
if (match[1] !== undefined) {
|
||
section = unsafe(match[1]);
|
||
if (section === '__proto__') {
|
||
// not allowed
|
||
// keep parsing the section, but don't attach it.
|
||
p = Object.create(null);
|
||
continue
|
||
}
|
||
p = out[section] = out[section] || Object.create(null);
|
||
continue
|
||
}
|
||
const keyRaw = unsafe(match[2]);
|
||
let isArray;
|
||
if (opt.bracketedArray) {
|
||
isArray = keyRaw.length > 2 && keyRaw.slice(-2) === '[]';
|
||
} else {
|
||
duplicates[keyRaw] = (duplicates?.[keyRaw] || 0) + 1;
|
||
isArray = duplicates[keyRaw] > 1;
|
||
}
|
||
const key = isArray && keyRaw.endsWith('[]')
|
||
? keyRaw.slice(0, -2) : keyRaw;
|
||
|
||
if (key === '__proto__') {
|
||
continue
|
||
}
|
||
const valueRaw = match[3] ? unsafe(match[4]) : true;
|
||
const value = valueRaw === 'true' ||
|
||
valueRaw === 'false' ||
|
||
valueRaw === 'null' ? JSON.parse(valueRaw)
|
||
: valueRaw;
|
||
|
||
// Convert keys with '[]' suffix to an array
|
||
if (isArray) {
|
||
if (!hasOwnProperty.call(p, key)) {
|
||
p[key] = [];
|
||
} else if (!Array.isArray(p[key])) {
|
||
p[key] = [p[key]];
|
||
}
|
||
}
|
||
|
||
// safeguard against resetting a previously defined
|
||
// array by accidentally forgetting the brackets
|
||
if (Array.isArray(p[key])) {
|
||
p[key].push(value);
|
||
} else {
|
||
p[key] = value;
|
||
}
|
||
}
|
||
|
||
// {a:{y:1},"a.b":{x:2}} --> {a:{y:1,b:{x:2}}}
|
||
// use a filter to return the keys that have to be deleted.
|
||
const remove = [];
|
||
for (const k of Object.keys(out)) {
|
||
if (!hasOwnProperty.call(out, k) ||
|
||
typeof out[k] !== 'object' ||
|
||
Array.isArray(out[k])) {
|
||
continue
|
||
}
|
||
|
||
// see if the parent section is also an object.
|
||
// if so, add it to that, and mark this one for deletion
|
||
const parts = splitSections(k, '.');
|
||
p = out;
|
||
const l = parts.pop();
|
||
const nl = l.replace(/\\\./g, '.');
|
||
for (const part of parts) {
|
||
if (part === '__proto__') {
|
||
continue
|
||
}
|
||
if (!hasOwnProperty.call(p, part) || typeof p[part] !== 'object') {
|
||
p[part] = Object.create(null);
|
||
}
|
||
p = p[part];
|
||
}
|
||
if (p === out && nl === l) {
|
||
continue
|
||
}
|
||
|
||
p[nl] = out[k];
|
||
remove.push(k);
|
||
}
|
||
for (const del of remove) {
|
||
delete out[del];
|
||
}
|
||
|
||
return out
|
||
};
|
||
|
||
const isQuoted = val => {
|
||
return (val.startsWith('"') && val.endsWith('"')) ||
|
||
(val.startsWith("'") && val.endsWith("'"))
|
||
};
|
||
|
||
const safe = val => {
|
||
if (
|
||
typeof val !== 'string' ||
|
||
val.match(/[=\r\n]/) ||
|
||
val.match(/^\[/) ||
|
||
(val.length > 1 && isQuoted(val)) ||
|
||
val !== val.trim()
|
||
) {
|
||
return JSON.stringify(val)
|
||
}
|
||
return val.split(';').join('\\;').split('#').join('\\#')
|
||
};
|
||
|
||
const unsafe = val => {
|
||
val = (val || '').trim();
|
||
if (isQuoted(val)) {
|
||
// remove the single quotes before calling JSON.parse
|
||
if (val.charAt(0) === "'") {
|
||
val = val.slice(1, -1);
|
||
}
|
||
try {
|
||
val = JSON.parse(val);
|
||
} catch {
|
||
// ignore errors
|
||
}
|
||
} else {
|
||
// walk the val to find the first not-escaped ; character
|
||
let esc = false;
|
||
let unesc = '';
|
||
for (let i = 0, l = val.length; i < l; i++) {
|
||
const c = val.charAt(i);
|
||
if (esc) {
|
||
if ('\\;#'.indexOf(c) !== -1) {
|
||
unesc += c;
|
||
} else {
|
||
unesc += '\\' + c;
|
||
}
|
||
|
||
esc = false;
|
||
} else if (';#'.indexOf(c) !== -1) {
|
||
break
|
||
} else if (c === '\\') {
|
||
esc = true;
|
||
} else {
|
||
unesc += c;
|
||
}
|
||
}
|
||
if (esc) {
|
||
unesc += '\\';
|
||
}
|
||
|
||
return unesc.trim()
|
||
}
|
||
return val
|
||
};
|
||
|
||
ini$1 = {
|
||
parse: decode,
|
||
decode,
|
||
stringify: encode,
|
||
encode,
|
||
safe,
|
||
unsafe,
|
||
};
|
||
return ini$1;
|
||
}
|
||
|
||
var iniExports = requireIni();
|
||
const ini = /*@__PURE__*/getDefaultExportFromCjs(iniExports);
|
||
|
||
var prompts$2 = {};
|
||
|
||
var kleur;
|
||
var hasRequiredKleur;
|
||
|
||
function requireKleur () {
|
||
if (hasRequiredKleur) return kleur;
|
||
hasRequiredKleur = 1;
|
||
|
||
let FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM, isTTY=true;
|
||
if (typeof process !== 'undefined') {
|
||
({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = process.env || {});
|
||
isTTY = process.stdout && process.stdout.isTTY;
|
||
}
|
||
|
||
const $ = {
|
||
enabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== 'dumb' && (
|
||
FORCE_COLOR != null && FORCE_COLOR !== '0' || isTTY
|
||
),
|
||
|
||
// modifiers
|
||
reset: init(0, 0),
|
||
bold: init(1, 22),
|
||
dim: init(2, 22),
|
||
italic: init(3, 23),
|
||
underline: init(4, 24),
|
||
inverse: init(7, 27),
|
||
hidden: init(8, 28),
|
||
strikethrough: init(9, 29),
|
||
|
||
// colors
|
||
black: init(30, 39),
|
||
red: init(31, 39),
|
||
green: init(32, 39),
|
||
yellow: init(33, 39),
|
||
blue: init(34, 39),
|
||
magenta: init(35, 39),
|
||
cyan: init(36, 39),
|
||
white: init(37, 39),
|
||
gray: init(90, 39),
|
||
grey: init(90, 39),
|
||
|
||
// background colors
|
||
bgBlack: init(40, 49),
|
||
bgRed: init(41, 49),
|
||
bgGreen: init(42, 49),
|
||
bgYellow: init(43, 49),
|
||
bgBlue: init(44, 49),
|
||
bgMagenta: init(45, 49),
|
||
bgCyan: init(46, 49),
|
||
bgWhite: init(47, 49)
|
||
};
|
||
|
||
function run(arr, str) {
|
||
let i=0, tmp, beg='', end='';
|
||
for (; i < arr.length; i++) {
|
||
tmp = arr[i];
|
||
beg += tmp.open;
|
||
end += tmp.close;
|
||
if (!!~str.indexOf(tmp.close)) {
|
||
str = str.replace(tmp.rgx, tmp.close + tmp.open);
|
||
}
|
||
}
|
||
return beg + str + end;
|
||
}
|
||
|
||
function chain(has, keys) {
|
||
let ctx = { has, keys };
|
||
|
||
ctx.reset = $.reset.bind(ctx);
|
||
ctx.bold = $.bold.bind(ctx);
|
||
ctx.dim = $.dim.bind(ctx);
|
||
ctx.italic = $.italic.bind(ctx);
|
||
ctx.underline = $.underline.bind(ctx);
|
||
ctx.inverse = $.inverse.bind(ctx);
|
||
ctx.hidden = $.hidden.bind(ctx);
|
||
ctx.strikethrough = $.strikethrough.bind(ctx);
|
||
|
||
ctx.black = $.black.bind(ctx);
|
||
ctx.red = $.red.bind(ctx);
|
||
ctx.green = $.green.bind(ctx);
|
||
ctx.yellow = $.yellow.bind(ctx);
|
||
ctx.blue = $.blue.bind(ctx);
|
||
ctx.magenta = $.magenta.bind(ctx);
|
||
ctx.cyan = $.cyan.bind(ctx);
|
||
ctx.white = $.white.bind(ctx);
|
||
ctx.gray = $.gray.bind(ctx);
|
||
ctx.grey = $.grey.bind(ctx);
|
||
|
||
ctx.bgBlack = $.bgBlack.bind(ctx);
|
||
ctx.bgRed = $.bgRed.bind(ctx);
|
||
ctx.bgGreen = $.bgGreen.bind(ctx);
|
||
ctx.bgYellow = $.bgYellow.bind(ctx);
|
||
ctx.bgBlue = $.bgBlue.bind(ctx);
|
||
ctx.bgMagenta = $.bgMagenta.bind(ctx);
|
||
ctx.bgCyan = $.bgCyan.bind(ctx);
|
||
ctx.bgWhite = $.bgWhite.bind(ctx);
|
||
|
||
return ctx;
|
||
}
|
||
|
||
function init(open, close) {
|
||
let blk = {
|
||
open: `\x1b[${open}m`,
|
||
close: `\x1b[${close}m`,
|
||
rgx: new RegExp(`\\x1b\\[${close}m`, 'g')
|
||
};
|
||
return function (txt) {
|
||
if (this !== void 0 && this.has !== void 0) {
|
||
!!~this.has.indexOf(open) || (this.has.push(open),this.keys.push(blk));
|
||
return txt === void 0 ? this : $.enabled ? run(this.keys, txt+'') : txt+'';
|
||
}
|
||
return txt === void 0 ? chain([open], [blk]) : $.enabled ? run([blk], txt+'') : txt+'';
|
||
};
|
||
}
|
||
|
||
kleur = $;
|
||
return kleur;
|
||
}
|
||
|
||
var action;
|
||
var hasRequiredAction;
|
||
|
||
function requireAction () {
|
||
if (hasRequiredAction) return action;
|
||
hasRequiredAction = 1;
|
||
|
||
action = (key, isSelect) => {
|
||
if (key.meta && key.name !== 'escape') return;
|
||
|
||
if (key.ctrl) {
|
||
if (key.name === 'a') return 'first';
|
||
if (key.name === 'c') return 'abort';
|
||
if (key.name === 'd') return 'abort';
|
||
if (key.name === 'e') return 'last';
|
||
if (key.name === 'g') return 'reset';
|
||
if (key.name === 'n') return 'down';
|
||
if (key.name === 'p') return 'up';
|
||
// avoid any non-ascii characters
|
||
return
|
||
}
|
||
|
||
if (isSelect) {
|
||
if (key.name === 'j') return 'down';
|
||
if (key.name === 'k') return 'up';
|
||
}
|
||
|
||
if (key.name === 'return') return 'submit';
|
||
if (key.name === 'enter') return 'submit'; // ctrl + J
|
||
if (key.name === 'backspace') return 'delete';
|
||
if (key.name === 'delete') return 'deleteForward';
|
||
if (key.name === 'abort') return 'abort';
|
||
if (key.name === 'escape') return 'exit';
|
||
// TODO: shift tab for prev
|
||
if (key.name === 'tab') return 'next';
|
||
if (key.name === 'pagedown') return 'nextPage';
|
||
if (key.name === 'pageup') return 'prevPage';
|
||
// TODO create home() in prompt types (e.g. TextPrompt)
|
||
if (key.name === 'home') return 'home';
|
||
// TODO create end() in prompt types (e.g. TextPrompt)
|
||
if (key.name === 'end') return 'end';
|
||
|
||
if (key.name === 'up') return 'up';
|
||
if (key.name === 'down') return 'down';
|
||
if (key.name === 'right') return 'right';
|
||
if (key.name === 'left') return 'left';
|
||
|
||
return false;
|
||
};
|
||
return action;
|
||
}
|
||
|
||
var strip;
|
||
var hasRequiredStrip;
|
||
|
||
function requireStrip () {
|
||
if (hasRequiredStrip) return strip;
|
||
hasRequiredStrip = 1;
|
||
|
||
strip = str => {
|
||
const pattern = [
|
||
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
|
||
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))'
|
||
].join('|');
|
||
|
||
const RGX = new RegExp(pattern, 'g');
|
||
return typeof str === 'string' ? str.replace(RGX, '') : str;
|
||
};
|
||
return strip;
|
||
}
|
||
|
||
var src;
|
||
var hasRequiredSrc;
|
||
|
||
function requireSrc () {
|
||
if (hasRequiredSrc) return src;
|
||
hasRequiredSrc = 1;
|
||
|
||
const ESC = '\x1B';
|
||
const CSI = `${ESC}[`;
|
||
const beep = '\u0007';
|
||
|
||
const cursor = {
|
||
to(x, y) {
|
||
if (!y) return `${CSI}${x + 1}G`;
|
||
return `${CSI}${y + 1};${x + 1}H`;
|
||
},
|
||
move(x, y) {
|
||
let ret = '';
|
||
|
||
if (x < 0) ret += `${CSI}${-x}D`;
|
||
else if (x > 0) ret += `${CSI}${x}C`;
|
||
|
||
if (y < 0) ret += `${CSI}${-y}A`;
|
||
else if (y > 0) ret += `${CSI}${y}B`;
|
||
|
||
return ret;
|
||
},
|
||
up: (count = 1) => `${CSI}${count}A`,
|
||
down: (count = 1) => `${CSI}${count}B`,
|
||
forward: (count = 1) => `${CSI}${count}C`,
|
||
backward: (count = 1) => `${CSI}${count}D`,
|
||
nextLine: (count = 1) => `${CSI}E`.repeat(count),
|
||
prevLine: (count = 1) => `${CSI}F`.repeat(count),
|
||
left: `${CSI}G`,
|
||
hide: `${CSI}?25l`,
|
||
show: `${CSI}?25h`,
|
||
save: `${ESC}7`,
|
||
restore: `${ESC}8`
|
||
};
|
||
|
||
const scroll = {
|
||
up: (count = 1) => `${CSI}S`.repeat(count),
|
||
down: (count = 1) => `${CSI}T`.repeat(count)
|
||
};
|
||
|
||
const erase = {
|
||
screen: `${CSI}2J`,
|
||
up: (count = 1) => `${CSI}1J`.repeat(count),
|
||
down: (count = 1) => `${CSI}J`.repeat(count),
|
||
line: `${CSI}2K`,
|
||
lineEnd: `${CSI}K`,
|
||
lineStart: `${CSI}1K`,
|
||
lines(count) {
|
||
let clear = '';
|
||
for (let i = 0; i < count; i++)
|
||
clear += this.line + (i < count - 1 ? cursor.up() : '');
|
||
if (count)
|
||
clear += cursor.left;
|
||
return clear;
|
||
}
|
||
};
|
||
|
||
src = { cursor, scroll, erase, beep };
|
||
return src;
|
||
}
|
||
|
||
var clear;
|
||
var hasRequiredClear;
|
||
|
||
function requireClear () {
|
||
if (hasRequiredClear) return clear;
|
||
hasRequiredClear = 1;
|
||
|
||
const strip = requireStrip();
|
||
const { erase, cursor } = requireSrc();
|
||
|
||
const width = str => [...strip(str)].length;
|
||
|
||
/**
|
||
* @param {string} prompt
|
||
* @param {number} perLine
|
||
*/
|
||
clear = function(prompt, perLine) {
|
||
if (!perLine) return erase.line + cursor.to(0);
|
||
|
||
let rows = 0;
|
||
const lines = prompt.split(/\r?\n/);
|
||
for (let line of lines) {
|
||
rows += 1 + Math.floor(Math.max(width(line) - 1, 0) / perLine);
|
||
}
|
||
|
||
return erase.lines(rows);
|
||
};
|
||
return clear;
|
||
}
|
||
|
||
var figures_1;
|
||
var hasRequiredFigures;
|
||
|
||
function requireFigures () {
|
||
if (hasRequiredFigures) return figures_1;
|
||
hasRequiredFigures = 1;
|
||
|
||
const main = {
|
||
arrowUp: '↑',
|
||
arrowDown: '↓',
|
||
arrowLeft: '←',
|
||
arrowRight: '→',
|
||
radioOn: '◉',
|
||
radioOff: '◯',
|
||
tick: '✔',
|
||
cross: '✖',
|
||
ellipsis: '…',
|
||
pointerSmall: '›',
|
||
line: '─',
|
||
pointer: '❯'
|
||
};
|
||
const win = {
|
||
arrowUp: main.arrowUp,
|
||
arrowDown: main.arrowDown,
|
||
arrowLeft: main.arrowLeft,
|
||
arrowRight: main.arrowRight,
|
||
radioOn: '(*)',
|
||
radioOff: '( )',
|
||
tick: '√',
|
||
cross: '×',
|
||
ellipsis: '...',
|
||
pointerSmall: '»',
|
||
line: '─',
|
||
pointer: '>'
|
||
};
|
||
const figures = process.platform === 'win32' ? win : main;
|
||
|
||
figures_1 = figures;
|
||
return figures_1;
|
||
}
|
||
|
||
var style;
|
||
var hasRequiredStyle;
|
||
|
||
function requireStyle () {
|
||
if (hasRequiredStyle) return style;
|
||
hasRequiredStyle = 1;
|
||
|
||
const c = requireKleur();
|
||
const figures = requireFigures();
|
||
|
||
// rendering user input.
|
||
const styles = Object.freeze({
|
||
password: { scale: 1, render: input => '*'.repeat(input.length) },
|
||
emoji: { scale: 2, render: input => '😃'.repeat(input.length) },
|
||
invisible: { scale: 0, render: input => '' },
|
||
default: { scale: 1, render: input => `${input}` }
|
||
});
|
||
const render = type => styles[type] || styles.default;
|
||
|
||
// icon to signalize a prompt.
|
||
const symbols = Object.freeze({
|
||
aborted: c.red(figures.cross),
|
||
done: c.green(figures.tick),
|
||
exited: c.yellow(figures.cross),
|
||
default: c.cyan('?')
|
||
});
|
||
|
||
const symbol = (done, aborted, exited) =>
|
||
aborted ? symbols.aborted : exited ? symbols.exited : done ? symbols.done : symbols.default;
|
||
|
||
// between the question and the user's input.
|
||
const delimiter = completing =>
|
||
c.gray(completing ? figures.ellipsis : figures.pointerSmall);
|
||
|
||
const item = (expandable, expanded) =>
|
||
c.gray(expandable ? (expanded ? figures.pointerSmall : '+') : figures.line);
|
||
|
||
style = {
|
||
styles,
|
||
render,
|
||
symbols,
|
||
symbol,
|
||
delimiter,
|
||
item
|
||
};
|
||
return style;
|
||
}
|
||
|
||
var lines;
|
||
var hasRequiredLines;
|
||
|
||
function requireLines () {
|
||
if (hasRequiredLines) return lines;
|
||
hasRequiredLines = 1;
|
||
|
||
const strip = requireStrip();
|
||
|
||
/**
|
||
* @param {string} msg
|
||
* @param {number} perLine
|
||
*/
|
||
lines = function (msg, perLine) {
|
||
let lines = String(strip(msg) || '').split(/\r?\n/);
|
||
|
||
if (!perLine) return lines.length;
|
||
return lines.map(l => Math.ceil(l.length / perLine))
|
||
.reduce((a, b) => a + b);
|
||
};
|
||
return lines;
|
||
}
|
||
|
||
var wrap;
|
||
var hasRequiredWrap;
|
||
|
||
function requireWrap () {
|
||
if (hasRequiredWrap) return wrap;
|
||
hasRequiredWrap = 1;
|
||
|
||
/**
|
||
* @param {string} msg The message to wrap
|
||
* @param {object} opts
|
||
* @param {number|string} [opts.margin] Left margin
|
||
* @param {number} opts.width Maximum characters per line including the margin
|
||
*/
|
||
wrap = (msg, opts = {}) => {
|
||
const tab = Number.isSafeInteger(parseInt(opts.margin))
|
||
? new Array(parseInt(opts.margin)).fill(' ').join('')
|
||
: (opts.margin || '');
|
||
|
||
const width = opts.width;
|
||
|
||
return (msg || '').split(/\r?\n/g)
|
||
.map(line => line
|
||
.split(/\s+/g)
|
||
.reduce((arr, w) => {
|
||
if (w.length + tab.length >= width || arr[arr.length - 1].length + w.length + 1 < width)
|
||
arr[arr.length - 1] += ` ${w}`;
|
||
else arr.push(`${tab}${w}`);
|
||
return arr;
|
||
}, [ tab ])
|
||
.join('\n'))
|
||
.join('\n');
|
||
};
|
||
return wrap;
|
||
}
|
||
|
||
var entriesToDisplay;
|
||
var hasRequiredEntriesToDisplay;
|
||
|
||
function requireEntriesToDisplay () {
|
||
if (hasRequiredEntriesToDisplay) return entriesToDisplay;
|
||
hasRequiredEntriesToDisplay = 1;
|
||
|
||
/**
|
||
* Determine what entries should be displayed on the screen, based on the
|
||
* currently selected index and the maximum visible. Used in list-based
|
||
* prompts like `select` and `multiselect`.
|
||
*
|
||
* @param {number} cursor the currently selected entry
|
||
* @param {number} total the total entries available to display
|
||
* @param {number} [maxVisible] the number of entries that can be displayed
|
||
*/
|
||
entriesToDisplay = (cursor, total, maxVisible) => {
|
||
maxVisible = maxVisible || total;
|
||
|
||
let startIndex = Math.min(total- maxVisible, cursor - Math.floor(maxVisible / 2));
|
||
if (startIndex < 0) startIndex = 0;
|
||
|
||
let endIndex = Math.min(startIndex + maxVisible, total);
|
||
|
||
return { startIndex, endIndex };
|
||
};
|
||
return entriesToDisplay;
|
||
}
|
||
|
||
var util;
|
||
var hasRequiredUtil;
|
||
|
||
function requireUtil () {
|
||
if (hasRequiredUtil) return util;
|
||
hasRequiredUtil = 1;
|
||
|
||
util = {
|
||
action: requireAction(),
|
||
clear: requireClear(),
|
||
style: requireStyle(),
|
||
strip: requireStrip(),
|
||
figures: requireFigures(),
|
||
lines: requireLines(),
|
||
wrap: requireWrap(),
|
||
entriesToDisplay: requireEntriesToDisplay()
|
||
};
|
||
return util;
|
||
}
|
||
|
||
var prompt;
|
||
var hasRequiredPrompt;
|
||
|
||
function requirePrompt () {
|
||
if (hasRequiredPrompt) return prompt;
|
||
hasRequiredPrompt = 1;
|
||
|
||
const readline = require$$0__default;
|
||
const { action } = requireUtil();
|
||
const EventEmitter = require$$2__default;
|
||
const { beep, cursor } = requireSrc();
|
||
const color = requireKleur();
|
||
|
||
/**
|
||
* Base prompt skeleton
|
||
* @param {Stream} [opts.stdin] The Readable stream to listen to
|
||
* @param {Stream} [opts.stdout] The Writable stream to write readline data to
|
||
*/
|
||
class Prompt extends EventEmitter {
|
||
constructor(opts={}) {
|
||
super();
|
||
|
||
this.firstRender = true;
|
||
this.in = opts.stdin || process.stdin;
|
||
this.out = opts.stdout || process.stdout;
|
||
this.onRender = (opts.onRender || (() => void 0)).bind(this);
|
||
const rl = readline.createInterface({ input:this.in, escapeCodeTimeout:50 });
|
||
readline.emitKeypressEvents(this.in, rl);
|
||
|
||
if (this.in.isTTY) this.in.setRawMode(true);
|
||
const isSelect = [ 'SelectPrompt', 'MultiselectPrompt' ].indexOf(this.constructor.name) > -1;
|
||
const keypress = (str, key) => {
|
||
let a = action(key, isSelect);
|
||
if (a === false) {
|
||
this._ && this._(str, key);
|
||
} else if (typeof this[a] === 'function') {
|
||
this[a](key);
|
||
} else {
|
||
this.bell();
|
||
}
|
||
};
|
||
|
||
this.close = () => {
|
||
this.out.write(cursor.show);
|
||
this.in.removeListener('keypress', keypress);
|
||
if (this.in.isTTY) this.in.setRawMode(false);
|
||
rl.close();
|
||
this.emit(this.aborted ? 'abort' : this.exited ? 'exit' : 'submit', this.value);
|
||
this.closed = true;
|
||
};
|
||
|
||
this.in.on('keypress', keypress);
|
||
}
|
||
|
||
fire() {
|
||
this.emit('state', {
|
||
value: this.value,
|
||
aborted: !!this.aborted,
|
||
exited: !!this.exited
|
||
});
|
||
}
|
||
|
||
bell() {
|
||
this.out.write(beep);
|
||
}
|
||
|
||
render() {
|
||
this.onRender(color);
|
||
if (this.firstRender) this.firstRender = false;
|
||
}
|
||
}
|
||
|
||
prompt = Prompt;
|
||
return prompt;
|
||
}
|
||
|
||
var text;
|
||
var hasRequiredText;
|
||
|
||
function requireText () {
|
||
if (hasRequiredText) return text;
|
||
hasRequiredText = 1;
|
||
const color = requireKleur();
|
||
const Prompt = requirePrompt();
|
||
const { erase, cursor } = requireSrc();
|
||
const { style, clear, lines, figures } = requireUtil();
|
||
|
||
/**
|
||
* TextPrompt Base Element
|
||
* @param {Object} opts Options
|
||
* @param {String} opts.message Message
|
||
* @param {String} [opts.style='default'] Render style
|
||
* @param {String} [opts.initial] Default value
|
||
* @param {Function} [opts.validate] Validate function
|
||
* @param {Stream} [opts.stdin] The Readable stream to listen to
|
||
* @param {Stream} [opts.stdout] The Writable stream to write readline data to
|
||
* @param {String} [opts.error] The invalid error label
|
||
*/
|
||
class TextPrompt extends Prompt {
|
||
constructor(opts={}) {
|
||
super(opts);
|
||
this.transform = style.render(opts.style);
|
||
this.scale = this.transform.scale;
|
||
this.msg = opts.message;
|
||
this.initial = opts.initial || ``;
|
||
this.validator = opts.validate || (() => true);
|
||
this.value = ``;
|
||
this.errorMsg = opts.error || `Please Enter A Valid Value`;
|
||
this.cursor = Number(!!this.initial);
|
||
this.cursorOffset = 0;
|
||
this.clear = clear(``, this.out.columns);
|
||
this.render();
|
||
}
|
||
|
||
set value(v) {
|
||
if (!v && this.initial) {
|
||
this.placeholder = true;
|
||
this.rendered = color.gray(this.transform.render(this.initial));
|
||
} else {
|
||
this.placeholder = false;
|
||
this.rendered = this.transform.render(v);
|
||
}
|
||
this._value = v;
|
||
this.fire();
|
||
}
|
||
|
||
get value() {
|
||
return this._value;
|
||
}
|
||
|
||
reset() {
|
||
this.value = ``;
|
||
this.cursor = Number(!!this.initial);
|
||
this.cursorOffset = 0;
|
||
this.fire();
|
||
this.render();
|
||
}
|
||
|
||
exit() {
|
||
this.abort();
|
||
}
|
||
|
||
abort() {
|
||
this.value = this.value || this.initial;
|
||
this.done = this.aborted = true;
|
||
this.error = false;
|
||
this.red = false;
|
||
this.fire();
|
||
this.render();
|
||
this.out.write('\n');
|
||
this.close();
|
||
}
|
||
|
||
async validate() {
|
||
let valid = await this.validator(this.value);
|
||
if (typeof valid === `string`) {
|
||
this.errorMsg = valid;
|
||
valid = false;
|
||
}
|
||
this.error = !valid;
|
||
}
|
||
|
||
async submit() {
|
||
this.value = this.value || this.initial;
|
||
this.cursorOffset = 0;
|
||
this.cursor = this.rendered.length;
|
||
await this.validate();
|
||
if (this.error) {
|
||
this.red = true;
|
||
this.fire();
|
||
this.render();
|
||
return;
|
||
}
|
||
this.done = true;
|
||
this.aborted = false;
|
||
this.fire();
|
||
this.render();
|
||
this.out.write('\n');
|
||
this.close();
|
||
}
|
||
|
||
next() {
|
||
if (!this.placeholder) return this.bell();
|
||
this.value = this.initial;
|
||
this.cursor = this.rendered.length;
|
||
this.fire();
|
||
this.render();
|
||
}
|
||
|
||
moveCursor(n) {
|
||
if (this.placeholder) return;
|
||
this.cursor = this.cursor+n;
|
||
this.cursorOffset += n;
|
||
}
|
||
|
||
_(c, key) {
|
||
let s1 = this.value.slice(0, this.cursor);
|
||
let s2 = this.value.slice(this.cursor);
|
||
this.value = `${s1}${c}${s2}`;
|
||
this.red = false;
|
||
this.cursor = this.placeholder ? 0 : s1.length+1;
|
||
this.render();
|
||
}
|
||
|
||
delete() {
|
||
if (this.isCursorAtStart()) return this.bell();
|
||
let s1 = this.value.slice(0, this.cursor-1);
|
||
let s2 = this.value.slice(this.cursor);
|
||
this.value = `${s1}${s2}`;
|
||
this.red = false;
|
||
if (this.isCursorAtStart()) {
|
||
this.cursorOffset = 0;
|
||
} else {
|
||
this.cursorOffset++;
|
||
this.moveCursor(-1);
|
||
}
|
||
this.render();
|
||
}
|
||
|
||
deleteForward() {
|
||
if(this.cursor*this.scale >= this.rendered.length || this.placeholder) return this.bell();
|
||
let s1 = this.value.slice(0, this.cursor);
|
||
let s2 = this.value.slice(this.cursor+1);
|
||
this.value = `${s1}${s2}`;
|
||
this.red = false;
|
||
if (this.isCursorAtEnd()) {
|
||
this.cursorOffset = 0;
|
||
} else {
|
||
this.cursorOffset++;
|
||
}
|
||
this.render();
|
||
}
|
||
|
||
first() {
|
||
this.cursor = 0;
|
||
this.render();
|
||
}
|
||
|
||
last() {
|
||
this.cursor = this.value.length;
|
||
this.render();
|
||
}
|
||
|
||
left() {
|
||
if (this.cursor <= 0 || this.placeholder) return this.bell();
|
||
this.moveCursor(-1);
|
||
this.render();
|
||
}
|
||
|
||
right() {
|
||
if (this.cursor*this.scale >= this.rendered.length || this.placeholder) return this.bell();
|
||
this.moveCursor(1);
|
||
this.render();
|
||
}
|
||
|
||
isCursorAtStart() {
|
||
return this.cursor === 0 || (this.placeholder && this.cursor === 1);
|
||
}
|
||
|
||
isCursorAtEnd() {
|
||
return this.cursor === this.rendered.length || (this.placeholder && this.cursor === this.rendered.length + 1)
|
||
}
|
||
|
||
render() {
|
||
if (this.closed) return;
|
||
if (!this.firstRender) {
|
||
if (this.outputError)
|
||
this.out.write(cursor.down(lines(this.outputError, this.out.columns) - 1) + clear(this.outputError, this.out.columns));
|
||
this.out.write(clear(this.outputText, this.out.columns));
|
||
}
|
||
super.render();
|
||
this.outputError = '';
|
||
|
||
this.outputText = [
|
||
style.symbol(this.done, this.aborted),
|
||
color.bold(this.msg),
|
||
style.delimiter(this.done),
|
||
this.red ? color.red(this.rendered) : this.rendered
|
||
].join(` `);
|
||
|
||
if (this.error) {
|
||
this.outputError += this.errorMsg.split(`\n`)
|
||
.reduce((a, l, i) => a + `\n${i ? ' ' : figures.pointerSmall} ${color.red().italic(l)}`, ``);
|
||
}
|
||
|
||
this.out.write(erase.line + cursor.to(0) + this.outputText + cursor.save + this.outputError + cursor.restore + cursor.move(this.cursorOffset, 0));
|
||
}
|
||
}
|
||
|
||
text = TextPrompt;
|
||
return text;
|
||
}
|
||
|
||
var select;
|
||
var hasRequiredSelect;
|
||
|
||
function requireSelect () {
|
||
if (hasRequiredSelect) return select;
|
||
hasRequiredSelect = 1;
|
||
|
||
const color = requireKleur();
|
||
const Prompt = requirePrompt();
|
||
const { style, clear, figures, wrap, entriesToDisplay } = requireUtil();
|
||
const { cursor } = requireSrc();
|
||
|
||
/**
|
||
* SelectPrompt Base Element
|
||
* @param {Object} opts Options
|
||
* @param {String} opts.message Message
|
||
* @param {Array} opts.choices Array of choice objects
|
||
* @param {String} [opts.hint] Hint to display
|
||
* @param {Number} [opts.initial] Index of default value
|
||
* @param {Stream} [opts.stdin] The Readable stream to listen to
|
||
* @param {Stream} [opts.stdout] The Writable stream to write readline data to
|
||
* @param {Number} [opts.optionsPerPage=10] Max options to display at once
|
||
*/
|
||
class SelectPrompt extends Prompt {
|
||
constructor(opts={}) {
|
||
super(opts);
|
||
this.msg = opts.message;
|
||
this.hint = opts.hint || '- Use arrow-keys. Return to submit.';
|
||
this.warn = opts.warn || '- This option is disabled';
|
||
this.cursor = opts.initial || 0;
|
||
this.choices = opts.choices.map((ch, idx) => {
|
||
if (typeof ch === 'string')
|
||
ch = {title: ch, value: idx};
|
||
return {
|
||
title: ch && (ch.title || ch.value || ch),
|
||
value: ch && (ch.value === undefined ? idx : ch.value),
|
||
description: ch && ch.description,
|
||
selected: ch && ch.selected,
|
||
disabled: ch && ch.disabled
|
||
};
|
||
});
|
||
this.optionsPerPage = opts.optionsPerPage || 10;
|
||
this.value = (this.choices[this.cursor] || {}).value;
|
||
this.clear = clear('', this.out.columns);
|
||
this.render();
|
||
}
|
||
|
||
moveCursor(n) {
|
||
this.cursor = n;
|
||
this.value = this.choices[n].value;
|
||
this.fire();
|
||
}
|
||
|
||
reset() {
|
||
this.moveCursor(0);
|
||
this.fire();
|
||
this.render();
|
||
}
|
||
|
||
exit() {
|
||
this.abort();
|
||
}
|
||
|
||
abort() {
|
||
this.done = this.aborted = true;
|
||
this.fire();
|
||
this.render();
|
||
this.out.write('\n');
|
||
this.close();
|
||
}
|
||
|
||
submit() {
|
||
if (!this.selection.disabled) {
|
||
this.done = true;
|
||
this.aborted = false;
|
||
this.fire();
|
||
this.render();
|
||
this.out.write('\n');
|
||
this.close();
|
||
} else
|
||
this.bell();
|
||
}
|
||
|
||
first() {
|
||
this.moveCursor(0);
|
||
this.render();
|
||
}
|
||
|
||
last() {
|
||
this.moveCursor(this.choices.length - 1);
|
||
this.render();
|
||
}
|
||
|
||
up() {
|
||
if (this.cursor === 0) {
|
||
this.moveCursor(this.choices.length - 1);
|
||
} else {
|
||
this.moveCursor(this.cursor - 1);
|
||
}
|
||
this.render();
|
||
}
|
||
|
||
down() {
|
||
if (this.cursor === this.choices.length - 1) {
|
||
this.moveCursor(0);
|
||
} else {
|
||
this.moveCursor(this.cursor + 1);
|
||
}
|
||
this.render();
|
||
}
|
||
|
||
next() {
|
||
this.moveCursor((this.cursor + 1) % this.choices.length);
|
||
this.render();
|
||
}
|
||
|
||
_(c, key) {
|
||
if (c === ' ') return this.submit();
|
||
}
|
||
|
||
get selection() {
|
||
return this.choices[this.cursor];
|
||
}
|
||
|
||
render() {
|
||
if (this.closed) return;
|
||
if (this.firstRender) this.out.write(cursor.hide);
|
||
else this.out.write(clear(this.outputText, this.out.columns));
|
||
super.render();
|
||
|
||
let { startIndex, endIndex } = entriesToDisplay(this.cursor, this.choices.length, this.optionsPerPage);
|
||
|
||
// Print prompt
|
||
this.outputText = [
|
||
style.symbol(this.done, this.aborted),
|
||
color.bold(this.msg),
|
||
style.delimiter(false),
|
||
this.done ? this.selection.title : this.selection.disabled
|
||
? color.yellow(this.warn) : color.gray(this.hint)
|
||
].join(' ');
|
||
|
||
// Print choices
|
||
if (!this.done) {
|
||
this.outputText += '\n';
|
||
for (let i = startIndex; i < endIndex; i++) {
|
||
let title, prefix, desc = '', v = this.choices[i];
|
||
|
||
// Determine whether to display "more choices" indicators
|
||
if (i === startIndex && startIndex > 0) {
|
||
prefix = figures.arrowUp;
|
||
} else if (i === endIndex - 1 && endIndex < this.choices.length) {
|
||
prefix = figures.arrowDown;
|
||
} else {
|
||
prefix = ' ';
|
||
}
|
||
|
||
if (v.disabled) {
|
||
title = this.cursor === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title);
|
||
prefix = (this.cursor === i ? color.bold().gray(figures.pointer) + ' ' : ' ') + prefix;
|
||
} else {
|
||
title = this.cursor === i ? color.cyan().underline(v.title) : v.title;
|
||
prefix = (this.cursor === i ? color.cyan(figures.pointer) + ' ' : ' ') + prefix;
|
||
if (v.description && this.cursor === i) {
|
||
desc = ` - ${v.description}`;
|
||
if (prefix.length + title.length + desc.length >= this.out.columns
|
||
|| v.description.split(/\r?\n/).length > 1) {
|
||
desc = '\n' + wrap(v.description, { margin: 3, width: this.out.columns });
|
||
}
|
||
}
|
||
}
|
||
|
||
this.outputText += `${prefix} ${title}${color.gray(desc)}\n`;
|
||
}
|
||
}
|
||
|
||
this.out.write(this.outputText);
|
||
}
|
||
}
|
||
|
||
select = SelectPrompt;
|
||
return select;
|
||
}
|
||
|
||
var toggle;
|
||
var hasRequiredToggle;
|
||
|
||
function requireToggle () {
|
||
if (hasRequiredToggle) return toggle;
|
||
hasRequiredToggle = 1;
|
||
const color = requireKleur();
|
||
const Prompt = requirePrompt();
|
||
const { style, clear } = requireUtil();
|
||
const { cursor, erase } = requireSrc();
|
||
|
||
/**
|
||
* TogglePrompt Base Element
|
||
* @param {Object} opts Options
|
||
* @param {String} opts.message Message
|
||
* @param {Boolean} [opts.initial=false] Default value
|
||
* @param {String} [opts.active='no'] Active label
|
||
* @param {String} [opts.inactive='off'] Inactive label
|
||
* @param {Stream} [opts.stdin] The Readable stream to listen to
|
||
* @param {Stream} [opts.stdout] The Writable stream to write readline data to
|
||
*/
|
||
class TogglePrompt extends Prompt {
|
||
constructor(opts={}) {
|
||
super(opts);
|
||
this.msg = opts.message;
|
||
this.value = !!opts.initial;
|
||
this.active = opts.active || 'on';
|
||
this.inactive = opts.inactive || 'off';
|
||
this.initialValue = this.value;
|
||
this.render();
|
||
}
|
||
|
||
reset() {
|
||
this.value = this.initialValue;
|
||
this.fire();
|
||
this.render();
|
||
}
|
||
|
||
exit() {
|
||
this.abort();
|
||
}
|
||
|
||
abort() {
|
||
this.done = this.aborted = true;
|
||
this.fire();
|
||
this.render();
|
||
this.out.write('\n');
|
||
this.close();
|
||
}
|
||
|
||
submit() {
|
||
this.done = true;
|
||
this.aborted = false;
|
||
this.fire();
|
||
this.render();
|
||
this.out.write('\n');
|
||
this.close();
|
||
}
|
||
|
||
deactivate() {
|
||
if (this.value === false) return this.bell();
|
||
this.value = false;
|
||
this.render();
|
||
}
|
||
|
||
activate() {
|
||
if (this.value === true) return this.bell();
|
||
this.value = true;
|
||
this.render();
|
||
}
|
||
|
||
delete() {
|
||
this.deactivate();
|
||
}
|
||
left() {
|
||
this.deactivate();
|
||
}
|
||
right() {
|
||
this.activate();
|
||
}
|
||
down() {
|
||
this.deactivate();
|
||
}
|
||
up() {
|
||
this.activate();
|
||
}
|
||
|
||
next() {
|
||
this.value = !this.value;
|
||
this.fire();
|
||
this.render();
|
||
}
|
||
|
||
_(c, key) {
|
||
if (c === ' ') {
|
||
this.value = !this.value;
|
||
} else if (c === '1') {
|
||
this.value = true;
|
||
} else if (c === '0') {
|
||
this.value = false;
|
||
} else return this.bell();
|
||
this.render();
|
||
}
|
||
|
||
render() {
|
||
if (this.closed) return;
|
||
if (this.firstRender) this.out.write(cursor.hide);
|
||
else this.out.write(clear(this.outputText, this.out.columns));
|
||
super.render();
|
||
|
||
this.outputText = [
|
||
style.symbol(this.done, this.aborted),
|
||
color.bold(this.msg),
|
||
style.delimiter(this.done),
|
||
this.value ? this.inactive : color.cyan().underline(this.inactive),
|
||
color.gray('/'),
|
||
this.value ? color.cyan().underline(this.active) : this.active
|
||
].join(' ');
|
||
|
||
this.out.write(erase.line + cursor.to(0) + this.outputText);
|
||
}
|
||
}
|
||
|
||
toggle = TogglePrompt;
|
||
return toggle;
|
||
}
|
||
|
||
var datepart;
|
||
var hasRequiredDatepart;
|
||
|
||
function requireDatepart () {
|
||
if (hasRequiredDatepart) return datepart;
|
||
hasRequiredDatepart = 1;
|
||
|
||
class DatePart {
|
||
constructor({token, date, parts, locales}) {
|
||
this.token = token;
|
||
this.date = date || new Date();
|
||
this.parts = parts || [this];
|
||
this.locales = locales || {};
|
||
}
|
||
|
||
up() {}
|
||
|
||
down() {}
|
||
|
||
next() {
|
||
const currentIdx = this.parts.indexOf(this);
|
||
return this.parts.find((part, idx) => idx > currentIdx && part instanceof DatePart);
|
||
}
|
||
|
||
setTo(val) {}
|
||
|
||
prev() {
|
||
let parts = [].concat(this.parts).reverse();
|
||
const currentIdx = parts.indexOf(this);
|
||
return parts.find((part, idx) => idx > currentIdx && part instanceof DatePart);
|
||
}
|
||
|
||
toString() {
|
||
return String(this.date);
|
||
}
|
||
}
|
||
|
||
datepart = DatePart;
|
||
return datepart;
|
||
}
|
||
|
||
var meridiem;
|
||
var hasRequiredMeridiem;
|
||
|
||
function requireMeridiem () {
|
||
if (hasRequiredMeridiem) return meridiem;
|
||
hasRequiredMeridiem = 1;
|
||
|
||
const DatePart = requireDatepart();
|
||
|
||
class Meridiem extends DatePart {
|
||
constructor(opts={}) {
|
||
super(opts);
|
||
}
|
||
|
||
up() {
|
||
this.date.setHours((this.date.getHours() + 12) % 24);
|
||
}
|
||
|
||
down() {
|
||
this.up();
|
||
}
|
||
|
||
toString() {
|
||
let meridiem = this.date.getHours() > 12 ? 'pm' : 'am';
|
||
return /\A/.test(this.token) ? meridiem.toUpperCase() : meridiem;
|
||
}
|
||
}
|
||
|
||
meridiem = Meridiem;
|
||
return meridiem;
|
||
}
|
||
|
||
var day;
|
||
var hasRequiredDay;
|
||
|
||
function requireDay () {
|
||
if (hasRequiredDay) return day;
|
||
hasRequiredDay = 1;
|
||
|
||
const DatePart = requireDatepart();
|
||
|
||
const pos = n => {
|
||
n = n % 10;
|
||
return n === 1 ? 'st'
|
||
: n === 2 ? 'nd'
|
||
: n === 3 ? 'rd'
|
||
: 'th';
|
||
};
|
||
|
||
class Day extends DatePart {
|
||
constructor(opts={}) {
|
||
super(opts);
|
||
}
|
||
|
||
up() {
|
||
this.date.setDate(this.date.getDate() + 1);
|
||
}
|
||
|
||
down() {
|
||
this.date.setDate(this.date.getDate() - 1);
|
||
}
|
||
|
||
setTo(val) {
|
||
this.date.setDate(parseInt(val.substr(-2)));
|
||
}
|
||
|
||
toString() {
|
||
let date = this.date.getDate();
|
||
let day = this.date.getDay();
|
||
return this.token === 'DD' ? String(date).padStart(2, '0')
|
||
: this.token === 'Do' ? date + pos(date)
|
||
: this.token === 'd' ? day + 1
|
||
: this.token === 'ddd' ? this.locales.weekdaysShort[day]
|
||
: this.token === 'dddd' ? this.locales.weekdays[day]
|
||
: date;
|
||
}
|
||
}
|
||
|
||
day = Day;
|
||
return day;
|
||
}
|
||
|
||
var hours;
|
||
var hasRequiredHours;
|
||
|
||
function requireHours () {
|
||
if (hasRequiredHours) return hours;
|
||
hasRequiredHours = 1;
|
||
|
||
const DatePart = requireDatepart();
|
||
|
||
class Hours extends DatePart {
|
||
constructor(opts={}) {
|
||
super(opts);
|
||
}
|
||
|
||
up() {
|
||
this.date.setHours(this.date.getHours() + 1);
|
||
}
|
||
|
||
down() {
|
||
this.date.setHours(this.date.getHours() - 1);
|
||
}
|
||
|
||
setTo(val) {
|
||
this.date.setHours(parseInt(val.substr(-2)));
|
||
}
|
||
|
||
toString() {
|
||
let hours = this.date.getHours();
|
||
if (/h/.test(this.token))
|
||
hours = (hours % 12) || 12;
|
||
return this.token.length > 1 ? String(hours).padStart(2, '0') : hours;
|
||
}
|
||
}
|
||
|
||
hours = Hours;
|
||
return hours;
|
||
}
|
||
|
||
var milliseconds;
|
||
var hasRequiredMilliseconds;
|
||
|
||
function requireMilliseconds () {
|
||
if (hasRequiredMilliseconds) return milliseconds;
|
||
hasRequiredMilliseconds = 1;
|
||
|
||
const DatePart = requireDatepart();
|
||
|
||
class Milliseconds extends DatePart {
|
||
constructor(opts={}) {
|
||
super(opts);
|
||
}
|
||
|
||
up() {
|
||
this.date.setMilliseconds(this.date.getMilliseconds() + 1);
|
||
}
|
||
|
||
down() {
|
||
this.date.setMilliseconds(this.date.getMilliseconds() - 1);
|
||
}
|
||
|
||
setTo(val) {
|
||
this.date.setMilliseconds(parseInt(val.substr(-(this.token.length))));
|
||
}
|
||
|
||
toString() {
|
||
return String(this.date.getMilliseconds()).padStart(4, '0')
|
||
.substr(0, this.token.length);
|
||
}
|
||
}
|
||
|
||
milliseconds = Milliseconds;
|
||
return milliseconds;
|
||
}
|
||
|
||
var minutes;
|
||
var hasRequiredMinutes;
|
||
|
||
function requireMinutes () {
|
||
if (hasRequiredMinutes) return minutes;
|
||
hasRequiredMinutes = 1;
|
||
|
||
const DatePart = requireDatepart();
|
||
|
||
class Minutes extends DatePart {
|
||
constructor(opts={}) {
|
||
super(opts);
|
||
}
|
||
|
||
up() {
|
||
this.date.setMinutes(this.date.getMinutes() + 1);
|
||
}
|
||
|
||
down() {
|
||
this.date.setMinutes(this.date.getMinutes() - 1);
|
||
}
|
||
|
||
setTo(val) {
|
||
this.date.setMinutes(parseInt(val.substr(-2)));
|
||
}
|
||
|
||
toString() {
|
||
let m = this.date.getMinutes();
|
||
return this.token.length > 1 ? String(m).padStart(2, '0') : m;
|
||
}
|
||
}
|
||
|
||
minutes = Minutes;
|
||
return minutes;
|
||
}
|
||
|
||
var month;
|
||
var hasRequiredMonth;
|
||
|
||
function requireMonth () {
|
||
if (hasRequiredMonth) return month;
|
||
hasRequiredMonth = 1;
|
||
|
||
const DatePart = requireDatepart();
|
||
|
||
class Month extends DatePart {
|
||
constructor(opts={}) {
|
||
super(opts);
|
||
}
|
||
|
||
up() {
|
||
this.date.setMonth(this.date.getMonth() + 1);
|
||
}
|
||
|
||
down() {
|
||
this.date.setMonth(this.date.getMonth() - 1);
|
||
}
|
||
|
||
setTo(val) {
|
||
val = parseInt(val.substr(-2)) - 1;
|
||
this.date.setMonth(val < 0 ? 0 : val);
|
||
}
|
||
|
||
toString() {
|
||
let month = this.date.getMonth();
|
||
let tl = this.token.length;
|
||
return tl === 2 ? String(month + 1).padStart(2, '0')
|
||
: tl === 3 ? this.locales.monthsShort[month]
|
||
: tl === 4 ? this.locales.months[month]
|
||
: String(month + 1);
|
||
}
|
||
}
|
||
|
||
month = Month;
|
||
return month;
|
||
}
|
||
|
||
var seconds;
|
||
var hasRequiredSeconds;
|
||
|
||
function requireSeconds () {
|
||
if (hasRequiredSeconds) return seconds;
|
||
hasRequiredSeconds = 1;
|
||
|
||
const DatePart = requireDatepart();
|
||
|
||
class Seconds extends DatePart {
|
||
constructor(opts={}) {
|
||
super(opts);
|
||
}
|
||
|
||
up() {
|
||
this.date.setSeconds(this.date.getSeconds() + 1);
|
||
}
|
||
|
||
down() {
|
||
this.date.setSeconds(this.date.getSeconds() - 1);
|
||
}
|
||
|
||
setTo(val) {
|
||
this.date.setSeconds(parseInt(val.substr(-2)));
|
||
}
|
||
|
||
toString() {
|
||
let s = this.date.getSeconds();
|
||
return this.token.length > 1 ? String(s).padStart(2, '0') : s;
|
||
}
|
||
}
|
||
|
||
seconds = Seconds;
|
||
return seconds;
|
||
}
|
||
|
||
var year;
|
||
var hasRequiredYear;
|
||
|
||
function requireYear () {
|
||
if (hasRequiredYear) return year;
|
||
hasRequiredYear = 1;
|
||
|
||
const DatePart = requireDatepart();
|
||
|
||
class Year extends DatePart {
|
||
constructor(opts={}) {
|
||
super(opts);
|
||
}
|
||
|
||
up() {
|
||
this.date.setFullYear(this.date.getFullYear() + 1);
|
||
}
|
||
|
||
down() {
|
||
this.date.setFullYear(this.date.getFullYear() - 1);
|
||
}
|
||
|
||
setTo(val) {
|
||
this.date.setFullYear(val.substr(-4));
|
||
}
|
||
|
||
toString() {
|
||
let year = String(this.date.getFullYear()).padStart(4, '0');
|
||
return this.token.length === 2 ? year.substr(-2) : year;
|
||
}
|
||
}
|
||
|
||
year = Year;
|
||
return year;
|
||
}
|
||
|
||
var dateparts;
|
||
var hasRequiredDateparts;
|
||
|
||
function requireDateparts () {
|
||
if (hasRequiredDateparts) return dateparts;
|
||
hasRequiredDateparts = 1;
|
||
|
||
dateparts = {
|
||
DatePart: requireDatepart(),
|
||
Meridiem: requireMeridiem(),
|
||
Day: requireDay(),
|
||
Hours: requireHours(),
|
||
Milliseconds: requireMilliseconds(),
|
||
Minutes: requireMinutes(),
|
||
Month: requireMonth(),
|
||
Seconds: requireSeconds(),
|
||
Year: requireYear(),
|
||
};
|
||
return dateparts;
|
||
}
|
||
|
||
var date;
|
||
var hasRequiredDate;
|
||
|
||
function requireDate () {
|
||
if (hasRequiredDate) return date;
|
||
hasRequiredDate = 1;
|
||
|
||
const color = requireKleur();
|
||
const Prompt = requirePrompt();
|
||
const { style, clear, figures } = requireUtil();
|
||
const { erase, cursor } = requireSrc();
|
||
const { DatePart, Meridiem, Day, Hours, Milliseconds, Minutes, Month, Seconds, Year } = requireDateparts();
|
||
|
||
const regex = /\\(.)|"((?:\\["\\]|[^"])+)"|(D[Do]?|d{3,4}|d)|(M{1,4})|(YY(?:YY)?)|([aA])|([Hh]{1,2})|(m{1,2})|(s{1,2})|(S{1,4})|./g;
|
||
const regexGroups = {
|
||
1: ({token}) => token.replace(/\\(.)/g, '$1'),
|
||
2: (opts) => new Day(opts), // Day // TODO
|
||
3: (opts) => new Month(opts), // Month
|
||
4: (opts) => new Year(opts), // Year
|
||
5: (opts) => new Meridiem(opts), // AM/PM // TODO (special)
|
||
6: (opts) => new Hours(opts), // Hours
|
||
7: (opts) => new Minutes(opts), // Minutes
|
||
8: (opts) => new Seconds(opts), // Seconds
|
||
9: (opts) => new Milliseconds(opts), // Fractional seconds
|
||
};
|
||
|
||
const dfltLocales = {
|
||
months: 'January,February,March,April,May,June,July,August,September,October,November,December'.split(','),
|
||
monthsShort: 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'.split(','),
|
||
weekdays: 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday'.split(','),
|
||
weekdaysShort: 'Sun,Mon,Tue,Wed,Thu,Fri,Sat'.split(',')
|
||
};
|
||
|
||
|
||
/**
|
||
* DatePrompt Base Element
|
||
* @param {Object} opts Options
|
||
* @param {String} opts.message Message
|
||
* @param {Number} [opts.initial] Index of default value
|
||
* @param {String} [opts.mask] The format mask
|
||
* @param {object} [opts.locales] The date locales
|
||
* @param {String} [opts.error] The error message shown on invalid value
|
||
* @param {Function} [opts.validate] Function to validate the submitted value
|
||
* @param {Stream} [opts.stdin] The Readable stream to listen to
|
||
* @param {Stream} [opts.stdout] The Writable stream to write readline data to
|
||
*/
|
||
class DatePrompt extends Prompt {
|
||
constructor(opts={}) {
|
||
super(opts);
|
||
this.msg = opts.message;
|
||
this.cursor = 0;
|
||
this.typed = '';
|
||
this.locales = Object.assign(dfltLocales, opts.locales);
|
||
this._date = opts.initial || new Date();
|
||
this.errorMsg = opts.error || 'Please Enter A Valid Value';
|
||
this.validator = opts.validate || (() => true);
|
||
this.mask = opts.mask || 'YYYY-MM-DD HH:mm:ss';
|
||
this.clear = clear('', this.out.columns);
|
||
this.render();
|
||
}
|
||
|
||
get value() {
|
||
return this.date
|
||
}
|
||
|
||
get date() {
|
||
return this._date;
|
||
}
|
||
|
||
set date(date) {
|
||
if (date) this._date.setTime(date.getTime());
|
||
}
|
||
|
||
set mask(mask) {
|
||
let result;
|
||
this.parts = [];
|
||
while(result = regex.exec(mask)) {
|
||
let match = result.shift();
|
||
let idx = result.findIndex(gr => gr != null);
|
||
this.parts.push(idx in regexGroups
|
||
? regexGroups[idx]({ token: result[idx] || match, date: this.date, parts: this.parts, locales: this.locales })
|
||
: result[idx] || match);
|
||
}
|
||
|
||
let parts = this.parts.reduce((arr, i) => {
|
||
if (typeof i === 'string' && typeof arr[arr.length - 1] === 'string')
|
||
arr[arr.length - 1] += i;
|
||
else arr.push(i);
|
||
return arr;
|
||
}, []);
|
||
|
||
this.parts.splice(0);
|
||
this.parts.push(...parts);
|
||
this.reset();
|
||
}
|
||
|
||
moveCursor(n) {
|
||
this.typed = '';
|
||
this.cursor = n;
|
||
this.fire();
|
||
}
|
||
|
||
reset() {
|
||
this.moveCursor(this.parts.findIndex(p => p instanceof DatePart));
|
||
this.fire();
|
||
this.render();
|
||
}
|
||
|
||
exit() {
|
||
this.abort();
|
||
}
|
||
|
||
abort() {
|
||
this.done = this.aborted = true;
|
||
this.error = false;
|
||
this.fire();
|
||
this.render();
|
||
this.out.write('\n');
|
||
this.close();
|
||
}
|
||
|
||
async validate() {
|
||
let valid = await this.validator(this.value);
|
||
if (typeof valid === 'string') {
|
||
this.errorMsg = valid;
|
||
valid = false;
|
||
}
|
||
this.error = !valid;
|
||
}
|
||
|
||
async submit() {
|
||
await this.validate();
|
||
if (this.error) {
|
||
this.color = 'red';
|
||
this.fire();
|
||
this.render();
|
||
return;
|
||
}
|
||
this.done = true;
|
||
this.aborted = false;
|
||
this.fire();
|
||
this.render();
|
||
this.out.write('\n');
|
||
this.close();
|
||
}
|
||
|
||
up() {
|
||
this.typed = '';
|
||
this.parts[this.cursor].up();
|
||
this.render();
|
||
}
|
||
|
||
down() {
|
||
this.typed = '';
|
||
this.parts[this.cursor].down();
|
||
this.render();
|
||
}
|
||
|
||
left() {
|
||
let prev = this.parts[this.cursor].prev();
|
||
if (prev == null) return this.bell();
|
||
this.moveCursor(this.parts.indexOf(prev));
|
||
this.render();
|
||
}
|
||
|
||
right() {
|
||
let next = this.parts[this.cursor].next();
|
||
if (next == null) return this.bell();
|
||
this.moveCursor(this.parts.indexOf(next));
|
||
this.render();
|
||
}
|
||
|
||
next() {
|
||
let next = this.parts[this.cursor].next();
|
||
this.moveCursor(next
|
||
? this.parts.indexOf(next)
|
||
: this.parts.findIndex((part) => part instanceof DatePart));
|
||
this.render();
|
||
}
|
||
|
||
_(c) {
|
||
if (/\d/.test(c)) {
|
||
this.typed += c;
|
||
this.parts[this.cursor].setTo(this.typed);
|
||
this.render();
|
||
}
|
||
}
|
||
|
||
render() {
|
||
if (this.closed) return;
|
||
if (this.firstRender) this.out.write(cursor.hide);
|
||
else this.out.write(clear(this.outputText, this.out.columns));
|
||
super.render();
|
||
|
||
// Print prompt
|
||
this.outputText = [
|
||
style.symbol(this.done, this.aborted),
|
||
color.bold(this.msg),
|
||
style.delimiter(false),
|
||
this.parts.reduce((arr, p, idx) => arr.concat(idx === this.cursor && !this.done ? color.cyan().underline(p.toString()) : p), [])
|
||
.join('')
|
||
].join(' ');
|
||
|
||
// Print error
|
||
if (this.error) {
|
||
this.outputText += this.errorMsg.split('\n').reduce(
|
||
(a, l, i) => a + `\n${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``);
|
||
}
|
||
|
||
this.out.write(erase.line + cursor.to(0) + this.outputText);
|
||
}
|
||
}
|
||
|
||
date = DatePrompt;
|
||
return date;
|
||
}
|
||
|
||
var number;
|
||
var hasRequiredNumber;
|
||
|
||
function requireNumber () {
|
||
if (hasRequiredNumber) return number;
|
||
hasRequiredNumber = 1;
|
||
const color = requireKleur();
|
||
const Prompt = requirePrompt();
|
||
const { cursor, erase } = requireSrc();
|
||
const { style, figures, clear, lines } = requireUtil();
|
||
|
||
const isNumber = /[0-9]/;
|
||
const isDef = any => any !== undefined;
|
||
const round = (number, precision) => {
|
||
let factor = Math.pow(10, precision);
|
||
return Math.round(number * factor) / factor;
|
||
};
|
||
|
||
/**
|
||
* NumberPrompt Base Element
|
||
* @param {Object} opts Options
|
||
* @param {String} opts.message Message
|
||
* @param {String} [opts.style='default'] Render style
|
||
* @param {Number} [opts.initial] Default value
|
||
* @param {Number} [opts.max=+Infinity] Max value
|
||
* @param {Number} [opts.min=-Infinity] Min value
|
||
* @param {Boolean} [opts.float=false] Parse input as floats
|
||
* @param {Number} [opts.round=2] Round floats to x decimals
|
||
* @param {Number} [opts.increment=1] Number to increment by when using arrow-keys
|
||
* @param {Function} [opts.validate] Validate function
|
||
* @param {Stream} [opts.stdin] The Readable stream to listen to
|
||
* @param {Stream} [opts.stdout] The Writable stream to write readline data to
|
||
* @param {String} [opts.error] The invalid error label
|
||
*/
|
||
class NumberPrompt extends Prompt {
|
||
constructor(opts={}) {
|
||
super(opts);
|
||
this.transform = style.render(opts.style);
|
||
this.msg = opts.message;
|
||
this.initial = isDef(opts.initial) ? opts.initial : '';
|
||
this.float = !!opts.float;
|
||
this.round = opts.round || 2;
|
||
this.inc = opts.increment || 1;
|
||
this.min = isDef(opts.min) ? opts.min : -Infinity;
|
||
this.max = isDef(opts.max) ? opts.max : Infinity;
|
||
this.errorMsg = opts.error || `Please Enter A Valid Value`;
|
||
this.validator = opts.validate || (() => true);
|
||
this.color = `cyan`;
|
||
this.value = ``;
|
||
this.typed = ``;
|
||
this.lastHit = 0;
|
||
this.render();
|
||
}
|
||
|
||
set value(v) {
|
||
if (!v && v !== 0) {
|
||
this.placeholder = true;
|
||
this.rendered = color.gray(this.transform.render(`${this.initial}`));
|
||
this._value = ``;
|
||
} else {
|
||
this.placeholder = false;
|
||
this.rendered = this.transform.render(`${round(v, this.round)}`);
|
||
this._value = round(v, this.round);
|
||
}
|
||
this.fire();
|
||
}
|
||
|
||
get value() {
|
||
return this._value;
|
||
}
|
||
|
||
parse(x) {
|
||
return this.float ? parseFloat(x) : parseInt(x);
|
||
}
|
||
|
||
valid(c) {
|
||
return c === `-` || c === `.` && this.float || isNumber.test(c)
|
||
}
|
||
|
||
reset() {
|
||
this.typed = ``;
|
||
this.value = ``;
|
||
this.fire();
|
||
this.render();
|
||
}
|
||
|
||
exit() {
|
||
this.abort();
|
||
}
|
||
|
||
abort() {
|
||
let x = this.value;
|
||
this.value = x !== `` ? x : this.initial;
|
||
this.done = this.aborted = true;
|
||
this.error = false;
|
||
this.fire();
|
||
this.render();
|
||
this.out.write(`\n`);
|
||
this.close();
|
||
}
|
||
|
||
async validate() {
|
||
let valid = await this.validator(this.value);
|
||
if (typeof valid === `string`) {
|
||
this.errorMsg = valid;
|
||
valid = false;
|
||
}
|
||
this.error = !valid;
|
||
}
|
||
|
||
async submit() {
|
||
await this.validate();
|
||
if (this.error) {
|
||
this.color = `red`;
|
||
this.fire();
|
||
this.render();
|
||
return;
|
||
}
|
||
let x = this.value;
|
||
this.value = x !== `` ? x : this.initial;
|
||
this.done = true;
|
||
this.aborted = false;
|
||
this.error = false;
|
||
this.fire();
|
||
this.render();
|
||
this.out.write(`\n`);
|
||
this.close();
|
||
}
|
||
|
||
up() {
|
||
this.typed = ``;
|
||
if(this.value === '') {
|
||
this.value = this.min - this.inc;
|
||
}
|
||
if (this.value >= this.max) return this.bell();
|
||
this.value += this.inc;
|
||
this.color = `cyan`;
|
||
this.fire();
|
||
this.render();
|
||
}
|
||
|
||
down() {
|
||
this.typed = ``;
|
||
if(this.value === '') {
|
||
this.value = this.min + this.inc;
|
||
}
|
||
if (this.value <= this.min) return this.bell();
|
||
this.value -= this.inc;
|
||
this.color = `cyan`;
|
||
this.fire();
|
||
this.render();
|
||
}
|
||
|
||
delete() {
|
||
let val = this.value.toString();
|
||
if (val.length === 0) return this.bell();
|
||
this.value = this.parse((val = val.slice(0, -1))) || ``;
|
||
if (this.value !== '' && this.value < this.min) {
|
||
this.value = this.min;
|
||
}
|
||
this.color = `cyan`;
|
||
this.fire();
|
||
this.render();
|
||
}
|
||
|
||
next() {
|
||
this.value = this.initial;
|
||
this.fire();
|
||
this.render();
|
||
}
|
||
|
||
_(c, key) {
|
||
if (!this.valid(c)) return this.bell();
|
||
|
||
const now = Date.now();
|
||
if (now - this.lastHit > 1000) this.typed = ``; // 1s elapsed
|
||
this.typed += c;
|
||
this.lastHit = now;
|
||
this.color = `cyan`;
|
||
|
||
if (c === `.`) return this.fire();
|
||
|
||
this.value = Math.min(this.parse(this.typed), this.max);
|
||
if (this.value > this.max) this.value = this.max;
|
||
if (this.value < this.min) this.value = this.min;
|
||
this.fire();
|
||
this.render();
|
||
}
|
||
|
||
render() {
|
||
if (this.closed) return;
|
||
if (!this.firstRender) {
|
||
if (this.outputError)
|
||
this.out.write(cursor.down(lines(this.outputError, this.out.columns) - 1) + clear(this.outputError, this.out.columns));
|
||
this.out.write(clear(this.outputText, this.out.columns));
|
||
}
|
||
super.render();
|
||
this.outputError = '';
|
||
|
||
// Print prompt
|
||
this.outputText = [
|
||
style.symbol(this.done, this.aborted),
|
||
color.bold(this.msg),
|
||
style.delimiter(this.done),
|
||
!this.done || (!this.done && !this.placeholder)
|
||
? color[this.color]().underline(this.rendered) : this.rendered
|
||
].join(` `);
|
||
|
||
// Print error
|
||
if (this.error) {
|
||
this.outputError += this.errorMsg.split(`\n`)
|
||
.reduce((a, l, i) => a + `\n${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``);
|
||
}
|
||
|
||
this.out.write(erase.line + cursor.to(0) + this.outputText + cursor.save + this.outputError + cursor.restore);
|
||
}
|
||
}
|
||
|
||
number = NumberPrompt;
|
||
return number;
|
||
}
|
||
|
||
var multiselect;
|
||
var hasRequiredMultiselect;
|
||
|
||
function requireMultiselect () {
|
||
if (hasRequiredMultiselect) return multiselect;
|
||
hasRequiredMultiselect = 1;
|
||
|
||
const color = requireKleur();
|
||
const { cursor } = requireSrc();
|
||
const Prompt = requirePrompt();
|
||
const { clear, figures, style, wrap, entriesToDisplay } = requireUtil();
|
||
|
||
/**
|
||
* MultiselectPrompt Base Element
|
||
* @param {Object} opts Options
|
||
* @param {String} opts.message Message
|
||
* @param {Array} opts.choices Array of choice objects
|
||
* @param {String} [opts.hint] Hint to display
|
||
* @param {String} [opts.warn] Hint shown for disabled choices
|
||
* @param {Number} [opts.max] Max choices
|
||
* @param {Number} [opts.cursor=0] Cursor start position
|
||
* @param {Number} [opts.optionsPerPage=10] Max options to display at once
|
||
* @param {Stream} [opts.stdin] The Readable stream to listen to
|
||
* @param {Stream} [opts.stdout] The Writable stream to write readline data to
|
||
*/
|
||
class MultiselectPrompt extends Prompt {
|
||
constructor(opts={}) {
|
||
super(opts);
|
||
this.msg = opts.message;
|
||
this.cursor = opts.cursor || 0;
|
||
this.scrollIndex = opts.cursor || 0;
|
||
this.hint = opts.hint || '';
|
||
this.warn = opts.warn || '- This option is disabled -';
|
||
this.minSelected = opts.min;
|
||
this.showMinError = false;
|
||
this.maxChoices = opts.max;
|
||
this.instructions = opts.instructions;
|
||
this.optionsPerPage = opts.optionsPerPage || 10;
|
||
this.value = opts.choices.map((ch, idx) => {
|
||
if (typeof ch === 'string')
|
||
ch = {title: ch, value: idx};
|
||
return {
|
||
title: ch && (ch.title || ch.value || ch),
|
||
description: ch && ch.description,
|
||
value: ch && (ch.value === undefined ? idx : ch.value),
|
||
selected: ch && ch.selected,
|
||
disabled: ch && ch.disabled
|
||
};
|
||
});
|
||
this.clear = clear('', this.out.columns);
|
||
if (!opts.overrideRender) {
|
||
this.render();
|
||
}
|
||
}
|
||
|
||
reset() {
|
||
this.value.map(v => !v.selected);
|
||
this.cursor = 0;
|
||
this.fire();
|
||
this.render();
|
||
}
|
||
|
||
selected() {
|
||
return this.value.filter(v => v.selected);
|
||
}
|
||
|
||
exit() {
|
||
this.abort();
|
||
}
|
||
|
||
abort() {
|
||
this.done = this.aborted = true;
|
||
this.fire();
|
||
this.render();
|
||
this.out.write('\n');
|
||
this.close();
|
||
}
|
||
|
||
submit() {
|
||
const selected = this.value
|
||
.filter(e => e.selected);
|
||
if (this.minSelected && selected.length < this.minSelected) {
|
||
this.showMinError = true;
|
||
this.render();
|
||
} else {
|
||
this.done = true;
|
||
this.aborted = false;
|
||
this.fire();
|
||
this.render();
|
||
this.out.write('\n');
|
||
this.close();
|
||
}
|
||
}
|
||
|
||
first() {
|
||
this.cursor = 0;
|
||
this.render();
|
||
}
|
||
|
||
last() {
|
||
this.cursor = this.value.length - 1;
|
||
this.render();
|
||
}
|
||
next() {
|
||
this.cursor = (this.cursor + 1) % this.value.length;
|
||
this.render();
|
||
}
|
||
|
||
up() {
|
||
if (this.cursor === 0) {
|
||
this.cursor = this.value.length - 1;
|
||
} else {
|
||
this.cursor--;
|
||
}
|
||
this.render();
|
||
}
|
||
|
||
down() {
|
||
if (this.cursor === this.value.length - 1) {
|
||
this.cursor = 0;
|
||
} else {
|
||
this.cursor++;
|
||
}
|
||
this.render();
|
||
}
|
||
|
||
left() {
|
||
this.value[this.cursor].selected = false;
|
||
this.render();
|
||
}
|
||
|
||
right() {
|
||
if (this.value.filter(e => e.selected).length >= this.maxChoices) return this.bell();
|
||
this.value[this.cursor].selected = true;
|
||
this.render();
|
||
}
|
||
|
||
handleSpaceToggle() {
|
||
const v = this.value[this.cursor];
|
||
|
||
if (v.selected) {
|
||
v.selected = false;
|
||
this.render();
|
||
} else if (v.disabled || this.value.filter(e => e.selected).length >= this.maxChoices) {
|
||
return this.bell();
|
||
} else {
|
||
v.selected = true;
|
||
this.render();
|
||
}
|
||
}
|
||
|
||
toggleAll() {
|
||
if (this.maxChoices !== undefined || this.value[this.cursor].disabled) {
|
||
return this.bell();
|
||
}
|
||
|
||
const newSelected = !this.value[this.cursor].selected;
|
||
this.value.filter(v => !v.disabled).forEach(v => v.selected = newSelected);
|
||
this.render();
|
||
}
|
||
|
||
_(c, key) {
|
||
if (c === ' ') {
|
||
this.handleSpaceToggle();
|
||
} else if (c === 'a') {
|
||
this.toggleAll();
|
||
} else {
|
||
return this.bell();
|
||
}
|
||
}
|
||
|
||
renderInstructions() {
|
||
if (this.instructions === undefined || this.instructions) {
|
||
if (typeof this.instructions === 'string') {
|
||
return this.instructions;
|
||
}
|
||
return '\nInstructions:\n'
|
||
+ ` ${figures.arrowUp}/${figures.arrowDown}: Highlight option\n`
|
||
+ ` ${figures.arrowLeft}/${figures.arrowRight}/[space]: Toggle selection\n`
|
||
+ (this.maxChoices === undefined ? ` a: Toggle all\n` : '')
|
||
+ ` enter/return: Complete answer`;
|
||
}
|
||
return '';
|
||
}
|
||
|
||
renderOption(cursor, v, i, arrowIndicator) {
|
||
const prefix = (v.selected ? color.green(figures.radioOn) : figures.radioOff) + ' ' + arrowIndicator + ' ';
|
||
let title, desc;
|
||
|
||
if (v.disabled) {
|
||
title = cursor === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title);
|
||
} else {
|
||
title = cursor === i ? color.cyan().underline(v.title) : v.title;
|
||
if (cursor === i && v.description) {
|
||
desc = ` - ${v.description}`;
|
||
if (prefix.length + title.length + desc.length >= this.out.columns
|
||
|| v.description.split(/\r?\n/).length > 1) {
|
||
desc = '\n' + wrap(v.description, { margin: prefix.length, width: this.out.columns });
|
||
}
|
||
}
|
||
}
|
||
|
||
return prefix + title + color.gray(desc || '');
|
||
}
|
||
|
||
// shared with autocompleteMultiselect
|
||
paginateOptions(options) {
|
||
if (options.length === 0) {
|
||
return color.red('No matches for this query.');
|
||
}
|
||
|
||
let { startIndex, endIndex } = entriesToDisplay(this.cursor, options.length, this.optionsPerPage);
|
||
let prefix, styledOptions = [];
|
||
|
||
for (let i = startIndex; i < endIndex; i++) {
|
||
if (i === startIndex && startIndex > 0) {
|
||
prefix = figures.arrowUp;
|
||
} else if (i === endIndex - 1 && endIndex < options.length) {
|
||
prefix = figures.arrowDown;
|
||
} else {
|
||
prefix = ' ';
|
||
}
|
||
styledOptions.push(this.renderOption(this.cursor, options[i], i, prefix));
|
||
}
|
||
|
||
return '\n' + styledOptions.join('\n');
|
||
}
|
||
|
||
// shared with autocomleteMultiselect
|
||
renderOptions(options) {
|
||
if (!this.done) {
|
||
return this.paginateOptions(options);
|
||
}
|
||
return '';
|
||
}
|
||
|
||
renderDoneOrInstructions() {
|
||
if (this.done) {
|
||
return this.value
|
||
.filter(e => e.selected)
|
||
.map(v => v.title)
|
||
.join(', ');
|
||
}
|
||
|
||
const output = [color.gray(this.hint), this.renderInstructions()];
|
||
|
||
if (this.value[this.cursor].disabled) {
|
||
output.push(color.yellow(this.warn));
|
||
}
|
||
return output.join(' ');
|
||
}
|
||
|
||
render() {
|
||
if (this.closed) return;
|
||
if (this.firstRender) this.out.write(cursor.hide);
|
||
super.render();
|
||
|
||
// print prompt
|
||
let prompt = [
|
||
style.symbol(this.done, this.aborted),
|
||
color.bold(this.msg),
|
||
style.delimiter(false),
|
||
this.renderDoneOrInstructions()
|
||
].join(' ');
|
||
if (this.showMinError) {
|
||
prompt += color.red(`You must select a minimum of ${this.minSelected} choices.`);
|
||
this.showMinError = false;
|
||
}
|
||
prompt += this.renderOptions(this.value);
|
||
|
||
this.out.write(this.clear + prompt);
|
||
this.clear = clear(prompt, this.out.columns);
|
||
}
|
||
}
|
||
|
||
multiselect = MultiselectPrompt;
|
||
return multiselect;
|
||
}
|
||
|
||
var autocomplete;
|
||
var hasRequiredAutocomplete;
|
||
|
||
function requireAutocomplete () {
|
||
if (hasRequiredAutocomplete) return autocomplete;
|
||
hasRequiredAutocomplete = 1;
|
||
|
||
const color = requireKleur();
|
||
const Prompt = requirePrompt();
|
||
const { erase, cursor } = requireSrc();
|
||
const { style, clear, figures, wrap, entriesToDisplay } = requireUtil();
|
||
|
||
const getVal = (arr, i) => arr[i] && (arr[i].value || arr[i].title || arr[i]);
|
||
const getTitle = (arr, i) => arr[i] && (arr[i].title || arr[i].value || arr[i]);
|
||
const getIndex = (arr, valOrTitle) => {
|
||
const index = arr.findIndex(el => el.value === valOrTitle || el.title === valOrTitle);
|
||
return index > -1 ? index : undefined;
|
||
};
|
||
|
||
/**
|
||
* TextPrompt Base Element
|
||
* @param {Object} opts Options
|
||
* @param {String} opts.message Message
|
||
* @param {Array} opts.choices Array of auto-complete choices objects
|
||
* @param {Function} [opts.suggest] Filter function. Defaults to sort by title
|
||
* @param {Number} [opts.limit=10] Max number of results to show
|
||
* @param {Number} [opts.cursor=0] Cursor start position
|
||
* @param {String} [opts.style='default'] Render style
|
||
* @param {String} [opts.fallback] Fallback message - initial to default value
|
||
* @param {String} [opts.initial] Index of the default value
|
||
* @param {Boolean} [opts.clearFirst] The first ESCAPE keypress will clear the input
|
||
* @param {Stream} [opts.stdin] The Readable stream to listen to
|
||
* @param {Stream} [opts.stdout] The Writable stream to write readline data to
|
||
* @param {String} [opts.noMatches] The no matches found label
|
||
*/
|
||
class AutocompletePrompt extends Prompt {
|
||
constructor(opts={}) {
|
||
super(opts);
|
||
this.msg = opts.message;
|
||
this.suggest = opts.suggest;
|
||
this.choices = opts.choices;
|
||
this.initial = typeof opts.initial === 'number'
|
||
? opts.initial
|
||
: getIndex(opts.choices, opts.initial);
|
||
this.select = this.initial || opts.cursor || 0;
|
||
this.i18n = { noMatches: opts.noMatches || 'no matches found' };
|
||
this.fallback = opts.fallback || this.initial;
|
||
this.clearFirst = opts.clearFirst || false;
|
||
this.suggestions = [];
|
||
this.input = '';
|
||
this.limit = opts.limit || 10;
|
||
this.cursor = 0;
|
||
this.transform = style.render(opts.style);
|
||
this.scale = this.transform.scale;
|
||
this.render = this.render.bind(this);
|
||
this.complete = this.complete.bind(this);
|
||
this.clear = clear('', this.out.columns);
|
||
this.complete(this.render);
|
||
this.render();
|
||
}
|
||
|
||
set fallback(fb) {
|
||
this._fb = Number.isSafeInteger(parseInt(fb)) ? parseInt(fb) : fb;
|
||
}
|
||
|
||
get fallback() {
|
||
let choice;
|
||
if (typeof this._fb === 'number')
|
||
choice = this.choices[this._fb];
|
||
else if (typeof this._fb === 'string')
|
||
choice = { title: this._fb };
|
||
return choice || this._fb || { title: this.i18n.noMatches };
|
||
}
|
||
|
||
moveSelect(i) {
|
||
this.select = i;
|
||
if (this.suggestions.length > 0)
|
||
this.value = getVal(this.suggestions, i);
|
||
else this.value = this.fallback.value;
|
||
this.fire();
|
||
}
|
||
|
||
async complete(cb) {
|
||
const p = (this.completing = this.suggest(this.input, this.choices));
|
||
const suggestions = await p;
|
||
|
||
if (this.completing !== p) return;
|
||
this.suggestions = suggestions
|
||
.map((s, i, arr) => ({ title: getTitle(arr, i), value: getVal(arr, i), description: s.description }));
|
||
this.completing = false;
|
||
const l = Math.max(suggestions.length - 1, 0);
|
||
this.moveSelect(Math.min(l, this.select));
|
||
|
||
cb && cb();
|
||
}
|
||
|
||
reset() {
|
||
this.input = '';
|
||
this.complete(() => {
|
||
this.moveSelect(this.initial !== void 0 ? this.initial : 0);
|
||
this.render();
|
||
});
|
||
this.render();
|
||
}
|
||
|
||
exit() {
|
||
if (this.clearFirst && this.input.length > 0) {
|
||
this.reset();
|
||
} else {
|
||
this.done = this.exited = true;
|
||
this.aborted = false;
|
||
this.fire();
|
||
this.render();
|
||
this.out.write('\n');
|
||
this.close();
|
||
}
|
||
}
|
||
|
||
abort() {
|
||
this.done = this.aborted = true;
|
||
this.exited = false;
|
||
this.fire();
|
||
this.render();
|
||
this.out.write('\n');
|
||
this.close();
|
||
}
|
||
|
||
submit() {
|
||
this.done = true;
|
||
this.aborted = this.exited = false;
|
||
this.fire();
|
||
this.render();
|
||
this.out.write('\n');
|
||
this.close();
|
||
}
|
||
|
||
_(c, key) {
|
||
let s1 = this.input.slice(0, this.cursor);
|
||
let s2 = this.input.slice(this.cursor);
|
||
this.input = `${s1}${c}${s2}`;
|
||
this.cursor = s1.length+1;
|
||
this.complete(this.render);
|
||
this.render();
|
||
}
|
||
|
||
delete() {
|
||
if (this.cursor === 0) return this.bell();
|
||
let s1 = this.input.slice(0, this.cursor-1);
|
||
let s2 = this.input.slice(this.cursor);
|
||
this.input = `${s1}${s2}`;
|
||
this.complete(this.render);
|
||
this.cursor = this.cursor-1;
|
||
this.render();
|
||
}
|
||
|
||
deleteForward() {
|
||
if(this.cursor*this.scale >= this.rendered.length) return this.bell();
|
||
let s1 = this.input.slice(0, this.cursor);
|
||
let s2 = this.input.slice(this.cursor+1);
|
||
this.input = `${s1}${s2}`;
|
||
this.complete(this.render);
|
||
this.render();
|
||
}
|
||
|
||
first() {
|
||
this.moveSelect(0);
|
||
this.render();
|
||
}
|
||
|
||
last() {
|
||
this.moveSelect(this.suggestions.length - 1);
|
||
this.render();
|
||
}
|
||
|
||
up() {
|
||
if (this.select === 0) {
|
||
this.moveSelect(this.suggestions.length - 1);
|
||
} else {
|
||
this.moveSelect(this.select - 1);
|
||
}
|
||
this.render();
|
||
}
|
||
|
||
down() {
|
||
if (this.select === this.suggestions.length - 1) {
|
||
this.moveSelect(0);
|
||
} else {
|
||
this.moveSelect(this.select + 1);
|
||
}
|
||
this.render();
|
||
}
|
||
|
||
next() {
|
||
if (this.select === this.suggestions.length - 1) {
|
||
this.moveSelect(0);
|
||
} else this.moveSelect(this.select + 1);
|
||
this.render();
|
||
}
|
||
|
||
nextPage() {
|
||
this.moveSelect(Math.min(this.select + this.limit, this.suggestions.length - 1));
|
||
this.render();
|
||
}
|
||
|
||
prevPage() {
|
||
this.moveSelect(Math.max(this.select - this.limit, 0));
|
||
this.render();
|
||
}
|
||
|
||
left() {
|
||
if (this.cursor <= 0) return this.bell();
|
||
this.cursor = this.cursor-1;
|
||
this.render();
|
||
}
|
||
|
||
right() {
|
||
if (this.cursor*this.scale >= this.rendered.length) return this.bell();
|
||
this.cursor = this.cursor+1;
|
||
this.render();
|
||
}
|
||
|
||
renderOption(v, hovered, isStart, isEnd) {
|
||
let desc;
|
||
let prefix = isStart ? figures.arrowUp : isEnd ? figures.arrowDown : ' ';
|
||
let title = hovered ? color.cyan().underline(v.title) : v.title;
|
||
prefix = (hovered ? color.cyan(figures.pointer) + ' ' : ' ') + prefix;
|
||
if (v.description) {
|
||
desc = ` - ${v.description}`;
|
||
if (prefix.length + title.length + desc.length >= this.out.columns
|
||
|| v.description.split(/\r?\n/).length > 1) {
|
||
desc = '\n' + wrap(v.description, { margin: 3, width: this.out.columns });
|
||
}
|
||
}
|
||
return prefix + ' ' + title + color.gray(desc || '');
|
||
}
|
||
|
||
render() {
|
||
if (this.closed) return;
|
||
if (this.firstRender) this.out.write(cursor.hide);
|
||
else this.out.write(clear(this.outputText, this.out.columns));
|
||
super.render();
|
||
|
||
let { startIndex, endIndex } = entriesToDisplay(this.select, this.choices.length, this.limit);
|
||
|
||
this.outputText = [
|
||
style.symbol(this.done, this.aborted, this.exited),
|
||
color.bold(this.msg),
|
||
style.delimiter(this.completing),
|
||
this.done && this.suggestions[this.select]
|
||
? this.suggestions[this.select].title
|
||
: this.rendered = this.transform.render(this.input)
|
||
].join(' ');
|
||
|
||
if (!this.done) {
|
||
const suggestions = this.suggestions
|
||
.slice(startIndex, endIndex)
|
||
.map((item, i) => this.renderOption(item,
|
||
this.select === i + startIndex,
|
||
i === 0 && startIndex > 0,
|
||
i + startIndex === endIndex - 1 && endIndex < this.choices.length))
|
||
.join('\n');
|
||
this.outputText += `\n` + (suggestions || color.gray(this.fallback.title));
|
||
}
|
||
|
||
this.out.write(erase.line + cursor.to(0) + this.outputText);
|
||
}
|
||
}
|
||
|
||
autocomplete = AutocompletePrompt;
|
||
return autocomplete;
|
||
}
|
||
|
||
var autocompleteMultiselect;
|
||
var hasRequiredAutocompleteMultiselect;
|
||
|
||
function requireAutocompleteMultiselect () {
|
||
if (hasRequiredAutocompleteMultiselect) return autocompleteMultiselect;
|
||
hasRequiredAutocompleteMultiselect = 1;
|
||
|
||
const color = requireKleur();
|
||
const { cursor } = requireSrc();
|
||
const MultiselectPrompt = requireMultiselect();
|
||
const { clear, style, figures } = requireUtil();
|
||
/**
|
||
* MultiselectPrompt Base Element
|
||
* @param {Object} opts Options
|
||
* @param {String} opts.message Message
|
||
* @param {Array} opts.choices Array of choice objects
|
||
* @param {String} [opts.hint] Hint to display
|
||
* @param {String} [opts.warn] Hint shown for disabled choices
|
||
* @param {Number} [opts.max] Max choices
|
||
* @param {Number} [opts.cursor=0] Cursor start position
|
||
* @param {Stream} [opts.stdin] The Readable stream to listen to
|
||
* @param {Stream} [opts.stdout] The Writable stream to write readline data to
|
||
*/
|
||
class AutocompleteMultiselectPrompt extends MultiselectPrompt {
|
||
constructor(opts={}) {
|
||
opts.overrideRender = true;
|
||
super(opts);
|
||
this.inputValue = '';
|
||
this.clear = clear('', this.out.columns);
|
||
this.filteredOptions = this.value;
|
||
this.render();
|
||
}
|
||
|
||
last() {
|
||
this.cursor = this.filteredOptions.length - 1;
|
||
this.render();
|
||
}
|
||
next() {
|
||
this.cursor = (this.cursor + 1) % this.filteredOptions.length;
|
||
this.render();
|
||
}
|
||
|
||
up() {
|
||
if (this.cursor === 0) {
|
||
this.cursor = this.filteredOptions.length - 1;
|
||
} else {
|
||
this.cursor--;
|
||
}
|
||
this.render();
|
||
}
|
||
|
||
down() {
|
||
if (this.cursor === this.filteredOptions.length - 1) {
|
||
this.cursor = 0;
|
||
} else {
|
||
this.cursor++;
|
||
}
|
||
this.render();
|
||
}
|
||
|
||
left() {
|
||
this.filteredOptions[this.cursor].selected = false;
|
||
this.render();
|
||
}
|
||
|
||
right() {
|
||
if (this.value.filter(e => e.selected).length >= this.maxChoices) return this.bell();
|
||
this.filteredOptions[this.cursor].selected = true;
|
||
this.render();
|
||
}
|
||
|
||
delete() {
|
||
if (this.inputValue.length) {
|
||
this.inputValue = this.inputValue.substr(0, this.inputValue.length - 1);
|
||
this.updateFilteredOptions();
|
||
}
|
||
}
|
||
|
||
updateFilteredOptions() {
|
||
const currentHighlight = this.filteredOptions[this.cursor];
|
||
this.filteredOptions = this.value
|
||
.filter(v => {
|
||
if (this.inputValue) {
|
||
if (typeof v.title === 'string') {
|
||
if (v.title.toLowerCase().includes(this.inputValue.toLowerCase())) {
|
||
return true;
|
||
}
|
||
}
|
||
if (typeof v.value === 'string') {
|
||
if (v.value.toLowerCase().includes(this.inputValue.toLowerCase())) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
return true;
|
||
});
|
||
const newHighlightIndex = this.filteredOptions.findIndex(v => v === currentHighlight);
|
||
this.cursor = newHighlightIndex < 0 ? 0 : newHighlightIndex;
|
||
this.render();
|
||
}
|
||
|
||
handleSpaceToggle() {
|
||
const v = this.filteredOptions[this.cursor];
|
||
|
||
if (v.selected) {
|
||
v.selected = false;
|
||
this.render();
|
||
} else if (v.disabled || this.value.filter(e => e.selected).length >= this.maxChoices) {
|
||
return this.bell();
|
||
} else {
|
||
v.selected = true;
|
||
this.render();
|
||
}
|
||
}
|
||
|
||
handleInputChange(c) {
|
||
this.inputValue = this.inputValue + c;
|
||
this.updateFilteredOptions();
|
||
}
|
||
|
||
_(c, key) {
|
||
if (c === ' ') {
|
||
this.handleSpaceToggle();
|
||
} else {
|
||
this.handleInputChange(c);
|
||
}
|
||
}
|
||
|
||
renderInstructions() {
|
||
if (this.instructions === undefined || this.instructions) {
|
||
if (typeof this.instructions === 'string') {
|
||
return this.instructions;
|
||
}
|
||
return `
|
||
Instructions:
|
||
${figures.arrowUp}/${figures.arrowDown}: Highlight option
|
||
${figures.arrowLeft}/${figures.arrowRight}/[space]: Toggle selection
|
||
[a,b,c]/delete: Filter choices
|
||
enter/return: Complete answer
|
||
`;
|
||
}
|
||
return '';
|
||
}
|
||
|
||
renderCurrentInput() {
|
||
return `
|
||
Filtered results for: ${this.inputValue ? this.inputValue : color.gray('Enter something to filter')}\n`;
|
||
}
|
||
|
||
renderOption(cursor, v, i, arrowIndicator) {
|
||
const prefix = (v.selected ? color.green(figures.radioOn) : figures.radioOff) + ' ' + arrowIndicator + ' ';
|
||
let title;
|
||
if (v.disabled) title = cursor === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title);
|
||
else title = cursor === i ? color.cyan().underline(v.title) : v.title;
|
||
return prefix + title;
|
||
}
|
||
|
||
renderDoneOrInstructions() {
|
||
if (this.done) {
|
||
return this.value
|
||
.filter(e => e.selected)
|
||
.map(v => v.title)
|
||
.join(', ');
|
||
}
|
||
|
||
const output = [color.gray(this.hint), this.renderInstructions(), this.renderCurrentInput()];
|
||
|
||
if (this.filteredOptions.length && this.filteredOptions[this.cursor].disabled) {
|
||
output.push(color.yellow(this.warn));
|
||
}
|
||
return output.join(' ');
|
||
}
|
||
|
||
render() {
|
||
if (this.closed) return;
|
||
if (this.firstRender) this.out.write(cursor.hide);
|
||
super.render();
|
||
|
||
// print prompt
|
||
|
||
let prompt = [
|
||
style.symbol(this.done, this.aborted),
|
||
color.bold(this.msg),
|
||
style.delimiter(false),
|
||
this.renderDoneOrInstructions()
|
||
].join(' ');
|
||
|
||
if (this.showMinError) {
|
||
prompt += color.red(`You must select a minimum of ${this.minSelected} choices.`);
|
||
this.showMinError = false;
|
||
}
|
||
prompt += this.renderOptions(this.filteredOptions);
|
||
|
||
this.out.write(this.clear + prompt);
|
||
this.clear = clear(prompt, this.out.columns);
|
||
}
|
||
}
|
||
|
||
autocompleteMultiselect = AutocompleteMultiselectPrompt;
|
||
return autocompleteMultiselect;
|
||
}
|
||
|
||
var confirm;
|
||
var hasRequiredConfirm;
|
||
|
||
function requireConfirm () {
|
||
if (hasRequiredConfirm) return confirm;
|
||
hasRequiredConfirm = 1;
|
||
const color = requireKleur();
|
||
const Prompt = requirePrompt();
|
||
const { style, clear } = requireUtil();
|
||
const { erase, cursor } = requireSrc();
|
||
|
||
/**
|
||
* ConfirmPrompt Base Element
|
||
* @param {Object} opts Options
|
||
* @param {String} opts.message Message
|
||
* @param {Boolean} [opts.initial] Default value (true/false)
|
||
* @param {Stream} [opts.stdin] The Readable stream to listen to
|
||
* @param {Stream} [opts.stdout] The Writable stream to write readline data to
|
||
* @param {String} [opts.yes] The "Yes" label
|
||
* @param {String} [opts.yesOption] The "Yes" option when choosing between yes/no
|
||
* @param {String} [opts.no] The "No" label
|
||
* @param {String} [opts.noOption] The "No" option when choosing between yes/no
|
||
*/
|
||
class ConfirmPrompt extends Prompt {
|
||
constructor(opts={}) {
|
||
super(opts);
|
||
this.msg = opts.message;
|
||
this.value = opts.initial;
|
||
this.initialValue = !!opts.initial;
|
||
this.yesMsg = opts.yes || 'yes';
|
||
this.yesOption = opts.yesOption || '(Y/n)';
|
||
this.noMsg = opts.no || 'no';
|
||
this.noOption = opts.noOption || '(y/N)';
|
||
this.render();
|
||
}
|
||
|
||
reset() {
|
||
this.value = this.initialValue;
|
||
this.fire();
|
||
this.render();
|
||
}
|
||
|
||
exit() {
|
||
this.abort();
|
||
}
|
||
|
||
abort() {
|
||
this.done = this.aborted = true;
|
||
this.fire();
|
||
this.render();
|
||
this.out.write('\n');
|
||
this.close();
|
||
}
|
||
|
||
submit() {
|
||
this.value = this.value || false;
|
||
this.done = true;
|
||
this.aborted = false;
|
||
this.fire();
|
||
this.render();
|
||
this.out.write('\n');
|
||
this.close();
|
||
}
|
||
|
||
_(c, key) {
|
||
if (c.toLowerCase() === 'y') {
|
||
this.value = true;
|
||
return this.submit();
|
||
}
|
||
if (c.toLowerCase() === 'n') {
|
||
this.value = false;
|
||
return this.submit();
|
||
}
|
||
return this.bell();
|
||
}
|
||
|
||
render() {
|
||
if (this.closed) return;
|
||
if (this.firstRender) this.out.write(cursor.hide);
|
||
else this.out.write(clear(this.outputText, this.out.columns));
|
||
super.render();
|
||
|
||
this.outputText = [
|
||
style.symbol(this.done, this.aborted),
|
||
color.bold(this.msg),
|
||
style.delimiter(this.done),
|
||
this.done ? (this.value ? this.yesMsg : this.noMsg)
|
||
: color.gray(this.initialValue ? this.yesOption : this.noOption)
|
||
].join(' ');
|
||
|
||
this.out.write(erase.line + cursor.to(0) + this.outputText);
|
||
}
|
||
}
|
||
|
||
confirm = ConfirmPrompt;
|
||
return confirm;
|
||
}
|
||
|
||
var elements;
|
||
var hasRequiredElements;
|
||
|
||
function requireElements () {
|
||
if (hasRequiredElements) return elements;
|
||
hasRequiredElements = 1;
|
||
|
||
elements = {
|
||
TextPrompt: requireText(),
|
||
SelectPrompt: requireSelect(),
|
||
TogglePrompt: requireToggle(),
|
||
DatePrompt: requireDate(),
|
||
NumberPrompt: requireNumber(),
|
||
MultiselectPrompt: requireMultiselect(),
|
||
AutocompletePrompt: requireAutocomplete(),
|
||
AutocompleteMultiselectPrompt: requireAutocompleteMultiselect(),
|
||
ConfirmPrompt: requireConfirm()
|
||
};
|
||
return elements;
|
||
}
|
||
|
||
var hasRequiredPrompts$1;
|
||
|
||
function requirePrompts$1 () {
|
||
if (hasRequiredPrompts$1) return prompts$2;
|
||
hasRequiredPrompts$1 = 1;
|
||
(function (exports) {
|
||
const $ = exports;
|
||
const el = requireElements();
|
||
const noop = v => v;
|
||
|
||
function toPrompt(type, args, opts={}) {
|
||
return new Promise((res, rej) => {
|
||
const p = new el[type](args);
|
||
const onAbort = opts.onAbort || noop;
|
||
const onSubmit = opts.onSubmit || noop;
|
||
const onExit = opts.onExit || noop;
|
||
p.on('state', args.onState || noop);
|
||
p.on('submit', x => res(onSubmit(x)));
|
||
p.on('exit', x => res(onExit(x)));
|
||
p.on('abort', x => rej(onAbort(x)));
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Text prompt
|
||
* @param {string} args.message Prompt message to display
|
||
* @param {string} [args.initial] Default string value
|
||
* @param {string} [args.style="default"] Render style ('default', 'password', 'invisible')
|
||
* @param {function} [args.onState] On state change callback
|
||
* @param {function} [args.validate] Function to validate user input
|
||
* @param {Stream} [args.stdin] The Readable stream to listen to
|
||
* @param {Stream} [args.stdout] The Writable stream to write readline data to
|
||
* @returns {Promise} Promise with user input
|
||
*/
|
||
$.text = args => toPrompt('TextPrompt', args);
|
||
|
||
/**
|
||
* Password prompt with masked input
|
||
* @param {string} args.message Prompt message to display
|
||
* @param {string} [args.initial] Default string value
|
||
* @param {function} [args.onState] On state change callback
|
||
* @param {function} [args.validate] Function to validate user input
|
||
* @param {Stream} [args.stdin] The Readable stream to listen to
|
||
* @param {Stream} [args.stdout] The Writable stream to write readline data to
|
||
* @returns {Promise} Promise with user input
|
||
*/
|
||
$.password = args => {
|
||
args.style = 'password';
|
||
return $.text(args);
|
||
};
|
||
|
||
/**
|
||
* Prompt where input is invisible, like sudo
|
||
* @param {string} args.message Prompt message to display
|
||
* @param {string} [args.initial] Default string value
|
||
* @param {function} [args.onState] On state change callback
|
||
* @param {function} [args.validate] Function to validate user input
|
||
* @param {Stream} [args.stdin] The Readable stream to listen to
|
||
* @param {Stream} [args.stdout] The Writable stream to write readline data to
|
||
* @returns {Promise} Promise with user input
|
||
*/
|
||
$.invisible = args => {
|
||
args.style = 'invisible';
|
||
return $.text(args);
|
||
};
|
||
|
||
/**
|
||
* Number prompt
|
||
* @param {string} args.message Prompt message to display
|
||
* @param {number} args.initial Default number value
|
||
* @param {function} [args.onState] On state change callback
|
||
* @param {number} [args.max] Max value
|
||
* @param {number} [args.min] Min value
|
||
* @param {string} [args.style="default"] Render style ('default', 'password', 'invisible')
|
||
* @param {Boolean} [opts.float=false] Parse input as floats
|
||
* @param {Number} [opts.round=2] Round floats to x decimals
|
||
* @param {Number} [opts.increment=1] Number to increment by when using arrow-keys
|
||
* @param {function} [args.validate] Function to validate user input
|
||
* @param {Stream} [args.stdin] The Readable stream to listen to
|
||
* @param {Stream} [args.stdout] The Writable stream to write readline data to
|
||
* @returns {Promise} Promise with user input
|
||
*/
|
||
$.number = args => toPrompt('NumberPrompt', args);
|
||
|
||
/**
|
||
* Date prompt
|
||
* @param {string} args.message Prompt message to display
|
||
* @param {number} args.initial Default number value
|
||
* @param {function} [args.onState] On state change callback
|
||
* @param {number} [args.max] Max value
|
||
* @param {number} [args.min] Min value
|
||
* @param {string} [args.style="default"] Render style ('default', 'password', 'invisible')
|
||
* @param {Boolean} [opts.float=false] Parse input as floats
|
||
* @param {Number} [opts.round=2] Round floats to x decimals
|
||
* @param {Number} [opts.increment=1] Number to increment by when using arrow-keys
|
||
* @param {function} [args.validate] Function to validate user input
|
||
* @param {Stream} [args.stdin] The Readable stream to listen to
|
||
* @param {Stream} [args.stdout] The Writable stream to write readline data to
|
||
* @returns {Promise} Promise with user input
|
||
*/
|
||
$.date = args => toPrompt('DatePrompt', args);
|
||
|
||
/**
|
||
* Classic yes/no prompt
|
||
* @param {string} args.message Prompt message to display
|
||
* @param {boolean} [args.initial=false] Default value
|
||
* @param {function} [args.onState] On state change callback
|
||
* @param {Stream} [args.stdin] The Readable stream to listen to
|
||
* @param {Stream} [args.stdout] The Writable stream to write readline data to
|
||
* @returns {Promise} Promise with user input
|
||
*/
|
||
$.confirm = args => toPrompt('ConfirmPrompt', args);
|
||
|
||
/**
|
||
* List prompt, split intput string by `seperator`
|
||
* @param {string} args.message Prompt message to display
|
||
* @param {string} [args.initial] Default string value
|
||
* @param {string} [args.style="default"] Render style ('default', 'password', 'invisible')
|
||
* @param {string} [args.separator] String separator
|
||
* @param {function} [args.onState] On state change callback
|
||
* @param {Stream} [args.stdin] The Readable stream to listen to
|
||
* @param {Stream} [args.stdout] The Writable stream to write readline data to
|
||
* @returns {Promise} Promise with user input, in form of an `Array`
|
||
*/
|
||
$.list = args => {
|
||
const sep = args.separator || ',';
|
||
return toPrompt('TextPrompt', args, {
|
||
onSubmit: str => str.split(sep).map(s => s.trim())
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Toggle/switch prompt
|
||
* @param {string} args.message Prompt message to display
|
||
* @param {boolean} [args.initial=false] Default value
|
||
* @param {string} [args.active="on"] Text for `active` state
|
||
* @param {string} [args.inactive="off"] Text for `inactive` state
|
||
* @param {function} [args.onState] On state change callback
|
||
* @param {Stream} [args.stdin] The Readable stream to listen to
|
||
* @param {Stream} [args.stdout] The Writable stream to write readline data to
|
||
* @returns {Promise} Promise with user input
|
||
*/
|
||
$.toggle = args => toPrompt('TogglePrompt', args);
|
||
|
||
/**
|
||
* Interactive select prompt
|
||
* @param {string} args.message Prompt message to display
|
||
* @param {Array} args.choices Array of choices objects `[{ title, value }, ...]`
|
||
* @param {number} [args.initial] Index of default value
|
||
* @param {String} [args.hint] Hint to display
|
||
* @param {function} [args.onState] On state change callback
|
||
* @param {Stream} [args.stdin] The Readable stream to listen to
|
||
* @param {Stream} [args.stdout] The Writable stream to write readline data to
|
||
* @returns {Promise} Promise with user input
|
||
*/
|
||
$.select = args => toPrompt('SelectPrompt', args);
|
||
|
||
/**
|
||
* Interactive multi-select / autocompleteMultiselect prompt
|
||
* @param {string} args.message Prompt message to display
|
||
* @param {Array} args.choices Array of choices objects `[{ title, value, [selected] }, ...]`
|
||
* @param {number} [args.max] Max select
|
||
* @param {string} [args.hint] Hint to display user
|
||
* @param {Number} [args.cursor=0] Cursor start position
|
||
* @param {function} [args.onState] On state change callback
|
||
* @param {Stream} [args.stdin] The Readable stream to listen to
|
||
* @param {Stream} [args.stdout] The Writable stream to write readline data to
|
||
* @returns {Promise} Promise with user input
|
||
*/
|
||
$.multiselect = args => {
|
||
args.choices = [].concat(args.choices || []);
|
||
const toSelected = items => items.filter(item => item.selected).map(item => item.value);
|
||
return toPrompt('MultiselectPrompt', args, {
|
||
onAbort: toSelected,
|
||
onSubmit: toSelected
|
||
});
|
||
};
|
||
|
||
$.autocompleteMultiselect = args => {
|
||
args.choices = [].concat(args.choices || []);
|
||
const toSelected = items => items.filter(item => item.selected).map(item => item.value);
|
||
return toPrompt('AutocompleteMultiselectPrompt', args, {
|
||
onAbort: toSelected,
|
||
onSubmit: toSelected
|
||
});
|
||
};
|
||
|
||
const byTitle = (input, choices) => Promise.resolve(
|
||
choices.filter(item => item.title.slice(0, input.length).toLowerCase() === input.toLowerCase())
|
||
);
|
||
|
||
/**
|
||
* Interactive auto-complete prompt
|
||
* @param {string} args.message Prompt message to display
|
||
* @param {Array} args.choices Array of auto-complete choices objects `[{ title, value }, ...]`
|
||
* @param {Function} [args.suggest] Function to filter results based on user input. Defaults to sort by `title`
|
||
* @param {number} [args.limit=10] Max number of results to show
|
||
* @param {string} [args.style="default"] Render style ('default', 'password', 'invisible')
|
||
* @param {String} [args.initial] Index of the default value
|
||
* @param {boolean} [opts.clearFirst] The first ESCAPE keypress will clear the input
|
||
* @param {String} [args.fallback] Fallback message - defaults to initial value
|
||
* @param {function} [args.onState] On state change callback
|
||
* @param {Stream} [args.stdin] The Readable stream to listen to
|
||
* @param {Stream} [args.stdout] The Writable stream to write readline data to
|
||
* @returns {Promise} Promise with user input
|
||
*/
|
||
$.autocomplete = args => {
|
||
args.suggest = args.suggest || byTitle;
|
||
args.choices = [].concat(args.choices || []);
|
||
return toPrompt('AutocompletePrompt', args);
|
||
};
|
||
} (prompts$2));
|
||
return prompts$2;
|
||
}
|
||
|
||
var lib$1;
|
||
var hasRequiredLib$1;
|
||
|
||
function requireLib$1 () {
|
||
if (hasRequiredLib$1) return lib$1;
|
||
hasRequiredLib$1 = 1;
|
||
|
||
const prompts = requirePrompts$1();
|
||
|
||
const passOn = ['suggest', 'format', 'onState', 'validate', 'onRender', 'type'];
|
||
const noop = () => {};
|
||
|
||
/**
|
||
* Prompt for a series of questions
|
||
* @param {Array|Object} questions Single question object or Array of question objects
|
||
* @param {Function} [onSubmit] Callback function called on prompt submit
|
||
* @param {Function} [onCancel] Callback function called on cancel/abort
|
||
* @returns {Object} Object with values from user input
|
||
*/
|
||
async function prompt(questions=[], { onSubmit=noop, onCancel=noop }={}) {
|
||
const answers = {};
|
||
const override = prompt._override || {};
|
||
questions = [].concat(questions);
|
||
let answer, question, quit, name, type, lastPrompt;
|
||
|
||
const getFormattedAnswer = async (question, answer, skipValidation = false) => {
|
||
if (!skipValidation && question.validate && question.validate(answer) !== true) {
|
||
return;
|
||
}
|
||
return question.format ? await question.format(answer, answers) : answer
|
||
};
|
||
|
||
for (question of questions) {
|
||
({ name, type } = question);
|
||
|
||
// evaluate type first and skip if type is a falsy value
|
||
if (typeof type === 'function') {
|
||
type = await type(answer, { ...answers }, question);
|
||
question['type'] = type;
|
||
}
|
||
if (!type) continue;
|
||
|
||
// if property is a function, invoke it unless it's a special function
|
||
for (let key in question) {
|
||
if (passOn.includes(key)) continue;
|
||
let value = question[key];
|
||
question[key] = typeof value === 'function' ? await value(answer, { ...answers }, lastPrompt) : value;
|
||
}
|
||
|
||
lastPrompt = question;
|
||
|
||
if (typeof question.message !== 'string') {
|
||
throw new Error('prompt message is required');
|
||
}
|
||
|
||
// update vars in case they changed
|
||
({ name, type } = question);
|
||
|
||
if (prompts[type] === void 0) {
|
||
throw new Error(`prompt type (${type}) is not defined`);
|
||
}
|
||
|
||
if (override[question.name] !== undefined) {
|
||
answer = await getFormattedAnswer(question, override[question.name]);
|
||
if (answer !== undefined) {
|
||
answers[name] = answer;
|
||
continue;
|
||
}
|
||
}
|
||
|
||
try {
|
||
// Get the injected answer if there is one or prompt the user
|
||
answer = prompt._injected ? getInjectedAnswer(prompt._injected, question.initial) : await prompts[type](question);
|
||
answers[name] = answer = await getFormattedAnswer(question, answer, true);
|
||
quit = await onSubmit(question, answer, answers);
|
||
} catch (err) {
|
||
quit = !(await onCancel(question, answers));
|
||
}
|
||
|
||
if (quit) return answers;
|
||
}
|
||
|
||
return answers;
|
||
}
|
||
|
||
function getInjectedAnswer(injected, deafultValue) {
|
||
const answer = injected.shift();
|
||
if (answer instanceof Error) {
|
||
throw answer;
|
||
}
|
||
|
||
return (answer === undefined) ? deafultValue : answer;
|
||
}
|
||
|
||
function inject(answers) {
|
||
prompt._injected = (prompt._injected || []).concat(answers);
|
||
}
|
||
|
||
function override(answers) {
|
||
prompt._override = Object.assign({}, answers);
|
||
}
|
||
|
||
lib$1 = Object.assign(prompt, { prompt, prompts, inject, override });
|
||
return lib$1;
|
||
}
|
||
|
||
var prompts$1;
|
||
var hasRequiredPrompts;
|
||
|
||
function requirePrompts () {
|
||
if (hasRequiredPrompts) return prompts$1;
|
||
hasRequiredPrompts = 1;
|
||
prompts$1 = requireLib$1();
|
||
return prompts$1;
|
||
}
|
||
|
||
var promptsExports = requirePrompts();
|
||
const prompts = /*@__PURE__*/getDefaultExportFromCjs(promptsExports);
|
||
|
||
function npmRun(agent) {
|
||
return (args) => {
|
||
if (args.length > 1) {
|
||
return [agent, "run", args[0], "--", ...args.slice(1)];
|
||
} else {
|
||
return [agent, "run", args[0]];
|
||
}
|
||
};
|
||
}
|
||
function denoExecute() {
|
||
return (args) => {
|
||
return ["deno", "run", `npm:${args[0]}`, ...args.slice(1)];
|
||
};
|
||
}
|
||
const npm = {
|
||
"agent": ["npm", 0],
|
||
"run": npmRun("npm"),
|
||
"install": ["npm", "i", 0],
|
||
"frozen": ["npm", "ci"],
|
||
"global": ["npm", "i", "-g", 0],
|
||
"add": ["npm", "i", 0],
|
||
"upgrade": ["npm", "update", 0],
|
||
"upgrade-interactive": null,
|
||
"execute": ["npx", 0],
|
||
"execute-local": ["npx", 0],
|
||
"uninstall": ["npm", "uninstall", 0],
|
||
"global_uninstall": ["npm", "uninstall", "-g", 0]
|
||
};
|
||
const yarn = {
|
||
"agent": ["yarn", 0],
|
||
"run": ["yarn", "run", 0],
|
||
"install": ["yarn", "install", 0],
|
||
"frozen": ["yarn", "install", "--frozen-lockfile"],
|
||
"global": ["yarn", "global", "add", 0],
|
||
"add": ["yarn", "add", 0],
|
||
"upgrade": ["yarn", "upgrade", 0],
|
||
"upgrade-interactive": ["yarn", "upgrade-interactive", 0],
|
||
"execute": ["npx", 0],
|
||
"execute-local": ["yarn", "exec", 0],
|
||
"uninstall": ["yarn", "remove", 0],
|
||
"global_uninstall": ["yarn", "global", "remove", 0]
|
||
};
|
||
const yarnBerry = {
|
||
...yarn,
|
||
"frozen": ["yarn", "install", "--immutable"],
|
||
"upgrade": ["yarn", "up", 0],
|
||
"upgrade-interactive": ["yarn", "up", "-i", 0],
|
||
"execute": ["yarn", "dlx", 0],
|
||
"execute-local": ["yarn", "exec", 0],
|
||
// Yarn 2+ removed 'global', see https://github.com/yarnpkg/berry/issues/821
|
||
"global": ["npm", "i", "-g", 0],
|
||
"global_uninstall": ["npm", "uninstall", "-g", 0]
|
||
};
|
||
const pnpm = {
|
||
"agent": ["pnpm", 0],
|
||
"run": ["pnpm", "run", 0],
|
||
"install": ["pnpm", "i", 0],
|
||
"frozen": ["pnpm", "i", "--frozen-lockfile"],
|
||
"global": ["pnpm", "add", "-g", 0],
|
||
"add": ["pnpm", "add", 0],
|
||
"upgrade": ["pnpm", "update", 0],
|
||
"upgrade-interactive": ["pnpm", "update", "-i", 0],
|
||
"execute": ["pnpm", "dlx", 0],
|
||
"execute-local": ["pnpm", "exec", 0],
|
||
"uninstall": ["pnpm", "remove", 0],
|
||
"global_uninstall": ["pnpm", "remove", "--global", 0]
|
||
};
|
||
const bun = {
|
||
"agent": ["bun", 0],
|
||
"run": ["bun", "run", 0],
|
||
"install": ["bun", "install", 0],
|
||
"frozen": ["bun", "install", "--frozen-lockfile"],
|
||
"global": ["bun", "add", "-g", 0],
|
||
"add": ["bun", "add", 0],
|
||
"upgrade": ["bun", "update", 0],
|
||
"upgrade-interactive": ["bun", "update", 0],
|
||
"execute": ["bun", "x", 0],
|
||
"execute-local": ["bun", "x", 0],
|
||
"uninstall": ["bun", "remove", 0],
|
||
"global_uninstall": ["bun", "remove", "-g", 0]
|
||
};
|
||
const deno = {
|
||
"agent": ["deno", 0],
|
||
"run": ["deno", "task", 0],
|
||
"install": ["deno", "install", 0],
|
||
"frozen": ["deno", "install", "--frozen"],
|
||
"global": ["deno", "install", "-g", 0],
|
||
"add": ["deno", "add", 0],
|
||
"upgrade": ["deno", "outdated", "--update", 0],
|
||
"upgrade-interactive": ["deno", "outdated", "--update", 0],
|
||
"execute": denoExecute(),
|
||
"execute-local": ["deno", "task", "--eval", 0],
|
||
"uninstall": ["deno", "remove", 0],
|
||
"global_uninstall": ["deno", "uninstall", "-g", 0]
|
||
};
|
||
const COMMANDS = {
|
||
"npm": npm,
|
||
"yarn": yarn,
|
||
"yarn@berry": yarnBerry,
|
||
"pnpm": pnpm,
|
||
// pnpm v6.x or below
|
||
"pnpm@6": {
|
||
...pnpm,
|
||
run: npmRun("pnpm")
|
||
},
|
||
"bun": bun,
|
||
"deno": deno
|
||
};
|
||
function resolveCommand(agent, command, args) {
|
||
const value = COMMANDS[agent][command];
|
||
return constructCommand(value, args);
|
||
}
|
||
function constructCommand(value, args) {
|
||
if (value == null)
|
||
return null;
|
||
const list = typeof value === "function" ? value(args) : value.flatMap((v) => {
|
||
if (typeof v === "number")
|
||
return args;
|
||
return [v];
|
||
});
|
||
return {
|
||
command: list[0],
|
||
args: list.slice(1)
|
||
};
|
||
}
|
||
|
||
const AGENTS = [
|
||
"npm",
|
||
"yarn",
|
||
"yarn@berry",
|
||
"pnpm",
|
||
"pnpm@6",
|
||
"bun",
|
||
"deno"
|
||
];
|
||
const LOCKS = {
|
||
"bun.lock": "bun",
|
||
"bun.lockb": "bun",
|
||
"deno.lock": "deno",
|
||
"pnpm-lock.yaml": "pnpm",
|
||
"yarn.lock": "yarn",
|
||
"package-lock.json": "npm",
|
||
"npm-shrinkwrap.json": "npm"
|
||
};
|
||
const INSTALL_PAGE = {
|
||
"bun": "https://bun.sh",
|
||
"deno": "https://deno.com",
|
||
"pnpm": "https://pnpm.io/installation",
|
||
"pnpm@6": "https://pnpm.io/6.x/installation",
|
||
"yarn": "https://classic.yarnpkg.com/en/docs/install",
|
||
"yarn@berry": "https://yarnpkg.com/getting-started/install",
|
||
"npm": "https://docs.npmjs.com/cli/v8/configuring-npm/install"
|
||
};
|
||
|
||
async function detect$1(options = {}) {
|
||
const { cwd, onUnknown } = options;
|
||
for (const directory of lookup(cwd)) {
|
||
for (const lock of Object.keys(LOCKS)) {
|
||
if (await fileExists(path__default.join(directory, lock))) {
|
||
const name = LOCKS[lock];
|
||
const result2 = await parsePackageJson(path__default.join(directory, "package.json"), onUnknown);
|
||
if (result2)
|
||
return result2;
|
||
else
|
||
return { name, agent: name };
|
||
}
|
||
}
|
||
const result = await parsePackageJson(path__default.join(directory, "package.json"), onUnknown);
|
||
if (result)
|
||
return result;
|
||
}
|
||
return null;
|
||
}
|
||
function* lookup(cwd = process__default.cwd()) {
|
||
let directory = path__default.resolve(cwd);
|
||
const { root } = path__default.parse(directory);
|
||
while (directory && directory !== root) {
|
||
yield directory;
|
||
directory = path__default.dirname(directory);
|
||
}
|
||
}
|
||
async function parsePackageJson(filepath, onUnknown) {
|
||
return !filepath || !await fileExists(filepath) ? null : handlePackageManager(filepath, onUnknown);
|
||
}
|
||
function handlePackageManager(filepath, onUnknown) {
|
||
try {
|
||
const pkg = JSON.parse(fs__default.readFileSync(filepath, "utf8"));
|
||
let agent;
|
||
if (typeof pkg.packageManager === "string") {
|
||
const [name, ver] = pkg.packageManager.replace(/^\^/, "").split("@");
|
||
let version = ver;
|
||
if (name === "yarn" && Number.parseInt(ver) > 1) {
|
||
agent = "yarn@berry";
|
||
version = "berry";
|
||
return { name, agent, version };
|
||
} else if (name === "pnpm" && Number.parseInt(ver) < 7) {
|
||
agent = "pnpm@6";
|
||
return { name, agent, version };
|
||
} else if (AGENTS.includes(name)) {
|
||
agent = name;
|
||
return { name, agent, version };
|
||
} else {
|
||
return onUnknown?.(pkg.packageManager) ?? null;
|
||
}
|
||
}
|
||
} catch {
|
||
}
|
||
return null;
|
||
}
|
||
async function fileExists(filePath) {
|
||
try {
|
||
const stats = await fsPromises__default.stat(filePath);
|
||
if (stats.isFile()) {
|
||
return true;
|
||
}
|
||
} catch {
|
||
}
|
||
return false;
|
||
}
|
||
|
||
const ESC = '\u001B[';
|
||
const OSC = '\u001B]';
|
||
const BEL = '\u0007';
|
||
const SEP = ';';
|
||
const isTerminalApp = process.env.TERM_PROGRAM === 'Apple_Terminal';
|
||
|
||
const ansiEscapes = {};
|
||
|
||
ansiEscapes.cursorTo = (x, y) => {
|
||
if (typeof x !== 'number') {
|
||
throw new TypeError('The `x` argument is required');
|
||
}
|
||
|
||
if (typeof y !== 'number') {
|
||
return ESC + (x + 1) + 'G';
|
||
}
|
||
|
||
return ESC + (y + 1) + ';' + (x + 1) + 'H';
|
||
};
|
||
|
||
ansiEscapes.cursorMove = (x, y) => {
|
||
if (typeof x !== 'number') {
|
||
throw new TypeError('The `x` argument is required');
|
||
}
|
||
|
||
let returnValue = '';
|
||
|
||
if (x < 0) {
|
||
returnValue += ESC + (-x) + 'D';
|
||
} else if (x > 0) {
|
||
returnValue += ESC + x + 'C';
|
||
}
|
||
|
||
if (y < 0) {
|
||
returnValue += ESC + (-y) + 'A';
|
||
} else if (y > 0) {
|
||
returnValue += ESC + y + 'B';
|
||
}
|
||
|
||
return returnValue;
|
||
};
|
||
|
||
ansiEscapes.cursorUp = (count = 1) => ESC + count + 'A';
|
||
ansiEscapes.cursorDown = (count = 1) => ESC + count + 'B';
|
||
ansiEscapes.cursorForward = (count = 1) => ESC + count + 'C';
|
||
ansiEscapes.cursorBackward = (count = 1) => ESC + count + 'D';
|
||
|
||
ansiEscapes.cursorLeft = ESC + 'G';
|
||
ansiEscapes.cursorSavePosition = isTerminalApp ? '\u001B7' : ESC + 's';
|
||
ansiEscapes.cursorRestorePosition = isTerminalApp ? '\u001B8' : ESC + 'u';
|
||
ansiEscapes.cursorGetPosition = ESC + '6n';
|
||
ansiEscapes.cursorNextLine = ESC + 'E';
|
||
ansiEscapes.cursorPrevLine = ESC + 'F';
|
||
ansiEscapes.cursorHide = ESC + '?25l';
|
||
ansiEscapes.cursorShow = ESC + '?25h';
|
||
|
||
ansiEscapes.eraseLines = count => {
|
||
let clear = '';
|
||
|
||
for (let i = 0; i < count; i++) {
|
||
clear += ansiEscapes.eraseLine + (i < count - 1 ? ansiEscapes.cursorUp() : '');
|
||
}
|
||
|
||
if (count) {
|
||
clear += ansiEscapes.cursorLeft;
|
||
}
|
||
|
||
return clear;
|
||
};
|
||
|
||
ansiEscapes.eraseEndLine = ESC + 'K';
|
||
ansiEscapes.eraseStartLine = ESC + '1K';
|
||
ansiEscapes.eraseLine = ESC + '2K';
|
||
ansiEscapes.eraseDown = ESC + 'J';
|
||
ansiEscapes.eraseUp = ESC + '1J';
|
||
ansiEscapes.eraseScreen = ESC + '2J';
|
||
ansiEscapes.scrollUp = ESC + 'S';
|
||
ansiEscapes.scrollDown = ESC + 'T';
|
||
|
||
ansiEscapes.clearScreen = '\u001Bc';
|
||
|
||
ansiEscapes.clearTerminal = process.platform === 'win32' ?
|
||
`${ansiEscapes.eraseScreen}${ESC}0f` :
|
||
// 1. Erases the screen (Only done in case `2` is not supported)
|
||
// 2. Erases the whole screen including scrollback buffer
|
||
// 3. Moves cursor to the top-left position
|
||
// More info: https://www.real-world-systems.com/docs/ANSIcode.html
|
||
`${ansiEscapes.eraseScreen}${ESC}3J${ESC}H`;
|
||
|
||
ansiEscapes.beep = BEL;
|
||
|
||
ansiEscapes.link = (text, url) => {
|
||
return [
|
||
OSC,
|
||
'8',
|
||
SEP,
|
||
SEP,
|
||
url,
|
||
BEL,
|
||
text,
|
||
OSC,
|
||
'8',
|
||
SEP,
|
||
SEP,
|
||
BEL
|
||
].join('');
|
||
};
|
||
|
||
ansiEscapes.image = (buffer, options = {}) => {
|
||
let returnValue = `${OSC}1337;File=inline=1`;
|
||
|
||
if (options.width) {
|
||
returnValue += `;width=${options.width}`;
|
||
}
|
||
|
||
if (options.height) {
|
||
returnValue += `;height=${options.height}`;
|
||
}
|
||
|
||
if (options.preserveAspectRatio === false) {
|
||
returnValue += ';preserveAspectRatio=0';
|
||
}
|
||
|
||
return returnValue + ':' + buffer.toString('base64') + BEL;
|
||
};
|
||
|
||
ansiEscapes.iTerm = {
|
||
setCwd: (cwd = process.cwd()) => `${OSC}50;CurrentDir=${cwd}${BEL}`,
|
||
|
||
annotation: (message, options = {}) => {
|
||
let returnValue = `${OSC}1337;`;
|
||
|
||
const hasX = typeof options.x !== 'undefined';
|
||
const hasY = typeof options.y !== 'undefined';
|
||
if ((hasX || hasY) && !(hasX && hasY && typeof options.length !== 'undefined')) {
|
||
throw new Error('`x`, `y` and `length` must be defined when `x` or `y` is defined');
|
||
}
|
||
|
||
message = message.replace(/\|/g, '');
|
||
|
||
returnValue += options.isHidden ? 'AddHiddenAnnotation=' : 'AddAnnotation=';
|
||
|
||
if (options.length > 0) {
|
||
returnValue +=
|
||
(hasX ?
|
||
[message, options.length, options.x, options.y] :
|
||
[options.length, message]).join('|');
|
||
} else {
|
||
returnValue += message;
|
||
}
|
||
|
||
return returnValue + BEL;
|
||
}
|
||
};
|
||
|
||
var hasFlag;
|
||
var hasRequiredHasFlag;
|
||
|
||
function requireHasFlag () {
|
||
if (hasRequiredHasFlag) return hasFlag;
|
||
hasRequiredHasFlag = 1;
|
||
|
||
hasFlag = (flag, argv = process.argv) => {
|
||
const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
|
||
const position = argv.indexOf(prefix + flag);
|
||
const terminatorPosition = argv.indexOf('--');
|
||
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
||
};
|
||
return hasFlag;
|
||
}
|
||
|
||
var supportsColor_1;
|
||
var hasRequiredSupportsColor;
|
||
|
||
function requireSupportsColor () {
|
||
if (hasRequiredSupportsColor) return supportsColor_1;
|
||
hasRequiredSupportsColor = 1;
|
||
const os = require$$0__default$1;
|
||
const tty = require$$1__default;
|
||
const hasFlag = requireHasFlag();
|
||
|
||
const {env} = process;
|
||
|
||
let forceColor;
|
||
if (hasFlag('no-color') ||
|
||
hasFlag('no-colors') ||
|
||
hasFlag('color=false') ||
|
||
hasFlag('color=never')) {
|
||
forceColor = 0;
|
||
} else if (hasFlag('color') ||
|
||
hasFlag('colors') ||
|
||
hasFlag('color=true') ||
|
||
hasFlag('color=always')) {
|
||
forceColor = 1;
|
||
}
|
||
|
||
if ('FORCE_COLOR' in env) {
|
||
if (env.FORCE_COLOR === 'true') {
|
||
forceColor = 1;
|
||
} else if (env.FORCE_COLOR === 'false') {
|
||
forceColor = 0;
|
||
} else {
|
||
forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3);
|
||
}
|
||
}
|
||
|
||
function translateLevel(level) {
|
||
if (level === 0) {
|
||
return false;
|
||
}
|
||
|
||
return {
|
||
level,
|
||
hasBasic: true,
|
||
has256: level >= 2,
|
||
has16m: level >= 3
|
||
};
|
||
}
|
||
|
||
function supportsColor(haveStream, streamIsTTY) {
|
||
if (forceColor === 0) {
|
||
return 0;
|
||
}
|
||
|
||
if (hasFlag('color=16m') ||
|
||
hasFlag('color=full') ||
|
||
hasFlag('color=truecolor')) {
|
||
return 3;
|
||
}
|
||
|
||
if (hasFlag('color=256')) {
|
||
return 2;
|
||
}
|
||
|
||
if (haveStream && !streamIsTTY && forceColor === undefined) {
|
||
return 0;
|
||
}
|
||
|
||
const min = forceColor || 0;
|
||
|
||
if (env.TERM === 'dumb') {
|
||
return min;
|
||
}
|
||
|
||
if (process.platform === 'win32') {
|
||
// Windows 10 build 10586 is the first Windows release that supports 256 colors.
|
||
// Windows 10 build 14931 is the first release that supports 16m/TrueColor.
|
||
const osRelease = os.release().split('.');
|
||
if (
|
||
Number(osRelease[0]) >= 10 &&
|
||
Number(osRelease[2]) >= 10586
|
||
) {
|
||
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
||
}
|
||
|
||
return 1;
|
||
}
|
||
|
||
if ('CI' in env) {
|
||
if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'GITHUB_ACTIONS', 'BUILDKITE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
|
||
return 1;
|
||
}
|
||
|
||
return min;
|
||
}
|
||
|
||
if ('TEAMCITY_VERSION' in env) {
|
||
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
|
||
}
|
||
|
||
if (env.COLORTERM === 'truecolor') {
|
||
return 3;
|
||
}
|
||
|
||
if ('TERM_PROGRAM' in env) {
|
||
const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
|
||
|
||
switch (env.TERM_PROGRAM) {
|
||
case 'iTerm.app':
|
||
return version >= 3 ? 3 : 2;
|
||
case 'Apple_Terminal':
|
||
return 2;
|
||
// No default
|
||
}
|
||
}
|
||
|
||
if (/-256(color)?$/i.test(env.TERM)) {
|
||
return 2;
|
||
}
|
||
|
||
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
|
||
return 1;
|
||
}
|
||
|
||
if ('COLORTERM' in env) {
|
||
return 1;
|
||
}
|
||
|
||
return min;
|
||
}
|
||
|
||
function getSupportLevel(stream) {
|
||
const level = supportsColor(stream, stream && stream.isTTY);
|
||
return translateLevel(level);
|
||
}
|
||
|
||
supportsColor_1 = {
|
||
supportsColor: getSupportLevel,
|
||
stdout: translateLevel(supportsColor(true, tty.isatty(1))),
|
||
stderr: translateLevel(supportsColor(true, tty.isatty(2)))
|
||
};
|
||
return supportsColor_1;
|
||
}
|
||
|
||
var supportsHyperlinks$1;
|
||
var hasRequiredSupportsHyperlinks;
|
||
|
||
function requireSupportsHyperlinks () {
|
||
if (hasRequiredSupportsHyperlinks) return supportsHyperlinks$1;
|
||
hasRequiredSupportsHyperlinks = 1;
|
||
const supportsColor = requireSupportsColor();
|
||
const hasFlag = requireHasFlag();
|
||
|
||
function parseVersion(versionString) {
|
||
if (/^\d{3,4}$/.test(versionString)) {
|
||
// Env var doesn't always use dots. example: 4601 => 46.1.0
|
||
const m = /(\d{1,2})(\d{2})/.exec(versionString);
|
||
return {
|
||
major: 0,
|
||
minor: parseInt(m[1], 10),
|
||
patch: parseInt(m[2], 10)
|
||
};
|
||
}
|
||
|
||
const versions = (versionString || '').split('.').map(n => parseInt(n, 10));
|
||
return {
|
||
major: versions[0],
|
||
minor: versions[1],
|
||
patch: versions[2]
|
||
};
|
||
}
|
||
|
||
function supportsHyperlink(stream) {
|
||
const {env} = process;
|
||
|
||
if ('FORCE_HYPERLINK' in env) {
|
||
return !(env.FORCE_HYPERLINK.length > 0 && parseInt(env.FORCE_HYPERLINK, 10) === 0);
|
||
}
|
||
|
||
if (hasFlag('no-hyperlink') || hasFlag('no-hyperlinks') || hasFlag('hyperlink=false') || hasFlag('hyperlink=never')) {
|
||
return false;
|
||
}
|
||
|
||
if (hasFlag('hyperlink=true') || hasFlag('hyperlink=always')) {
|
||
return true;
|
||
}
|
||
|
||
// If they specify no colors, they probably don't want hyperlinks.
|
||
if (!supportsColor.supportsColor(stream)) {
|
||
return false;
|
||
}
|
||
|
||
if (stream && !stream.isTTY) {
|
||
return false;
|
||
}
|
||
|
||
if (process.platform === 'win32') {
|
||
return false;
|
||
}
|
||
|
||
if ('NETLIFY' in env) {
|
||
return true;
|
||
}
|
||
|
||
if ('CI' in env) {
|
||
return false;
|
||
}
|
||
|
||
if ('TEAMCITY_VERSION' in env) {
|
||
return false;
|
||
}
|
||
|
||
if ('TERM_PROGRAM' in env) {
|
||
const version = parseVersion(env.TERM_PROGRAM_VERSION);
|
||
|
||
switch (env.TERM_PROGRAM) {
|
||
case 'iTerm.app':
|
||
if (version.major === 3) {
|
||
return version.minor >= 1;
|
||
}
|
||
|
||
return version.major > 3;
|
||
// No default
|
||
}
|
||
}
|
||
|
||
if ('VTE_VERSION' in env) {
|
||
// 0.50.0 was supposed to support hyperlinks, but throws a segfault
|
||
if (env.VTE_VERSION === '0.50.0') {
|
||
return false;
|
||
}
|
||
|
||
const version = parseVersion(env.VTE_VERSION);
|
||
return version.major > 0 || version.minor >= 50;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
supportsHyperlinks$1 = {
|
||
supportsHyperlink,
|
||
stdout: supportsHyperlink(process.stdout),
|
||
stderr: supportsHyperlink(process.stderr)
|
||
};
|
||
return supportsHyperlinks$1;
|
||
}
|
||
|
||
var supportsHyperlinksExports = requireSupportsHyperlinks();
|
||
const supportsHyperlinks = /*@__PURE__*/getDefaultExportFromCjs(supportsHyperlinksExports);
|
||
|
||
function terminalLink(text, url, {target = 'stdout', ...options} = {}) {
|
||
if (!supportsHyperlinks[target]) {
|
||
// If the fallback has been explicitly disabled, don't modify the text itself.
|
||
if (options.fallback === false) {
|
||
return text;
|
||
}
|
||
|
||
return typeof options.fallback === 'function' ? options.fallback(text, url) : `${text} (\u200B${url}\u200B)`;
|
||
}
|
||
|
||
return ansiEscapes.link(text, url);
|
||
}
|
||
|
||
terminalLink.isSupported = supportsHyperlinks.stdout;
|
||
terminalLink.stderr = (text, url, options = {}) => terminalLink(text, url, {target: 'stderr', ...options});
|
||
terminalLink.stderr.isSupported = supportsHyperlinks.stderr;
|
||
|
||
const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/ni.C82eau-4.cjs', document.baseURI).href)));
|
||
var St = Object.create;
|
||
var $ = Object.defineProperty;
|
||
var kt = Object.getOwnPropertyDescriptor;
|
||
var Tt = Object.getOwnPropertyNames;
|
||
var At = Object.getPrototypeOf, Rt = Object.prototype.hasOwnProperty;
|
||
var h = /* @__PURE__ */ ((t) => typeof require$1 < "u" ? require$1 : typeof Proxy < "u" ? new Proxy(t, {
|
||
get: (e, n) => (typeof require$1 < "u" ? require$1 : e)[n]
|
||
}) : t)(function(t) {
|
||
if (typeof require$1 < "u") return require$1.apply(this, arguments);
|
||
throw Error('Dynamic require of "' + t + '" is not supported');
|
||
});
|
||
var l = (t, e) => () => (e || t((e = { exports: {} }).exports, e), e.exports);
|
||
var $t = (t, e, n, r) => {
|
||
if (e && typeof e == "object" || typeof e == "function")
|
||
for (let s of Tt(e))
|
||
!Rt.call(t, s) && s !== n && $(t, s, { get: () => e[s], enumerable: !(r = kt(e, s)) || r.enumerable });
|
||
return t;
|
||
};
|
||
var Nt = (t, e, n) => (n = t != null ? St(At(t)) : {}, $t(
|
||
// If the importer is in node compatibility mode or this is not an ESM
|
||
// file that has been converted to a CommonJS file using a Babel-
|
||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||
$(n, "default", { value: t, enumerable: !0 }) ,
|
||
t
|
||
));
|
||
|
||
// node_modules/isexe/windows.js
|
||
var W = l((Se, H) => {
|
||
H.exports = z;
|
||
z.sync = Wt;
|
||
var j = h("fs");
|
||
function Ht(t, e) {
|
||
var n = e.pathExt !== void 0 ? e.pathExt : process.env.PATHEXT;
|
||
if (!n || (n = n.split(";"), n.indexOf("") !== -1))
|
||
return !0;
|
||
for (var r = 0; r < n.length; r++) {
|
||
var s = n[r].toLowerCase();
|
||
if (s && t.substr(-s.length).toLowerCase() === s)
|
||
return !0;
|
||
}
|
||
return !1;
|
||
}
|
||
function F(t, e, n) {
|
||
return !t.isSymbolicLink() && !t.isFile() ? !1 : Ht(e, n);
|
||
}
|
||
function z(t, e, n) {
|
||
j.stat(t, function(r, s) {
|
||
n(r, r ? !1 : F(s, t, e));
|
||
});
|
||
}
|
||
function Wt(t, e) {
|
||
return F(j.statSync(t), t, e);
|
||
}
|
||
});
|
||
|
||
// node_modules/isexe/mode.js
|
||
var X = l((ke, B) => {
|
||
B.exports = K;
|
||
K.sync = Dt;
|
||
var D = h("fs");
|
||
function K(t, e, n) {
|
||
D.stat(t, function(r, s) {
|
||
n(r, r ? !1 : M(s, e));
|
||
});
|
||
}
|
||
function Dt(t, e) {
|
||
return M(D.statSync(t), e);
|
||
}
|
||
function M(t, e) {
|
||
return t.isFile() && Kt(t, e);
|
||
}
|
||
function Kt(t, e) {
|
||
var n = t.mode, r = t.uid, s = t.gid, o = e.uid !== void 0 ? e.uid : process.getuid && process.getuid(), i = e.gid !== void 0 ? e.gid : process.getgid && process.getgid(), a = parseInt("100", 8), c = parseInt("010", 8), u = parseInt("001", 8), f = a | c, p = n & u || n & c && s === i || n & a && r === o || n & f && o === 0;
|
||
return p;
|
||
}
|
||
});
|
||
|
||
// node_modules/isexe/index.js
|
||
var U = l((Ae, G) => {
|
||
h("fs"); var v;
|
||
process.platform === "win32" || global.TESTING_WINDOWS ? v = W() : v = X();
|
||
G.exports = y;
|
||
y.sync = Mt;
|
||
function y(t, e, n) {
|
||
if (typeof e == "function" && (n = e, e = {}), !n) {
|
||
if (typeof Promise != "function")
|
||
throw new TypeError("callback not provided");
|
||
return new Promise(function(r, s) {
|
||
y(t, e || {}, function(o, i) {
|
||
o ? s(o) : r(i);
|
||
});
|
||
});
|
||
}
|
||
v(t, e || {}, function(r, s) {
|
||
r && (r.code === "EACCES" || e && e.ignoreErrors) && (r = null, s = !1), n(r, s);
|
||
});
|
||
}
|
||
function Mt(t, e) {
|
||
try {
|
||
return v.sync(t, e || {});
|
||
} catch (n) {
|
||
if (e && e.ignoreErrors || n.code === "EACCES")
|
||
return !1;
|
||
throw n;
|
||
}
|
||
}
|
||
});
|
||
|
||
// node_modules/which/which.js
|
||
var et = l((Re, tt) => {
|
||
var g = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys", Y = h("path"), Bt = g ? ";" : ":", V = U(), J = (t) => Object.assign(new Error(`not found: ${t}`), { code: "ENOENT" }), Q = (t, e) => {
|
||
let n = e.colon || Bt, r = t.match(/\//) || g && t.match(/\\/) ? [""] : [
|
||
// windows always checks the cwd first
|
||
...g ? [process.cwd()] : [],
|
||
...(e.path || process.env.PATH || /* istanbul ignore next: very unusual */
|
||
"").split(n)
|
||
], s = g ? e.pathExt || process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM" : "", o = g ? s.split(n) : [""];
|
||
return g && t.indexOf(".") !== -1 && o[0] !== "" && o.unshift(""), {
|
||
pathEnv: r,
|
||
pathExt: o,
|
||
pathExtExe: s
|
||
};
|
||
}, Z = (t, e, n) => {
|
||
typeof e == "function" && (n = e, e = {}), e || (e = {});
|
||
let { pathEnv: r, pathExt: s, pathExtExe: o } = Q(t, e), i = [], a = (u) => new Promise((f, p) => {
|
||
if (u === r.length)
|
||
return e.all && i.length ? f(i) : p(J(t));
|
||
let d = r[u], w = /^".*"$/.test(d) ? d.slice(1, -1) : d, m = Y.join(w, t), b = !w && /^\.[\\\/]/.test(t) ? t.slice(0, 2) + m : m;
|
||
f(c(b, u, 0));
|
||
}), c = (u, f, p) => new Promise((d, w) => {
|
||
if (p === s.length)
|
||
return d(a(f + 1));
|
||
let m = s[p];
|
||
V(u + m, { pathExt: o }, (b, Ot) => {
|
||
if (!b && Ot)
|
||
if (e.all)
|
||
i.push(u + m);
|
||
else
|
||
return d(u + m);
|
||
return d(c(u, f, p + 1));
|
||
});
|
||
});
|
||
return n ? a(0).then((u) => n(null, u), n) : a(0);
|
||
}, Xt = (t, e) => {
|
||
e = e || {};
|
||
let { pathEnv: n, pathExt: r, pathExtExe: s } = Q(t, e), o = [];
|
||
for (let i = 0; i < n.length; i++) {
|
||
let a = n[i], c = /^".*"$/.test(a) ? a.slice(1, -1) : a, u = Y.join(c, t), f = !c && /^\.[\\\/]/.test(t) ? t.slice(0, 2) + u : u;
|
||
for (let p = 0; p < r.length; p++) {
|
||
let d = f + r[p];
|
||
try {
|
||
if (V.sync(d, { pathExt: s }))
|
||
if (e.all)
|
||
o.push(d);
|
||
else
|
||
return d;
|
||
} catch {
|
||
}
|
||
}
|
||
}
|
||
if (e.all && o.length)
|
||
return o;
|
||
if (e.nothrow)
|
||
return null;
|
||
throw J(t);
|
||
};
|
||
tt.exports = Z;
|
||
Z.sync = Xt;
|
||
});
|
||
|
||
// node_modules/path-key/index.js
|
||
var rt = l(($e, _) => {
|
||
var nt = (t = {}) => {
|
||
let e = t.env || process.env;
|
||
return (t.platform || process.platform) !== "win32" ? "PATH" : Object.keys(e).reverse().find((r) => r.toUpperCase() === "PATH") || "Path";
|
||
};
|
||
_.exports = nt;
|
||
_.exports.default = nt;
|
||
});
|
||
|
||
// node_modules/cross-spawn/lib/util/resolveCommand.js
|
||
var ct = l((Ne, it) => {
|
||
var st = h("path"), Gt = et(), Ut = rt();
|
||
function ot(t, e) {
|
||
let n = t.options.env || process.env, r = process.cwd(), s = t.options.cwd != null, o = s && process.chdir !== void 0 && !process.chdir.disabled;
|
||
if (o)
|
||
try {
|
||
process.chdir(t.options.cwd);
|
||
} catch {
|
||
}
|
||
let i;
|
||
try {
|
||
i = Gt.sync(t.command, {
|
||
path: n[Ut({ env: n })],
|
||
pathExt: e ? st.delimiter : void 0
|
||
});
|
||
} catch {
|
||
} finally {
|
||
o && process.chdir(r);
|
||
}
|
||
return i && (i = st.resolve(s ? t.options.cwd : "", i)), i;
|
||
}
|
||
function Yt(t) {
|
||
return ot(t) || ot(t, !0);
|
||
}
|
||
it.exports = Yt;
|
||
});
|
||
|
||
// node_modules/cross-spawn/lib/util/escape.js
|
||
var ut = l((qe, P) => {
|
||
var C = /([()\][%!^"`<>&|;, *?])/g;
|
||
function Vt(t) {
|
||
return t = t.replace(C, "^$1"), t;
|
||
}
|
||
function Jt(t, e) {
|
||
return t = `${t}`, t = t.replace(/(\\*)"/g, '$1$1\\"'), t = t.replace(/(\\*)$/, "$1$1"), t = `"${t}"`, t = t.replace(C, "^$1"), e && (t = t.replace(C, "^$1")), t;
|
||
}
|
||
P.exports.command = Vt;
|
||
P.exports.argument = Jt;
|
||
});
|
||
|
||
// node_modules/shebang-regex/index.js
|
||
var lt = l((Ie, at) => {
|
||
at.exports = /^#!(.*)/;
|
||
});
|
||
|
||
// node_modules/shebang-command/index.js
|
||
var dt = l((Le, pt) => {
|
||
var Qt = lt();
|
||
pt.exports = (t = "") => {
|
||
let e = t.match(Qt);
|
||
if (!e)
|
||
return null;
|
||
let [n, r] = e[0].replace(/#! ?/, "").split(" "), s = n.split("/").pop();
|
||
return s === "env" ? r : r ? `${s} ${r}` : s;
|
||
};
|
||
});
|
||
|
||
// node_modules/cross-spawn/lib/util/readShebang.js
|
||
var ht = l((je, ft) => {
|
||
var O = h("fs"), Zt = dt();
|
||
function te(t) {
|
||
let n = Buffer.alloc(150), r;
|
||
try {
|
||
r = O.openSync(t, "r"), O.readSync(r, n, 0, 150, 0), O.closeSync(r);
|
||
} catch {
|
||
}
|
||
return Zt(n.toString());
|
||
}
|
||
ft.exports = te;
|
||
});
|
||
|
||
// node_modules/cross-spawn/lib/parse.js
|
||
var wt = l((Fe, Et) => {
|
||
var ee = h("path"), mt = ct(), gt = ut(), ne = ht(), re = process.platform === "win32", se = /\.(?:com|exe)$/i, oe = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;
|
||
function ie(t) {
|
||
t.file = mt(t);
|
||
let e = t.file && ne(t.file);
|
||
return e ? (t.args.unshift(t.file), t.command = e, mt(t)) : t.file;
|
||
}
|
||
function ce(t) {
|
||
if (!re)
|
||
return t;
|
||
let e = ie(t), n = !se.test(e);
|
||
if (t.options.forceShell || n) {
|
||
let r = oe.test(e);
|
||
t.command = ee.normalize(t.command), t.command = gt.command(t.command), t.args = t.args.map((o) => gt.argument(o, r));
|
||
let s = [t.command].concat(t.args).join(" ");
|
||
t.args = ["/d", "/s", "/c", `"${s}"`], t.command = process.env.comspec || "cmd.exe", t.options.windowsVerbatimArguments = !0;
|
||
}
|
||
return t;
|
||
}
|
||
function ue(t, e, n) {
|
||
e && !Array.isArray(e) && (n = e, e = null), e = e ? e.slice(0) : [], n = Object.assign({}, n);
|
||
let r = {
|
||
command: t,
|
||
args: e,
|
||
options: n,
|
||
file: void 0,
|
||
original: {
|
||
command: t,
|
||
args: e
|
||
}
|
||
};
|
||
return n.shell ? r : ce(r);
|
||
}
|
||
Et.exports = ue;
|
||
});
|
||
|
||
// node_modules/cross-spawn/lib/enoent.js
|
||
var bt = l((ze, vt) => {
|
||
var S = process.platform === "win32";
|
||
function k(t, e) {
|
||
return Object.assign(new Error(`${e} ${t.command} ENOENT`), {
|
||
code: "ENOENT",
|
||
errno: "ENOENT",
|
||
syscall: `${e} ${t.command}`,
|
||
path: t.command,
|
||
spawnargs: t.args
|
||
});
|
||
}
|
||
function ae(t, e) {
|
||
if (!S)
|
||
return;
|
||
let n = t.emit;
|
||
t.emit = function(r, s) {
|
||
if (r === "exit") {
|
||
let o = xt(s, e);
|
||
if (o)
|
||
return n.call(t, "error", o);
|
||
}
|
||
return n.apply(t, arguments);
|
||
};
|
||
}
|
||
function xt(t, e) {
|
||
return S && t === 1 && !e.file ? k(e.original, "spawn") : null;
|
||
}
|
||
function le(t, e) {
|
||
return S && t === 1 && !e.file ? k(e.original, "spawnSync") : null;
|
||
}
|
||
vt.exports = {
|
||
hookChildProcess: ae,
|
||
verifyENOENT: xt,
|
||
verifyENOENTSync: le,
|
||
notFoundError: k
|
||
};
|
||
});
|
||
|
||
// node_modules/cross-spawn/index.js
|
||
var Ct = l((He, E) => {
|
||
var yt = h("child_process"), T = wt(), A = bt();
|
||
function _t(t, e, n) {
|
||
let r = T(t, e, n), s = yt.spawn(r.command, r.args, r.options);
|
||
return A.hookChildProcess(s, r), s;
|
||
}
|
||
function pe(t, e, n) {
|
||
let r = T(t, e, n), s = yt.spawnSync(r.command, r.args, r.options);
|
||
return s.error = s.error || A.verifyENOENTSync(s.status, r), s;
|
||
}
|
||
E.exports = _t;
|
||
E.exports.spawn = _t;
|
||
E.exports.sync = pe;
|
||
E.exports._parse = T;
|
||
E.exports._enoent = A;
|
||
});
|
||
var Lt = /^path$/i, q = { key: "PATH", value: "" };
|
||
function jt(t) {
|
||
for (let e in t) {
|
||
if (!Object.prototype.hasOwnProperty.call(t, e) || !Lt.test(e))
|
||
continue;
|
||
let n = t[e];
|
||
return n ? { key: e, value: n } : q;
|
||
}
|
||
return q;
|
||
}
|
||
function Ft(t, e) {
|
||
let n = e.value.split(require$$1$1.delimiter), r = t, s;
|
||
do
|
||
n.push(require$$1$1.resolve(r, "node_modules", ".bin")), s = r, r = require$$1$1.dirname(r);
|
||
while (r !== s);
|
||
return { key: e.key, value: n.join(require$$1$1.delimiter) };
|
||
}
|
||
function I(t, e) {
|
||
let n = {
|
||
...process.env,
|
||
...e
|
||
}, r = Ft(t, jt(n));
|
||
return n[r.key] = r.value, n;
|
||
}
|
||
var L = (t) => {
|
||
let e = t.length, n = new stream.PassThrough(), r = () => {
|
||
--e === 0 && n.emit("end");
|
||
};
|
||
for (let s of t)
|
||
s.pipe(n, { end: !1 }), s.on("end", r);
|
||
return n;
|
||
};
|
||
|
||
// src/main.ts
|
||
var Pt = Nt(Ct());
|
||
|
||
// src/non-zero-exit-error.ts
|
||
var x = class extends Error {
|
||
result;
|
||
output;
|
||
get exitCode() {
|
||
if (this.result.exitCode !== null)
|
||
return this.result.exitCode;
|
||
}
|
||
constructor(e, n) {
|
||
super(`Process exited with non-zero status (${e.exitCode})`), this.result = e, this.output = n;
|
||
}
|
||
};
|
||
|
||
// src/main.ts
|
||
var ge = {
|
||
timeout: void 0,
|
||
persist: !1
|
||
}, Ee = {
|
||
windowsHide: !0
|
||
};
|
||
function we(t, e) {
|
||
return {
|
||
command: require$$1$1.normalize(t),
|
||
args: e ?? []
|
||
};
|
||
}
|
||
function xe(t) {
|
||
let e = new AbortController();
|
||
for (let n of t) {
|
||
if (n.aborted)
|
||
return e.abort(), n;
|
||
let r = () => {
|
||
e.abort(n.reason);
|
||
};
|
||
n.addEventListener("abort", r, {
|
||
signal: e.signal
|
||
});
|
||
}
|
||
return e.signal;
|
||
}
|
||
var R = class {
|
||
_process;
|
||
_aborted = !1;
|
||
_options;
|
||
_command;
|
||
_args;
|
||
_resolveClose;
|
||
_processClosed;
|
||
_thrownError;
|
||
get process() {
|
||
return this._process;
|
||
}
|
||
get pid() {
|
||
return this._process?.pid;
|
||
}
|
||
get exitCode() {
|
||
if (this._process && this._process.exitCode !== null)
|
||
return this._process.exitCode;
|
||
}
|
||
constructor(e, n, r) {
|
||
this._options = {
|
||
...ge,
|
||
...r
|
||
}, this._command = e, this._args = n ?? [], this._processClosed = new Promise((s) => {
|
||
this._resolveClose = s;
|
||
});
|
||
}
|
||
kill(e) {
|
||
return this._process?.kill(e) === !0;
|
||
}
|
||
get aborted() {
|
||
return this._aborted;
|
||
}
|
||
get killed() {
|
||
return this._process?.killed === !0;
|
||
}
|
||
pipe(e, n, r) {
|
||
return be(e, n, {
|
||
...r,
|
||
stdin: this
|
||
});
|
||
}
|
||
async *[Symbol.asyncIterator]() {
|
||
let e = this._process;
|
||
if (!e)
|
||
return;
|
||
let n = [];
|
||
this._streamErr && n.push(this._streamErr), this._streamOut && n.push(this._streamOut);
|
||
let r = L(n), s = require$$0__default.createInterface({
|
||
input: r
|
||
});
|
||
for await (let o of s)
|
||
yield o.toString();
|
||
if (await this._processClosed, e.removeAllListeners(), this._thrownError)
|
||
throw this._thrownError;
|
||
if (this._options?.throwOnError && this.exitCode !== 0 && this.exitCode !== void 0)
|
||
throw new x(this);
|
||
}
|
||
async _waitForOutput() {
|
||
let e = this._process;
|
||
if (!e)
|
||
throw new Error("No process was started");
|
||
let n = "", r = "";
|
||
if (this._streamErr)
|
||
for await (let o of this._streamErr)
|
||
n += o.toString();
|
||
if (this._streamOut)
|
||
for await (let o of this._streamOut)
|
||
r += o.toString();
|
||
if (await this._processClosed, this._options?.stdin && await this._options.stdin, e.removeAllListeners(), this._thrownError)
|
||
throw this._thrownError;
|
||
let s = {
|
||
stderr: n,
|
||
stdout: r,
|
||
exitCode: this.exitCode
|
||
};
|
||
if (this._options.throwOnError && this.exitCode !== 0 && this.exitCode !== void 0)
|
||
throw new x(this, s);
|
||
return s;
|
||
}
|
||
then(e, n) {
|
||
return this._waitForOutput().then(e, n);
|
||
}
|
||
_streamOut;
|
||
_streamErr;
|
||
spawn() {
|
||
let e = process$2.cwd(), n = this._options, r = {
|
||
...Ee,
|
||
...n.nodeOptions
|
||
}, s = [];
|
||
this._resetState(), n.timeout !== void 0 && s.push(AbortSignal.timeout(n.timeout)), n.signal !== void 0 && s.push(n.signal), n.persist === !0 && (r.detached = !0), s.length > 0 && (r.signal = xe(s)), r.env = I(e, r.env);
|
||
let { command: o, args: i } = we(this._command, this._args), a = (0, Pt._parse)(o, i, r), c = child_process.spawn(
|
||
a.command,
|
||
a.args,
|
||
a.options
|
||
);
|
||
if (c.stderr && (this._streamErr = c.stderr), c.stdout && (this._streamOut = c.stdout), this._process = c, c.once("error", this._onError), c.once("close", this._onClose), n.stdin !== void 0 && c.stdin && n.stdin.process) {
|
||
let { stdout: u } = n.stdin.process;
|
||
u && u.pipe(c.stdin);
|
||
}
|
||
}
|
||
_resetState() {
|
||
this._aborted = !1, this._processClosed = new Promise((e) => {
|
||
this._resolveClose = e;
|
||
}), this._thrownError = void 0;
|
||
}
|
||
_onError = (e) => {
|
||
if (e.name === "AbortError" && (!(e.cause instanceof Error) || e.cause.name !== "TimeoutError")) {
|
||
this._aborted = !0;
|
||
return;
|
||
}
|
||
this._thrownError = e;
|
||
};
|
||
_onClose = () => {
|
||
this._resolveClose && this._resolveClose();
|
||
};
|
||
}, ve = (t, e, n) => {
|
||
let r = new R(t, e, n);
|
||
return r.spawn(), r;
|
||
}, be = ve;
|
||
|
||
var picocolors = {exports: {}};
|
||
|
||
var hasRequiredPicocolors;
|
||
|
||
function requirePicocolors () {
|
||
if (hasRequiredPicocolors) return picocolors.exports;
|
||
hasRequiredPicocolors = 1;
|
||
let p = process || {}, argv = p.argv || [], env = p.env || {};
|
||
let isColorSupported =
|
||
!(!!env.NO_COLOR || argv.includes("--no-color")) &&
|
||
(!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || ((p.stdout || {}).isTTY && env.TERM !== "dumb") || !!env.CI);
|
||
|
||
let formatter = (open, close, replace = open) =>
|
||
input => {
|
||
let string = "" + input, index = string.indexOf(close, open.length);
|
||
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close
|
||
};
|
||
|
||
let replaceClose = (string, close, replace, index) => {
|
||
let result = "", cursor = 0;
|
||
do {
|
||
result += string.substring(cursor, index) + replace;
|
||
cursor = index + close.length;
|
||
index = string.indexOf(close, cursor);
|
||
} while (~index)
|
||
return result + string.substring(cursor)
|
||
};
|
||
|
||
let createColors = (enabled = isColorSupported) => {
|
||
let f = enabled ? formatter : () => String;
|
||
return {
|
||
isColorSupported: enabled,
|
||
reset: f("\x1b[0m", "\x1b[0m"),
|
||
bold: f("\x1b[1m", "\x1b[22m", "\x1b[22m\x1b[1m"),
|
||
dim: f("\x1b[2m", "\x1b[22m", "\x1b[22m\x1b[2m"),
|
||
italic: f("\x1b[3m", "\x1b[23m"),
|
||
underline: f("\x1b[4m", "\x1b[24m"),
|
||
inverse: f("\x1b[7m", "\x1b[27m"),
|
||
hidden: f("\x1b[8m", "\x1b[28m"),
|
||
strikethrough: f("\x1b[9m", "\x1b[29m"),
|
||
|
||
black: f("\x1b[30m", "\x1b[39m"),
|
||
red: f("\x1b[31m", "\x1b[39m"),
|
||
green: f("\x1b[32m", "\x1b[39m"),
|
||
yellow: f("\x1b[33m", "\x1b[39m"),
|
||
blue: f("\x1b[34m", "\x1b[39m"),
|
||
magenta: f("\x1b[35m", "\x1b[39m"),
|
||
cyan: f("\x1b[36m", "\x1b[39m"),
|
||
white: f("\x1b[37m", "\x1b[39m"),
|
||
gray: f("\x1b[90m", "\x1b[39m"),
|
||
|
||
bgBlack: f("\x1b[40m", "\x1b[49m"),
|
||
bgRed: f("\x1b[41m", "\x1b[49m"),
|
||
bgGreen: f("\x1b[42m", "\x1b[49m"),
|
||
bgYellow: f("\x1b[43m", "\x1b[49m"),
|
||
bgBlue: f("\x1b[44m", "\x1b[49m"),
|
||
bgMagenta: f("\x1b[45m", "\x1b[49m"),
|
||
bgCyan: f("\x1b[46m", "\x1b[49m"),
|
||
bgWhite: f("\x1b[47m", "\x1b[49m"),
|
||
|
||
blackBright: f("\x1b[90m", "\x1b[39m"),
|
||
redBright: f("\x1b[91m", "\x1b[39m"),
|
||
greenBright: f("\x1b[92m", "\x1b[39m"),
|
||
yellowBright: f("\x1b[93m", "\x1b[39m"),
|
||
blueBright: f("\x1b[94m", "\x1b[39m"),
|
||
magentaBright: f("\x1b[95m", "\x1b[39m"),
|
||
cyanBright: f("\x1b[96m", "\x1b[39m"),
|
||
whiteBright: f("\x1b[97m", "\x1b[39m"),
|
||
|
||
bgBlackBright: f("\x1b[100m", "\x1b[49m"),
|
||
bgRedBright: f("\x1b[101m", "\x1b[49m"),
|
||
bgGreenBright: f("\x1b[102m", "\x1b[49m"),
|
||
bgYellowBright: f("\x1b[103m", "\x1b[49m"),
|
||
bgBlueBright: f("\x1b[104m", "\x1b[49m"),
|
||
bgMagentaBright: f("\x1b[105m", "\x1b[49m"),
|
||
bgCyanBright: f("\x1b[106m", "\x1b[49m"),
|
||
bgWhiteBright: f("\x1b[107m", "\x1b[49m"),
|
||
}
|
||
};
|
||
|
||
picocolors.exports = createColors();
|
||
picocolors.exports.createColors = createColors;
|
||
return picocolors.exports;
|
||
}
|
||
|
||
var picocolorsExports = /*@__PURE__*/ requirePicocolors();
|
||
const c = /*@__PURE__*/getDefaultExportFromCjs(picocolorsExports);
|
||
|
||
var cjs = {};
|
||
|
||
var posix = {};
|
||
|
||
var hasRequiredPosix;
|
||
|
||
function requirePosix () {
|
||
if (hasRequiredPosix) return posix;
|
||
hasRequiredPosix = 1;
|
||
/**
|
||
* This is the Posix implementation of isexe, which uses the file
|
||
* mode and uid/gid values.
|
||
*
|
||
* @module
|
||
*/
|
||
Object.defineProperty(posix, "__esModule", { value: true });
|
||
posix.sync = posix.isexe = void 0;
|
||
const fs_1 = require$$0__default$2;
|
||
const promises_1 = require$$1__default$1;
|
||
/**
|
||
* Determine whether a path is executable according to the mode and
|
||
* current (or specified) user and group IDs.
|
||
*/
|
||
const isexe = async (path, options = {}) => {
|
||
const { ignoreErrors = false } = options;
|
||
try {
|
||
return checkStat(await (0, promises_1.stat)(path), options);
|
||
}
|
||
catch (e) {
|
||
const er = e;
|
||
if (ignoreErrors || er.code === 'EACCES')
|
||
return false;
|
||
throw er;
|
||
}
|
||
};
|
||
posix.isexe = isexe;
|
||
/**
|
||
* Synchronously determine whether a path is executable according to
|
||
* the mode and current (or specified) user and group IDs.
|
||
*/
|
||
const sync = (path, options = {}) => {
|
||
const { ignoreErrors = false } = options;
|
||
try {
|
||
return checkStat((0, fs_1.statSync)(path), options);
|
||
}
|
||
catch (e) {
|
||
const er = e;
|
||
if (ignoreErrors || er.code === 'EACCES')
|
||
return false;
|
||
throw er;
|
||
}
|
||
};
|
||
posix.sync = sync;
|
||
const checkStat = (stat, options) => stat.isFile() && checkMode(stat, options);
|
||
const checkMode = (stat, options) => {
|
||
const myUid = options.uid ?? process.getuid?.();
|
||
const myGroups = options.groups ?? process.getgroups?.() ?? [];
|
||
const myGid = options.gid ?? process.getgid?.() ?? myGroups[0];
|
||
if (myUid === undefined || myGid === undefined) {
|
||
throw new Error('cannot get uid or gid');
|
||
}
|
||
const groups = new Set([myGid, ...myGroups]);
|
||
const mod = stat.mode;
|
||
const uid = stat.uid;
|
||
const gid = stat.gid;
|
||
const u = parseInt('100', 8);
|
||
const g = parseInt('010', 8);
|
||
const o = parseInt('001', 8);
|
||
const ug = u | g;
|
||
return !!(mod & o ||
|
||
(mod & g && groups.has(gid)) ||
|
||
(mod & u && uid === myUid) ||
|
||
(mod & ug && myUid === 0));
|
||
};
|
||
|
||
return posix;
|
||
}
|
||
|
||
var win32 = {};
|
||
|
||
var hasRequiredWin32;
|
||
|
||
function requireWin32 () {
|
||
if (hasRequiredWin32) return win32;
|
||
hasRequiredWin32 = 1;
|
||
/**
|
||
* This is the Windows implementation of isexe, which uses the file
|
||
* extension and PATHEXT setting.
|
||
*
|
||
* @module
|
||
*/
|
||
Object.defineProperty(win32, "__esModule", { value: true });
|
||
win32.sync = win32.isexe = void 0;
|
||
const fs_1 = require$$0__default$2;
|
||
const promises_1 = require$$1__default$1;
|
||
/**
|
||
* Determine whether a path is executable based on the file extension
|
||
* and PATHEXT environment variable (or specified pathExt option)
|
||
*/
|
||
const isexe = async (path, options = {}) => {
|
||
const { ignoreErrors = false } = options;
|
||
try {
|
||
return checkStat(await (0, promises_1.stat)(path), path, options);
|
||
}
|
||
catch (e) {
|
||
const er = e;
|
||
if (ignoreErrors || er.code === 'EACCES')
|
||
return false;
|
||
throw er;
|
||
}
|
||
};
|
||
win32.isexe = isexe;
|
||
/**
|
||
* Synchronously determine whether a path is executable based on the file
|
||
* extension and PATHEXT environment variable (or specified pathExt option)
|
||
*/
|
||
const sync = (path, options = {}) => {
|
||
const { ignoreErrors = false } = options;
|
||
try {
|
||
return checkStat((0, fs_1.statSync)(path), path, options);
|
||
}
|
||
catch (e) {
|
||
const er = e;
|
||
if (ignoreErrors || er.code === 'EACCES')
|
||
return false;
|
||
throw er;
|
||
}
|
||
};
|
||
win32.sync = sync;
|
||
const checkPathExt = (path, options) => {
|
||
const { pathExt = process.env.PATHEXT || '' } = options;
|
||
const peSplit = pathExt.split(';');
|
||
if (peSplit.indexOf('') !== -1) {
|
||
return true;
|
||
}
|
||
for (let i = 0; i < peSplit.length; i++) {
|
||
const p = peSplit[i].toLowerCase();
|
||
const ext = path.substring(path.length - p.length).toLowerCase();
|
||
if (p && ext === p) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
const checkStat = (stat, path, options) => stat.isFile() && checkPathExt(path, options);
|
||
|
||
return win32;
|
||
}
|
||
|
||
var options = {};
|
||
|
||
var hasRequiredOptions;
|
||
|
||
function requireOptions () {
|
||
if (hasRequiredOptions) return options;
|
||
hasRequiredOptions = 1;
|
||
Object.defineProperty(options, "__esModule", { value: true });
|
||
|
||
return options;
|
||
}
|
||
|
||
var hasRequiredCjs;
|
||
|
||
function requireCjs () {
|
||
if (hasRequiredCjs) return cjs;
|
||
hasRequiredCjs = 1;
|
||
(function (exports) {
|
||
var __createBinding = (cjs && cjs.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
if (k2 === undefined) k2 = k;
|
||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||
}
|
||
Object.defineProperty(o, k2, desc);
|
||
}) : (function(o, m, k, k2) {
|
||
if (k2 === undefined) k2 = k;
|
||
o[k2] = m[k];
|
||
}));
|
||
var __setModuleDefault = (cjs && cjs.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
}) : function(o, v) {
|
||
o["default"] = v;
|
||
});
|
||
var __importStar = (cjs && cjs.__importStar) || function (mod) {
|
||
if (mod && mod.__esModule) return mod;
|
||
var result = {};
|
||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
__setModuleDefault(result, mod);
|
||
return result;
|
||
};
|
||
var __exportStar = (cjs && cjs.__exportStar) || function(m, exports) {
|
||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||
};
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
exports.sync = exports.isexe = exports.posix = exports.win32 = void 0;
|
||
const posix = __importStar(requirePosix());
|
||
exports.posix = posix;
|
||
const win32 = __importStar(requireWin32());
|
||
exports.win32 = win32;
|
||
__exportStar(requireOptions(), exports);
|
||
const platform = process.env._ISEXE_TEST_PLATFORM_ || process.platform;
|
||
const impl = platform === 'win32' ? win32 : posix;
|
||
/**
|
||
* Determine whether a path is executable on the current platform.
|
||
*/
|
||
exports.isexe = impl.isexe;
|
||
/**
|
||
* Synchronously determine whether a path is executable on the
|
||
* current platform.
|
||
*/
|
||
exports.sync = impl.sync;
|
||
|
||
} (cjs));
|
||
return cjs;
|
||
}
|
||
|
||
var lib;
|
||
var hasRequiredLib;
|
||
|
||
function requireLib () {
|
||
if (hasRequiredLib) return lib;
|
||
hasRequiredLib = 1;
|
||
const { isexe, sync: isexeSync } = requireCjs();
|
||
const { join, delimiter, sep, posix } = require$$1__default$2;
|
||
|
||
const isWindows = process.platform === 'win32';
|
||
|
||
// used to check for slashed in commands passed in. always checks for the posix
|
||
// seperator on all platforms, and checks for the current separator when not on
|
||
// a posix platform. don't use the isWindows check for this since that is mocked
|
||
// in tests but we still need the code to actually work when called. that is also
|
||
// why it is ignored from coverage.
|
||
/* istanbul ignore next */
|
||
const rSlash = new RegExp(`[${posix.sep}${sep === posix.sep ? '' : sep}]`.replace(/(\\)/g, '\\$1'));
|
||
const rRel = new RegExp(`^\\.${rSlash.source}`);
|
||
|
||
const getNotFoundError = (cmd) =>
|
||
Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' });
|
||
|
||
const getPathInfo = (cmd, {
|
||
path: optPath = process.env.PATH,
|
||
pathExt: optPathExt = process.env.PATHEXT,
|
||
delimiter: optDelimiter = delimiter,
|
||
}) => {
|
||
// If it has a slash, then we don't bother searching the pathenv.
|
||
// just check the file itself, and that's it.
|
||
const pathEnv = cmd.match(rSlash) ? [''] : [
|
||
// windows always checks the cwd first
|
||
...(isWindows ? [process.cwd()] : []),
|
||
...(optPath || /* istanbul ignore next: very unusual */ '').split(optDelimiter),
|
||
];
|
||
|
||
if (isWindows) {
|
||
const pathExtExe = optPathExt ||
|
||
['.EXE', '.CMD', '.BAT', '.COM'].join(optDelimiter);
|
||
const pathExt = pathExtExe.split(optDelimiter).flatMap((item) => [item, item.toLowerCase()]);
|
||
if (cmd.includes('.') && pathExt[0] !== '') {
|
||
pathExt.unshift('');
|
||
}
|
||
return { pathEnv, pathExt, pathExtExe }
|
||
}
|
||
|
||
return { pathEnv, pathExt: [''] }
|
||
};
|
||
|
||
const getPathPart = (raw, cmd) => {
|
||
const pathPart = /^".*"$/.test(raw) ? raw.slice(1, -1) : raw;
|
||
const prefix = !pathPart && rRel.test(cmd) ? cmd.slice(0, 2) : '';
|
||
return prefix + join(pathPart, cmd)
|
||
};
|
||
|
||
const which = async (cmd, opt = {}) => {
|
||
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
||
const found = [];
|
||
|
||
for (const envPart of pathEnv) {
|
||
const p = getPathPart(envPart, cmd);
|
||
|
||
for (const ext of pathExt) {
|
||
const withExt = p + ext;
|
||
const is = await isexe(withExt, { pathExt: pathExtExe, ignoreErrors: true });
|
||
if (is) {
|
||
if (!opt.all) {
|
||
return withExt
|
||
}
|
||
found.push(withExt);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (opt.all && found.length) {
|
||
return found
|
||
}
|
||
|
||
if (opt.nothrow) {
|
||
return null
|
||
}
|
||
|
||
throw getNotFoundError(cmd)
|
||
};
|
||
|
||
const whichSync = (cmd, opt = {}) => {
|
||
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
||
const found = [];
|
||
|
||
for (const pathEnvPart of pathEnv) {
|
||
const p = getPathPart(pathEnvPart, cmd);
|
||
|
||
for (const ext of pathExt) {
|
||
const withExt = p + ext;
|
||
const is = isexeSync(withExt, { pathExt: pathExtExe, ignoreErrors: true });
|
||
if (is) {
|
||
if (!opt.all) {
|
||
return withExt
|
||
}
|
||
found.push(withExt);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (opt.all && found.length) {
|
||
return found
|
||
}
|
||
|
||
if (opt.nothrow) {
|
||
return null
|
||
}
|
||
|
||
throw getNotFoundError(cmd)
|
||
};
|
||
|
||
lib = which;
|
||
which.sync = whichSync;
|
||
return lib;
|
||
}
|
||
|
||
var libExports = requireLib();
|
||
const which = /*@__PURE__*/getDefaultExportFromCjs(libExports);
|
||
|
||
const CLI_TEMP_DIR = path.join(os__default.tmpdir(), "antfu-ni");
|
||
function remove(arr, v) {
|
||
const index = arr.indexOf(v);
|
||
if (index >= 0)
|
||
arr.splice(index, 1);
|
||
return arr;
|
||
}
|
||
function exclude(arr, ...v) {
|
||
return arr.slice().filter((item) => !v.includes(item));
|
||
}
|
||
function cmdExists(cmd) {
|
||
return which.sync(cmd, { nothrow: true }) !== null;
|
||
}
|
||
let counter = 0;
|
||
async function openTemp() {
|
||
if (!fs.existsSync(CLI_TEMP_DIR))
|
||
await fs.promises.mkdir(CLI_TEMP_DIR, { recursive: true });
|
||
const competitivePath = path.join(CLI_TEMP_DIR, `.${process__default.pid}.${counter}`);
|
||
counter += 1;
|
||
return fs.promises.open(competitivePath, "wx").then((fd) => ({
|
||
fd,
|
||
path: competitivePath,
|
||
cleanup() {
|
||
fd.close().then(() => {
|
||
if (fs.existsSync(competitivePath))
|
||
fs.promises.unlink(competitivePath);
|
||
});
|
||
}
|
||
})).catch((error) => {
|
||
if (error && error.code === "EEXIST")
|
||
return openTemp();
|
||
else
|
||
return void 0;
|
||
});
|
||
}
|
||
async function writeFileSafe(path$1, data = "") {
|
||
const temp = await openTemp();
|
||
if (temp) {
|
||
fs.promises.writeFile(temp.path, data).then(() => {
|
||
const directory = path.dirname(path$1);
|
||
if (!fs.existsSync(directory))
|
||
fs.promises.mkdir(directory, { recursive: true });
|
||
return fs.promises.rename(temp.path, path$1).then(() => true).catch(() => false);
|
||
}).catch(() => false).finally(temp.cleanup);
|
||
}
|
||
return false;
|
||
}
|
||
function limitText(text, maxWidth) {
|
||
if (text.length <= maxWidth)
|
||
return text;
|
||
return `${text.slice(0, maxWidth)}${c.dim("\u2026")}`;
|
||
}
|
||
function formatPackageWithUrl(pkg, url, limits = 80) {
|
||
return url ? terminalLink(
|
||
pkg,
|
||
url,
|
||
{
|
||
fallback: (_, url2) => pkg.length + url2.length > limits ? pkg : pkg + c.dim(` - ${url2}`)
|
||
}
|
||
) : pkg;
|
||
}
|
||
|
||
async function detect({ autoInstall, programmatic, cwd } = {}) {
|
||
const {
|
||
name,
|
||
agent,
|
||
version
|
||
} = await detect$1({
|
||
cwd,
|
||
onUnknown: (packageManager) => {
|
||
if (!programmatic) {
|
||
console.warn("[ni] Unknown packageManager:", packageManager);
|
||
}
|
||
return void 0;
|
||
}
|
||
}) || {};
|
||
if (name && !cmdExists(name) && !programmatic) {
|
||
if (!autoInstall) {
|
||
console.warn(`[ni] Detected ${name} but it doesn't seem to be installed.
|
||
`);
|
||
if (process__default.env.CI)
|
||
process__default.exit(1);
|
||
const link = terminalLink(name, INSTALL_PAGE[name]);
|
||
const { tryInstall } = await prompts({
|
||
name: "tryInstall",
|
||
type: "confirm",
|
||
message: `Would you like to globally install ${link}?`
|
||
});
|
||
if (!tryInstall)
|
||
process__default.exit(1);
|
||
}
|
||
await ve(
|
||
"npm",
|
||
["i", "-g", `${name}${version ? `@${version}` : ""}`],
|
||
{
|
||
nodeOptions: {
|
||
stdio: "inherit",
|
||
cwd
|
||
},
|
||
throwOnError: true
|
||
}
|
||
);
|
||
}
|
||
return agent;
|
||
}
|
||
|
||
const customRcPath = process__default.env.NI_CONFIG_FILE;
|
||
const home = process__default.platform === "win32" ? process__default.env.USERPROFILE : process__default.env.HOME;
|
||
const defaultRcPath = path__default.join(home || "~/", ".nirc");
|
||
const rcPath = customRcPath || defaultRcPath;
|
||
const defaultConfig = {
|
||
defaultAgent: "prompt",
|
||
globalAgent: "npm"
|
||
};
|
||
let config;
|
||
async function getConfig() {
|
||
if (!config) {
|
||
config = Object.assign(
|
||
{},
|
||
defaultConfig,
|
||
fs__default.existsSync(rcPath) ? ini.parse(fs__default.readFileSync(rcPath, "utf-8")) : null
|
||
);
|
||
if (process__default.env.NI_DEFAULT_AGENT)
|
||
config.defaultAgent = process__default.env.NI_DEFAULT_AGENT;
|
||
if (process__default.env.NI_GLOBAL_AGENT)
|
||
config.globalAgent = process__default.env.NI_GLOBAL_AGENT;
|
||
const agent = await detect({ programmatic: true });
|
||
if (agent)
|
||
config.defaultAgent = agent;
|
||
}
|
||
return config;
|
||
}
|
||
async function getDefaultAgent(programmatic) {
|
||
const { defaultAgent } = await getConfig();
|
||
if (defaultAgent === "prompt" && (programmatic || process__default.env.CI))
|
||
return "npm";
|
||
return defaultAgent;
|
||
}
|
||
async function getGlobalAgent() {
|
||
const { globalAgent } = await getConfig();
|
||
return globalAgent;
|
||
}
|
||
|
||
class UnsupportedCommand extends Error {
|
||
constructor({ agent, command }) {
|
||
super(`Command "${command}" is not support by agent "${agent}"`);
|
||
}
|
||
}
|
||
function getCommand(agent, command, args = []) {
|
||
if (!COMMANDS[agent])
|
||
throw new Error(`Unsupported agent "${agent}"`);
|
||
if (!COMMANDS[agent][command])
|
||
throw new UnsupportedCommand({ agent, command });
|
||
return constructCommand(COMMANDS[agent][command], args);
|
||
}
|
||
const parseNi = (agent, args, ctx) => {
|
||
if (agent === "bun")
|
||
args = args.map((i) => i === "-D" ? "-d" : i);
|
||
if (args.includes("-g"))
|
||
return getCommand(agent, "global", exclude(args, "-g"));
|
||
if (args.includes("--frozen-if-present")) {
|
||
args = exclude(args, "--frozen-if-present");
|
||
return getCommand(agent, ctx?.hasLock ? "frozen" : "install", args);
|
||
}
|
||
if (args.includes("--frozen"))
|
||
return getCommand(agent, "frozen", exclude(args, "--frozen"));
|
||
if (args.length === 0 || args.every((i) => i.startsWith("-")))
|
||
return getCommand(agent, "install", args);
|
||
return getCommand(agent, "add", args);
|
||
};
|
||
const parseNr = (agent, args) => {
|
||
if (args.length === 0)
|
||
args.push("start");
|
||
let hasIfPresent = false;
|
||
if (args.includes("--if-present")) {
|
||
args = exclude(args, "--if-present");
|
||
hasIfPresent = true;
|
||
}
|
||
const cmd = getCommand(agent, "run", args);
|
||
if (!cmd)
|
||
return cmd;
|
||
if (hasIfPresent)
|
||
cmd.args.splice(1, 0, "--if-present");
|
||
return cmd;
|
||
};
|
||
const parseNu = (agent, args) => {
|
||
if (args.includes("-i"))
|
||
return getCommand(agent, "upgrade-interactive", exclude(args, "-i"));
|
||
return getCommand(agent, "upgrade", args);
|
||
};
|
||
const parseNun = (agent, args) => {
|
||
if (args.includes("-g"))
|
||
return getCommand(agent, "global_uninstall", exclude(args, "-g"));
|
||
return getCommand(agent, "uninstall", args);
|
||
};
|
||
const parseNlx = (agent, args) => {
|
||
return getCommand(agent, "execute", args);
|
||
};
|
||
const parseNa = (agent, args) => {
|
||
return getCommand(agent, "agent", args);
|
||
};
|
||
function serializeCommand(command) {
|
||
if (!command)
|
||
return void 0;
|
||
if (command.args.length === 0)
|
||
return command.command;
|
||
return `${command.command} ${command.args.map((i) => i.includes(" ") ? `"${i}"` : i).join(" ")}`;
|
||
}
|
||
|
||
const version = "0.23.2";
|
||
|
||
const DEBUG_SIGN = "?";
|
||
async function runCli(fn, options = {}) {
|
||
const {
|
||
args = process__default.argv.slice(2).filter(Boolean)
|
||
} = options;
|
||
try {
|
||
await run(fn, args, options);
|
||
} catch (error) {
|
||
if (error instanceof UnsupportedCommand && !options.programmatic)
|
||
console.log(c.red(`\u2717 ${error.message}`));
|
||
if (!options.programmatic)
|
||
process__default.exit(1);
|
||
throw error;
|
||
}
|
||
}
|
||
async function getCliCommand(fn, args, options = {}, cwd = options.cwd ?? process__default.cwd()) {
|
||
const isGlobal = args.includes("-g");
|
||
if (isGlobal)
|
||
return await fn(await getGlobalAgent(), args);
|
||
let agent = await detect({ ...options, cwd }) || await getDefaultAgent(options.programmatic);
|
||
if (agent === "prompt") {
|
||
agent = (await prompts({
|
||
name: "agent",
|
||
type: "select",
|
||
message: "Choose the agent",
|
||
choices: AGENTS.filter((i) => !i.includes("@")).map((value) => ({ title: value, value }))
|
||
})).agent;
|
||
if (!agent)
|
||
return;
|
||
}
|
||
return await fn(agent, args, {
|
||
programmatic: options.programmatic,
|
||
hasLock: Boolean(agent),
|
||
cwd
|
||
});
|
||
}
|
||
async function run(fn, args, options = {}) {
|
||
const {
|
||
detectVolta = true
|
||
} = options;
|
||
const debug = args.includes(DEBUG_SIGN);
|
||
if (debug)
|
||
remove(args, DEBUG_SIGN);
|
||
let cwd = options.cwd ?? process__default.cwd();
|
||
if (args[0] === "-C") {
|
||
cwd = path.resolve(cwd, args[1]);
|
||
args.splice(0, 2);
|
||
}
|
||
if (args.length === 1 && (args[0]?.toLowerCase() === "-v" || args[0] === "--version")) {
|
||
const getCmd = (a) => AGENTS.includes(a) ? getCommand(a, "agent", ["-v"]) : { command: a, args: ["-v"] };
|
||
const xVersionOptions = {
|
||
nodeOptions: {
|
||
cwd
|
||
},
|
||
throwOnError: true
|
||
};
|
||
const getV = (a) => {
|
||
const { command: command2, args: args2 } = getCmd(a);
|
||
return ve(command2, args2, xVersionOptions).then((e) => e.stdout).then((e) => e.startsWith("v") ? e : `v${e}`);
|
||
};
|
||
const globalAgentPromise = getGlobalAgent();
|
||
const globalAgentVersionPromise = globalAgentPromise.then(getV);
|
||
const agentPromise = detect({ ...options, cwd }).then((a) => a || "");
|
||
const agentVersionPromise = agentPromise.then((a) => a && getV(a));
|
||
const nodeVersionPromise = getV("node");
|
||
console.log(`@antfu/ni ${c.cyan(`v${version}`)}`);
|
||
console.log(`node ${c.green(await nodeVersionPromise)}`);
|
||
const [agent, agentVersion] = await Promise.all([agentPromise, agentVersionPromise]);
|
||
if (agent)
|
||
console.log(`${agent.padEnd(10)} ${c.blue(agentVersion)}`);
|
||
else
|
||
console.log("agent no lock file");
|
||
const [globalAgent, globalAgentVersion] = await Promise.all([globalAgentPromise, globalAgentVersionPromise]);
|
||
console.log(`${`${globalAgent} -g`.padEnd(10)} ${c.blue(globalAgentVersion)}`);
|
||
return;
|
||
}
|
||
if (args.length === 1 && ["-h", "--help"].includes(args[0])) {
|
||
const dash = c.dim("-");
|
||
console.log(c.green(c.bold("@antfu/ni")) + c.dim(` use the right package manager v${version}
|
||
`));
|
||
console.log(`ni ${dash} install`);
|
||
console.log(`nr ${dash} run`);
|
||
console.log(`nlx ${dash} execute`);
|
||
console.log(`nu ${dash} upgrade`);
|
||
console.log(`nun ${dash} uninstall`);
|
||
console.log(`nci ${dash} clean install`);
|
||
console.log(`na ${dash} agent alias`);
|
||
console.log(`ni -v ${dash} show used agent`);
|
||
console.log(`ni -i ${dash} interactive package management`);
|
||
console.log(c.yellow("\ncheck https://github.com/antfu/ni for more documentation."));
|
||
return;
|
||
}
|
||
const command = await getCliCommand(fn, args, options, cwd);
|
||
if (!command)
|
||
return;
|
||
if (detectVolta && cmdExists("volta")) {
|
||
command.args = ["run", command.command, ...command.args];
|
||
command.command = "volta";
|
||
}
|
||
if (debug) {
|
||
console.log(command);
|
||
return;
|
||
}
|
||
await ve(
|
||
command.command,
|
||
command.args,
|
||
{
|
||
nodeOptions: {
|
||
stdio: "inherit",
|
||
cwd
|
||
},
|
||
throwOnError: true
|
||
}
|
||
);
|
||
}
|
||
|
||
exports.AGENTS = AGENTS;
|
||
exports.CLI_TEMP_DIR = CLI_TEMP_DIR;
|
||
exports.COMMANDS = COMMANDS;
|
||
exports.INSTALL_PAGE = INSTALL_PAGE;
|
||
exports.LOCKS = LOCKS;
|
||
exports.UnsupportedCommand = UnsupportedCommand;
|
||
exports.c = c;
|
||
exports.cmdExists = cmdExists;
|
||
exports.constructCommand = constructCommand;
|
||
exports.detect = detect;
|
||
exports.exclude = exclude;
|
||
exports.formatPackageWithUrl = formatPackageWithUrl;
|
||
exports.getCliCommand = getCliCommand;
|
||
exports.getCommand = getCommand;
|
||
exports.getConfig = getConfig;
|
||
exports.getDefaultAgent = getDefaultAgent;
|
||
exports.getGlobalAgent = getGlobalAgent;
|
||
exports.limitText = limitText;
|
||
exports.parseNa = parseNa;
|
||
exports.parseNi = parseNi;
|
||
exports.parseNlx = parseNlx;
|
||
exports.parseNr = parseNr;
|
||
exports.parseNu = parseNu;
|
||
exports.parseNun = parseNun;
|
||
exports.prompts = prompts;
|
||
exports.remove = remove;
|
||
exports.resolveCommand = resolveCommand;
|
||
exports.run = run;
|
||
exports.runCli = runCli;
|
||
exports.serializeCommand = serializeCommand;
|
||
exports.writeFileSafe = writeFileSafe;
|