mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core: cli: allow interactive mode
This commit is contained in:
1 parent
e86fab8387
commit
72fbe2bb2d
3 files changed
+42
-5
No files matched your search
@@ -49,6 +49,7 @@
|
|||||||
"sanitize-filename": "^1.6.4",
|
"sanitize-filename": "^1.6.4",
|
||||||
"schemastery": "^3.18.0",
|
"schemastery": "^3.18.0",
|
||||||
"semver": "^7.8.5",
|
"semver": "^7.8.5",
|
||||||
|
"shell-quote": "^1.8.4",
|
||||||
"shorty.js": "^1.0.1",
|
"shorty.js": "^1.0.1",
|
||||||
"superagent": "^10.3.0",
|
"superagent": "^10.3.0",
|
||||||
"superagent-proxy": "^3.0.0",
|
"superagent-proxy": "^3.0.0",
|
||||||
@@ -66,6 +67,7 @@
|
|||||||
"@types/mongodb-uri": "^0.9.4",
|
"@types/mongodb-uri": "^0.9.4",
|
||||||
"@types/nodemailer": "^8.0.1",
|
"@types/nodemailer": "^8.0.1",
|
||||||
"@types/semver": "^7.7.1",
|
"@types/semver": "^7.7.1",
|
||||||
|
"@types/shell-quote": "^1.7.5",
|
||||||
"@types/superagent": "^8.1.10",
|
"@types/superagent": "^8.1.10",
|
||||||
"@types/superagent-proxy": "^3.0.4",
|
"@types/superagent-proxy": "^3.0.4",
|
||||||
"@types/ua-parser-js": "^0.7.39",
|
"@types/ua-parser-js": "^0.7.39",
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import os from 'os';
|
import os from 'os';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
import readline from 'readline/promises';
|
||||||
import cac from 'cac';
|
import cac from 'cac';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import { ObjectId } from 'mongodb';
|
import { ObjectId } from 'mongodb';
|
||||||
|
import { parse, type ParseEntry } from 'shell-quote';
|
||||||
import { Context } from '../context';
|
import { Context } from '../context';
|
||||||
import SystemModel from '../model/system';
|
import SystemModel from '../model/system';
|
||||||
import { load as loadOptions } from '../options';
|
import { load as loadOptions } from '../options';
|
||||||
@@ -32,8 +34,20 @@ async function runScript(name: string, arg: any) {
|
|||||||
return await s.run(arg, console.info);
|
return await s.run(arg, console.info);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function cli() {
|
function checkStringArray(args: ParseEntry[]): args is string[] {
|
||||||
const [, modelName, func, ...args] = argv.args as [string, string, string, ...any[]];
|
return args.every((arg) => typeof arg === 'string');
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseInteractiveArgv(line: string) {
|
||||||
|
const args = parse(line);
|
||||||
|
if (!checkStringArray(args)) throw new Error('Shell operators are not supported in interactive mode.');
|
||||||
|
if (args[0] === 'hydrooj') args.shift();
|
||||||
|
if (args[0] === 'cli') args.shift();
|
||||||
|
return cac().parse(['node', 'hydrooj', 'cli', ...args], { run: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function cli(commandArgv = argv) {
|
||||||
|
const [, modelName, func, ...args] = commandArgv.args as [string, string, string, ...any[]];
|
||||||
if (modelName === 'execute') {
|
if (modelName === 'execute') {
|
||||||
try {
|
try {
|
||||||
// eslint-disable-next-line no-eval
|
// eslint-disable-next-line no-eval
|
||||||
@@ -84,7 +98,7 @@ async function cli() {
|
|||||||
} else if ((+args[i]).toString() === args[i]) {
|
} else if ((+args[i]).toString() === args[i]) {
|
||||||
args[i] = +args[i];
|
args[i] = +args[i];
|
||||||
} else if (args[i].startsWith('~')) {
|
} else if (args[i].startsWith('~')) {
|
||||||
args[i] = argv.options[args[i].substr(1)];
|
args[i] = commandArgv.options[args[i].substr(1)];
|
||||||
} else if ((args[i].startsWith('[') && args[i].endsWith(']')) || (args[i].startsWith('{') && args[i].endsWith('}'))) {
|
} else if ((args[i].startsWith('[') && args[i].endsWith(']')) || (args[i].startsWith('{') && args[i].endsWith('}'))) {
|
||||||
try {
|
try {
|
||||||
args[i] = JSON.parse(args[i]);
|
args[i] = JSON.parse(args[i]);
|
||||||
@@ -137,5 +151,26 @@ export async function load(ctx: Context) {
|
|||||||
const scriptDir = path.resolve(__dirname, '..', 'script');
|
const scriptDir = path.resolve(__dirname, '..', 'script');
|
||||||
await Promise.all((await fs.readdir(scriptDir))
|
await Promise.all((await fs.readdir(scriptDir))
|
||||||
.map((h) => ctx.loader.reloadPlugin(path.resolve(scriptDir, h), '')));
|
.map((h) => ctx.loader.reloadPlugin(path.resolve(scriptDir, h), '')));
|
||||||
await cli();
|
if (argv.args.length > 1) {
|
||||||
|
await cli();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const rl = readline.createInterface(process.stdin, process.stdout);
|
||||||
|
console.log('Hydro CLI interactive mode. Type `exit` or press Ctrl+D to exit.');
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
const line = await rl.question('hydrooj> ');
|
||||||
|
if (!line.trim()) continue;
|
||||||
|
if (['exit', 'quit'].includes(line.trim())) break;
|
||||||
|
try {
|
||||||
|
await cli(parseInteractiveArgv(line));
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (e?.code !== 'ERR_USE_AFTER_CLOSE') console.error(e);
|
||||||
|
} finally {
|
||||||
|
rl.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,6 @@ import child from 'child_process';
|
|||||||
// eslint-disable-next-line import/no-duplicates
|
// eslint-disable-next-line import/no-duplicates
|
||||||
import './utils';
|
import './utils';
|
||||||
import cac from 'cac';
|
import cac from 'cac';
|
||||||
import './ui';
|
|
||||||
import { I18nService } from './lib/i18n';
|
import { I18nService } from './lib/i18n';
|
||||||
|
|
||||||
import { Logger } from './logger';
|
import { Logger } from './logger';
|
||||||
@@ -205,6 +204,7 @@ async function preload() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function load() {
|
export async function load() {
|
||||||
|
require('./ui');
|
||||||
await preload();
|
await preload();
|
||||||
Error.stackTraceLimit = 50;
|
Error.stackTraceLimit = 50;
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in new issue
Block a user