@srouter/cli 0.1.3-rc.1 → 0.1.3-rc.3
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/bin/srouter.js +3 -37
- package/dist/index.js +105 -6
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/bin/srouter.js
CHANGED
|
@@ -2,48 +2,14 @@
|
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { spawn } from "node:child_process";
|
|
6
|
-
import { createRequire } from "node:module";
|
|
7
5
|
|
|
8
6
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
7
|
const distEntry = path.join(__dirname, "../dist/index.js");
|
|
10
|
-
const srcEntry = path.join(__dirname, "../src/index.ts");
|
|
11
8
|
|
|
12
9
|
if (fs.existsSync(distEntry)) {
|
|
13
10
|
await import("../dist/index.js");
|
|
14
11
|
} else {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
try {
|
|
18
|
-
const tsxPkg = require.resolve("tsx/package.json");
|
|
19
|
-
const distCli = path.join(path.dirname(tsxPkg), "dist/cli.mjs");
|
|
20
|
-
if (fs.existsSync(distCli)) {
|
|
21
|
-
tsxCli = distCli;
|
|
22
|
-
}
|
|
23
|
-
} catch {
|
|
24
|
-
const localBin = path.join(__dirname, "../node_modules/.bin/tsx");
|
|
25
|
-
if (fs.existsSync(localBin)) {
|
|
26
|
-
tsxCli = localBin;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (tsxCli && fs.existsSync(tsxCli)) {
|
|
31
|
-
const child = spawn(process.execPath, [tsxCli, srcEntry, ...process.argv.slice(2)], {
|
|
32
|
-
stdio: "inherit"
|
|
33
|
-
});
|
|
34
|
-
child.on("exit", (code) => {
|
|
35
|
-
process.exit(code ?? 0);
|
|
36
|
-
});
|
|
37
|
-
} else {
|
|
38
|
-
const child = spawn(
|
|
39
|
-
"pnpm",
|
|
40
|
-
["--filter", "@srouter/cli", "exec", "tsx", srcEntry, ...process.argv.slice(2)],
|
|
41
|
-
{
|
|
42
|
-
stdio: "inherit"
|
|
43
|
-
}
|
|
44
|
-
);
|
|
45
|
-
child.on("exit", (code) => {
|
|
46
|
-
process.exit(code ?? 0);
|
|
47
|
-
});
|
|
48
|
-
}
|
|
12
|
+
console.error("Error: @srouter/cli distribution entry not found at " + distEntry);
|
|
13
|
+
process.exit(1);
|
|
49
14
|
}
|
|
15
|
+
|
package/dist/index.js
CHANGED
|
@@ -2307,6 +2307,56 @@ function backupDb(source, label) {
|
|
|
2307
2307
|
p.log.step(`Backed up to ${pc.dim(backupPath)}`);
|
|
2308
2308
|
return backupPath;
|
|
2309
2309
|
}
|
|
2310
|
+
function getDownloadDirs() {
|
|
2311
|
+
const home = os5.homedir();
|
|
2312
|
+
const dirs = [
|
|
2313
|
+
path6.join(home, "Downloads"),
|
|
2314
|
+
path6.join(home, "download"),
|
|
2315
|
+
path6.join(home, "downloads"),
|
|
2316
|
+
path6.join(home, "Desktop")
|
|
2317
|
+
];
|
|
2318
|
+
if (process.platform === "win32") {
|
|
2319
|
+
if (process.env.USERPROFILE) {
|
|
2320
|
+
dirs.push(path6.join(process.env.USERPROFILE, "Downloads"));
|
|
2321
|
+
dirs.push(path6.join(process.env.USERPROFILE, "Desktop"));
|
|
2322
|
+
}
|
|
2323
|
+
}
|
|
2324
|
+
return Array.from(new Set(dirs.filter((d) => fs6.existsSync(d))));
|
|
2325
|
+
}
|
|
2326
|
+
function scanFor9RouterFiles() {
|
|
2327
|
+
const results = [];
|
|
2328
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2329
|
+
const addFile = (filePath, label) => {
|
|
2330
|
+
const resolved = path6.resolve(filePath);
|
|
2331
|
+
if (!seen.has(resolved) && fs6.existsSync(resolved)) {
|
|
2332
|
+
try {
|
|
2333
|
+
const stat = fs6.statSync(resolved);
|
|
2334
|
+
if (stat.isFile()) {
|
|
2335
|
+
seen.add(resolved);
|
|
2336
|
+
results.push({ path: resolved, label, mtime: stat.mtimeMs });
|
|
2337
|
+
}
|
|
2338
|
+
} catch {
|
|
2339
|
+
}
|
|
2340
|
+
}
|
|
2341
|
+
};
|
|
2342
|
+
for (const loc of NineRouterDbLocations) {
|
|
2343
|
+
addFile(loc, "Installed Database");
|
|
2344
|
+
}
|
|
2345
|
+
for (const downloadDir of getDownloadDirs()) {
|
|
2346
|
+
try {
|
|
2347
|
+
const files = fs6.readdirSync(downloadDir);
|
|
2348
|
+
for (const file of files) {
|
|
2349
|
+
const lower = file.toLowerCase();
|
|
2350
|
+
const fullPath = path6.join(downloadDir, file);
|
|
2351
|
+
if (lower.includes("9router") || lower.includes("srouter-backup") || lower.endsWith(".db") || lower.endsWith(".json") && lower.includes("backup")) {
|
|
2352
|
+
addFile(fullPath, path6.basename(downloadDir));
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2355
|
+
} catch {
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2358
|
+
return results.sort((a, b) => b.mtime - a.mtime);
|
|
2359
|
+
}
|
|
2310
2360
|
function findDatabase(candidates, label) {
|
|
2311
2361
|
for (const candidate of candidates) {
|
|
2312
2362
|
const fullPath = path6.resolve(candidate);
|
|
@@ -2351,11 +2401,56 @@ async function migrateDb(options) {
|
|
|
2351
2401
|
}
|
|
2352
2402
|
async function migrateNineRouter(options) {
|
|
2353
2403
|
p.intro("9Router \u2192 SRouter Database Migration");
|
|
2354
|
-
|
|
2404
|
+
let source = options.source && fs6.existsSync(options.source) ? path6.resolve(options.source) : null;
|
|
2405
|
+
if (!source) {
|
|
2406
|
+
const foundFiles = scanFor9RouterFiles();
|
|
2407
|
+
if (foundFiles.length === 1) {
|
|
2408
|
+
source = foundFiles[0].path;
|
|
2409
|
+
p.log.info(`Found 9Router file: ${pc.bold(source)} (${fileKb(source)}) [${foundFiles[0].label}]`);
|
|
2410
|
+
} else if (foundFiles.length > 1) {
|
|
2411
|
+
if (options.yes) {
|
|
2412
|
+
source = foundFiles[0].path;
|
|
2413
|
+
p.log.info(`Auto-selected latest 9Router file: ${pc.bold(source)} (${fileKb(source)})`);
|
|
2414
|
+
} else {
|
|
2415
|
+
const choice = await p.select({
|
|
2416
|
+
message: "Multiple 9Router database/backup files found. Select one to migrate:",
|
|
2417
|
+
options: [
|
|
2418
|
+
...foundFiles.map((f) => ({
|
|
2419
|
+
value: f.path,
|
|
2420
|
+
label: `${path6.basename(f.path)} (${fileKb(f.path)})`,
|
|
2421
|
+
hint: `${f.label} \u2022 ${f.path}`
|
|
2422
|
+
})),
|
|
2423
|
+
{ value: "custom", label: "Enter custom path manually..." }
|
|
2424
|
+
]
|
|
2425
|
+
});
|
|
2426
|
+
if (p.isCancel(choice)) {
|
|
2427
|
+
p.outro("Migration cancelled.");
|
|
2428
|
+
return;
|
|
2429
|
+
}
|
|
2430
|
+
if (choice === "custom") {
|
|
2431
|
+
const customPath = await p.text({
|
|
2432
|
+
message: "Enter path to 9Router .db or .json backup file:",
|
|
2433
|
+
validate: (val) => {
|
|
2434
|
+
if (!val || !fs6.existsSync(path6.resolve(val))) {
|
|
2435
|
+
return "File does not exist. Please check the path.";
|
|
2436
|
+
}
|
|
2437
|
+
}
|
|
2438
|
+
});
|
|
2439
|
+
if (p.isCancel(customPath) || !customPath) {
|
|
2440
|
+
p.outro("Migration cancelled.");
|
|
2441
|
+
return;
|
|
2442
|
+
}
|
|
2443
|
+
source = path6.resolve(customPath);
|
|
2444
|
+
} else {
|
|
2445
|
+
source = choice;
|
|
2446
|
+
}
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2449
|
+
}
|
|
2355
2450
|
if (!source) {
|
|
2356
|
-
p.log.error("No 9Router database found.");
|
|
2451
|
+
p.log.error("No 9Router database or backup file found.");
|
|
2357
2452
|
p.outro(
|
|
2358
|
-
"Pass the location explicitly: srouter migrate 9router --source /path/to/9router.
|
|
2453
|
+
"Pass the location explicitly: srouter migrate 9router --source /path/to/9router-backup.json"
|
|
2359
2454
|
);
|
|
2360
2455
|
process.exitCode = 1;
|
|
2361
2456
|
return;
|
|
@@ -2566,10 +2661,14 @@ function createCli() {
|
|
|
2566
2661
|
});
|
|
2567
2662
|
return program;
|
|
2568
2663
|
}
|
|
2569
|
-
|
|
2570
|
-
const
|
|
2571
|
-
|
|
2664
|
+
function runCli() {
|
|
2665
|
+
const isEntrypoint = process.argv[1]?.endsWith("srouter.js") || process.argv[1]?.endsWith("index.js") || process.argv[1]?.endsWith("index.ts") || process.argv[1]?.includes("/.bin/srouter") || process.argv[1]?.includes("/bin/srouter");
|
|
2666
|
+
if (isEntrypoint) {
|
|
2667
|
+
const program = createCli();
|
|
2668
|
+
program.parse(process.argv);
|
|
2669
|
+
}
|
|
2572
2670
|
}
|
|
2671
|
+
runCli();
|
|
2573
2672
|
export {
|
|
2574
2673
|
createCli
|
|
2575
2674
|
};
|