diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs index a326693a..669fa5ed 100644 --- a/src/manifest/mod.rs +++ b/src/manifest/mod.rs @@ -7,6 +7,7 @@ )] use anyhow::{anyhow, bail, Context, Result}; +use log::debug; mod npm; use std::path::Path; @@ -625,16 +626,44 @@ impl CrateData { target: Target, ) -> Result<()> { let pkg_file_path = out_dir.join("package.json"); - // Check if a `package.json` was already generated by wasm-bindgen, if so + + // Check if a `package.json` was already generated by wasm-bindgen, if so, // we merge the NPM dependencies already specified in it. let existing_deps = if pkg_file_path.exists() { - // It's just a map of dependency names to versions - Some(serde_json::from_str::>( - &fs::read_to_string(&pkg_file_path)?, - )?) + let package_json_content = fs::read_to_string(&pkg_file_path)?; + debug!("Input package.json path: {:?} content:\n{}", pkg_file_path, package_json_content); + + // NOTE: The previous logic failed because it attempted to parse the entire package.json + // as a simple HashMap. We now use a two-step parsing process: + + // 1. Parse the entire file content into a generic serde_json::Value. + debug!("Starting full JSON parse."); + let full_json: serde_json::Value = serde_json::from_str(&package_json_content)?; + debug!("Finished full JSON parse."); + + // 2. Extract the value associated with the "dependencies" key. + if let Some(deps_value) = full_json.get("dependencies") { + // The value must be a JSON object (a map). + if deps_value.is_object() { + // Deserialize the dependency map (Value::Object) back into the + // expected target type: HashMap. This handles + // the dependency merging downstream. + debug!("Attempting to deserialize dependencies into HashMap."); + let map: HashMap = serde_json::from_value(deps_value.clone())?; + debug!("Successfully deserialized dependencies."); + Some(map) + } else { + // If "dependencies" key exists but its value is not an object, skip merging. + None + } + } else { + // If the "dependencies" key does not exist, skip merging. + None + } } else { None }; + let npm_data = match target { Target::Nodejs => self.to_commonjs(scope, disable_dts, existing_deps, out_dir), Target::NoModules => self.to_nomodules(scope, disable_dts, existing_deps, out_dir), @@ -643,9 +672,10 @@ impl CrateData { // Deno does not need package.json Target::Deno => return Ok(()), }; - + let npm_json = serde_json::to_string_pretty(&npm_data)?; - + debug!("Output package.json path: {:?} content:\n{}", pkg_file_path, npm_json); + fs::write(&pkg_file_path, npm_json) .with_context(|| anyhow!("failed to write: {}", pkg_file_path.display()))?; Ok(())