browser4-cli 0.1.24 → 0.1.26
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 +103 -55
- package/scripts/install-browser4-cli.sh +47 -42
- package/scripts/tests/install-browser4-cli.tests.ps1 +366 -0
- package/scripts/tests/install-browser4-cli.tests.sh +322 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<#
|
|
2
2
|
.SYNOPSIS
|
|
3
|
-
Install browser4-cli
|
|
3
|
+
Install browser4-cli -- download the native binary and set it up on your PATH.
|
|
4
4
|
|
|
5
5
|
.DESCRIPTION
|
|
6
6
|
Detects your OS and CPU architecture, downloads the matching native binary from
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
Download sources (auto-selected by locale; use -Source to override):
|
|
15
15
|
Outside China: 1. GitHub Releases -> 2. Aliyun OSS
|
|
16
16
|
China mainland: 1. Aliyun OSS -> 2. GitHub Releases
|
|
17
|
-
GitHub Releases
|
|
18
|
-
Aliyun OSS
|
|
17
|
+
GitHub Releases -- https://github.com/platonai/Browser4
|
|
18
|
+
Aliyun OSS -- https://browser4.oss-cn-beijing.aliyuncs.com
|
|
19
19
|
|
|
20
20
|
.PARAMETER Version
|
|
21
21
|
Release version tag to download (e.g. "v4.11.0" or "v0.1.12-cli").
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
.PARAMETER Source
|
|
29
29
|
Force a specific download source: "github" or "oss".
|
|
30
|
-
Default (auto): locale-aware
|
|
30
|
+
Default (auto): locale-aware -- OSS first in China mainland, GitHub first elsewhere.
|
|
31
31
|
|
|
32
32
|
.PARAMETER AddToPath
|
|
33
33
|
Add the install directory to the current user's PATH environment variable.
|
|
@@ -39,17 +39,21 @@
|
|
|
39
39
|
.PARAMETER DryRun
|
|
40
40
|
Print what would be done without actually doing it.
|
|
41
41
|
|
|
42
|
+
.PARAMETER SkipIfInstalled
|
|
43
|
+
Skip download if the binary already exists at the install path.
|
|
44
|
+
By default the script always downloads the latest version.
|
|
45
|
+
|
|
42
46
|
.PARAMETER SkipLocal
|
|
43
47
|
Skip checking for a locally-bundled binary alongside the script.
|
|
44
48
|
By default the script looks for the platform binary in its own directory
|
|
45
|
-
before downloading
|
|
49
|
+
before downloading -- use this to force a fresh download.
|
|
46
50
|
|
|
47
51
|
.PARAMETER Locate
|
|
48
52
|
Print detection results (OS, architecture, script location, China locale)
|
|
49
53
|
and exit without installing. Useful for diagnostics.
|
|
50
54
|
|
|
51
55
|
.EXAMPLE
|
|
52
|
-
# Quick install
|
|
56
|
+
# Quick install -- default location, latest version, add to PATH
|
|
53
57
|
powershell -ExecutionPolicy Bypass -File install-browser4-cli.ps1
|
|
54
58
|
|
|
55
59
|
.EXAMPLE
|
|
@@ -61,7 +65,7 @@
|
|
|
61
65
|
powershell -ExecutionPolicy Bypass -File install-browser4-cli.ps1 -Source oss -InstallDir "C:\tools\browser4"
|
|
62
66
|
|
|
63
67
|
.EXAMPLE
|
|
64
|
-
# Run diagnostics
|
|
68
|
+
# Run diagnostics -- see what the script detects without installing
|
|
65
69
|
powershell -ExecutionPolicy Bypass -File install-browser4-cli.ps1 -Locate
|
|
66
70
|
|
|
67
71
|
.EXAMPLE
|
|
@@ -73,6 +77,10 @@
|
|
|
73
77
|
# Force download even when a local binary exists
|
|
74
78
|
powershell -ExecutionPolicy Bypass -File install-browser4-cli.ps1 -SkipLocal
|
|
75
79
|
|
|
80
|
+
.EXAMPLE
|
|
81
|
+
# Skip download if already installed (opt out of default reinstall)
|
|
82
|
+
powershell -ExecutionPolicy Bypass -File install-browser4-cli.ps1 -SkipIfInstalled
|
|
83
|
+
|
|
76
84
|
.EXAMPLE
|
|
77
85
|
# For China mainland: OSS is auto-preferred via locale detection,
|
|
78
86
|
# or force it explicitly
|
|
@@ -83,20 +91,21 @@
|
|
|
83
91
|
param(
|
|
84
92
|
[string]$Version = "",
|
|
85
93
|
[string]$InstallDir = "",
|
|
86
|
-
[ValidateSet("github", "oss")]
|
|
94
|
+
[ValidateSet("", "github", "oss")]
|
|
87
95
|
[string]$Source = "",
|
|
88
96
|
[bool]$AddToPath = $true,
|
|
89
97
|
[switch]$Silent,
|
|
90
98
|
[switch]$DryRun,
|
|
99
|
+
[switch]$SkipIfInstalled,
|
|
91
100
|
[switch]$SkipLocal,
|
|
92
101
|
[switch]$Locate
|
|
93
102
|
)
|
|
94
103
|
|
|
95
104
|
$ErrorActionPreference = "Stop"
|
|
96
105
|
|
|
97
|
-
#
|
|
98
|
-
# Script location
|
|
99
|
-
#
|
|
106
|
+
# ----------------------------------------------
|
|
107
|
+
# Script location -- find ourselves on disk
|
|
108
|
+
# ----------------------------------------------
|
|
100
109
|
|
|
101
110
|
# $PSScriptRoot is the directory containing this script (PS 3+).
|
|
102
111
|
# Falls back to $MyInvocation for edge cases (dot-sourced, PS 2).
|
|
@@ -146,11 +155,11 @@ function Test-LocalBinary {
|
|
|
146
155
|
}
|
|
147
156
|
}
|
|
148
157
|
|
|
149
|
-
#
|
|
158
|
+
# ----------------------------------------------
|
|
150
159
|
# OS detection (compatible with PS 5.1+)
|
|
151
|
-
#
|
|
160
|
+
# ----------------------------------------------
|
|
152
161
|
|
|
153
|
-
# Avoid assigning to $IsLinux / $IsWindows / $IsMacOS directly
|
|
162
|
+
# Avoid assigning to $IsLinux / $IsWindows / $IsMacOS directly --
|
|
154
163
|
# they are read-only automatic variables in PowerShell 7+.
|
|
155
164
|
if ($PSVersionTable.PSVersion.Major -ge 6) {
|
|
156
165
|
$script:OSWin = $IsWindows
|
|
@@ -162,9 +171,9 @@ if ($PSVersionTable.PSVersion.Major -ge 6) {
|
|
|
162
171
|
$script:OSLinux = $false
|
|
163
172
|
}
|
|
164
173
|
|
|
165
|
-
#
|
|
174
|
+
# ----------------------------------------------
|
|
166
175
|
# Helpers
|
|
167
|
-
#
|
|
176
|
+
# ----------------------------------------------
|
|
168
177
|
|
|
169
178
|
function Write-Summary {
|
|
170
179
|
param([string]$Message, [string]$Color = "White")
|
|
@@ -173,22 +182,22 @@ function Write-Summary {
|
|
|
173
182
|
|
|
174
183
|
function Write-Step {
|
|
175
184
|
param([string]$Message)
|
|
176
|
-
if (-not $Silent) { Write-Host "
|
|
185
|
+
if (-not $Silent) { Write-Host " >> $Message" -ForegroundColor Gray }
|
|
177
186
|
}
|
|
178
187
|
|
|
179
188
|
function Write-Check {
|
|
180
189
|
param([string]$Message)
|
|
181
|
-
if (-not $Silent) { Write-Host "
|
|
190
|
+
if (-not $Silent) { Write-Host " [v] $Message" -ForegroundColor Green }
|
|
182
191
|
}
|
|
183
192
|
|
|
184
193
|
function Write-WarnMsg {
|
|
185
194
|
param([string]$Message)
|
|
186
|
-
if (-not $Silent) { Write-Host "
|
|
195
|
+
if (-not $Silent) { Write-Host " [!] $Message" -ForegroundColor Yellow }
|
|
187
196
|
}
|
|
188
197
|
|
|
189
|
-
#
|
|
198
|
+
# ----------------------------------------------
|
|
190
199
|
# Detection
|
|
191
|
-
#
|
|
200
|
+
# ----------------------------------------------
|
|
192
201
|
|
|
193
202
|
function Get-PlatformKey {
|
|
194
203
|
$arch = if ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture -eq [System.Runtime.InteropServices.Architecture]::Arm64) { "arm64" } else { "x64" }
|
|
@@ -237,29 +246,29 @@ function Get-DefaultInstallDir {
|
|
|
237
246
|
throw "Unsupported OS"
|
|
238
247
|
}
|
|
239
248
|
|
|
240
|
-
#
|
|
249
|
+
# ----------------------------------------------
|
|
241
250
|
# China mainland locale detection (zero-network)
|
|
242
|
-
#
|
|
251
|
+
# ----------------------------------------------
|
|
243
252
|
|
|
244
253
|
<#
|
|
245
254
|
.SYNOPSIS
|
|
246
255
|
Detect whether the current system is likely in China mainland.
|
|
247
|
-
Uses only local env vars and .NET APIs
|
|
256
|
+
Uses only local env vars and .NET APIs -- no network calls.
|
|
248
257
|
#>
|
|
249
258
|
function Test-ChinaLocale {
|
|
250
|
-
# 1
|
|
259
|
+
# 1 -- Locale env vars
|
|
251
260
|
$lang = $env:LC_ALL, $env:LANG, $env:LC_CTYPE, $env:LC_MESSAGES | Where-Object { $_ } | Select-Object -First 1
|
|
252
261
|
if ($lang -and ($lang -match '^zh_CN' -or $lang -match '^zh-CN' -or $lang -match '^Chinese \(Simplified\)_China')) {
|
|
253
262
|
return $true
|
|
254
263
|
}
|
|
255
264
|
|
|
256
|
-
# 2
|
|
265
|
+
# 2 -- TZ env var
|
|
257
266
|
$tzEnv = $env:TZ
|
|
258
267
|
if ($tzEnv -and ($tzEnv -match '^Asia/(Shanghai|Chongqing|Urumqi|Harbin)$')) {
|
|
259
268
|
return $true
|
|
260
269
|
}
|
|
261
270
|
|
|
262
|
-
# 3
|
|
271
|
+
# 3 -- .NET TimeZoneInfo (works on Windows and Unix PowerShell 7+)
|
|
263
272
|
try {
|
|
264
273
|
$tzId = [System.TimeZoneInfo]::Local.Id
|
|
265
274
|
if ($tzId -match '^Asia/(Shanghai|Chongqing|Urumqi|Harbin)$') {
|
|
@@ -269,7 +278,7 @@ function Test-ChinaLocale {
|
|
|
269
278
|
# TimeZoneInfo not available (unlikely on PS 5.1+ but guard anyway)
|
|
270
279
|
}
|
|
271
280
|
|
|
272
|
-
# 4
|
|
281
|
+
# 4 -- /etc/timezone (PowerShell on Linux/macOS)
|
|
273
282
|
if (-not $script:OSWin -and (Test-Path '/etc/timezone')) {
|
|
274
283
|
try {
|
|
275
284
|
$tz = Get-Content '/etc/timezone' -Raw -ErrorAction Stop
|
|
@@ -277,16 +286,16 @@ function Test-ChinaLocale {
|
|
|
277
286
|
return $true
|
|
278
287
|
}
|
|
279
288
|
} catch {
|
|
280
|
-
# Permission or read error
|
|
289
|
+
# Permission or read error -- skip
|
|
281
290
|
}
|
|
282
291
|
}
|
|
283
292
|
|
|
284
293
|
return $false
|
|
285
294
|
}
|
|
286
295
|
|
|
287
|
-
#
|
|
296
|
+
# ----------------------------------------------
|
|
288
297
|
# Download URLs
|
|
289
|
-
#
|
|
298
|
+
# ----------------------------------------------
|
|
290
299
|
|
|
291
300
|
$GITHUB_REPO = "platonai/Browser4"
|
|
292
301
|
$OSS_BASE = "https://browser4.oss-cn-beijing.aliyuncs.com"
|
|
@@ -347,7 +356,7 @@ function Invoke-Download {
|
|
|
347
356
|
Write-Check "Downloaded $( [math]::Round($size / 1MB, 1) ) MB"
|
|
348
357
|
return $true
|
|
349
358
|
} else {
|
|
350
|
-
Write-WarnMsg "Downloaded file too small ($size bytes)
|
|
359
|
+
Write-WarnMsg "Downloaded file too small ($size bytes) -- may be an error page"
|
|
351
360
|
Remove-Item $OutFile -Force -ErrorAction SilentlyContinue
|
|
352
361
|
return $false
|
|
353
362
|
}
|
|
@@ -360,9 +369,9 @@ function Invoke-Download {
|
|
|
360
369
|
}
|
|
361
370
|
}
|
|
362
371
|
|
|
363
|
-
#
|
|
372
|
+
# ----------------------------------------------
|
|
364
373
|
# Symlinks
|
|
365
|
-
#
|
|
374
|
+
# ----------------------------------------------
|
|
366
375
|
|
|
367
376
|
function New-PlatformLink {
|
|
368
377
|
param([string]$LinkPath, [string]$TargetName, [string]$DisplayName)
|
|
@@ -373,7 +382,7 @@ function New-PlatformLink {
|
|
|
373
382
|
Write-Check "Created symlink: $DisplayName -> $TargetName"
|
|
374
383
|
return $true
|
|
375
384
|
} catch {
|
|
376
|
-
# Symbolic link failed
|
|
385
|
+
# Symbolic link failed -- try hard link on Windows
|
|
377
386
|
}
|
|
378
387
|
|
|
379
388
|
# Try hard link (Windows, same volume)
|
|
@@ -384,7 +393,7 @@ function New-PlatformLink {
|
|
|
384
393
|
Write-Check "Created hard link: $DisplayName -> $TargetName"
|
|
385
394
|
return $true
|
|
386
395
|
} catch {
|
|
387
|
-
# Hard link also failed
|
|
396
|
+
# Hard link also failed -- create a .cmd wrapper as last resort
|
|
388
397
|
}
|
|
389
398
|
|
|
390
399
|
# Last resort: .cmd wrapper that forwards all arguments
|
|
@@ -451,9 +460,9 @@ function New-Symlinks {
|
|
|
451
460
|
}
|
|
452
461
|
}
|
|
453
462
|
|
|
454
|
-
#
|
|
463
|
+
# ----------------------------------------------
|
|
455
464
|
# PATH management
|
|
456
|
-
#
|
|
465
|
+
# ----------------------------------------------
|
|
457
466
|
|
|
458
467
|
function Add-DirectoryToUserPath {
|
|
459
468
|
param([string]$Dir)
|
|
@@ -485,14 +494,55 @@ function Add-DirectoryToUserPath {
|
|
|
485
494
|
$env:Path = "$env:Path;$Dir"
|
|
486
495
|
}
|
|
487
496
|
|
|
488
|
-
#
|
|
497
|
+
# ----------------------------------------------
|
|
498
|
+
# Helper: replace a binary that may be locked (i.e. currently running)
|
|
499
|
+
# ----------------------------------------------
|
|
500
|
+
function Set-BinaryFile {
|
|
501
|
+
param(
|
|
502
|
+
[Parameter(Mandatory=$true)] [string]$TargetPath,
|
|
503
|
+
[Parameter(Mandatory=$true)] [string]$SourcePath,
|
|
504
|
+
[Parameter(Mandatory=$false)] [switch]$Move # $true = move temp file, $false = copy
|
|
505
|
+
)
|
|
506
|
+
|
|
507
|
+
if (Test-Path $TargetPath) {
|
|
508
|
+
# Remove any stale .old from a previous upgrade
|
|
509
|
+
$oldPath = "$TargetPath.old"
|
|
510
|
+
try {
|
|
511
|
+
if (Test-Path $oldPath) { Remove-Item $oldPath -Force -ErrorAction Stop }
|
|
512
|
+
} catch { }
|
|
513
|
+
|
|
514
|
+
try {
|
|
515
|
+
Remove-Item $TargetPath -Force -ErrorAction Stop
|
|
516
|
+
} catch {
|
|
517
|
+
# The binary is locked (likely the currently-running process).
|
|
518
|
+
# On Windows we can rename a running executable — move the old binary
|
|
519
|
+
# out of the way, place the new one alongside, and clean up the old one
|
|
520
|
+
# on the next install/upgrade.
|
|
521
|
+
try {
|
|
522
|
+
Move-Item $TargetPath $oldPath -Force -ErrorAction Stop
|
|
523
|
+
Write-WarnMsg "Existing binary is locked (it may be running)."
|
|
524
|
+
Write-WarnMsg "The old copy will be cleaned up on the next install or upgrade."
|
|
525
|
+
} catch {
|
|
526
|
+
throw "Cannot replace '$TargetPath' — it is locked and cannot be renamed. Close all browser4-cli processes and try again."
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
# Place the new binary at the target path
|
|
532
|
+
if ($Move) {
|
|
533
|
+
Move-Item $SourcePath $TargetPath -Force -ErrorAction Stop
|
|
534
|
+
} else {
|
|
535
|
+
Copy-Item $SourcePath $TargetPath -Force -ErrorAction Stop
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
# ----------------------------------------------
|
|
489
539
|
# Main
|
|
490
|
-
#
|
|
540
|
+
# ----------------------------------------------
|
|
491
541
|
|
|
492
542
|
function Main {
|
|
493
|
-
Write-Summary "
|
|
494
|
-
Write-Summary "
|
|
495
|
-
Write-Summary "
|
|
543
|
+
Write-Summary "==========================================" -Color Cyan
|
|
544
|
+
Write-Summary " browser4-cli Installer" -Color Cyan
|
|
545
|
+
Write-Summary "==========================================" -Color Cyan
|
|
496
546
|
Write-Summary ""
|
|
497
547
|
|
|
498
548
|
# Auto-detect China mainland locale when no explicit source is given
|
|
@@ -507,9 +557,9 @@ function Main {
|
|
|
507
557
|
$platformKey = Get-PlatformKey
|
|
508
558
|
$binaryName = Get-BinaryName -PlatformKey $platformKey
|
|
509
559
|
|
|
510
|
-
#
|
|
560
|
+
# -- Locate mode: print diagnostics and exit --
|
|
511
561
|
if ($Locate) {
|
|
512
|
-
Write-Summary "
|
|
562
|
+
Write-Summary "--- Locate / diagnostics ---" -Color Cyan
|
|
513
563
|
Write-Summary ""
|
|
514
564
|
Write-Step "Script dir: $ScriptDir"
|
|
515
565
|
Write-Step "Platform key: $platformKey"
|
|
@@ -566,7 +616,7 @@ function Main {
|
|
|
566
616
|
|
|
567
617
|
$binaryPath = Join-Path $installDir $binaryName
|
|
568
618
|
|
|
569
|
-
#
|
|
619
|
+
# -- Local binary discovery (bundled/sideload) --
|
|
570
620
|
$useLocalBinary = $false
|
|
571
621
|
if (-not $SkipLocal) {
|
|
572
622
|
$localBinaryPath = Find-LocalBinary -BinaryName $binaryName
|
|
@@ -576,21 +626,20 @@ function Main {
|
|
|
576
626
|
Write-Check "Local binary verified (--version OK)"
|
|
577
627
|
$useLocalBinary = $true
|
|
578
628
|
} else {
|
|
579
|
-
Write-WarnMsg "Local binary found but --version check failed
|
|
629
|
+
Write-WarnMsg "Local binary found but --version check failed -- will download instead"
|
|
580
630
|
}
|
|
581
631
|
}
|
|
582
632
|
} elseif ($SkipLocal) {
|
|
583
633
|
Write-Step "Skipping local binary check (-SkipLocal)"
|
|
584
634
|
}
|
|
585
635
|
|
|
586
|
-
#
|
|
587
|
-
if ((Test-Path $binaryPath) -and (-not $Version) -and (-not $useLocalBinary)) {
|
|
636
|
+
# Skip download only when --skip-if-installed is set and binary already exists
|
|
637
|
+
if ((Test-Path $binaryPath) -and (-not $Version) -and $SkipIfInstalled -and (-not $useLocalBinary)) {
|
|
588
638
|
Write-Check "Binary already installed: $binaryPath"
|
|
589
639
|
} elseif ($useLocalBinary) {
|
|
590
640
|
# Copy local binary to install dir
|
|
591
641
|
if (-not $DryRun) {
|
|
592
|
-
|
|
593
|
-
Copy-Item $localBinaryPath $binaryPath -Force
|
|
642
|
+
Set-BinaryFile -TargetPath $binaryPath -SourcePath $localBinaryPath
|
|
594
643
|
}
|
|
595
644
|
Write-Check "Installed (local): $binaryPath"
|
|
596
645
|
} else {
|
|
@@ -628,8 +677,7 @@ Please check:
|
|
|
628
677
|
|
|
629
678
|
# Move from temp to install dir
|
|
630
679
|
if (-not $DryRun) {
|
|
631
|
-
|
|
632
|
-
Move-Item $tempFile $binaryPath -Force
|
|
680
|
+
Set-BinaryFile -TargetPath $binaryPath -SourcePath $tempFile -Move
|
|
633
681
|
}
|
|
634
682
|
Write-Check "Installed: $binaryPath"
|
|
635
683
|
}
|
|
@@ -672,10 +720,10 @@ Please check:
|
|
|
672
720
|
if (-not $DryRun) {
|
|
673
721
|
try {
|
|
674
722
|
$versionOutput = & $binaryPath --version 2>&1
|
|
675
|
-
Write-Summary "
|
|
723
|
+
Write-Summary "[v] browser4-cli installed successfully" -Color Green
|
|
676
724
|
Write-Summary " Version: $versionOutput"
|
|
677
725
|
} catch {
|
|
678
|
-
Write-Summary "
|
|
726
|
+
Write-Summary "[v] Binary installed at: $binaryPath" -Color Green
|
|
679
727
|
Write-WarnMsg "Could not verify --version (this is normal on first install)"
|
|
680
728
|
}
|
|
681
729
|
} else {
|