lianrouter 2.2.0 → 2.2.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.
Files changed (2) hide show
  1. package/dist/cli.js +36 -12
  2. package/package.json +43 -43
package/dist/cli.js CHANGED
@@ -17,7 +17,7 @@ var package_default;
17
17
  var init_package = __esm(() => {
18
18
  package_default = {
19
19
  name: "lianrouter",
20
- version: "2.2.0",
20
+ version: "2.2.1",
21
21
  description: "LianRouter launcher: install, run and control the gateway from one command",
22
22
  type: "module",
23
23
  bin: {
@@ -482,7 +482,7 @@ class GitHubReleaseSource {
482
482
  };
483
483
  });
484
484
  return {
485
- version: newest.tag_name,
485
+ version: normalizeVersion(newest.tag_name),
486
486
  notesUrl: newest.html_url,
487
487
  ...newest.published_at.length > 0 ? { publishedAt: newest.published_at } : {},
488
488
  assets
@@ -507,7 +507,7 @@ var init_github_source = __esm(() => {
507
507
  });
508
508
 
509
509
  // cli/update/install.ts
510
- import { cp, mkdir as mkdir2, rename, rm as rm3, stat } from "fs/promises";
510
+ import { cp, mkdir as mkdir2, readdir as readdir2, rename, rm as rm3, stat } from "fs/promises";
511
511
  import { dirname, join as join2, relative, resolve as resolve2, sep as sep2 } from "path";
512
512
  async function pathExists(target) {
513
513
  try {
@@ -534,6 +534,26 @@ async function assertNotDevCheckout(installRoot) {
534
534
  throw new Error(`refusing to self-update ${root}: it is a source checkout (.git and src/main.ts present). ` + "Build locally with `bun run build` instead of installing a release over the working tree.");
535
535
  }
536
536
  }
537
+ async function sweepBackups(root, remove = rm3) {
538
+ const backupDir = join2(resolve2(root), BACKUP_DIR_NAME);
539
+ let entries;
540
+ try {
541
+ entries = await readdir2(backupDir);
542
+ } catch {
543
+ return;
544
+ }
545
+ let failed = false;
546
+ for (const entry of entries) {
547
+ await remove(join2(backupDir, entry), { recursive: true, force: true }).catch(() => {
548
+ failed = true;
549
+ });
550
+ }
551
+ if (!failed) {
552
+ await remove(backupDir, { recursive: true, force: true }).catch(() => {
553
+ return;
554
+ });
555
+ }
556
+ }
537
557
  async function installAtomically(options) {
538
558
  const root = resolve2(options.installRoot);
539
559
  const staged = resolve2(options.stagedDir);
@@ -590,7 +610,7 @@ async function installAtomically(options) {
590
610
  throw error;
591
611
  }
592
612
  onProgress?.({ percent: 100, message: "install complete" });
593
- await rm3(backupRoot, { recursive: true, force: true });
613
+ await sweepBackups(root, options.remove ?? rm3);
594
614
  }
595
615
  var BACKUP_DIR_NAME = ".backup";
596
616
  var init_install = () => {};
@@ -618,15 +638,19 @@ async function readInstalledVersion(installRoot) {
618
638
  if (typeof version !== "string" || version.trim().length === 0) {
619
639
  return;
620
640
  }
641
+ const normalized = normalizeVersion(version);
642
+ if (normalized.length === 0) {
643
+ return;
644
+ }
621
645
  return {
622
- version: version.trim(),
646
+ version: normalized,
623
647
  installedAt: typeof installedAt === "string" ? installedAt : "",
624
648
  assetName: typeof assetName === "string" ? assetName : ""
625
649
  };
626
650
  }
627
651
  async function writeInstalledVersion(installRoot, record) {
628
652
  const payload = {
629
- version: record.version,
653
+ version: normalizeVersion(record.version),
630
654
  installedAt: record.installedAt,
631
655
  assetName: record.assetName
632
656
  };
@@ -646,7 +670,7 @@ var init_version_file = __esm(() => {
646
670
  });
647
671
 
648
672
  // cli/update/engine.ts
649
- import { mkdtemp, readdir as readdir2, rm as rm4 } from "fs/promises";
673
+ import { mkdtemp, readdir as readdir3, rm as rm4 } from "fs/promises";
650
674
  import { tmpdir } from "os";
651
675
  import { join as join4 } from "path";
652
676
  function withinSlice(start, end, percent) {
@@ -700,7 +724,7 @@ async function resolveInstallCandidate(opts) {
700
724
  };
701
725
  }
702
726
  async function payloadEntries(stagedDir) {
703
- const entries = await readdir2(stagedDir, { withFileTypes: true });
727
+ const entries = await readdir3(stagedDir, { withFileTypes: true });
704
728
  return entries.map((entry) => entry.name);
705
729
  }
706
730
  async function runUpdate(opts) {
@@ -1572,7 +1596,7 @@ init_install();
1572
1596
  init_version_file();
1573
1597
  init_paths();
1574
1598
  import { statSync } from "fs";
1575
- import { mkdir as mkdir3, mkdtemp as mkdtemp2, readdir as readdir3, rm as rm5 } from "fs/promises";
1599
+ import { mkdir as mkdir3, mkdtemp as mkdtemp2, readdir as readdir4, rm as rm5 } from "fs/promises";
1576
1600
  import { tmpdir as tmpdir2 } from "os";
1577
1601
  import { join as join6 } from "path";
1578
1602
  var SLICE2 = {
@@ -1601,7 +1625,7 @@ function withinSlice2(start, end, percent) {
1601
1625
  return start + (end - start) * clamped / 100;
1602
1626
  }
1603
1627
  async function payloadEntries2(stagedDir) {
1604
- const entries = await readdir3(stagedDir, { withFileTypes: true });
1628
+ const entries = await readdir4(stagedDir, { withFileTypes: true });
1605
1629
  return entries.map((entry) => entry.name);
1606
1630
  }
1607
1631
  async function ensureGatewayInstalled(options) {
@@ -1990,7 +2014,7 @@ function buildMenuItems(input) {
1990
2014
  if (input.update !== undefined) {
1991
2015
  items.push({
1992
2016
  action: "update",
1993
- label: `Update to v${input.update.latest} (current: v${input.version})`
2017
+ label: `Update to v${input.update.latest} (current: v${input.update.current})`
1994
2018
  });
1995
2019
  }
1996
2020
  items.push({ action: "web", label: "Web UI (Open in Browser)" }, { action: "tui", label: "Terminal UI (Interactive CLI)" }, { action: "tray", label: "Hide to Tray (Background)" }, { action: "exit", label: "Exit" });
@@ -3271,7 +3295,7 @@ async function runInteractive(supervisor, options, runtime) {
3271
3295
  const action = await promptMenu({
3272
3296
  version: CLI_VERSION,
3273
3297
  port: supervisor.status.port,
3274
- update: update !== null && update.available ? { latest: update.latest } : undefined
3298
+ update: update !== null && update.available ? { latest: update.latest, current: update.current } : undefined
3275
3299
  });
3276
3300
  return await dispatch(action, supervisor, session, options, runtime);
3277
3301
  }
package/package.json CHANGED
@@ -1,43 +1,43 @@
1
- {
2
- "name": "lianrouter",
3
- "version": "2.2.0",
4
- "description": "LianRouter launcher: install, run and control the gateway from one command",
5
- "type": "module",
6
- "bin": {
7
- "lianrouter": "./dist/cli.js"
8
- },
9
- "engines": {
10
- "bun": ">=1.4.2"
11
- },
12
- "files": [
13
- "dist",
14
- "README.md"
15
- ],
16
- "scripts": {
17
- "build": "bun run ../scripts/build-cli.ts",
18
- "typecheck": "tsc --noEmit -p .",
19
- "postinstall": "echo lianrouter: the gateway binary installs on first run, not during this install",
20
- "prepublishOnly": "bun run build"
21
- },
22
- "repository": {
23
- "type": "git",
24
- "url": "git+https://github.com/ReXooGen/Lian-Router.git",
25
- "directory": "cli"
26
- },
27
- "bugs": {
28
- "url": "https://github.com/ReXooGen/Lian-Router/issues"
29
- },
30
- "homepage": "https://github.com/ReXooGen/Lian-Router#readme",
31
- "publishConfig": {
32
- "access": "public"
33
- },
34
- "keywords": [
35
- "lianrouter",
36
- "ai-gateway",
37
- "openai-compatible",
38
- "llm-router",
39
- "self-hosted",
40
- "cli",
41
- "launcher"
42
- ]
43
- }
1
+ {
2
+ "name": "lianrouter",
3
+ "version": "2.2.1",
4
+ "description": "LianRouter launcher: install, run and control the gateway from one command",
5
+ "type": "module",
6
+ "bin": {
7
+ "lianrouter": "./dist/cli.js"
8
+ },
9
+ "engines": {
10
+ "bun": ">=1.4.2"
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "README.md"
15
+ ],
16
+ "scripts": {
17
+ "build": "bun run ../scripts/build-cli.ts",
18
+ "typecheck": "tsc --noEmit -p .",
19
+ "postinstall": "echo lianrouter: the gateway binary installs on first run, not during this install",
20
+ "prepublishOnly": "bun run build"
21
+ },
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/ReXooGen/Lian-Router.git",
25
+ "directory": "cli"
26
+ },
27
+ "bugs": {
28
+ "url": "https://github.com/ReXooGen/Lian-Router/issues"
29
+ },
30
+ "homepage": "https://github.com/ReXooGen/Lian-Router#readme",
31
+ "publishConfig": {
32
+ "access": "public"
33
+ },
34
+ "keywords": [
35
+ "lianrouter",
36
+ "ai-gateway",
37
+ "openai-compatible",
38
+ "llm-router",
39
+ "self-hosted",
40
+ "cli",
41
+ "launcher"
42
+ ]
43
+ }