miraipie
Version:
the most powerful nodejs development kit for mirai-api-http
533 lines (532 loc) • 24.7 kB
JavaScript
;
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);