mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-06 15:22:12 +03:00
fix: add Termux/Android support for playwright-core and better-sqlite3 (#8922)
Validated in local merge-train (devbox-vm-06-dev002) @ combined-tip (FAST gates green: static + changed tests + vitest — only pre-existing audit.test.ts flake). Evidence: /home/diegosouzapw/dev/proxys/OmniRoute/.claude/worktrees/merge-train-20260805-213228-suite.log
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
".env.example",
|
||||
"scripts/build/postinstall.mjs",
|
||||
"scripts/build/fixTlsClientNodeBinary.mjs",
|
||||
"scripts/build/fixPlaywrightAndroid.mjs",
|
||||
"bin/cli/runtime/",
|
||||
"scripts/postinstall.mjs",
|
||||
"scripts/build/postinstallSupport.mjs",
|
||||
|
||||
90
scripts/build/fixPlaywrightAndroid.mjs
Normal file
90
scripts/build/fixPlaywrightAndroid.mjs
Normal file
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* playwright-core Android/Termux platform patch (#7265).
|
||||
*
|
||||
* playwright-core's bundled coreBundle.js has three IIFEs that compute the
|
||||
* browser-cache directory by checking `process.platform` for "linux", "darwin",
|
||||
* or "win32". On Android (Termux), Node.js may report process.platform as
|
||||
* "android", causing each IIFE to throw "Unsupported platform: android" at
|
||||
* module load time — crashing the entire server before any browser is launched.
|
||||
*
|
||||
* This script patches the three platform checks to also accept "android",
|
||||
* treating it identically to "linux" (same XDG_CACHE_HOME convention).
|
||||
*
|
||||
* The patch is applied to both root node_modules (for dev/build) and
|
||||
* dist/node_modules (for the standalone bundle). It is idempotent — running
|
||||
* multiple times is safe.
|
||||
*
|
||||
* Fixes: https://github.com/diegosouzapw/OmniRoute/issues/7265
|
||||
*/
|
||||
|
||||
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
|
||||
const PATCHED_MARKER = "/* omniroute-android-patch */";
|
||||
|
||||
/**
|
||||
* Patch coreBundle.js to accept Android as a valid platform.
|
||||
* Returns true if the file was modified, false if already patched or not found.
|
||||
*/
|
||||
function patchCoreBundle(filePath) {
|
||||
if (!existsSync(filePath)) return false;
|
||||
|
||||
let content = readFileSync(filePath, "utf8");
|
||||
|
||||
// Already patched — skip
|
||||
if (content.includes(PATCHED_MARKER)) return false;
|
||||
|
||||
// The three platform-check patterns in coreBundle.js:
|
||||
// 1. defaultCacheDirectory IIFE (line ~28594)
|
||||
// 2. defaultCacheDirectory2 IIFE (line ~51278)
|
||||
// 3. daemon session dir computation (line ~68847)
|
||||
//
|
||||
// Original pattern: if (process.platform === "linux")
|
||||
// Patched pattern: if (process.platform === "linux" || process.platform === "android")
|
||||
//
|
||||
// We use a regex that matches the exact pattern and only replaces the first
|
||||
// occurrence in each of the three IIFEs. The marker comment is appended once
|
||||
// to signal idempotency.
|
||||
|
||||
const original = /if \(process\.platform === "linux"\)/g;
|
||||
const patched = `if (process.platform === "linux" || process.platform === "android") ${PATCHED_MARKER}`;
|
||||
|
||||
const count = (content.match(original) || []).length;
|
||||
if (count === 0) {
|
||||
// Either already patched or different version — check for our marker
|
||||
return false;
|
||||
}
|
||||
|
||||
content = content.replace(original, patched);
|
||||
writeFileSync(filePath, content, "utf8");
|
||||
return true;
|
||||
}
|
||||
|
||||
export function fixPlaywrightAndroid({ rootDir, log = (m) => console.log(m) } = {}) {
|
||||
const targets = [
|
||||
join(rootDir, "node_modules", "playwright-core", "lib", "coreBundle.js"),
|
||||
join(rootDir, "dist", "node_modules", "playwright-core", "lib", "coreBundle.js"),
|
||||
];
|
||||
|
||||
let patched = 0;
|
||||
for (const target of targets) {
|
||||
if (patchCoreBundle(target)) {
|
||||
patched++;
|
||||
log(` ✅ Patched playwright-core for Android: ${target}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (patched > 0) {
|
||||
log(` ✅ playwright-core Android patch applied (${patched} file(s))\n`);
|
||||
}
|
||||
|
||||
return patched;
|
||||
}
|
||||
|
||||
// When run directly (not imported), execute the patch
|
||||
if (process.argv[1] && process.argv[1].endsWith("fixPlaywrightAndroid.mjs")) {
|
||||
const rootDir = process.argv[2] || process.cwd();
|
||||
fixPlaywrightAndroid({ rootDir });
|
||||
}
|
||||
@@ -24,7 +24,7 @@
|
||||
* Fixes: https://github.com/diegosouzapw/OmniRoute/issues/7802
|
||||
*/
|
||||
|
||||
import { copyFileSync, cpSync, existsSync, mkdirSync, readdirSync } from "node:fs";
|
||||
import { copyFileSync, cpSync, existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
||||
import { dirname, join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
@@ -32,11 +32,61 @@ import { PUBLISHED_BUILD_ARCH, PUBLISHED_BUILD_PLATFORM } from "./native-binary-
|
||||
import { hasStandaloneAppBundle, isTermux } from "./postinstallSupport.mjs";
|
||||
import { colocateLlmlinguaOptionals } from "./colocateOptionals.mjs";
|
||||
import { fixTlsClientNodeBinary } from "./fixTlsClientNodeBinary.mjs";
|
||||
import { fixPlaywrightAndroid } from "./fixPlaywrightAndroid.mjs";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
const ROOT = join(__dirname, "..", "..");
|
||||
|
||||
/**
|
||||
* Patch node-gyp's common.gypi to include the android_ndk_path variable.
|
||||
*
|
||||
* On Termux/Android, node-gyp's bundled common.gypi (in ~/.cache/node-gyp/<version>/)
|
||||
* does not define the `android_ndk_path` variable that the build system expects.
|
||||
* Setting GYP_DEFINES="android_ndk_path=''" is not enough because common.gypi
|
||||
* is parsed separately and the variable must be declared in the 'variables' section.
|
||||
*
|
||||
* This function finds and patches the common.gypi for the current Node.js version,
|
||||
* adding `'android_ndk_path%': ''` to the variables block. The patch is idempotent.
|
||||
*/
|
||||
function patchNodeGypCommonGypi() {
|
||||
try {
|
||||
const nodeVersion = process.version; // e.g. "v26.4.0"
|
||||
const gypDir = join(
|
||||
process.env.HOME || process.env.USERPROFILE || "/root",
|
||||
".cache",
|
||||
"node-gyp",
|
||||
nodeVersion.replace(/^v/, "")
|
||||
);
|
||||
const commonGypi = join(gypDir, "include", "node", "common.gypi");
|
||||
|
||||
if (!existsSync(commonGypi)) {
|
||||
console.warn(` ⚠️ common.gypi not found at ${commonGypi}, skipping patch`);
|
||||
return;
|
||||
}
|
||||
|
||||
let content = readFileSync(commonGypi, "utf8");
|
||||
|
||||
// Check if already patched
|
||||
if (content.includes("android_ndk_path")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the variables section and add android_ndk_path
|
||||
// The pattern is: 'variables': { 'node_use_openssl%': ... }
|
||||
// We insert our variable right after the opening of the variables block
|
||||
const variablesMatch = content.match(/('variables'\s*:\s*\{)/);
|
||||
if (variablesMatch) {
|
||||
const insertPos = content.indexOf(variablesMatch[0]) + variablesMatch[0].length;
|
||||
content = content.slice(0, insertPos) + "\n 'android_ndk_path%': ''," + content.slice(insertPos);
|
||||
writeFileSync(commonGypi, content, "utf8");
|
||||
console.log(` ✅ Patched common.gypi for Android at ${commonGypi}`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(` ⚠️ Could not patch common.gypi: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
const appBinary = join(
|
||||
ROOT,
|
||||
"dist",
|
||||
@@ -148,6 +198,9 @@ async function fixBetterSqliteBinary() {
|
||||
const env = { ...process.env };
|
||||
if (isAndroid) {
|
||||
env.GYP_DEFINES = "android_ndk_path=''";
|
||||
// Patch node-gyp's common.gypi to include android_ndk_path variable
|
||||
// so the gyp build system doesn't fail with "Unknown variable"
|
||||
patchNodeGypCommonGypi();
|
||||
}
|
||||
|
||||
execSync(rebuildCmd, {
|
||||
@@ -348,6 +401,7 @@ async function ensureLlmlinguaOptionals() {
|
||||
await fixBetterSqliteBinary();
|
||||
await fixWreqJsBinary();
|
||||
await fixTlsClientNodeBinary({ rootDir: ROOT });
|
||||
await fixPlaywrightAndroid({ rootDir: ROOT });
|
||||
await ensureSwcHelpers();
|
||||
await ensureLlmlinguaOptionals();
|
||||
await syncProjectEnv();
|
||||
|
||||
Reference in New Issue
Block a user