napcat-plugin-debug-cli 1.2.6 → 1.2.8
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/cli.mjs +59 -25
- package/package.json +1 -1
- package/vite.mjs +72 -22
package/cli.mjs
CHANGED
|
@@ -5141,7 +5141,7 @@ class RpcClient {
|
|
|
5141
5141
|
this.pending.delete(id);
|
|
5142
5142
|
reject(new Error("RPC timeout"));
|
|
5143
5143
|
}
|
|
5144
|
-
},
|
|
5144
|
+
}, 3e4);
|
|
5145
5145
|
});
|
|
5146
5146
|
}
|
|
5147
5147
|
}
|
|
@@ -5251,6 +5251,23 @@ function copyDirRecursive(src, dest) {
|
|
|
5251
5251
|
else fs.copyFileSync(srcPath, destPath);
|
|
5252
5252
|
}
|
|
5253
5253
|
}
|
|
5254
|
+
function collectFiles(dir, prefix = "") {
|
|
5255
|
+
const files = [];
|
|
5256
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
5257
|
+
const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
5258
|
+
const fullPath = path.join(dir, entry.name);
|
|
5259
|
+
if (entry.isDirectory()) {
|
|
5260
|
+
files.push(...collectFiles(fullPath, relPath));
|
|
5261
|
+
} else {
|
|
5262
|
+
files.push({
|
|
5263
|
+
path: relPath,
|
|
5264
|
+
content: fs.readFileSync(fullPath).toString("base64"),
|
|
5265
|
+
encoding: "base64"
|
|
5266
|
+
});
|
|
5267
|
+
}
|
|
5268
|
+
}
|
|
5269
|
+
return files;
|
|
5270
|
+
}
|
|
5254
5271
|
function countFiles(dir) {
|
|
5255
5272
|
let count = 0;
|
|
5256
5273
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
@@ -5259,7 +5276,7 @@ function countFiles(dir) {
|
|
|
5259
5276
|
}
|
|
5260
5277
|
return count;
|
|
5261
5278
|
}
|
|
5262
|
-
async function deployPlugin(projectDir, remotePluginPath, rpc) {
|
|
5279
|
+
async function deployPlugin(projectDir, remotePluginPath, rpc, supportsRemoteTransfer) {
|
|
5263
5280
|
const distDir = path.resolve(projectDir, "dist");
|
|
5264
5281
|
if (!fs.existsSync(distDir)) {
|
|
5265
5282
|
logErr(`dist/ 目录不存在: ${distDir}`);
|
|
@@ -5283,34 +5300,44 @@ async function deployPlugin(projectDir, remotePluginPath, rpc) {
|
|
|
5283
5300
|
logErr(`解析 dist/package.json 失败: ${e.message}`);
|
|
5284
5301
|
return false;
|
|
5285
5302
|
}
|
|
5286
|
-
|
|
5287
|
-
logInfo(`部署 ${co(pluginName, C.bold, C.cyan)} → ${co(destDir, C.dim)}`);
|
|
5303
|
+
logInfo(`部署 ${co(pluginName, C.bold, C.cyan)} → 远程插件目录`);
|
|
5288
5304
|
try {
|
|
5289
|
-
if (
|
|
5290
|
-
|
|
5305
|
+
if (supportsRemoteTransfer) {
|
|
5306
|
+
await rpc.call("removeDir", pluginName);
|
|
5307
|
+
const files = collectFiles(distDir, pluginName);
|
|
5308
|
+
await rpc.call("writeFiles", files);
|
|
5309
|
+
} else {
|
|
5310
|
+
const destPath = path.join(remotePluginPath, pluginName);
|
|
5311
|
+
if (fs.existsSync(destPath)) {
|
|
5312
|
+
fs.rmSync(destPath, { recursive: true, force: true });
|
|
5313
|
+
}
|
|
5314
|
+
copyDirRecursive(distDir, destPath);
|
|
5291
5315
|
}
|
|
5292
|
-
|
|
5293
|
-
logOk(`文件复制完成 (${countFiles(distDir)} 个文件)`);
|
|
5316
|
+
logOk(`文件部署完成 (${countFiles(distDir)} 个文件)`);
|
|
5294
5317
|
} catch (e) {
|
|
5295
|
-
logErr(
|
|
5318
|
+
logErr(`部署失败: ${e.message}`);
|
|
5296
5319
|
return false;
|
|
5297
5320
|
}
|
|
5298
5321
|
try {
|
|
5299
|
-
await rpc.call("reloadPlugin", pluginName);
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
logInfo("
|
|
5304
|
-
await rpc.call("loadDirectoryPlugin", pluginName);
|
|
5322
|
+
const ok = await rpc.call("reloadPlugin", pluginName);
|
|
5323
|
+
if (ok) {
|
|
5324
|
+
logOk(`${co(pluginName, C.green, C.bold)} 重载成功`);
|
|
5325
|
+
} else {
|
|
5326
|
+
logInfo("插件未注册或重载失败,尝试从目录加载...");
|
|
5305
5327
|
try {
|
|
5306
|
-
await rpc.call("
|
|
5307
|
-
|
|
5308
|
-
|
|
5328
|
+
await rpc.call("loadDirectoryPlugin", pluginName);
|
|
5329
|
+
try {
|
|
5330
|
+
await rpc.call("setPluginStatus", pluginName, true);
|
|
5331
|
+
await rpc.call("loadPluginById", pluginName);
|
|
5332
|
+
} catch {
|
|
5333
|
+
}
|
|
5334
|
+
logOk(`${co(pluginName, C.green, C.bold)} 首次加载成功`);
|
|
5335
|
+
} catch (e2) {
|
|
5336
|
+
logWarn(`自动加载失败: ${e2.message},请手动 load ${pluginName}`);
|
|
5309
5337
|
}
|
|
5310
|
-
logOk(`${co(pluginName, C.green, C.bold)} 首次加载成功`);
|
|
5311
|
-
} catch (e2) {
|
|
5312
|
-
logWarn(`自动加载失败: ${e2.message},请手动 load ${pluginName}`);
|
|
5313
5338
|
}
|
|
5339
|
+
} catch (e) {
|
|
5340
|
+
logErr(`重载失败: ${e.message}`);
|
|
5314
5341
|
}
|
|
5315
5342
|
return true;
|
|
5316
5343
|
}
|
|
@@ -5329,6 +5356,7 @@ async function main() {
|
|
|
5329
5356
|
let rpc = null;
|
|
5330
5357
|
let watcher = null;
|
|
5331
5358
|
let remotePluginPath = null;
|
|
5359
|
+
let supportsRemoteTransfer = false;
|
|
5332
5360
|
const dirToId = /* @__PURE__ */ new Map();
|
|
5333
5361
|
async function refreshMap() {
|
|
5334
5362
|
if (!rpc) return;
|
|
@@ -5366,8 +5394,14 @@ async function main() {
|
|
|
5366
5394
|
} catch (e) {
|
|
5367
5395
|
logWarn(`获取信息失败: ${e.message}`);
|
|
5368
5396
|
}
|
|
5397
|
+
try {
|
|
5398
|
+
await rpc.call("removeDir", "__probe_nonexistent__");
|
|
5399
|
+
supportsRemoteTransfer = true;
|
|
5400
|
+
} catch {
|
|
5401
|
+
supportsRemoteTransfer = false;
|
|
5402
|
+
}
|
|
5369
5403
|
if (opts.deploy && remotePluginPath && rpc) {
|
|
5370
|
-
const ok = await deployPlugin(path.resolve(opts.deploy), remotePluginPath, rpc);
|
|
5404
|
+
const ok = await deployPlugin(path.resolve(opts.deploy), remotePluginPath, rpc, supportsRemoteTransfer);
|
|
5371
5405
|
ws.close(1e3);
|
|
5372
5406
|
process.exit(ok ? 0 : 1);
|
|
5373
5407
|
}
|
|
@@ -5378,7 +5412,7 @@ async function main() {
|
|
|
5378
5412
|
watcher = createWatcher(remotePluginPath, onFileChange);
|
|
5379
5413
|
watcher.start();
|
|
5380
5414
|
}
|
|
5381
|
-
startRepl(rpc, watcher, remotePluginPath, onFileChange);
|
|
5415
|
+
startRepl(rpc, watcher, remotePluginPath, onFileChange, supportsRemoteTransfer);
|
|
5382
5416
|
}
|
|
5383
5417
|
if (msg.method === "event" && opts.verbose) {
|
|
5384
5418
|
logInfo(`事件: ${JSON.stringify(msg.params).substring(0, 100)}`);
|
|
@@ -5399,7 +5433,7 @@ async function main() {
|
|
|
5399
5433
|
process.exit(0);
|
|
5400
5434
|
});
|
|
5401
5435
|
}
|
|
5402
|
-
function startRepl(rpc, watcher, remotePath, onFileChange) {
|
|
5436
|
+
function startRepl(rpc, watcher, remotePath, onFileChange, supportsRemoteTransfer) {
|
|
5403
5437
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout, prompt: co("debug> ", C.cyan) });
|
|
5404
5438
|
rl.prompt();
|
|
5405
5439
|
rl.on("line", async (line) => {
|
|
@@ -5484,7 +5518,7 @@ function startRepl(rpc, watcher, remotePath, onFileChange) {
|
|
|
5484
5518
|
break;
|
|
5485
5519
|
}
|
|
5486
5520
|
const dir = args[0] || ".";
|
|
5487
|
-
await deployPlugin(path.resolve(dir), remotePath, rpc);
|
|
5521
|
+
await deployPlugin(path.resolve(dir), remotePath, rpc, supportsRemoteTransfer);
|
|
5488
5522
|
break;
|
|
5489
5523
|
}
|
|
5490
5524
|
case "watch": {
|
package/package.json
CHANGED
package/vite.mjs
CHANGED
|
@@ -52,7 +52,7 @@ class SimpleRpcClient {
|
|
|
52
52
|
this.pending.delete(id);
|
|
53
53
|
reject(new Error("RPC timeout"));
|
|
54
54
|
}
|
|
55
|
-
},
|
|
55
|
+
}, 3e4);
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
get connected() {
|
|
@@ -82,6 +82,23 @@ function countFiles(dir) {
|
|
|
82
82
|
}
|
|
83
83
|
return count;
|
|
84
84
|
}
|
|
85
|
+
function collectFiles(dir, prefix = "") {
|
|
86
|
+
const files = [];
|
|
87
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
88
|
+
const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
89
|
+
const fullPath = path.join(dir, entry.name);
|
|
90
|
+
if (entry.isDirectory()) {
|
|
91
|
+
files.push(...collectFiles(fullPath, relPath));
|
|
92
|
+
} else {
|
|
93
|
+
files.push({
|
|
94
|
+
path: relPath,
|
|
95
|
+
content: fs.readFileSync(fullPath).toString("base64"),
|
|
96
|
+
encoding: "base64"
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return files;
|
|
101
|
+
}
|
|
85
102
|
function napcatHmrPlugin(options = {}) {
|
|
86
103
|
const {
|
|
87
104
|
wsUrl = "ws://127.0.0.1:8998",
|
|
@@ -93,6 +110,7 @@ function napcatHmrPlugin(options = {}) {
|
|
|
93
110
|
const webuiConfigs = webui ? Array.isArray(webui) ? webui : [webui] : [];
|
|
94
111
|
let rpc = null;
|
|
95
112
|
let remotePluginPath = null;
|
|
113
|
+
let supportsRemoteTransfer = false;
|
|
96
114
|
let connecting = false;
|
|
97
115
|
let config;
|
|
98
116
|
let isFirstBuild = true;
|
|
@@ -134,6 +152,12 @@ function napcatHmrPlugin(options = {}) {
|
|
|
134
152
|
log(`远程插件目录: ${co(info.pluginPath, C.dim)}`);
|
|
135
153
|
} catch {
|
|
136
154
|
}
|
|
155
|
+
try {
|
|
156
|
+
await rpc.call("removeDir", "__probe_nonexistent__");
|
|
157
|
+
supportsRemoteTransfer = true;
|
|
158
|
+
} catch {
|
|
159
|
+
supportsRemoteTransfer = false;
|
|
160
|
+
}
|
|
137
161
|
connecting = false;
|
|
138
162
|
resolve(true);
|
|
139
163
|
}
|
|
@@ -148,6 +172,7 @@ function napcatHmrPlugin(options = {}) {
|
|
|
148
172
|
ws.on("close", () => {
|
|
149
173
|
rpc = null;
|
|
150
174
|
remotePluginPath = null;
|
|
175
|
+
supportsRemoteTransfer = false;
|
|
151
176
|
connecting = false;
|
|
152
177
|
});
|
|
153
178
|
});
|
|
@@ -178,15 +203,31 @@ function napcatHmrPlugin(options = {}) {
|
|
|
178
203
|
logErr("解析 dist/package.json 失败");
|
|
179
204
|
return;
|
|
180
205
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
206
|
+
if (supportsRemoteTransfer) {
|
|
207
|
+
try {
|
|
208
|
+
await rpc.call("removeDir", pluginName);
|
|
209
|
+
} catch (e) {
|
|
210
|
+
logErr(`清理远程目录失败: ${e.message}`);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
try {
|
|
214
|
+
const files = collectFiles(distDir, pluginName);
|
|
215
|
+
await rpc.call("writeFiles", files);
|
|
216
|
+
} catch (e) {
|
|
217
|
+
logErr(`传输文件失败: ${e.message}`);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
} else {
|
|
221
|
+
const destDir = path.join(remotePluginPath, pluginName);
|
|
222
|
+
try {
|
|
223
|
+
if (fs.existsSync(destDir)) {
|
|
224
|
+
fs.rmSync(destDir, { recursive: true, force: true });
|
|
225
|
+
}
|
|
226
|
+
copyDirRecursive(distDir, destDir);
|
|
227
|
+
} catch (e) {
|
|
228
|
+
logErr(`复制文件失败: ${e.message}`);
|
|
229
|
+
return;
|
|
185
230
|
}
|
|
186
|
-
copyDirRecursive(distDir, destDir);
|
|
187
|
-
} catch (e) {
|
|
188
|
-
logErr(`复制文件失败: ${e.message}`);
|
|
189
|
-
return;
|
|
190
231
|
}
|
|
191
232
|
const projectRoot = config.root || process.cwd();
|
|
192
233
|
for (const wc of webuiConfigs) {
|
|
@@ -214,20 +255,23 @@ function napcatHmrPlugin(options = {}) {
|
|
|
214
255
|
continue;
|
|
215
256
|
}
|
|
216
257
|
try {
|
|
217
|
-
|
|
218
|
-
|
|
258
|
+
if (supportsRemoteTransfer) {
|
|
259
|
+
const webuiFiles = collectFiles(webuiDistDir, `${pluginName}/${webuiTargetDir}`);
|
|
260
|
+
await rpc.call("writeFiles", webuiFiles);
|
|
261
|
+
} else {
|
|
262
|
+
const destDir = path.join(remotePluginPath, pluginName);
|
|
263
|
+
const webuiDestDir = path.join(destDir, webuiTargetDir);
|
|
264
|
+
copyDirRecursive(webuiDistDir, webuiDestDir);
|
|
265
|
+
}
|
|
219
266
|
logOk(`WebUI (${webuiTargetDir}) 已部署 (${countFiles(webuiDistDir)} 个文件)`);
|
|
220
267
|
} catch (e) {
|
|
221
268
|
logErr(`WebUI (${webuiTargetDir}) 部署失败: ${e.message}`);
|
|
222
269
|
}
|
|
223
270
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
if (reloaded === false) {
|
|
227
|
-
throw new Error("not registered");
|
|
228
|
-
}
|
|
271
|
+
const reloaded = await rpc.call("reloadPlugin", pluginName);
|
|
272
|
+
if (reloaded) {
|
|
229
273
|
logHmr(`${co(pluginName, C.green, C.bold)} 已重载 (${countFiles(distDir)} 个文件)`);
|
|
230
|
-
}
|
|
274
|
+
} else {
|
|
231
275
|
try {
|
|
232
276
|
await rpc.call("loadDirectoryPlugin", pluginName);
|
|
233
277
|
try {
|
|
@@ -260,7 +304,6 @@ function napcatHmrPlugin(options = {}) {
|
|
|
260
304
|
} catch {
|
|
261
305
|
return;
|
|
262
306
|
}
|
|
263
|
-
const destDir = path.join(remotePluginPath, pluginName);
|
|
264
307
|
const projectRoot = config.root || process.cwd();
|
|
265
308
|
let hasChanges = false;
|
|
266
309
|
for (const wc of webuiConfigs) {
|
|
@@ -288,11 +331,18 @@ function napcatHmrPlugin(options = {}) {
|
|
|
288
331
|
continue;
|
|
289
332
|
}
|
|
290
333
|
try {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
334
|
+
if (supportsRemoteTransfer) {
|
|
335
|
+
await rpc.call("removeDir", `${pluginName}/${webuiTargetDir}`);
|
|
336
|
+
const webuiFiles = collectFiles(webuiDistDir, `${pluginName}/${webuiTargetDir}`);
|
|
337
|
+
await rpc.call("writeFiles", webuiFiles);
|
|
338
|
+
} else {
|
|
339
|
+
const destDir = path.join(remotePluginPath, pluginName);
|
|
340
|
+
const webuiDestDir = path.join(destDir, webuiTargetDir);
|
|
341
|
+
if (fs.existsSync(webuiDestDir)) {
|
|
342
|
+
fs.rmSync(webuiDestDir, { recursive: true, force: true });
|
|
343
|
+
}
|
|
344
|
+
copyDirRecursive(webuiDistDir, webuiDestDir);
|
|
294
345
|
}
|
|
295
|
-
copyDirRecursive(webuiDistDir, webuiDestDir);
|
|
296
346
|
logOk(`WebUI (${webuiTargetDir}) 已部署 (${countFiles(webuiDistDir)} 个文件)`);
|
|
297
347
|
hasChanges = true;
|
|
298
348
|
} catch (e) {
|