@powernukkitx/cli 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle.js +18871 -0
- package/dist/commands/backup.d.ts +1 -0
- package/dist/commands/backup.js +74 -0
- package/dist/commands/config.d.ts +1 -0
- package/dist/commands/config.js +114 -0
- package/dist/commands/doctor.d.ts +1 -0
- package/dist/commands/doctor.js +119 -0
- package/dist/commands/info.d.ts +1 -0
- package/dist/commands/info.js +36 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.js +73 -0
- package/dist/commands/plugin.d.ts +12 -0
- package/dist/commands/plugin.js +385 -0
- package/dist/commands/start.d.ts +7 -0
- package/dist/commands/start.js +108 -0
- package/dist/commands/update.d.ts +5 -0
- package/dist/commands/update.js +55 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +260 -0
- package/dist/lang/en.json +178 -0
- package/dist/lang/fr.json +178 -0
- package/dist/lang/index.d.ts +7 -0
- package/dist/lang/index.js +83 -0
- package/dist/plugins.json +66 -0
- package/dist/types.d.ts +61 -0
- package/dist/types.js +1 -0
- package/dist/utils/api.d.ts +18 -0
- package/dist/utils/api.js +74 -0
- package/dist/utils/github.d.ts +27 -0
- package/dist/utils/github.js +187 -0
- package/dist/utils/logger.d.ts +15 -0
- package/dist/utils/logger.js +72 -0
- package/dist/utils/pause.d.ts +1 -0
- package/dist/utils/pause.js +6 -0
- package/dist/utils/plugins.d.ts +4 -0
- package/dist/utils/plugins.js +34 -0
- package/dist/utils/server.d.ts +3 -0
- package/dist/utils/server.js +39 -0
- package/dist/utils/updater.d.ts +1 -0
- package/dist/utils/updater.js +86 -0
- package/package.json +63 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function backupCmd(): Promise<void>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { readdirSync, statSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { mkdir, cp, readdir } from 'node:fs/promises';
|
|
4
|
+
import { cwd } from 'node:process';
|
|
5
|
+
import { confirm } from '@inquirer/prompts';
|
|
6
|
+
import { header, success, error, info, highlight, step } from '../utils/logger.js';
|
|
7
|
+
import { t } from '../lang/index.js';
|
|
8
|
+
import { resolveServerDir } from '../utils/server.js';
|
|
9
|
+
import { pauseForExit } from '../utils/pause.js';
|
|
10
|
+
const IGNORE = new Set(['logs', 'cache', 'crash-reports', 'backups', 'powernukkitx.jar.old']);
|
|
11
|
+
function getDirSize(dir) {
|
|
12
|
+
let total = 0;
|
|
13
|
+
try {
|
|
14
|
+
const items = readdirSync(dir);
|
|
15
|
+
for (const item of items) {
|
|
16
|
+
const full = join(dir, item);
|
|
17
|
+
const s = statSync(full);
|
|
18
|
+
if (s.isDirectory())
|
|
19
|
+
total += getDirSize(full);
|
|
20
|
+
else
|
|
21
|
+
total += s.size;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
catch { /* ignore */ }
|
|
25
|
+
return total;
|
|
26
|
+
}
|
|
27
|
+
function formatSize(bytes) {
|
|
28
|
+
if (bytes < 1024)
|
|
29
|
+
return `${bytes} B`;
|
|
30
|
+
if (bytes < 1024 * 1024)
|
|
31
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
32
|
+
return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
|
|
33
|
+
}
|
|
34
|
+
export async function backupCmd() {
|
|
35
|
+
const serverPath = await resolveServerDir(t('backup.selectServer'));
|
|
36
|
+
if (!serverPath) {
|
|
37
|
+
error(t('backup.noServer'));
|
|
38
|
+
await pauseForExit();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (serverPath === cwd()) {
|
|
42
|
+
const ok = await confirm({
|
|
43
|
+
message: t('backup.backupCurrent', highlight(serverPath)),
|
|
44
|
+
default: true,
|
|
45
|
+
});
|
|
46
|
+
if (!ok) {
|
|
47
|
+
info(t('backup.cancelled'));
|
|
48
|
+
await pauseForExit();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
header(`💾 ${t('backup.title')}`);
|
|
53
|
+
step(t('backup.collecting'));
|
|
54
|
+
const size = getDirSize(serverPath);
|
|
55
|
+
info(t('backup.estimatedSize', formatSize(size)));
|
|
56
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
|
|
57
|
+
const backupDir = join(serverPath, 'backups');
|
|
58
|
+
const destDir = join(backupDir, `pnx-backup-${timestamp}`);
|
|
59
|
+
await mkdir(destDir, { recursive: true });
|
|
60
|
+
step(t('backup.copying'));
|
|
61
|
+
const items = await readdir(serverPath);
|
|
62
|
+
let count = 0;
|
|
63
|
+
for (const item of items) {
|
|
64
|
+
if (IGNORE.has(item) || item.startsWith('.'))
|
|
65
|
+
continue;
|
|
66
|
+
const src = join(serverPath, item);
|
|
67
|
+
const dst = join(destDir, item);
|
|
68
|
+
await cp(src, dst, { recursive: true, force: true });
|
|
69
|
+
count++;
|
|
70
|
+
}
|
|
71
|
+
const finalSize = getDirSize(destDir);
|
|
72
|
+
success(t('backup.done', destDir, formatSize(finalSize)));
|
|
73
|
+
await pauseForExit();
|
|
74
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function configCmd(): Promise<void>;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { header, error, info, highlight, dim } from '../utils/logger.js';
|
|
5
|
+
import { t } from '../lang/index.js';
|
|
6
|
+
import { resolveServerDir } from '../utils/server.js';
|
|
7
|
+
import { pauseForExit } from '../utils/pause.js';
|
|
8
|
+
export async function configCmd() {
|
|
9
|
+
const serverPath = await resolveServerDir();
|
|
10
|
+
if (!serverPath) {
|
|
11
|
+
error(t('config.noServer'));
|
|
12
|
+
info(t('config.hintInit'));
|
|
13
|
+
await pauseForExit();
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
// Prefer pnx.yml, fallback to server.properties
|
|
17
|
+
let configPath = join(serverPath, 'pnx.yml');
|
|
18
|
+
if (!existsSync(configPath)) {
|
|
19
|
+
configPath = join(serverPath, 'server.properties');
|
|
20
|
+
if (!existsSync(configPath)) {
|
|
21
|
+
error(t('config.notFound'));
|
|
22
|
+
info(t('config.hintGenerate'));
|
|
23
|
+
await pauseForExit();
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const isYml = configPath.endsWith('.yml');
|
|
28
|
+
header(`⚙️ ${t('config.title')} ${dim(isYml ? '(pnx.yml)' : '(server.properties)')}`);
|
|
29
|
+
let content = readFileSync(configPath, 'utf-8');
|
|
30
|
+
// Strip BOM
|
|
31
|
+
if (content.charCodeAt(0) === 0xFEFF)
|
|
32
|
+
content = content.slice(1);
|
|
33
|
+
const lines = content.split('\n');
|
|
34
|
+
if (isYml) {
|
|
35
|
+
// Display YAML with syntax highlighting
|
|
36
|
+
for (let i = 0; i < lines.length; i++) {
|
|
37
|
+
const line = lines[i];
|
|
38
|
+
if (line.trim() === '' || line.trim().startsWith('#')) {
|
|
39
|
+
if (line.trim().startsWith('#')) {
|
|
40
|
+
console.log(` ${dim(line)}`);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
console.log();
|
|
44
|
+
}
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
// Key: value or nested key
|
|
48
|
+
const indent = line.match(/^(\s*)/)?.[1] || '';
|
|
49
|
+
const trimmed = line.trim();
|
|
50
|
+
const colonIdx = trimmed.indexOf(':');
|
|
51
|
+
if (colonIdx > 0) {
|
|
52
|
+
const key = trimmed.slice(0, colonIdx);
|
|
53
|
+
const rest = trimmed.slice(colonIdx + 1).trim();
|
|
54
|
+
const suffix = rest
|
|
55
|
+
? ` ${colorYamlValue(rest)}`
|
|
56
|
+
: '';
|
|
57
|
+
const prefix = indent ? chalk.dim(indent) : '';
|
|
58
|
+
console.log(` ${prefix}${chalk.hex('#6C8EBF')(key)}:${suffix}`);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
console.log(` ${chalk.dim(indent)}${chalk.white(trimmed)}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
// Display server.properties with highlighting
|
|
67
|
+
let inSection = false;
|
|
68
|
+
for (let i = 0; i < lines.length; i++) {
|
|
69
|
+
const line = lines[i];
|
|
70
|
+
if (line.startsWith('#') || line.trim() === '') {
|
|
71
|
+
const trimmed = line.replace(/^#\s*/, '').trim();
|
|
72
|
+
if (trimmed && !inSection) {
|
|
73
|
+
console.log(`\n ${dim(trimmed)}`);
|
|
74
|
+
inSection = true;
|
|
75
|
+
}
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
inSection = false;
|
|
79
|
+
const eqIdx = line.indexOf('=');
|
|
80
|
+
if (eqIdx > 0) {
|
|
81
|
+
const key = line.slice(0, eqIdx).trim();
|
|
82
|
+
const value = line.slice(eqIdx + 1).trim();
|
|
83
|
+
console.log(` ${highlight(key)} ${dim('=')} ${colorPropsValue(value)}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
console.log(`\n ${dim('─'.repeat(40))}`);
|
|
88
|
+
info(t('config.editHint', highlight(configPath)));
|
|
89
|
+
await pauseForExit();
|
|
90
|
+
}
|
|
91
|
+
function colorYamlValue(val) {
|
|
92
|
+
if (val === 'true')
|
|
93
|
+
return chalk.green(val);
|
|
94
|
+
if (val === 'false')
|
|
95
|
+
return chalk.red(val);
|
|
96
|
+
if (/^\d+(\.\d+)?$/.test(val))
|
|
97
|
+
return chalk.cyan(val);
|
|
98
|
+
if (val.startsWith('[') || val.startsWith('-'))
|
|
99
|
+
return chalk.hex('#E040FB')(val);
|
|
100
|
+
if (val.startsWith('"') && val.endsWith('"'))
|
|
101
|
+
return chalk.green(val);
|
|
102
|
+
if (val.startsWith("'") && val.endsWith("'"))
|
|
103
|
+
return chalk.green(val);
|
|
104
|
+
return chalk.white(val);
|
|
105
|
+
}
|
|
106
|
+
function colorPropsValue(val) {
|
|
107
|
+
if (val === 'true' || val === 'on')
|
|
108
|
+
return chalk.green(val);
|
|
109
|
+
if (val === 'false' || val === 'off')
|
|
110
|
+
return chalk.red(val);
|
|
111
|
+
if (/^\d+$/.test(val))
|
|
112
|
+
return chalk.cyan(val);
|
|
113
|
+
return chalk.white(val);
|
|
114
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function doctorCmd(): Promise<void>;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { existsSync, statSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { spawn } from 'node:child_process';
|
|
4
|
+
import { createSocket } from 'node:dgram';
|
|
5
|
+
import { header, success, error, info, warn, highlight, dim, step, divider } from '../utils/logger.js';
|
|
6
|
+
import { t } from '../lang/index.js';
|
|
7
|
+
import { resolveServerDir } from '../utils/server.js';
|
|
8
|
+
import { getInstalledPlugins } from '../utils/plugins.js';
|
|
9
|
+
import { pauseForExit } from '../utils/pause.js';
|
|
10
|
+
function checkPort(port) {
|
|
11
|
+
return new Promise((resolve) => {
|
|
12
|
+
const socket = createSocket('udp4');
|
|
13
|
+
socket.once('error', () => { socket.close(); resolve(false); });
|
|
14
|
+
socket.bind(port, '0.0.0.0', () => { socket.close(); resolve(true); });
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function checkJavaVersion() {
|
|
18
|
+
return new Promise((resolve) => {
|
|
19
|
+
const java = process.env.JAVA_HOME
|
|
20
|
+
? join(process.env.JAVA_HOME, 'bin', 'java')
|
|
21
|
+
: 'java';
|
|
22
|
+
const child = spawn(java, ['-version']);
|
|
23
|
+
let output = '';
|
|
24
|
+
child.on('error', () => resolve({ ok: false, version: '?', path: java }));
|
|
25
|
+
child.stderr.on('data', (data) => { output += data.toString(); });
|
|
26
|
+
child.on('close', () => {
|
|
27
|
+
const match = output.match(/(?:openjdk|java) version "?(?:1\.)?(\d+)/);
|
|
28
|
+
if (match) {
|
|
29
|
+
const ver = parseInt(match[1], 10);
|
|
30
|
+
resolve({ ok: ver >= 21, version: output.split('\n')[0]?.trim() || String(ver), path: java });
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
resolve({ ok: false, version: '?', path: java });
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
export async function doctorCmd() {
|
|
39
|
+
header(`🩺 ${t('doctor.title')}`);
|
|
40
|
+
// Java check
|
|
41
|
+
step(t('doctor.checkingJava'));
|
|
42
|
+
const java = await checkJavaVersion();
|
|
43
|
+
if (java.ok) {
|
|
44
|
+
success(t('doctor.javaOk', java.version));
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
warn(`Java ${highlight('21+')} required — ${dim(java.path)}`);
|
|
48
|
+
}
|
|
49
|
+
// Server detection
|
|
50
|
+
step(t('doctor.checkingServer'));
|
|
51
|
+
const serverPath = await resolveServerDir();
|
|
52
|
+
if (!serverPath) {
|
|
53
|
+
error(t('doctor.serverNotFound'));
|
|
54
|
+
await pauseForExit();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
success(`${t('doctor.serverFound')} ${dim(serverPath)}`);
|
|
58
|
+
// JAR check
|
|
59
|
+
step(t('doctor.checkingJar'));
|
|
60
|
+
const jarPath = join(serverPath, 'powernukkitx.jar');
|
|
61
|
+
if (existsSync(jarPath)) {
|
|
62
|
+
const size = statSync(jarPath).size;
|
|
63
|
+
const sizeMb = (size / 1024 / 1024).toFixed(1);
|
|
64
|
+
success(t('doctor.jarOk', sizeMb));
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
error(t('doctor.jarMissing'));
|
|
68
|
+
}
|
|
69
|
+
// pnx.yml check
|
|
70
|
+
step(t('doctor.checkingConfig'));
|
|
71
|
+
const ymlPath = join(serverPath, 'pnx.yml');
|
|
72
|
+
const propsPath = join(serverPath, 'server.properties');
|
|
73
|
+
if (existsSync(ymlPath)) {
|
|
74
|
+
success(t('doctor.configFound'));
|
|
75
|
+
}
|
|
76
|
+
else if (existsSync(propsPath)) {
|
|
77
|
+
info(t('doctor.configLegacy'));
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
warn(t('doctor.configMissing'));
|
|
81
|
+
}
|
|
82
|
+
// plugins dir
|
|
83
|
+
step(t('doctor.checkingPlugins'));
|
|
84
|
+
const pluginsDir = join(serverPath, 'plugins');
|
|
85
|
+
if (existsSync(pluginsDir)) {
|
|
86
|
+
const files = readdirSync(pluginsDir).filter(f => f.endsWith('.jar'));
|
|
87
|
+
success(t('doctor.pluginsOk', String(files.length)));
|
|
88
|
+
// Check for updates
|
|
89
|
+
const tracked = await getInstalledPlugins();
|
|
90
|
+
if (tracked.length > 0) {
|
|
91
|
+
info(t('doctor.pluginCheckHint', 'pnx plugin update'));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
info(t('doctor.pluginsMissing'));
|
|
96
|
+
}
|
|
97
|
+
// worlds dir
|
|
98
|
+
step(t('doctor.checkingWorlds'));
|
|
99
|
+
const worldsDir = join(serverPath, 'worlds');
|
|
100
|
+
if (existsSync(worldsDir)) {
|
|
101
|
+
const worlds = readdirSync(worldsDir).filter(f => statSync(join(worldsDir, f)).isDirectory());
|
|
102
|
+
info(t('doctor.worldsFound', String(worlds.length)));
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
info(t('doctor.worldsMissing'));
|
|
106
|
+
}
|
|
107
|
+
// Port check
|
|
108
|
+
step(t('doctor.checkingPort'));
|
|
109
|
+
const portFree = await checkPort(19132);
|
|
110
|
+
if (portFree) {
|
|
111
|
+
success(t('doctor.portFree'));
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
warn(t('doctor.portInUse', '19132'));
|
|
115
|
+
}
|
|
116
|
+
divider();
|
|
117
|
+
success(t('doctor.done'));
|
|
118
|
+
await pauseForExit();
|
|
119
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function infoCmd(): Promise<void>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { readdir } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { header, info, warn, table, highlight } from '../utils/logger.js';
|
|
6
|
+
import { t } from '../lang/index.js';
|
|
7
|
+
import { resolveServerDir } from '../utils/server.js';
|
|
8
|
+
import { pauseForExit } from '../utils/pause.js';
|
|
9
|
+
export async function infoCmd() {
|
|
10
|
+
header(`📊 ${t('info.title')}`);
|
|
11
|
+
const serverPath = await resolveServerDir();
|
|
12
|
+
const jarExists = serverPath !== null;
|
|
13
|
+
let plugins = [];
|
|
14
|
+
let worlds = [];
|
|
15
|
+
if (serverPath && existsSync(join(serverPath, 'plugins'))) {
|
|
16
|
+
const files = await readdir(join(serverPath, 'plugins'));
|
|
17
|
+
plugins = files.filter((f) => f.endsWith('.jar'));
|
|
18
|
+
}
|
|
19
|
+
if (serverPath && existsSync(join(serverPath, 'worlds'))) {
|
|
20
|
+
worlds = await readdir(join(serverPath, 'worlds'));
|
|
21
|
+
}
|
|
22
|
+
table([
|
|
23
|
+
[t('info.status'), jarExists ? chalk.green(`✔ ${t('info.installed')}`) : chalk.red(`✘ ${t('info.notInstalled')}`)],
|
|
24
|
+
[t('info.serverDir'), serverPath ? highlight(serverPath) : chalk.dim('—')],
|
|
25
|
+
[t('info.plugins'), `${plugins.length} ${t('info.plugins')}`],
|
|
26
|
+
[t('info.worlds'), `${worlds.length} ${t('info.worlds')}`],
|
|
27
|
+
]);
|
|
28
|
+
console.log();
|
|
29
|
+
if (jarExists) {
|
|
30
|
+
info(t('info.ready'));
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
warn(t('info.notInitialized'));
|
|
34
|
+
}
|
|
35
|
+
await pauseForExit();
|
|
36
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { mkdir } from 'node:fs/promises';
|
|
3
|
+
import { join, resolve } from 'node:path';
|
|
4
|
+
import { cwd } from 'node:process';
|
|
5
|
+
import { input, confirm } from '@inquirer/prompts';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import { header, success, dim, step, error } from '../utils/logger.js';
|
|
8
|
+
import { t } from '../lang/index.js';
|
|
9
|
+
import { getLatestRelease, findAsset, downloadFile, getStartScripts } from '../utils/github.js';
|
|
10
|
+
import { startCmd } from './start.js';
|
|
11
|
+
export async function initCmd(options) {
|
|
12
|
+
header(`⚡ ${t('init.title')}`);
|
|
13
|
+
const targetDir = options.dir
|
|
14
|
+
? resolve(cwd(), options.dir)
|
|
15
|
+
: resolve(cwd(), await input({
|
|
16
|
+
message: t('init.promptDir'),
|
|
17
|
+
default: 'pnx-server',
|
|
18
|
+
validate: (v) => {
|
|
19
|
+
if (!v.trim())
|
|
20
|
+
return 'Path is required';
|
|
21
|
+
const p = resolve(cwd(), v);
|
|
22
|
+
if (existsSync(join(p, 'powernukkitx.jar'))) {
|
|
23
|
+
return t('init.alreadyExists');
|
|
24
|
+
}
|
|
25
|
+
return true;
|
|
26
|
+
},
|
|
27
|
+
}));
|
|
28
|
+
const serverDir = resolve(cwd(), targetDir);
|
|
29
|
+
if (existsSync(join(serverDir, 'powernukkitx.jar'))) {
|
|
30
|
+
error(t('init.alreadyExists'));
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
step(t('init.fetchingInfo'));
|
|
35
|
+
const release = await getLatestRelease();
|
|
36
|
+
success(`${t('init.latestVersion')}: ${chalk.bold(release.tag_name)}`);
|
|
37
|
+
const asset = await findAsset(release, 'powernukkitx.jar');
|
|
38
|
+
if (!asset) {
|
|
39
|
+
error('powernukkitx.jar not found in latest release.');
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
await mkdir(serverDir, { recursive: true });
|
|
43
|
+
const jarDest = join(serverDir, 'powernukkitx.jar');
|
|
44
|
+
await downloadFile(asset.browser_download_url, jarDest, 'powernukkitx.jar');
|
|
45
|
+
success(t('init.downloaded', (asset.size / 1024 / 1024).toFixed(1)));
|
|
46
|
+
step(t('init.downloadingScripts'));
|
|
47
|
+
const scripts = getStartScripts();
|
|
48
|
+
for (const script of scripts) {
|
|
49
|
+
const dest = join(serverDir, script.name);
|
|
50
|
+
await downloadFile(script.url, dest, script.name);
|
|
51
|
+
}
|
|
52
|
+
success(t('init.scriptsDownloaded'));
|
|
53
|
+
console.log(`\n ${chalk.hex('#FFB347').bold(t('init.nextSteps'))}`);
|
|
54
|
+
console.log(` ${dim(' 1.')} ${chalk.hex('#FFB347')(`cd ${serverDir}`)}`);
|
|
55
|
+
console.log(` ${dim(' 2.')} ${chalk.hex('#FFB347')('pnx start')} ${dim(`# ${t('init.nextStepStart')}`)}`);
|
|
56
|
+
console.log(` ${dim(' 3.')} ${chalk.hex('#FFB347')('pnx plugin list')} ${dim(`# ${t('init.nextStepPlugins')}`)}`);
|
|
57
|
+
console.log(` ${dim(' 4.')} ${chalk.hex('#FFB347')('pnx plugin install <name>')} ${dim(`# ${t('init.nextStepInstall')}`)}`);
|
|
58
|
+
console.log();
|
|
59
|
+
success(t('init.success'));
|
|
60
|
+
const launchNow = await confirm({
|
|
61
|
+
message: t('init.launchPrompt'),
|
|
62
|
+
default: false,
|
|
63
|
+
});
|
|
64
|
+
if (launchNow) {
|
|
65
|
+
console.log();
|
|
66
|
+
await startCmd({});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
error(err.message);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare function pluginListCmd(options?: {
|
|
2
|
+
sort?: string;
|
|
3
|
+
limit?: number;
|
|
4
|
+
page?: number;
|
|
5
|
+
q?: string;
|
|
6
|
+
}): Promise<void>;
|
|
7
|
+
export declare function pluginSearchCmd(term?: string): Promise<void>;
|
|
8
|
+
export declare function pluginInfoCmd(slug?: string): Promise<void>;
|
|
9
|
+
export declare function pluginInstallCmd(names: string[]): Promise<void>;
|
|
10
|
+
export declare function pluginInstalledCmd(): Promise<void>;
|
|
11
|
+
export declare function pluginRemoveCmd(names: string[]): Promise<void>;
|
|
12
|
+
export declare function pluginUpdateCmd(names: string[]): Promise<void>;
|