155 lines
6.2 KiB
JavaScript
Executable File
155 lines
6.2 KiB
JavaScript
Executable File
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__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 __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.command = void 0;
|
|
const chalk_1 = __importDefault(require("chalk"));
|
|
const utils_1 = require("./utils");
|
|
const circuitbreaker_1 = require("./circuitbreaker");
|
|
const Result = __importStar(require("./Result"));
|
|
/**
|
|
* A command line utility.
|
|
*
|
|
* A combination of multiple flags, options and arguments
|
|
* with a common name and a handler that expects them as input.
|
|
*/
|
|
function command(config) {
|
|
const argEntries = utils_1.entries(config.args);
|
|
const circuitbreaker = circuitbreaker_1.createCircuitBreaker(!!config.version);
|
|
return {
|
|
name: config.name,
|
|
aliases: config.aliases,
|
|
handler: config.handler,
|
|
description: config.description,
|
|
version: config.version,
|
|
helpTopics() {
|
|
return utils_1.flatMap(Object.values(config.args).concat([circuitbreaker]), x => { var _a, _b; return (_b = (_a = x.helpTopics) === null || _a === void 0 ? void 0 : _a.call(x)) !== null && _b !== void 0 ? _b : []; });
|
|
},
|
|
printHelp(context) {
|
|
var _a, _b;
|
|
const lines = [];
|
|
let name = (_b = (_a = context.hotPath) === null || _a === void 0 ? void 0 : _a.join(' ')) !== null && _b !== void 0 ? _b : '';
|
|
if (!name) {
|
|
name = config.name;
|
|
}
|
|
name = chalk_1.default.bold(name);
|
|
if (config.version) {
|
|
name += ' ' + chalk_1.default.dim(config.version);
|
|
}
|
|
lines.push(name);
|
|
if (config.description) {
|
|
lines.push(chalk_1.default.dim('> ') + config.description);
|
|
}
|
|
const usageBreakdown = utils_1.groupBy(this.helpTopics(), x => x.category);
|
|
for (const [category, helpTopics] of utils_1.entries(usageBreakdown)) {
|
|
lines.push('');
|
|
lines.push(category.toUpperCase() + ':');
|
|
const widestUsage = helpTopics.reduce((len, curr) => {
|
|
return Math.max(len, curr.usage.length);
|
|
}, 0);
|
|
for (const helpTopic of helpTopics) {
|
|
let line = '';
|
|
line += ' ' + utils_1.padNoAnsi(helpTopic.usage, widestUsage, 'end');
|
|
line += ' - ';
|
|
line += helpTopic.description;
|
|
for (const defaultValue of helpTopic.defaults) {
|
|
line += chalk_1.default.dim(` [${defaultValue}]`);
|
|
}
|
|
lines.push(line);
|
|
}
|
|
}
|
|
return lines.join('\n');
|
|
},
|
|
register(opts) {
|
|
var _a;
|
|
for (const [, arg] of argEntries) {
|
|
(_a = arg.register) === null || _a === void 0 ? void 0 : _a.call(arg, opts);
|
|
}
|
|
},
|
|
async parse(context) {
|
|
var _a;
|
|
if (((_a = context.hotPath) === null || _a === void 0 ? void 0 : _a.length) === 0) {
|
|
context.hotPath.push(config.name);
|
|
}
|
|
const resultObject = {};
|
|
const errors = [];
|
|
for (const [argName, arg] of argEntries) {
|
|
const result = await arg.parse(context);
|
|
if (Result.isErr(result)) {
|
|
errors.push(...result.error.errors);
|
|
}
|
|
else {
|
|
resultObject[argName] = result.value;
|
|
}
|
|
}
|
|
const unknownArguments = [];
|
|
for (const node of context.nodes) {
|
|
if (context.visitedNodes.has(node)) {
|
|
continue;
|
|
}
|
|
if (node.type === 'forcePositional') {
|
|
// A `forcePositional` node can't really be visited since it has no meaning
|
|
// other than forcing a positional argument in the parsing phase
|
|
continue;
|
|
}
|
|
else if (node.type === 'shortOptions') {
|
|
for (const option of node.options) {
|
|
if (context.visitedNodes.has(option)) {
|
|
continue;
|
|
}
|
|
unknownArguments.push(option);
|
|
}
|
|
}
|
|
else {
|
|
unknownArguments.push(node);
|
|
}
|
|
}
|
|
if (unknownArguments.length > 0) {
|
|
errors.push({
|
|
message: 'Unknown arguments',
|
|
nodes: unknownArguments,
|
|
});
|
|
}
|
|
if (errors.length > 0) {
|
|
return Result.err({
|
|
errors: errors,
|
|
partialValue: resultObject,
|
|
});
|
|
}
|
|
else {
|
|
return Result.ok(resultObject);
|
|
}
|
|
},
|
|
async run(context) {
|
|
const parsed = await this.parse(context);
|
|
const breaker = await circuitbreaker.parse(context);
|
|
circuitbreaker_1.handleCircuitBreaker(context, this, breaker);
|
|
if (Result.isErr(parsed)) {
|
|
return Result.err(parsed.error);
|
|
}
|
|
return Result.ok(await this.handler(parsed.value));
|
|
},
|
|
};
|
|
}
|
|
exports.command = command;
|
|
//# sourceMappingURL=command.js.map
|