script-launcher
Version:
Enhance your package.json scripts with features like: menus, functions, arrays, concurrency and many more.
255 lines (254 loc) • 9.35 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Limiter = exports.stringToArgv = exports.confirmPrompt = exports.toPromise = exports.formatTime = exports.showArgsHelp = exports.parseArgs = exports.stringify = exports.Colors = void 0;
const deepmerge = require("deepmerge");
const elements_1 = require("prompts/lib/elements");
var Colors;
(function (Colors) {
Colors["Red"] = "\u001B[31m";
Colors["Green"] = "\u001B[32m";
Colors["Yellow"] = "\u001B[33m";
Colors["Blue"] = "\u001B[94m";
Colors["Cyan"] = "\u001B[36m";
Colors["Bold"] = "\u001B[1m";
Colors["Dim"] = "\u001B[2m";
Colors["Normal"] = "\u001B[0m";
})(Colors = exports.Colors || (exports.Colors = {}));
function stringify(value, replacer, space = 2) {
if (typeof value !== 'string') {
value = JSON.stringify(value, replacer, space);
}
return value.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, match => {
let cls = Colors.Yellow;
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = Colors.Normal;
}
else {
cls = Colors.Green;
}
}
else if (/true|false/.test(match)) {
cls = Colors.Yellow;
}
else if (/null/.test(match)) {
cls = Colors.Dim;
}
return cls + match + Colors.Normal;
});
}
exports.stringify = stringify;
function parseArgs(argv, defaultData = null) {
const result = {
arguments: {},
optionals: [],
unknowns: []
};
const validArguments = Object.keys(defaultData.arguments);
let commandFound = false;
for (const rawArgument of argv) {
// Everything behind "--" is passed as an argument for the called command
if (rawArgument === '--')
break;
const splittedRawArgument = rawArgument.split('=', 2);
const [rawName, rawValue] = splittedRawArgument;
const name = rawName.replace(/^--/, '');
let value = true;
// There is at least a value given for the argument
if (rawValue !== undefined) {
if (name === rawName)
throw new Error(`Unexpected value for command ("${name}") use option syntax instead ("--${name}=${rawValue}").`);
if (!validArguments.includes(name)) {
// Unknown argument given
throw new Error(`The specified option ("--${name}") is invalid.`);
}
// Try parse it as a number
value = Number.parseInt(rawValue, 10);
// Reset it back to the rawValue if it wasn't a number
if (isNaN(value))
value = rawValue;
// Check if the rawValue is a boolean
if (rawValue === 'true' || rawValue === 'false')
value = rawValue === 'true';
const defaultValue = defaultData.arguments[name];
// Check if the value given is the same type as the default one
if (defaultValue !== null && defaultValue !== undefined && typeof defaultValue !== typeof value) {
throw new Error(`Unexpected type "${typeof value}" for argument "${name}". The argument should be of type "${typeof defaultValue}".`);
}
}
else {
if (!commandFound) {
if (!validArguments.includes(name)) {
result.unknowns.push(name);
continue;
}
if (!rawName.startsWith('--'))
commandFound = true;
}
else {
result.optionals.push(name);
continue;
}
}
result.arguments[name] = value;
}
if (result !== null) {
if (defaultData === null)
return result;
if (defaultData instanceof Function)
return result;
if (typeof defaultData === 'string')
return result;
if (defaultData instanceof String)
return result;
return deepmerge(defaultData, result);
}
return defaultData;
}
exports.parseArgs = parseArgs;
function showArgsHelp(name, descriptions) {
console.log('Usage: ' + name + ' [command] [options...]');
for (const description of Object.values(descriptions)) {
if (!description)
continue;
if (Array.isArray(description)) {
for (const item of Object.values(description)) {
console.log(item);
}
}
else {
console.log(description);
}
}
}
exports.showArgsHelp = showArgsHelp;
function formatTime(time = Date.now(), timezoneOffset = new Date().getTimezoneOffset() * -60000) {
return new Date(time + timezoneOffset).toISOString().replace('T', ' ').replace('Z', '');
}
exports.formatTime = formatTime;
function toPromise(prompt, options = {}) {
const dummyHandler = (...args) => args;
const onState = options.onState || dummyHandler;
const onAbort = options.onAbort || dummyHandler;
const onSubmit = options.onSubmit || dummyHandler;
return new Promise((resolve, reject) => {
prompt.on('state', onState);
prompt.on('submit', args => resolve(onSubmit(args)));
prompt.on('abort', args => reject(onAbort(args)));
});
}
exports.toPromise = toPromise;
function confirmPrompt(message, autoValue, defaultValue = false) {
return __awaiter(this, void 0, void 0, function* () {
const confirmPrompt = new elements_1.ConfirmPrompt({
type: 'confirm',
name: 'value',
initial: autoValue !== undefined ? autoValue : defaultValue,
message: message
});
const confirmPromise = toPromise(confirmPrompt);
if (autoValue !== undefined)
confirmPrompt.submit();
const choice = yield confirmPromise;
return choice[0];
});
}
exports.confirmPrompt = confirmPrompt;
function stringToArgv(value) {
const result = [];
const spaces = '\t ';
const quotes = '"\'';
let start = 0;
let index = 0;
function scanSpace() {
if (!(spaces + quotes).includes(value[index])) {
start = index;
while (index < value.length && !(spaces + quotes).includes(value[index]))
index++;
return value.substr(start, index - start);
}
return null;
}
function scanQuote() {
if (value[index] === "'") {
start = ++index;
while (index < value.length && value[index] !== "'")
index++;
return value.substr(start, index++ - start);
}
if (value[index] === '"') {
start = ++index;
while (index < value.length && value[index] !== '"')
index++;
return value.substr(start, index++ - start);
}
return null;
}
let param = null;
while (index < value.length) {
if (!spaces.includes(value[index])) {
if (param === null)
param = '';
const quoteParam = scanQuote();
if (quoteParam !== null) {
param += quoteParam;
continue;
}
const spaceParam = scanSpace();
if (spaceParam !== null) {
param += spaceParam;
continue;
}
}
if (param !== null) {
result.push(param);
param = null;
}
index++;
}
if (param !== null) {
result.push(param);
param = null;
}
return result;
}
exports.stringToArgv = stringToArgv;
class Limiter {
constructor(maximum) {
this.currentCount = 0;
this.maximumCount = maximum;
this.resolvers = [];
}
enter() {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve, reject) => {
if (this.currentCount < this.maximumCount) {
this.currentCount++;
resolve(this.currentCount);
return;
}
this.resolvers.push(resolve);
});
});
}
leave() {
this.currentCount--;
while (this.currentCount < this.maximumCount && this.resolvers.length > 0) {
const resolver = this.resolvers[0];
this.resolvers.shift();
this.currentCount++;
resolver(this.currentCount);
}
return this.currentCount;
}
}
exports.Limiter = Limiter;