rechrome 1.31.5 → 1.31.6
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/package.json +1 -1
- package/rechrome.js +47 -4
- package/rechrome.ts +47 -4
- package/serve.js +1 -1
- package/serve.ts +1 -1
package/package.json
CHANGED
package/rechrome.js
CHANGED
|
@@ -8,7 +8,7 @@ import { createHash, randomBytes } from "crypto";
|
|
|
8
8
|
import { mkdirSync, appendFileSync, existsSync, realpathSync, accessSync, cpSync, unlinkSync, readFileSync, readdirSync, renameSync, rmdirSync, constants as fsConstants } from "fs";
|
|
9
9
|
import { hostname, homedir, networkInterfaces } from "os";
|
|
10
10
|
import { isIPv4 } from "net";
|
|
11
|
-
import { join, basename, dirname } from "path";
|
|
11
|
+
import { join, basename, dirname, resolve } from "path";
|
|
12
12
|
import { pathToFileURL } from "url";
|
|
13
13
|
import { createRequire } from "node:module";
|
|
14
14
|
import { spawn as cpSpawn } from "child_process";
|
|
@@ -2053,9 +2053,48 @@ function oxmgrVersion(bin: string): string | null {
|
|
|
2053
2053
|
// RECH_DAEMON_MANAGER override — lives in ./daemon-manager.js (pure + tested);
|
|
2054
2054
|
// here we just supply the runtime inputs (what's on PATH, the oxmgr version).
|
|
2055
2055
|
let _daemonMgr: DaemonManager | undefined;
|
|
2056
|
+
/**
|
|
2057
|
+
* The first oxmgr that actually runs. PATH order alone isn't enough: a stale global shim
|
|
2058
|
+
* (e.g. bun's, printing "oxmgr binary is missing") can shadow a working build, and npm's
|
|
2059
|
+
* `oxmgr.cmd` re-parses argv through cmd.exe, so real executables come first. RECH_OXMGR
|
|
2060
|
+
* names one explicitly (a path, or a command looked up on PATH). The successful probe's
|
|
2061
|
+
* output seeds the version cache, so `--version` runs once.
|
|
2062
|
+
*/
|
|
2063
|
+
function findWorkingOxmgr(): string | null {
|
|
2064
|
+
const ext = IS_WINDOWS ? ".exe" : "";
|
|
2065
|
+
// Windows PATH entries may be quoted ("C:\Program Files\x"); quotes break the joined path.
|
|
2066
|
+
const dirs = (process.env.PATH ?? "").split(IS_WINDOWS ? ";" : ":").map(d => d.trim().replace(/^"(.*)"$/, "$1")).filter(Boolean);
|
|
2067
|
+
const override = process.env.RECH_OXMGR;
|
|
2068
|
+
const candidates = [
|
|
2069
|
+
override && (/[\\/]/.test(override) ? resolve(override) : Bun.which(override)),
|
|
2070
|
+
...dirs.map(d => join(d, `oxmgr${ext}`)),
|
|
2071
|
+
// The vendored binary inside a global npm / bun install of the `oxmgr` package
|
|
2072
|
+
// (npm: <dir>/node_modules on Windows, <prefix>/lib/node_modules beside <prefix>/bin elsewhere).
|
|
2073
|
+
...dirs.map(d => join(d, "node_modules", "oxmgr", "vendor", `oxmgr${ext}`)),
|
|
2074
|
+
...(IS_WINDOWS ? [] : dirs.map(d => join(d, "..", "lib", "node_modules", "oxmgr", "vendor", "oxmgr"))),
|
|
2075
|
+
join(HOME, ".bun", "install", "global", "node_modules", "oxmgr", "vendor", `oxmgr${ext}`),
|
|
2076
|
+
].filter((p): p is string => !!p && existsSync(p));
|
|
2077
|
+
const works = (p: string) => {
|
|
2078
|
+
try {
|
|
2079
|
+
const r = Bun.spawnSync([p, "--version"], { stdout: "pipe", stderr: "ignore", windowsHide: true });
|
|
2080
|
+
if (r.exitCode !== 0) return false;
|
|
2081
|
+
const m = /(\d+\.\d+\.\d+[^\s]*)/.exec(r.stdout?.toString() ?? "");
|
|
2082
|
+
_oxmgrVersion = m ? m[1]! : null;
|
|
2083
|
+
return true;
|
|
2084
|
+
} catch { return false; }
|
|
2085
|
+
};
|
|
2086
|
+
const exe = [...new Set(candidates)].find(works);
|
|
2087
|
+
if (exe) return exe;
|
|
2088
|
+
// Last resort (Windows): a working shim such as npm's oxmgr.cmd, but never over a working
|
|
2089
|
+
// pm2 — cmd.exe re-parses a shim's argv (see runPm).
|
|
2090
|
+
if (!IS_WINDOWS || Bun.which("pm2")) return null;
|
|
2091
|
+
const shim = Bun.which("oxmgr");
|
|
2092
|
+
return shim && works(shim) ? shim : null;
|
|
2093
|
+
}
|
|
2094
|
+
|
|
2056
2095
|
function daemonManager(): DaemonManager {
|
|
2057
2096
|
if (_daemonMgr) return _daemonMgr;
|
|
2058
|
-
const oxmgrBin =
|
|
2097
|
+
const oxmgrBin = findWorkingOxmgr();
|
|
2059
2098
|
const pm2Bin = Bun.which("pm2");
|
|
2060
2099
|
_daemonMgr = pickDaemonManager({
|
|
2061
2100
|
oxmgrBin,
|
|
@@ -2074,6 +2113,10 @@ function daemonManager(): DaemonManager {
|
|
|
2074
2113
|
// the managed process (it has no per-var flag like oxmgr's --env), so install
|
|
2075
2114
|
// passes daemon env this way.
|
|
2076
2115
|
async function runPm(mgr: DaemonManager, args: string[], env?: Record<string, string>): Promise<number> {
|
|
2116
|
+
// A .cmd/.bat shim runs through cmd.exe, which treats & | < > ^ in an argument as syntax
|
|
2117
|
+
// (e.g. the &s in a RECHROME_URL passed with --env): fail clearly instead of mangling it.
|
|
2118
|
+
if (/\.(cmd|bat)$/i.test(mgr.bin) && args.some(a => /[&|<>^]/.test(a)))
|
|
2119
|
+
throw new Error(`${mgr.bin} is a cmd.exe shim, which would mangle an argument containing & | < > ^. Install the ${mgr.id} executable (or set RECH_OXMGR to it) and try again.`);
|
|
2077
2120
|
const proc = Bun.spawn([mgr.bin, ...args], {
|
|
2078
2121
|
stdout: "inherit",
|
|
2079
2122
|
stderr: "inherit",
|
|
@@ -2176,7 +2219,7 @@ async function ensureDaemonManager(ask: (q: string, def?: string) => Promise<str
|
|
|
2176
2219
|
});
|
|
2177
2220
|
const code = await proc.exited;
|
|
2178
2221
|
if (code !== 0) throw new Error(`\`${command.join(" ")}\` failed (exit code ${code}). Resolve the installation error, then rerun setup.`);
|
|
2179
|
-
if (!
|
|
2222
|
+
if (!findWorkingOxmgr()) {
|
|
2180
2223
|
throw new Error("oxmgr was installed but is not on PATH. Add the package manager's global bin directory to PATH, then rerun setup.");
|
|
2181
2224
|
}
|
|
2182
2225
|
_daemonMgr = undefined;
|
|
@@ -2295,7 +2338,7 @@ async function daemonUninstall(): Promise<void> {
|
|
|
2295
2338
|
const mgr = daemonManager();
|
|
2296
2339
|
for (const name of [PM_PROCESS_NAME, ...LEGACY_PROCESS_NAMES]) await runPm(mgr, ["delete", name]);
|
|
2297
2340
|
if (mgr.id === "pm2") await runPm(mgr, ["save", "--force"]); // an emptied list must still overwrite the dump
|
|
2298
|
-
|
|
2341
|
+
// oxmgr's boot/login service is left installed: every other oxmgr-managed process depends on it.
|
|
2299
2342
|
console.log(`Removed ${mgr.id} process: ${PM_PROCESS_NAME}`);
|
|
2300
2343
|
}
|
|
2301
2344
|
|
package/rechrome.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { createHash, randomBytes } from "crypto";
|
|
|
8
8
|
import { mkdirSync, appendFileSync, existsSync, realpathSync, accessSync, cpSync, unlinkSync, readFileSync, readdirSync, renameSync, rmdirSync, constants as fsConstants } from "fs";
|
|
9
9
|
import { hostname, homedir, networkInterfaces } from "os";
|
|
10
10
|
import { isIPv4 } from "net";
|
|
11
|
-
import { join, basename, dirname } from "path";
|
|
11
|
+
import { join, basename, dirname, resolve } from "path";
|
|
12
12
|
import { pathToFileURL } from "url";
|
|
13
13
|
import { createRequire } from "node:module";
|
|
14
14
|
import { spawn as cpSpawn } from "child_process";
|
|
@@ -2053,9 +2053,48 @@ function oxmgrVersion(bin: string): string | null {
|
|
|
2053
2053
|
// RECH_DAEMON_MANAGER override — lives in ./daemon-manager.ts (pure + tested);
|
|
2054
2054
|
// here we just supply the runtime inputs (what's on PATH, the oxmgr version).
|
|
2055
2055
|
let _daemonMgr: DaemonManager | undefined;
|
|
2056
|
+
/**
|
|
2057
|
+
* The first oxmgr that actually runs. PATH order alone isn't enough: a stale global shim
|
|
2058
|
+
* (e.g. bun's, printing "oxmgr binary is missing") can shadow a working build, and npm's
|
|
2059
|
+
* `oxmgr.cmd` re-parses argv through cmd.exe, so real executables come first. RECH_OXMGR
|
|
2060
|
+
* names one explicitly (a path, or a command looked up on PATH). The successful probe's
|
|
2061
|
+
* output seeds the version cache, so `--version` runs once.
|
|
2062
|
+
*/
|
|
2063
|
+
function findWorkingOxmgr(): string | null {
|
|
2064
|
+
const ext = IS_WINDOWS ? ".exe" : "";
|
|
2065
|
+
// Windows PATH entries may be quoted ("C:\Program Files\x"); quotes break the joined path.
|
|
2066
|
+
const dirs = (process.env.PATH ?? "").split(IS_WINDOWS ? ";" : ":").map(d => d.trim().replace(/^"(.*)"$/, "$1")).filter(Boolean);
|
|
2067
|
+
const override = process.env.RECH_OXMGR;
|
|
2068
|
+
const candidates = [
|
|
2069
|
+
override && (/[\\/]/.test(override) ? resolve(override) : Bun.which(override)),
|
|
2070
|
+
...dirs.map(d => join(d, `oxmgr${ext}`)),
|
|
2071
|
+
// The vendored binary inside a global npm / bun install of the `oxmgr` package
|
|
2072
|
+
// (npm: <dir>/node_modules on Windows, <prefix>/lib/node_modules beside <prefix>/bin elsewhere).
|
|
2073
|
+
...dirs.map(d => join(d, "node_modules", "oxmgr", "vendor", `oxmgr${ext}`)),
|
|
2074
|
+
...(IS_WINDOWS ? [] : dirs.map(d => join(d, "..", "lib", "node_modules", "oxmgr", "vendor", "oxmgr"))),
|
|
2075
|
+
join(HOME, ".bun", "install", "global", "node_modules", "oxmgr", "vendor", `oxmgr${ext}`),
|
|
2076
|
+
].filter((p): p is string => !!p && existsSync(p));
|
|
2077
|
+
const works = (p: string) => {
|
|
2078
|
+
try {
|
|
2079
|
+
const r = Bun.spawnSync([p, "--version"], { stdout: "pipe", stderr: "ignore", windowsHide: true });
|
|
2080
|
+
if (r.exitCode !== 0) return false;
|
|
2081
|
+
const m = /(\d+\.\d+\.\d+[^\s]*)/.exec(r.stdout?.toString() ?? "");
|
|
2082
|
+
_oxmgrVersion = m ? m[1]! : null;
|
|
2083
|
+
return true;
|
|
2084
|
+
} catch { return false; }
|
|
2085
|
+
};
|
|
2086
|
+
const exe = [...new Set(candidates)].find(works);
|
|
2087
|
+
if (exe) return exe;
|
|
2088
|
+
// Last resort (Windows): a working shim such as npm's oxmgr.cmd, but never over a working
|
|
2089
|
+
// pm2 — cmd.exe re-parses a shim's argv (see runPm).
|
|
2090
|
+
if (!IS_WINDOWS || Bun.which("pm2")) return null;
|
|
2091
|
+
const shim = Bun.which("oxmgr");
|
|
2092
|
+
return shim && works(shim) ? shim : null;
|
|
2093
|
+
}
|
|
2094
|
+
|
|
2056
2095
|
function daemonManager(): DaemonManager {
|
|
2057
2096
|
if (_daemonMgr) return _daemonMgr;
|
|
2058
|
-
const oxmgrBin =
|
|
2097
|
+
const oxmgrBin = findWorkingOxmgr();
|
|
2059
2098
|
const pm2Bin = Bun.which("pm2");
|
|
2060
2099
|
_daemonMgr = pickDaemonManager({
|
|
2061
2100
|
oxmgrBin,
|
|
@@ -2074,6 +2113,10 @@ function daemonManager(): DaemonManager {
|
|
|
2074
2113
|
// the managed process (it has no per-var flag like oxmgr's --env), so install
|
|
2075
2114
|
// passes daemon env this way.
|
|
2076
2115
|
async function runPm(mgr: DaemonManager, args: string[], env?: Record<string, string>): Promise<number> {
|
|
2116
|
+
// A .cmd/.bat shim runs through cmd.exe, which treats & | < > ^ in an argument as syntax
|
|
2117
|
+
// (e.g. the &s in a RECHROME_URL passed with --env): fail clearly instead of mangling it.
|
|
2118
|
+
if (/\.(cmd|bat)$/i.test(mgr.bin) && args.some(a => /[&|<>^]/.test(a)))
|
|
2119
|
+
throw new Error(`${mgr.bin} is a cmd.exe shim, which would mangle an argument containing & | < > ^. Install the ${mgr.id} executable (or set RECH_OXMGR to it) and try again.`);
|
|
2077
2120
|
const proc = Bun.spawn([mgr.bin, ...args], {
|
|
2078
2121
|
stdout: "inherit",
|
|
2079
2122
|
stderr: "inherit",
|
|
@@ -2176,7 +2219,7 @@ async function ensureDaemonManager(ask: (q: string, def?: string) => Promise<str
|
|
|
2176
2219
|
});
|
|
2177
2220
|
const code = await proc.exited;
|
|
2178
2221
|
if (code !== 0) throw new Error(`\`${command.join(" ")}\` failed (exit code ${code}). Resolve the installation error, then rerun setup.`);
|
|
2179
|
-
if (!
|
|
2222
|
+
if (!findWorkingOxmgr()) {
|
|
2180
2223
|
throw new Error("oxmgr was installed but is not on PATH. Add the package manager's global bin directory to PATH, then rerun setup.");
|
|
2181
2224
|
}
|
|
2182
2225
|
_daemonMgr = undefined;
|
|
@@ -2295,7 +2338,7 @@ async function daemonUninstall(): Promise<void> {
|
|
|
2295
2338
|
const mgr = daemonManager();
|
|
2296
2339
|
for (const name of [PM_PROCESS_NAME, ...LEGACY_PROCESS_NAMES]) await runPm(mgr, ["delete", name]);
|
|
2297
2340
|
if (mgr.id === "pm2") await runPm(mgr, ["save", "--force"]); // an emptied list must still overwrite the dump
|
|
2298
|
-
|
|
2341
|
+
// oxmgr's boot/login service is left installed: every other oxmgr-managed process depends on it.
|
|
2299
2342
|
console.log(`Removed ${mgr.id} process: ${PM_PROCESS_NAME}`);
|
|
2300
2343
|
}
|
|
2301
2344
|
|
package/serve.js
CHANGED
|
@@ -496,7 +496,7 @@ export async function serve() {
|
|
|
496
496
|
if (certPath && keyPath) {
|
|
497
497
|
const renewed = await renewCertIfNeeded(certPath, keyPath);
|
|
498
498
|
if (renewed) { log("Restarting to load renewed TLS cert..."); process.exit(0); }
|
|
499
|
-
// Check daily; pm2 restarts cleanly after exit(0)
|
|
499
|
+
// Check daily; the process manager (oxmgr --restart always, or pm2) restarts cleanly after exit(0)
|
|
500
500
|
setInterval(async () => {
|
|
501
501
|
if (await renewCertIfNeeded(certPath, keyPath)) { log("Restarting to load renewed TLS cert..."); process.exit(0); }
|
|
502
502
|
}, 86_400_000);
|
package/serve.ts
CHANGED
|
@@ -496,7 +496,7 @@ export async function serve() {
|
|
|
496
496
|
if (certPath && keyPath) {
|
|
497
497
|
const renewed = await renewCertIfNeeded(certPath, keyPath);
|
|
498
498
|
if (renewed) { log("Restarting to load renewed TLS cert..."); process.exit(0); }
|
|
499
|
-
// Check daily; pm2 restarts cleanly after exit(0)
|
|
499
|
+
// Check daily; the process manager (oxmgr --restart always, or pm2) restarts cleanly after exit(0)
|
|
500
500
|
setInterval(async () => {
|
|
501
501
|
if (await renewCertIfNeeded(certPath, keyPath)) { log("Restarting to load renewed TLS cert..."); process.exit(0); }
|
|
502
502
|
}, 86_400_000);
|