diff --git a/core/tauri-build/src/lib.rs b/core/tauri-build/src/lib.rs index 8273506e2..e7ea74dd8 100644 --- a/core/tauri-build/src/lib.rs +++ b/core/tauri-build/src/lib.rs @@ -521,19 +521,47 @@ pub fn try_build(attributes: Attributes) -> Result<()> { }); for capability in &namespace.capabilities { - let (plugin, capability) = manifests.find_capability(capability).unwrap_or_else(|| { + let (target_plugin, capability_id) = capability + .split_once(':') + .map(|(plugin, id)| (Some(plugin), id)) + .unwrap_or_else(|| (None, capability.as_str())); + let capabilities = manifests.find_capability(capability_id); + + if capabilities.is_empty() { panic!("could not find capability specification matching id {capability}") - }); - if plugin == APP_MANIFEST_KEY { - member_resolution.commands.extend(capability.features); } else { - member_resolution.commands.extend( - capability - .features + let (plugin, capability) = if let Some(target) = target_plugin { + capabilities .into_iter() - .map(|f| format!("plugin:{plugin}|{f}")) - .collect::>(), - ); + .find(|(p, _)| p == target) + .unwrap_or_else(|| { + panic!("failed to find capability matching id {capability_id} for plugin {target}") + }) + } else if capabilities.len() > 1 { + panic!( + "found a conflict on capability id {capability}, please use one of the [{}] prefixes", + capabilities + .iter() + .map(|(p, _)| format!("'{p}:'")) + .collect::>() + .join(", ") + ); + } else { + // already checked that the capabilities aren't empty + capabilities.into_iter().next().unwrap() + }; + + if plugin == APP_MANIFEST_KEY { + member_resolution.commands.extend(capability.features); + } else { + member_resolution.commands.extend( + capability + .features + .into_iter() + .map(|f| format!("plugin:{plugin}|{f}")) + .collect::>(), + ); + } } } } diff --git a/core/tauri-utils/src/plugin.rs b/core/tauri-utils/src/plugin.rs index 258640060..e45b7cb05 100644 --- a/core/tauri-utils/src/plugin.rs +++ b/core/tauri-utils/src/plugin.rs @@ -176,21 +176,23 @@ impl From> for ManifestMap { impl ManifestMap { /// Finds the capability with the given identifier. - pub fn find_capability(&self, id: &str) -> Option<(String, Capability)> { + pub fn find_capability(&self, id: &str) -> Vec<(String, Capability)> { + let mut capabilities = Vec::new(); + for (plugin, manifest) in &self.0 { if id == format!("{DEFAULT_CAPABILITY_ID}-{plugin}") { - return Some(( + capabilities.push(( plugin.clone(), manifest.default_capability.clone().unwrap_or_default(), )); } for capability in &manifest.capabilities { if capability.id == id { - return Some((plugin.clone(), capability.clone())); + capabilities.push((plugin.clone(), capability.clone())); } } } - None + capabilities } }