UNPKG

miraipie

Version:

the most powerful nodejs development kit for mirai-api-http

533 lines (532 loc) 24.7 kB
"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 __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()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spreadArray = (this && this.__spreadArray) || function (to, from) { for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i]; return to; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var child_process_1 = require("child_process"); var commander_1 = require("commander"); var enquirer_1 = require("enquirer"); var events_1 = __importDefault(require("events")); var fs_extra_1 = __importDefault(require("fs-extra")); var log4js_1 = __importDefault(require("log4js")); var path_1 = __importDefault(require("path")); var MixedApiAdapter_1 = __importDefault(require("./builtin/MixedApiAdapter")); var config_1 = require("./config"); var miraipie_1 = __importStar(require("./miraipie")); var utils_1 = require("./utils"); log4js_1.default.configure({ appenders: { console: { type: 'console' } }, categories: { default: { appenders: ['console'], level: 'info' } } }); var logger = log4js_1.default.getLogger('cli'); var banner = "\n __ __ __ ______ ______ __ ______ __ ______ \n/\\ \"-./ \\ /\\ \\ /\\ == \\ /\\ __ \\ /\\ \\ /\\ == \\ /\\ \\ /\\ ___\\ \n\\ \\ \\-./\\ \\ \\ \\ \\ \\ \\ __< \\ \\ __ \\ \\ \\ \\ \\ \\ _-/ \\ \\ \\ \\ \\ __\\ \n \\ \\_\\ \\ \\_\\ \\ \\_\\ \\ \\_\\ \\_\\ \\ \\_\\ \\_\\ \\ \\_\\ \\ \\_\\ \\ \\_\\ \\ \\_____\\ \n \\/_/ \\/_/ \\/_/ \\/_/ /_/ \\/_/\\/_/ \\/_/ \\/_/ \\/_/ \\/_____/ \n"; // 提供虚拟环境 function MiraiPieApplicationMock() { return Object.assign(new events_1.default(), { config: {}, extensions: [], install: function (extension) { this.extensions.push(extension); }, adapter: function (adapter) { this.extensions.push(adapter); }, pie: function (pie) { this.extensions.push(pie); }, useAdapter: function () { return undefined; }, uninstallAdapter: function () { return undefined; }, enable: function () { return undefined; }, disable: function () { return undefined; }, uninstallPie: function () { return undefined; }, listen: function () { return undefined; }, stop: function () { return undefined; } }); } // 检查 miraipie 更新 function checkForUpdate() { var version = require('../package.json').version; child_process_1.exec('npm search miraipie -p --no-description', function (error, stdout) { var e_1, _a; if (!error && stdout) { var lines = stdout.split('\n'); try { for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) { var line = lines_1_1.value; var desc = line.split('\t'); if (desc[0] === 'miraipie' && version < desc[3]) { logger.warn("\u65B0\u7684 miraipie \u7248\u672C\u53EF\u7528: " + desc[3] + ", \u5F53\u524D\u7248\u672C: " + version + ", \u4F7F\u7528\u547D\u4EE4 npm install miraipie -g \u66F4\u65B0 miraipie"); } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1); } finally { if (e_1) throw e_1.error; } } } }); } // 填写用户配置 function writeUserConfig(configMeta) { return __awaiter(this, void 0, void 0, function () { var unsupportedConfig, questions, _a, _b, e_2; return __generator(this, function (_c) { switch (_c.label) { case 0: unsupportedConfig = {}; questions = Object.keys(configMeta).map(function (name) { var meta = configMeta[name]; var question = { type: null, name: name, message: "\u8BF7\u8F93\u5165\u914D\u7F6E\u9879 - " + name + (meta.description ? "(" + meta.description + ")" : ''), initial: typeof meta.default === 'function' ? meta.default() : null }; var type = typeof meta.type(); if (type === 'number') question.type = 'numeral'; else if (type === 'boolean') question.type = 'confirm'; else if (type === 'string') question.type = 'input'; else { logger.warn("\u6682\u4E0D\u652F\u6301CLI\u586B\u5199\u7684\u914D\u7F6E\u9879: " + name + " \u7C7B\u578B: " + type + " , \u8BF7\u624B\u52A8\u586B\u5199\u914D\u7F6E\u6587\u4EF6"); unsupportedConfig[name] = typeof meta.default === 'function' ? meta.default() : null; } return question.type ? question : null; }).filter(function (question) { return !!question; }); _c.label = 1; case 1: _c.trys.push([1, 3, , 4]); _b = (_a = Object).assign; return [4 /*yield*/, enquirer_1.prompt(questions)]; case 2: return [2 /*return*/, _b.apply(_a, [_c.sent(), unsupportedConfig])]; case 3: e_2 = _c.sent(); return [2 /*return*/, {}]; case 4: return [2 /*return*/]; } }); }); } // 加载配置文件 function useConfigFile(path) { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { return [2 /*return*/, new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { if (!fs_extra_1.default.existsSync(path)) { enquirer_1.prompt({ type: 'confirm', name: 'new', message: '没有检测到配置文件, 是否新建配置文件?', initial: true }).then(function (confirm) { if (confirm.new) { enquirer_1.prompt([ { type: 'numeral', name: 'qq', message: '请输入机器人服务的QQ号' }, { type: 'select', name: 'adapter', message: '请选择默认服务客户端adapter', choices: ['mixed', 'http', 'ws'], initial: 0 } ]).then(function (pro) { return __awaiter(_this, void 0, void 0, function () { var configMeta, adapterConfigs, config; return __generator(this, function (_a) { switch (_a.label) { case 0: configMeta = Object.assign({}, MixedApiAdapter_1.default.configMeta); delete configMeta['qq']; return [4 /*yield*/, writeUserConfig(configMeta)]; case 1: adapterConfigs = _a.sent(); config = config_1.ApplicationConfig.make({ qq: pro.qq, adapterInUse: pro.adapter }); config.adapters[pro.adapter] = { configs: adapterConfigs }; saveConfigFile(config, path); resolve(config); return [2 /*return*/]; } }); }); }).catch(reject); } else reject(); }).catch(reject); } else { fs_extra_1.default.readJson(path).then(function (content) { resolve(config_1.ApplicationConfig.make(content)); }).catch(reject); } return [2 /*return*/]; }); }); })]; }); }); } // 保存配置文件 function saveConfigFile(config, path) { fs_extra_1.default.writeJsonSync(path, config, { spaces: 4 }); } // miraipie commander_1.program .version("miraipie " + require('../package.json').version + " for mirai-api-http " + miraipie_1.Mirai.MIRAI_API_HTTP_VERSION, '-V, --version', '显示版本信息') .option('-c, --config <path>', 'miraipie的配置文件路径', 'miraipie.json') .helpOption('-h, --help', '显示帮助信息') .addHelpCommand('help [command]', '显示命令帮助'); // miraipie start commander_1.program .command('start') .description('启动miraipie应用程序') .option('-m, --modules <paths...>', 'miraipie需要额外加载的模块路径') .option('-l, --log-level <level>', 'miraipie日志输出级别') .option('-v, --verbose', '控制台打印miraipie接收到的消息和事件') .action(function (opts) { checkForUpdate(); useConfigFile(commander_1.program.opts().config).then(function (config) { return __awaiter(void 0, void 0, void 0, function () { var app; return __generator(this, function (_a) { switch (_a.label) { case 0: if (opts.logLevel) config.logLevel = opts.logLevel; if (opts.modules) config.extensions = __spreadArray(__spreadArray([], __read(config.extensions)), __read(opts.modules)); if (opts.verbose) config.verbose = true; app = miraipie_1.default(config); app.once('listen', function () { logger.info('miraipie应用程序已成功启动!\n' + banner); }); return [4 /*yield*/, app.listen()]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }).catch(function (err) { logger.error('启动应用程序失败:', err); }); }); // miraipie install commander_1.program .command('install') .description('添加本地模块(客户端adapter或pie)') .argument('module', '待安装的本地模块路径') .aliases(['i', 'add']) .action(function (module) { useConfigFile(commander_1.program.opts().config).then(function (config) { var e_3, _a; var mockApp = MiraiPieApplicationMock(); try { require(path_1.default.join(process.cwd(), module))(mockApp); var _loop_1 = function (extension) { if ((extension.__isPie || extension.__isApiAdapter) && extension.id) { writeUserConfig(extension.configMeta || {}).then(function (userConfigs) { if (extension.__isPie) { config.pies[extension.id] = { module: module, enabled: true, configs: userConfigs }; logger.info("\u5DF2\u6DFB\u52A0pie '" + extension.id + "'"); } else if (extension.__isApiAdapter) { config.adapters[extension.id] = { module: module, configs: userConfigs }; logger.info("\u5DF2\u6DFB\u52A0adapter '" + extension.id + "'"); } saveConfigFile(config, commander_1.program.opts().config); }); } else { config.extensions.push(module); logger.info("\u5DF2\u6DFB\u52A0\u6A21\u5757 " + module); saveConfigFile(config, commander_1.program.opts().config); } }; try { for (var _b = __values(mockApp.extensions), _c = _b.next(); !_c.done; _c = _b.next()) { var extension = _c.value; _loop_1(extension); } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_3) throw e_3.error; } } } catch (err) { logger.error('添加模块失败:', err); } }).catch(function () { logger.error('没有找到miraipie配置文件'); }); }); // miraipie pie var pie = commander_1.program .command('pie [command]') .description('miraipie关于pie相关选项'); // miraipie pie create pie .command('create') .description('使用模板创建pie项目') .aliases(['new', 'init']) .argument('[id]', 'pie id') .option('-j, --javascript', '使用javascript模板') .action(function (id, opts) { enquirer_1.prompt([ { type: 'input', name: 'id', message: '请输入pie id', initial: id || 'my-pie' }, { type: 'input', name: 'name', message: '请输入pie名称', initial: id || 'my-pie' }, { type: 'input', name: 'path', message: '请输入pie存放位置', initial: "pies/" + (id || 'my-pie') + "/" } ]).then(function (pro) { var src = path_1.default.join(__dirname, opts.javascript ? '../template/pie-js' : '../template/pie-ts'); fs_extra_1.default.ensureDirSync(pro.path); fs_extra_1.default.readdir(src, function (err, files) { var e_4, _a; if (err) { logger.error('创建pie项目失败:', err); return; } try { for (var files_1 = __values(files), files_1_1 = files_1.next(); !files_1_1.done; files_1_1 = files_1.next()) { var file = files_1_1.value; utils_1.makeTemplate(path_1.default.resolve(src, file), path_1.default.resolve(pro.path, file), pro); } } catch (e_4_1) { e_4 = { error: e_4_1 }; } finally { try { if (files_1_1 && !files_1_1.done && (_a = files_1.return)) _a.call(files_1); } finally { if (e_4) throw e_4.error; } } }); logger.info('已使用模板创建pie项目'); enquirer_1.prompt({ type: 'confirm', name: 'init', message: '是否使用npm初始化pie项目', initial: true }).then(function (proConfirm) { if (proConfirm.init) child_process_1.execSync("cd \"" + pro.path + "\" && npm install"); }).catch(function () { return undefined; }); }).catch(function () { logger.info('已取消创建项目'); }); }); // miraipie pie list pie .command('list') .description('显示已安装pie的列表') .option('-e, --enabled', '只显示已启用的pie') .action(function (opts) { useConfigFile(commander_1.program.opts().config).then(function (config) { var pies = config.pies; if (opts.enabled) { for (var id in pies) { if (!pies[id].enabled) delete pies[id]; } } if (Object.keys(pies).length === 0) { logger.info('当前没有已添加的pie'); return; } var header = "" + 'id'.padEnd(32) + 'enabled'.padEnd(12) + "path\n" + ("" + '-'.repeat(2).padEnd(32) + '-'.repeat(7).padEnd(12) + '-'.repeat(4)); var content = Object.keys(pies).map(function (id) { return "" + id.padEnd(32) + pies[id].enabled.toString().padEnd(12) + pies[id].module.toString(); }).join('\n'); logger.info("\u5F53\u524D\u52A0\u8F7D\u7684pie\u5217\u8868:\n" + header + "\n" + content); }).catch(function () { logger.error('没有找到miraipie配置文件'); }); }); // miraipie pie enable pie .command('enable') .description('启用已添加的pie') .argument('id', 'pie id') .action(function (id) { useConfigFile(commander_1.program.opts().config).then(function (config) { if (id in config.pies) { config.pies[id].enabled = true; logger.info("\u5DF2\u542F\u7528pie '" + id + "'"); saveConfigFile(config, commander_1.program.opts().config); } else { logger.error("\u914D\u7F6E\u6587\u4EF6\u4E2D\u4E0D\u5B58\u5728pie '" + id + "'"); } }).catch(function () { logger.error('没有找到miraipie配置文件'); }); }); // miraipie pie disable pie .command('disable') .description('禁用已添加的pie') .argument('id', 'pie id') .action(function (id) { useConfigFile(commander_1.program.opts().config).then(function (config) { if (id in config.pies) { config.pies[id].enabled = false; logger.info("\u5DF2\u7981\u7528pie '" + id + "'"); saveConfigFile(config, commander_1.program.opts().config); } else { logger.error("\u914D\u7F6E\u6587\u4EF6\u4E2D\u4E0D\u5B58\u5728pie '" + id + "'"); } }).catch(function () { logger.error('没有找到miraipie配置文件'); }); }); // miraipie pie delete pie .command('delete') .description('移除已添加的pie') .alias('remove') .argument('id', 'pie id') .action(function (id) { useConfigFile(commander_1.program.opts().config).then(function (config) { if (id in config.pies) { delete config.pies[id]; logger.info("\u5DF2\u79FB\u9664pie '" + id + "'"); saveConfigFile(config, commander_1.program.opts().config); } else { logger.error("\u914D\u7F6E\u6587\u4EF6\u4E2D\u4E0D\u5B58\u5728pie '" + id + "'"); } }).catch(function () { logger.error('没有找到miraipie配置文件'); }); }); commander_1.program.parse(process.argv);