runbay 0.1.1 → 0.1.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/out/main/index.js
CHANGED
|
@@ -632,7 +632,6 @@ async function scanAll(onBatch, onStatus) {
|
|
|
632
632
|
const REGISTRY = process.env.RUNBAY_REGISTRY ?? "https://registry.npmjs.org";
|
|
633
633
|
const PKG = "runbay";
|
|
634
634
|
const SIM_CMD = process.env.RUNBAY_SELFUPDATE_CMD;
|
|
635
|
-
const SIMULATED = !!SIM_CMD;
|
|
636
635
|
let available = null;
|
|
637
636
|
function selfUpdateStatus() {
|
|
638
637
|
return available;
|
|
@@ -658,46 +657,76 @@ async function checkSelfUpdate() {
|
|
|
658
657
|
}
|
|
659
658
|
return available;
|
|
660
659
|
}
|
|
661
|
-
async function
|
|
660
|
+
async function globalRoot() {
|
|
662
661
|
try {
|
|
663
|
-
|
|
664
|
-
return electron.app.getAppPath().toLowerCase().startsWith(root.toLowerCase());
|
|
662
|
+
return (await run("npm", ["root", "-g"], { shim: true, timeout: 3e4 })).trim();
|
|
665
663
|
} catch {
|
|
666
|
-
return
|
|
664
|
+
return null;
|
|
667
665
|
}
|
|
668
666
|
}
|
|
667
|
+
async function installedGlobally() {
|
|
668
|
+
const root = await globalRoot();
|
|
669
|
+
return !!root && electron.app.getAppPath().toLowerCase().startsWith(root.toLowerCase());
|
|
670
|
+
}
|
|
671
|
+
function runCommand(command) {
|
|
672
|
+
return new Promise((resolve2, reject) => {
|
|
673
|
+
const child = node_child_process.spawn(command, { shell: true, windowsHide: true });
|
|
674
|
+
const timer = setTimeout(() => {
|
|
675
|
+
child.kill();
|
|
676
|
+
reject(new Error("npm timed out"));
|
|
677
|
+
}, 5 * 6e4);
|
|
678
|
+
child.on("error", reject);
|
|
679
|
+
child.on("close", (code) => {
|
|
680
|
+
clearTimeout(timer);
|
|
681
|
+
if (code === 0) resolve2();
|
|
682
|
+
else reject(new Error(`npm exited with code ${code}`));
|
|
683
|
+
});
|
|
684
|
+
});
|
|
685
|
+
}
|
|
669
686
|
async function applySelfUpdate() {
|
|
670
687
|
if (!available) return { state: "error", message: "No update pending" };
|
|
671
688
|
const target = available.latest;
|
|
672
689
|
const registryFlag = REGISTRY === "https://registry.npmjs.org" ? "" : ` --registry "${REGISTRY}"`;
|
|
673
|
-
|
|
674
|
-
|
|
690
|
+
if (SIM_CMD) {
|
|
691
|
+
try {
|
|
692
|
+
await runCommand(SIM_CMD);
|
|
693
|
+
} catch (err) {
|
|
694
|
+
return { state: "error", message: err instanceof Error ? err.message : String(err) };
|
|
695
|
+
}
|
|
696
|
+
available = null;
|
|
697
|
+
return { state: "done", message: `Updated to ${target} — restart to apply` };
|
|
698
|
+
}
|
|
699
|
+
if (!await installedGlobally()) {
|
|
675
700
|
return { state: "manual", message: `npm install -g ${PKG}@latest` };
|
|
676
701
|
}
|
|
702
|
+
const root = await globalRoot();
|
|
703
|
+
const shim = node_path.join(node_path.dirname(root), `${PKG}.cmd`);
|
|
704
|
+
const script = node_path.join(electron.app.getPath("userData"), "update.cmd");
|
|
705
|
+
const log = node_path.join(electron.app.getPath("userData"), "update.log");
|
|
706
|
+
const install = `call npm install -g ${PKG}@latest${registryFlag}`;
|
|
707
|
+
const body = [
|
|
708
|
+
"@echo off",
|
|
709
|
+
"ping -n 5 127.0.0.1 >nul",
|
|
710
|
+
// le temps que l'app se ferme et relâche ses fichiers
|
|
711
|
+
`${install} > "${log}" 2>&1`,
|
|
712
|
+
"if errorlevel 1 (",
|
|
713
|
+
" ping -n 31 127.0.0.1 >nul",
|
|
714
|
+
// le registre met parfois une minute à propager une publication prouvée
|
|
715
|
+
`${install} --prefer-online >> "${log}" 2>&1`,
|
|
716
|
+
")",
|
|
717
|
+
`start "" "${shim}"`,
|
|
718
|
+
'del "%~f0"',
|
|
719
|
+
""
|
|
720
|
+
].join("\r\n");
|
|
677
721
|
try {
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
const timer = setTimeout(() => {
|
|
681
|
-
child.kill();
|
|
682
|
-
reject(new Error("npm timed out"));
|
|
683
|
-
}, 5 * 6e4);
|
|
684
|
-
child.on("error", reject);
|
|
685
|
-
child.on("close", (code) => {
|
|
686
|
-
clearTimeout(timer);
|
|
687
|
-
if (code === 0) resolve2();
|
|
688
|
-
else reject(new Error(`npm exited with code ${code}`));
|
|
689
|
-
});
|
|
690
|
-
});
|
|
722
|
+
node_fs.writeFileSync(script, body);
|
|
723
|
+
node_child_process.spawn(script, { detached: true, stdio: "ignore", windowsHide: true }).unref();
|
|
691
724
|
} catch (err) {
|
|
692
725
|
return { state: "error", message: err instanceof Error ? err.message : String(err) };
|
|
693
726
|
}
|
|
694
727
|
available = null;
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
electron.app.relaunch();
|
|
698
|
-
electron.app.quit();
|
|
699
|
-
}, 1500);
|
|
700
|
-
return { state: "done", message: `Updated to ${target} — restarting…` };
|
|
728
|
+
setTimeout(() => electron.app.quit(), 1500);
|
|
729
|
+
return { state: "done", message: `Updating to ${target} — restarting…` };
|
|
701
730
|
}
|
|
702
731
|
let scanning = false;
|
|
703
732
|
let mainHooks = null;
|
|
@@ -827,6 +856,7 @@ function registerIpc(hooks) {
|
|
|
827
856
|
}
|
|
828
857
|
return settings.theme === "light" ? "light" : "dark";
|
|
829
858
|
});
|
|
859
|
+
electron.ipcMain.handle("app:version", () => electron.app.getVersion());
|
|
830
860
|
electron.ipcMain.handle("update:self:status", () => selfUpdateStatus());
|
|
831
861
|
electron.ipcMain.handle("update:self:check", () => checkSelfUpdate());
|
|
832
862
|
electron.ipcMain.handle("update:self:apply", () => applySelfUpdate());
|
package/out/preload/index.js
CHANGED
|
@@ -18,6 +18,7 @@ const api = {
|
|
|
18
18
|
welcomeAtStartup: (value) => electron.ipcRenderer.invoke("settings:welcome", value),
|
|
19
19
|
foregroundOnStart: (value) => electron.ipcRenderer.invoke("settings:foreground", value),
|
|
20
20
|
theme: (value) => electron.ipcRenderer.invoke("settings:theme", value),
|
|
21
|
+
appVersion: () => electron.ipcRenderer.invoke("app:version"),
|
|
21
22
|
selfUpdateStatus: () => electron.ipcRenderer.invoke("update:self:status"),
|
|
22
23
|
checkSelfUpdate: () => electron.ipcRenderer.invoke("update:self:check"),
|
|
23
24
|
applySelfUpdate: () => electron.ipcRenderer.invoke("update:self:apply"),
|
|
@@ -364,6 +364,13 @@ input {
|
|
|
364
364
|
justify-content: center;
|
|
365
365
|
}
|
|
366
366
|
|
|
367
|
+
/* Version installée de RunBay : visible sans avoir à chercher dans les menus. */
|
|
368
|
+
.sidebar-footer .version {
|
|
369
|
+
text-align: center;
|
|
370
|
+
font-size: 11px;
|
|
371
|
+
color: var(--text-dim);
|
|
372
|
+
}
|
|
373
|
+
|
|
367
374
|
/* Signal de mise à jour de RunBay sur le bouton Options : même jaune et même
|
|
368
375
|
halo pulsé que les mises à jour d'applications — un jaune veut toujours
|
|
369
376
|
dire « une information attend », jamais un simple décor. */
|
|
@@ -1205,6 +1212,14 @@ button.rail-badge.neutral:hover {
|
|
|
1205
1212
|
color: var(--warning);
|
|
1206
1213
|
}
|
|
1207
1214
|
|
|
1215
|
+
/* Entrée d'information pure (ex. version de RunBay) : grise, non cliquable. */
|
|
1216
|
+
.ctx-menu button:disabled,
|
|
1217
|
+
.ctx-menu button:disabled:hover {
|
|
1218
|
+
color: var(--text-dim);
|
|
1219
|
+
background: transparent;
|
|
1220
|
+
cursor: default;
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1208
1223
|
/* Interrupteur on/off d'un réglage, aligné à droite de l'entrée. */
|
|
1209
1224
|
.ctx-switch {
|
|
1210
1225
|
margin-left: auto;
|
|
@@ -14805,11 +14805,12 @@ function ContextMenu({
|
|
|
14805
14805
|
section.items.map((item) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
14806
14806
|
"button",
|
|
14807
14807
|
{
|
|
14808
|
-
className: item.danger ? "danger" : item.highlight ? "highlight" : "",
|
|
14808
|
+
className: item.disabled ? "disabled" : item.danger ? "danger" : item.highlight ? "highlight" : "",
|
|
14809
14809
|
"data-tip": item.tip,
|
|
14810
|
+
disabled: item.disabled,
|
|
14810
14811
|
onClick: () => {
|
|
14811
14812
|
if (item.toggle === void 0) onClose();
|
|
14812
|
-
item.onSelect();
|
|
14813
|
+
item.onSelect?.();
|
|
14813
14814
|
},
|
|
14814
14815
|
children: [
|
|
14815
14816
|
item.icon && /* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { name: item.icon, size: 14 }),
|
|
@@ -15037,6 +15038,10 @@ function Sidebar({
|
|
|
15037
15038
|
onQuit
|
|
15038
15039
|
}) {
|
|
15039
15040
|
const [menu, setMenu] = reactExports.useState(null);
|
|
15041
|
+
const [version, setVersion] = reactExports.useState("");
|
|
15042
|
+
reactExports.useEffect(() => {
|
|
15043
|
+
void window.api.appVersion().then(setVersion);
|
|
15044
|
+
}, []);
|
|
15040
15045
|
reactExports.useEffect(() => {
|
|
15041
15046
|
if (!menu) return;
|
|
15042
15047
|
const onDown = (e) => {
|
|
@@ -15061,6 +15066,13 @@ function Sidebar({
|
|
|
15061
15066
|
setMenu({ x: rect.left, y: rect.top });
|
|
15062
15067
|
};
|
|
15063
15068
|
const runBayItems = [];
|
|
15069
|
+
if (version) {
|
|
15070
|
+
runBayItems.push({
|
|
15071
|
+
label: `Version ${version}`,
|
|
15072
|
+
disabled: true,
|
|
15073
|
+
tip: "This is the version currently running"
|
|
15074
|
+
});
|
|
15075
|
+
}
|
|
15064
15076
|
if (selfUpdate) {
|
|
15065
15077
|
runBayItems.push({
|
|
15066
15078
|
label: selfUpdating ? "Updating RunBay…" : `Update RunBay to v${selfUpdate.latest}`,
|
|
@@ -15216,30 +15228,36 @@ RunBay reinstalls itself through npm`,
|
|
|
15216
15228
|
);
|
|
15217
15229
|
})
|
|
15218
15230
|
] }),
|
|
15219
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
15220
|
-
|
|
15221
|
-
|
|
15222
|
-
|
|
15223
|
-
|
|
15224
|
-
|
|
15225
|
-
|
|
15226
|
-
|
|
15227
|
-
|
|
15228
|
-
|
|
15229
|
-
|
|
15230
|
-
|
|
15231
|
-
|
|
15232
|
-
|
|
15233
|
-
|
|
15234
|
-
|
|
15235
|
-
|
|
15236
|
-
|
|
15237
|
-
|
|
15238
|
-
|
|
15239
|
-
|
|
15240
|
-
|
|
15241
|
-
|
|
15242
|
-
|
|
15231
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sidebar-footer", children: [
|
|
15232
|
+
collapsed ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
15233
|
+
"button",
|
|
15234
|
+
{
|
|
15235
|
+
className: "rail-badge neutral options-btn",
|
|
15236
|
+
onClick: openOptions,
|
|
15237
|
+
"data-tip": selfUpdate ? "Options — RunBay update available" : "Options",
|
|
15238
|
+
children: [
|
|
15239
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { name: "settings", size: 16 }),
|
|
15240
|
+
selfUpdate && !selfUpdating && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "self-dot" })
|
|
15241
|
+
]
|
|
15242
|
+
}
|
|
15243
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
15244
|
+
"button",
|
|
15245
|
+
{
|
|
15246
|
+
className: "btn secondary options-btn",
|
|
15247
|
+
onClick: openOptions,
|
|
15248
|
+
"data-tip": selfUpdate ? "Options — RunBay update available" : "Configure RunBay",
|
|
15249
|
+
children: [
|
|
15250
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { name: "settings" }),
|
|
15251
|
+
selfUpdate && !selfUpdating && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "self-dot" }),
|
|
15252
|
+
" Options"
|
|
15253
|
+
]
|
|
15254
|
+
}
|
|
15255
|
+
),
|
|
15256
|
+
version && !collapsed && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "version", children: [
|
|
15257
|
+
"RunBay v",
|
|
15258
|
+
version
|
|
15259
|
+
] })
|
|
15260
|
+
] }),
|
|
15243
15261
|
menu && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
15244
15262
|
ContextMenu,
|
|
15245
15263
|
{
|
package/out/renderer/index.html
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
http-equiv="Content-Security-Policy"
|
|
9
9
|
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
|
|
10
10
|
/>
|
|
11
|
-
<script type="module" crossorigin src="./assets/index-
|
|
12
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
11
|
+
<script type="module" crossorigin src="./assets/index-ew8Rong5.js"></script>
|
|
12
|
+
<link rel="stylesheet" crossorigin href="./assets/index-CVOPEsTH.css">
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|
|
15
15
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "runbay",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Not an installer. A launcher. Detect, launch, update and uninstall apps installed from the command line (npm, pnpm, yarn, bun, scoop) — in one modern window.",
|
|
5
5
|
"main": "./out/main/index.js",
|
|
6
6
|
"bin": {
|