Skip to content

Commit 8c3ccf6

Browse files
author
Lei Shi
committed
fix(install): use dunce::canonicalize and support multiple extension IDs
- Use `dunce::canonicalize` instead of `std::fs::canonicalize` to avoid the `\?\` prefix on Windows paths in the manifest, which some browsers may not handle correctly. - Change `--extension-id` to accept multiple values so Chrome and Edge IDs can be specified in a single install command. - When writing the manifest, merge with any existing `allowed_origins` so that installing for one browser doesn't clobber another browser's extension ID.
1 parent 9d7b5b8 commit 8c3ccf6

3 files changed

Lines changed: 46 additions & 7 deletions

File tree

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] }
2929
uuid = { version = "1", features = ["v4"] }
3030
chrono = { version = "0.4", features = ["serde"] }
3131
interprocess = { version = "2.4.0", features = ["tokio"] }
32+
dunce = "1"
3233

3334
[target.'cfg(windows)'.dependencies]
3435
winreg = "0.55"

src/cli/commands/install.rs

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ pub struct InstallArgs {
1010
#[arg(long)]
1111
pub browser: BrowserFamily,
1212

13-
/// Extension ID (required for Chrome-family browsers)
13+
/// Extension ID (required for Chrome-family browsers).
14+
/// Can be specified multiple times for multi-browser setups sharing one manifest
15+
/// (e.g. `--extension-id <chrome-id> --extension-id <edge-id>`).
1416
#[arg(long)]
15-
pub extension_id: Option<String>,
17+
pub extension_id: Vec<String>,
1618
}
1719

1820
pub fn run(args: InstallArgs) -> Result<()> {
@@ -29,8 +31,9 @@ pub fn run(args: InstallArgs) -> Result<()> {
2931
);
3032
}
3133

32-
let host_path = host_binary
33-
.canonicalize()
34+
// Use dunce::canonicalize to avoid the \\?\ prefix on Windows,
35+
// which some browsers may not handle correctly.
36+
let host_path = dunce::canonicalize(&host_binary)
3437
.context("failed to resolve ptd-host path")?;
3538

3639
let manifest = if args.browser.is_firefox() {
@@ -42,17 +45,45 @@ pub fn run(args: InstallArgs) -> Result<()> {
4245
"allowed_extensions": ["ptdepiler.ptplugins@gmail.com"]
4346
})
4447
} else {
45-
let ext_id = args.extension_id.as_deref().unwrap_or_else(|| {
48+
if args.extension_id.is_empty() {
4649
eprintln!("--extension-id is required for Chrome-family browsers.");
4750
eprintln!("Find it at chrome://extensions with Developer Mode enabled.");
51+
eprintln!("Multiple IDs can be specified: --extension-id <id1> --extension-id <id2>");
4852
std::process::exit(1);
49-
});
53+
}
54+
55+
let origins: Vec<String> = args
56+
.extension_id
57+
.iter()
58+
.map(|id| format!("chrome-extension://{id}/"))
59+
.collect();
60+
61+
// If a manifest already exists, merge in any existing allowed_origins
62+
// so that installing for one browser doesn't break another.
63+
let manifest_path = args.browser.native_host_manifest_path();
64+
let mut all_origins = origins.clone();
65+
if manifest_path.exists() {
66+
if let Ok(content) = std::fs::read_to_string(&manifest_path) {
67+
if let Ok(existing) = serde_json::from_str::<serde_json::Value>(&content) {
68+
if let Some(arr) = existing.get("allowed_origins").and_then(|v| v.as_array()) {
69+
for v in arr {
70+
if let Some(s) = v.as_str() {
71+
if !all_origins.contains(&s.to_string()) {
72+
all_origins.push(s.to_string());
73+
}
74+
}
75+
}
76+
}
77+
}
78+
}
79+
}
80+
5081
serde_json::json!({
5182
"name": NATIVE_HOST_NAME,
5283
"description": "PT-Depiler CLI Native Messaging Host",
5384
"path": host_path.to_string_lossy(),
5485
"type": "stdio",
55-
"allowed_origins": [format!("chrome-extension://{ext_id}/")]
86+
"allowed_origins": all_origins
5687
})
5788
};
5889

0 commit comments

Comments
 (0)