browser4-cli 0.1.16 → 0.1.17
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/browser4-cli-darwin-arm64 +0 -0
- package/bin/browser4-cli-darwin-x64 +0 -0
- package/bin/browser4-cli-linux-arm64 +0 -0
- package/bin/browser4-cli-linux-musl-arm64 +0 -0
- package/bin/browser4-cli-linux-musl-x64 +0 -0
- package/bin/browser4-cli-linux-x64 +0 -0
- package/bin/browser4-cli-win32-x64.exe +0 -0
- package/package.json +1 -1
- package/scripts/install-browser4-cli.ps1 +63 -2
- package/scripts/install-browser4-cli.sh +45 -2
- package/scripts/postinstall.js +79 -11
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -154,12 +154,60 @@ function Get-DefaultInstallDir {
|
|
|
154
154
|
throw "Unsupported OS"
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
# ──────────────────────────────────────────────
|
|
158
|
+
# China mainland locale detection (zero-network)
|
|
159
|
+
# ──────────────────────────────────────────────
|
|
160
|
+
|
|
161
|
+
<#
|
|
162
|
+
.SYNOPSIS
|
|
163
|
+
Detect whether the current system is likely in China mainland.
|
|
164
|
+
Uses only local env vars and .NET APIs — no network calls.
|
|
165
|
+
#>
|
|
166
|
+
function Test-ChinaLocale {
|
|
167
|
+
# 1 — Locale env vars
|
|
168
|
+
$lang = $env:LC_ALL, $env:LANG, $env:LC_CTYPE, $env:LC_MESSAGES | Where-Object { $_ } | Select-Object -First 1
|
|
169
|
+
if ($lang -and ($lang -match '^zh_CN' -or $lang -match '^zh-CN' -or $lang -match '^Chinese \(Simplified\)_China')) {
|
|
170
|
+
return $true
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
# 2 — TZ env var
|
|
174
|
+
$tzEnv = $env:TZ
|
|
175
|
+
if ($tzEnv -and ($tzEnv -match '^Asia/(Shanghai|Chongqing|Urumqi|Harbin)$')) {
|
|
176
|
+
return $true
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
# 3 — .NET TimeZoneInfo (works on Windows and Unix PowerShell 7+)
|
|
180
|
+
try {
|
|
181
|
+
$tzId = [System.TimeZoneInfo]::Local.Id
|
|
182
|
+
if ($tzId -match '^Asia/(Shanghai|Chongqing|Urumqi|Harbin)$') {
|
|
183
|
+
return $true
|
|
184
|
+
}
|
|
185
|
+
} catch {
|
|
186
|
+
# TimeZoneInfo not available (unlikely on PS 5.1+ but guard anyway)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
# 4 — /etc/timezone (PowerShell on Linux/macOS)
|
|
190
|
+
if (-not $script:OSWin -and (Test-Path '/etc/timezone')) {
|
|
191
|
+
try {
|
|
192
|
+
$tz = Get-Content '/etc/timezone' -Raw -ErrorAction Stop
|
|
193
|
+
if ($tz -match '^Asia/(Shanghai|Chongqing|Urumqi|Harbin)$') {
|
|
194
|
+
return $true
|
|
195
|
+
}
|
|
196
|
+
} catch {
|
|
197
|
+
# Permission or read error — skip
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return $false
|
|
202
|
+
}
|
|
203
|
+
|
|
157
204
|
# ──────────────────────────────────────────────
|
|
158
205
|
# Download URLs
|
|
159
206
|
# ──────────────────────────────────────────────
|
|
160
207
|
|
|
161
208
|
$GITHUB_REPO = "platonai/Browser4"
|
|
162
209
|
$OSS_BASE = "https://browser4.oss-cn-beijing.aliyuncs.com"
|
|
210
|
+
$script:ChinaDetected = $false
|
|
163
211
|
|
|
164
212
|
function Get-DownloadUrls {
|
|
165
213
|
param([string]$BinaryName, [string]$VersionTag)
|
|
@@ -181,8 +229,13 @@ function Get-DownloadUrls {
|
|
|
181
229
|
} elseif ($Source -eq "oss") {
|
|
182
230
|
$urls += @{ Url = $ossUrl; Label = "Aliyun OSS" }
|
|
183
231
|
} else {
|
|
184
|
-
$
|
|
185
|
-
|
|
232
|
+
if ($script:ChinaDetected) {
|
|
233
|
+
$urls += @{ Url = $ossUrl; Label = "Aliyun OSS" }
|
|
234
|
+
$urls += @{ Url = $ghUrl; Label = "GitHub Releases" }
|
|
235
|
+
} else {
|
|
236
|
+
$urls += @{ Url = $ghUrl; Label = "GitHub Releases" }
|
|
237
|
+
$urls += @{ Url = $ossUrl; Label = "Aliyun OSS" }
|
|
238
|
+
}
|
|
186
239
|
}
|
|
187
240
|
|
|
188
241
|
return $urls
|
|
@@ -359,6 +412,14 @@ function Main {
|
|
|
359
412
|
Write-Summary "╚════════════════════════════════════════╝" -Color Cyan
|
|
360
413
|
Write-Summary ""
|
|
361
414
|
|
|
415
|
+
# Auto-detect China mainland locale when no explicit source is given
|
|
416
|
+
if (-not $Source) {
|
|
417
|
+
$script:ChinaDetected = Test-ChinaLocale
|
|
418
|
+
if ($script:ChinaDetected) {
|
|
419
|
+
Write-Step "China mainland locale detected: preferring Aliyun OSS mirror."
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
362
423
|
# Detect platform
|
|
363
424
|
$platformKey = Get-PlatformKey
|
|
364
425
|
$binaryName = Get-BinaryName -PlatformKey $platformKey
|
|
@@ -36,6 +36,7 @@ SOURCE=""
|
|
|
36
36
|
ADD_TO_PATH=true
|
|
37
37
|
SILENT=false
|
|
38
38
|
DRY_RUN=false
|
|
39
|
+
CHINA_DETECTED=false
|
|
39
40
|
|
|
40
41
|
# ──────────────────────────────────────────────
|
|
41
42
|
# Helpers
|
|
@@ -110,6 +111,35 @@ while [[ $# -gt 0 ]]; do
|
|
|
110
111
|
esac
|
|
111
112
|
done
|
|
112
113
|
|
|
114
|
+
# ──────────────────────────────────────────────
|
|
115
|
+
# China mainland locale detection (zero-network)
|
|
116
|
+
# ──────────────────────────────────────────────
|
|
117
|
+
|
|
118
|
+
detect_china_locale() {
|
|
119
|
+
# 1 — Locale env vars
|
|
120
|
+
local lang
|
|
121
|
+
lang="${LC_ALL:-${LANG:-${LC_CTYPE:-${LC_MESSAGES:-}}}}"
|
|
122
|
+
case "$lang" in
|
|
123
|
+
zh_CN*|zh-CN*|"Chinese (Simplified)_China"*) return 0 ;;
|
|
124
|
+
esac
|
|
125
|
+
|
|
126
|
+
# 2 — TZ env var
|
|
127
|
+
case "${TZ:-}" in
|
|
128
|
+
Asia/Shanghai|Asia/Chongqing|Asia/Urumqi|Asia/Harbin) return 0 ;;
|
|
129
|
+
esac
|
|
130
|
+
|
|
131
|
+
# 3 — /etc/timezone
|
|
132
|
+
if [[ -f /etc/timezone ]]; then
|
|
133
|
+
local tz
|
|
134
|
+
tz=$(cat /etc/timezone 2>/dev/null || true)
|
|
135
|
+
case "$tz" in
|
|
136
|
+
Asia/Shanghai|Asia/Chongqing|Asia/Urumqi|Asia/Harbin) return 0 ;;
|
|
137
|
+
esac
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
return 1
|
|
141
|
+
}
|
|
142
|
+
|
|
113
143
|
# ──────────────────────────────────────────────
|
|
114
144
|
# Platform detection
|
|
115
145
|
# ──────────────────────────────────────────────
|
|
@@ -245,8 +275,13 @@ get_download_urls() {
|
|
|
245
275
|
github) urls+=("GitHub Releases|${gh_url}") ;;
|
|
246
276
|
oss) urls+=("Aliyun OSS|${oss_url}") ;;
|
|
247
277
|
*)
|
|
248
|
-
|
|
249
|
-
|
|
278
|
+
if [[ "$CHINA_DETECTED" == true ]]; then
|
|
279
|
+
urls+=("Aliyun OSS|${oss_url}")
|
|
280
|
+
urls+=("GitHub Releases|${gh_url}")
|
|
281
|
+
else
|
|
282
|
+
urls+=("GitHub Releases|${gh_url}")
|
|
283
|
+
urls+=("Aliyun OSS|${oss_url}")
|
|
284
|
+
fi
|
|
250
285
|
;;
|
|
251
286
|
esac
|
|
252
287
|
|
|
@@ -430,6 +465,14 @@ main() {
|
|
|
430
465
|
check_commands
|
|
431
466
|
header
|
|
432
467
|
|
|
468
|
+
# Auto-detect China mainland locale when no explicit source is given
|
|
469
|
+
if [[ -z "$SOURCE" ]]; then
|
|
470
|
+
if detect_china_locale; then
|
|
471
|
+
CHINA_DETECTED=true
|
|
472
|
+
step "China mainland locale detected: preferring Aliyun OSS mirror."
|
|
473
|
+
fi
|
|
474
|
+
fi
|
|
475
|
+
|
|
433
476
|
# Detect platform
|
|
434
477
|
local platform_key binary_name
|
|
435
478
|
platform_key=$(get_platform_key)
|
package/scripts/postinstall.js
CHANGED
|
@@ -45,9 +45,65 @@ const packageJson = JSON.parse(
|
|
|
45
45
|
const version = packageJson.version;
|
|
46
46
|
const commandNames = Object.keys(packageJson.bin || { 'browser4-cli': './bin/browser4-cli.js' });
|
|
47
47
|
|
|
48
|
-
//
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
// China mainland locale detection (zero-network — uses only local env / Intl)
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
|
|
52
|
+
function isChinaLocale() {
|
|
53
|
+
// 1 — Locale env vars (Unix, Git Bash, WSL, Docker)
|
|
54
|
+
const lang = process.env.LC_ALL
|
|
55
|
+
|| process.env.LANG
|
|
56
|
+
|| process.env.LC_CTYPE
|
|
57
|
+
|| process.env.LC_MESSAGES
|
|
58
|
+
|| '';
|
|
59
|
+
if (/^(?:zh_CN|zh-CN|Chinese \(Simplified\)_China)/i.test(lang)) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 2 — TZ env var (Docker, CI)
|
|
64
|
+
const tz = process.env.TZ || '';
|
|
65
|
+
if (/^Asia\/(Shanghai|Chongqing|Urumqi|Harbin)$/.test(tz)) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// 3 — Intl timezone API (V8/Node.js, no filesystem access needed)
|
|
70
|
+
try {
|
|
71
|
+
const resolvedTz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
72
|
+
if (/^Asia\/(Shanghai|Chongqing|Urumqi|Harbin)$/.test(resolvedTz)) {
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
} catch {
|
|
76
|
+
// Intl not available (very old Node) — skip
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
// Download URLs (locale-aware ordering)
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
|
|
49
86
|
const GITHUB_REPO = 'platonai/Browser4';
|
|
50
|
-
const
|
|
87
|
+
const DOWNLOAD_URL_GITHUB = `https://github.com/${GITHUB_REPO}/releases/download/v${version}/${binaryName}`;
|
|
88
|
+
const DOWNLOAD_URL_OSS = `https://browser4.oss-cn-beijing.aliyuncs.com/releases/download/v${version}/${binaryName}`;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Return download URLs ordered by locale preference. `BROWSER4_RELEASES_BASE_URL`
|
|
92
|
+
* takes precedence; otherwise China mainland users get OSS-first ordering.
|
|
93
|
+
*/
|
|
94
|
+
function getDownloadUrls() {
|
|
95
|
+
// Single-source override
|
|
96
|
+
const envOverride = (process.env.BROWSER4_RELEASES_BASE_URL || '').trim();
|
|
97
|
+
if (envOverride) {
|
|
98
|
+
const base = envOverride.replace(/\/+$/, '');
|
|
99
|
+
return [`${base}/download/v${version}/${binaryName}`];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (isChinaLocale()) {
|
|
103
|
+
return [DOWNLOAD_URL_OSS, DOWNLOAD_URL_GITHUB];
|
|
104
|
+
}
|
|
105
|
+
return [DOWNLOAD_URL_GITHUB, DOWNLOAD_URL_OSS];
|
|
106
|
+
}
|
|
51
107
|
|
|
52
108
|
async function downloadFile(url, dest) {
|
|
53
109
|
return new Promise((resolve, reject) => {
|
|
@@ -130,19 +186,31 @@ async function main() {
|
|
|
130
186
|
}
|
|
131
187
|
|
|
132
188
|
console.log(`Downloading native binary for ${platformKey}...`);
|
|
133
|
-
console.log(`URL: ${DOWNLOAD_URL}`);
|
|
134
189
|
|
|
135
|
-
|
|
136
|
-
await downloadFile(DOWNLOAD_URL, binaryPath);
|
|
190
|
+
const urls = getDownloadUrls();
|
|
137
191
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
192
|
+
let lastError = null;
|
|
193
|
+
for (const url of urls) {
|
|
194
|
+
console.log(`URL: ${url}`);
|
|
195
|
+
try {
|
|
196
|
+
await downloadFile(url, binaryPath);
|
|
197
|
+
|
|
198
|
+
// Make executable on Unix
|
|
199
|
+
if (platform() !== 'win32') {
|
|
200
|
+
chmodSync(binaryPath, 0o755);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
console.log(`✓ Downloaded native binary: ${binaryName}`);
|
|
204
|
+
lastError = null;
|
|
205
|
+
break;
|
|
206
|
+
} catch (err) {
|
|
207
|
+
console.log(`Download failed: ${err.message}`);
|
|
208
|
+
lastError = err;
|
|
141
209
|
}
|
|
210
|
+
}
|
|
142
211
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
console.log(`Could not download native binary: ${err.message}`);
|
|
212
|
+
if (lastError) {
|
|
213
|
+
console.log(`Could not download native binary from any mirror: ${lastError.message}`);
|
|
146
214
|
console.log('');
|
|
147
215
|
console.log('To build the native binary locally:');
|
|
148
216
|
console.log(' 1. Install Rust: https://rustup.rs');
|