UNPKG

@rawcmd/core

Version:
177 lines 6.63 kB
"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