@rawcmd/core
Version:
Rawcmd core package.
177 lines • 6.63 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@rawcmd/utils");
const command_option_1 = require("./command-option");
const typewriter_1 = require("../writers/typewriter");
const core_1 = require("@rawmodel/core");
const types_1 = require("../types");
const validation_1 = require("../errors/validation");
const runtime_1 = require("../errors/runtime");
const command_link_1 = require("./command-link");
const spinwriter_1 = require("../writers/spinwriter");
class Command {
constructor(recipe, config) {
recipe = Object.assign({}, recipe);
Object.defineProperty(this, '__config', {
value: Object.assign({ typewriter: new typewriter_1.Typewriter(), spinwriter: new spinwriter_1.Spinwriter() }, config),
enumerable: false,
});
this.name = recipe.name || null;
this.description = recipe.description || null;
this.summary = recipe.summary || null;
config = Object.assign({}, this.__config, { parent: this });
this.options = (recipe.options || []).map((option) => {
option = utils_1.realize(option, this, [config]);
return option instanceof command_option_1.CommandOption ? option.clone() : new command_option_1.CommandOption(option);
});
this.commands = (recipe.commands || []).map((command) => {
command = utils_1.realize(command, this, [config]);
return command instanceof Command ? command.clone() : new Command(command, config);
});
this.links = (recipe.links || []).map((link) => {
link = utils_1.realize(link, this, [config]);
return link instanceof command_link_1.CommandLink ? link.clone() : new command_link_1.CommandLink(link);
});
this.resolver = recipe.resolver || (() => null);
}
getParent() {
return this.__config.parent || null;
}
getAncestors() {
const tree = [];
let parent = this;
while (true) {
parent = parent.getParent();
if (parent) {
tree.unshift(parent);
}
else {
break;
}
}
return tree;
}
getContext() {
return this.__config.context || null;
}
getTypewriter() {
return this.__config.typewriter || null;
}
getSpinwriter() {
return this.__config.spinwriter || null;
}
perform(...args) {
return __awaiter(this, void 0, void 0, function* () {
yield performCommand(this, [...args]);
return this;
});
}
write(...messages) {
this.getSpinwriter().stop();
messages.forEach((message) => {
this.getTypewriter().write(message);
});
return this;
}
print(...messages) {
return this.write(...messages).break();
}
break() {
this.getSpinwriter().stop();
this.getTypewriter().break();
return this;
}
spin(message) {
this.getSpinwriter().start();
this.getSpinwriter().write(message);
return this;
}
clone(recipe) {
return new this.constructor(Object.assign({ name: this.name, description: this.description, summary: this.summary, options: this.options, commands: this.commands, resolver: this.resolver }, recipe), Object.assign({}, this.__config));
}
}
exports.Command = Command;
function performCommand(command, args) {
return __awaiter(this, void 0, void 0, function* () {
if (!command) {
throw new runtime_1.RuntimeError(types_1.ErrorCode.INVALID_COMMAND);
}
else if (/^-\w|^--\w/.test(args[0]) || args.length === 0) {
return resolveCommand(command, args);
}
else {
return performCommand(command.commands.map((c) => utils_1.realize(c)).find((c) => c.name === args[0]), args.slice(1));
}
});
}
function resolveCommand(command, args) {
return __awaiter(this, void 0, void 0, function* () {
const tail = readTail(args);
const options = yield Promise.resolve().then(() => {
return readOptions(command, args);
}).then((data) => {
return sanitizeOptions(command, data);
});
return command.resolver.call(command, { options, tail }, command);
});
}
function readOptions(command, args) {
const data = {};
args = args.indexOf('--') >= 0 ? args.slice(0, args.indexOf('--')) : args;
command.options.map((o) => utils_1.realize(o)).forEach(({ name, alias }) => {
let value = readOptionValueByName(name, args);
if (typeof value === 'undefined') {
value = readOptionValueByAlias(alias, args);
}
if (typeof value !== 'undefined') {
data[name] = value;
}
});
return data;
}
function sanitizeOptions(command, data) {
return __awaiter(this, void 0, void 0, function* () {
const Model = core_1.createModelClass(command.options);
const model = new Model(data);
try {
yield model.validate();
return model.serialize();
}
catch (e) {
yield model.handle(e);
throw new validation_1.ValidationError(model);
}
});
}
function readOptionValueByName(name, args) {
const item = args.find((a) => a === `--${name}` || a.indexOf(`--${name}=`) === 0);
if (item) {
return item.indexOf(`--${name}=`) === 0 ? item.split('=', 2)[1] : true;
}
else {
return undefined;
}
}
function readOptionValueByAlias(alias, args) {
const index = alias ? args.indexOf(`-${alias}`) : -1;
if (index >= 0) {
const value = args[index + 1];
return /^-\w|^--\w/.test(value) ? true : value;
}
else {
return undefined;
}
}
function readTail(args) {
const index = args.indexOf('--');
return index >= 0 ? args.slice(index + 1).join(' ') : null;
}
//# sourceMappingURL=command.js.map