5369 lines
145 KiB
JavaScript
5369 lines
145 KiB
JavaScript
import path, { join, dirname as dirname$1, resolve as resolve$1 } from 'node:path';
|
||
import process$1 from 'node:process';
|
||
import require$$0 from 'readline';
|
||
import require$$2 from 'events';
|
||
import { createRequire } from 'node:module';
|
||
import { spawn } from 'child_process';
|
||
import require$$1$2, { normalize, delimiter, resolve, dirname } from 'path';
|
||
import { cwd } from 'process';
|
||
import { PassThrough } from 'stream';
|
||
import fs, { promises, existsSync } from 'node:fs';
|
||
import require$$0$1 from 'os';
|
||
import require$$1 from 'tty';
|
||
import os from 'node:os';
|
||
import require$$0$2 from 'fs';
|
||
import require$$1$1 from 'fs/promises';
|
||
import fsPromises from 'node:fs/promises';
|
||
|
||
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;
|
||
const { action } = requireUtil();
|
||
const EventEmitter = require$$2;
|
||
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.join(directory, lock))) {
|
||
const name = LOCKS[lock];
|
||
const result2 = await parsePackageJson(path.join(directory, "package.json"), onUnknown);
|
||
if (result2)
|
||
return result2;
|
||
else
|
||
return { name, agent: name };
|
||
}
|
||
}
|
||
const result = await parsePackageJson(path.join(directory, "package.json"), onUnknown);
|
||
if (result)
|
||
return result;
|
||
}
|
||
return null;
|
||
}
|
||
function* lookup(cwd = process$1.cwd()) {
|
||
let directory = path.resolve(cwd);
|
||
const { root } = path.parse(directory);
|
||
while (directory && directory !== root) {
|
||
yield directory;
|
||
directory = path.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.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.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$1;
|
||
const tty = require$$1;
|
||
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 = createRequire(import.meta.url);
|
||
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 < "u" ? require : typeof Proxy < "u" ? new Proxy(t, {
|
||
get: (e, n) => (typeof require < "u" ? require : e)[n]
|
||
}) : t)(function(t) {
|
||
if (typeof require < "u") return require.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(delimiter), r = t, s;
|
||
do
|
||
n.push(resolve(r, "node_modules", ".bin")), s = r, r = dirname(r);
|
||
while (r !== s);
|
||
return { key: e.key, value: n.join(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 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: 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.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 = 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 = 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$2;
|
||
const promises_1 = require$$1$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$2;
|
||
const promises_1 = require$$1$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$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 = join(os.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 (!existsSync(CLI_TEMP_DIR))
|
||
await promises.mkdir(CLI_TEMP_DIR, { recursive: true });
|
||
const competitivePath = join(CLI_TEMP_DIR, `.${process$1.pid}.${counter}`);
|
||
counter += 1;
|
||
return promises.open(competitivePath, "wx").then((fd) => ({
|
||
fd,
|
||
path: competitivePath,
|
||
cleanup() {
|
||
fd.close().then(() => {
|
||
if (existsSync(competitivePath))
|
||
promises.unlink(competitivePath);
|
||
});
|
||
}
|
||
})).catch((error) => {
|
||
if (error && error.code === "EEXIST")
|
||
return openTemp();
|
||
else
|
||
return void 0;
|
||
});
|
||
}
|
||
async function writeFileSafe(path, data = "") {
|
||
const temp = await openTemp();
|
||
if (temp) {
|
||
promises.writeFile(temp.path, data).then(() => {
|
||
const directory = dirname$1(path);
|
||
if (!existsSync(directory))
|
||
promises.mkdir(directory, { recursive: true });
|
||
return promises.rename(temp.path, path).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$1.env.CI)
|
||
process$1.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$1.exit(1);
|
||
}
|
||
await ve(
|
||
"npm",
|
||
["i", "-g", `${name}${version ? `@${version}` : ""}`],
|
||
{
|
||
nodeOptions: {
|
||
stdio: "inherit",
|
||
cwd
|
||
},
|
||
throwOnError: true
|
||
}
|
||
);
|
||
}
|
||
return agent;
|
||
}
|
||
|
||
const customRcPath = process$1.env.NI_CONFIG_FILE;
|
||
const home = process$1.platform === "win32" ? process$1.env.USERPROFILE : process$1.env.HOME;
|
||
const defaultRcPath = path.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.existsSync(rcPath) ? ini.parse(fs.readFileSync(rcPath, "utf-8")) : null
|
||
);
|
||
if (process$1.env.NI_DEFAULT_AGENT)
|
||
config.defaultAgent = process$1.env.NI_DEFAULT_AGENT;
|
||
if (process$1.env.NI_GLOBAL_AGENT)
|
||
config.globalAgent = process$1.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$1.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$1.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$1.exit(1);
|
||
throw error;
|
||
}
|
||
}
|
||
async function getCliCommand(fn, args, options = {}, cwd = options.cwd ?? process$1.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$1.cwd();
|
||
if (args[0] === "-C") {
|
||
cwd = resolve$1(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
|
||
}
|
||
);
|
||
}
|
||
|
||
export { AGENTS as A, CLI_TEMP_DIR as C, INSTALL_PAGE as I, LOCKS as L, UnsupportedCommand as U, getDefaultAgent as a, getGlobalAgent as b, getCommand as c, detect as d, parseNr as e, parseNu as f, getConfig as g, parseNun as h, parseNlx as i, parseNa as j, getCliCommand as k, run as l, remove as m, exclude as n, cmdExists as o, parseNi as p, limitText as q, runCli as r, serializeCommand as s, formatPackageWithUrl as t, COMMANDS as u, constructCommand as v, writeFileSafe as w, resolveCommand as x, prompts as y, c as z };
|