@@ -4,6 +4,7 @@ use crate::{Bindgen, EncodeInto, OutputMode};
44use failure:: { bail, Error , ResultExt } ;
55use std:: collections:: { HashMap , HashSet } ;
66use std:: env;
7+ use std:: fs;
78use walrus:: { MemoryId , Module } ;
89use wasm_bindgen_wasm_interpreter:: Interpreter ;
910
@@ -62,6 +63,10 @@ pub struct Context<'a> {
6263 /// snippets. This is incremented each time a `Program` is processed.
6364 pub snippet_offset : usize ,
6465
66+ /// All package.json dependencies we've learned about so far
67+ pub package_json_read : HashSet < & ' a str > ,
68+ pub npm_dependencies : HashMap < String , ( & ' a str , String ) > ,
69+
6570 pub anyref : wasm_bindgen_anyref_xform:: Context ,
6671}
6772
@@ -1250,8 +1255,7 @@ impl<'a> Context<'a> {
12501255 passStringToWasm = function(arg) {{ {} }};
12511256 }}
12521257 " ,
1253- use_encode_into,
1254- use_encode,
1258+ use_encode_into, use_encode,
12551259 ) ) ;
12561260 }
12571261 }
@@ -2409,6 +2413,10 @@ impl<'a, 'b> SubContext<'a, 'b> {
24092413 self . cx . typescript . push_str ( "\n \n " ) ;
24102414 }
24112415
2416+ if let Some ( path) = self . program . package_json {
2417+ self . add_package_json ( path) ?;
2418+ }
2419+
24122420 Ok ( ( ) )
24132421 }
24142422
@@ -2869,6 +2877,67 @@ impl<'a, 'b> SubContext<'a, 'b> {
28692877 let import = self . determine_import ( import, item) ?;
28702878 Ok ( self . cx . import_identifier ( import) )
28712879 }
2880+
2881+ fn add_package_json ( & mut self , path : & ' b str ) -> Result < ( ) , Error > {
2882+ if !self . cx . package_json_read . insert ( path) {
2883+ return Ok ( ( ) ) ;
2884+ }
2885+ if !self . cx . config . mode . nodejs ( ) && !self . cx . config . mode . bundler ( ) {
2886+ bail ! ( "NPM dependencies have been specified in `{}` but \
2887+ this is only compatible with the default output of \
2888+ `wasm-bindgen` or the `--nodejs` flag") ;
2889+ }
2890+ let contents = fs:: read_to_string ( path) . context ( format ! ( "failed to read `{}`" , path) ) ?;
2891+ let json: serde_json:: Value = serde_json:: from_str ( & contents) ?;
2892+ let object = match json. as_object ( ) {
2893+ Some ( s) => s,
2894+ None => bail ! (
2895+ "expected `package.json` to have an JSON object in `{}`" ,
2896+ path
2897+ ) ,
2898+ } ;
2899+ let mut iter = object. iter ( ) ;
2900+ let ( key, value) = match iter. next ( ) {
2901+ Some ( pair) => pair,
2902+ None => return Ok ( ( ) ) ,
2903+ } ;
2904+ if key != "dependencies" || iter. next ( ) . is_some ( ) {
2905+ bail ! (
2906+ "NPM manifest found at `{}` can currently only have one key, \
2907+ `dependencies`, and no other fields",
2908+ path
2909+ ) ;
2910+ }
2911+ let value = match value. as_object ( ) {
2912+ Some ( s) => s,
2913+ None => bail ! ( "expected `dependencies` to be a JSON object in `{}`" , path) ,
2914+ } ;
2915+
2916+ for ( name, value) in value. iter ( ) {
2917+ let value = match value. as_str ( ) {
2918+ Some ( s) => s,
2919+ None => bail ! (
2920+ "keys in `dependencies` are expected to be strings in `{}`" ,
2921+ path
2922+ ) ,
2923+ } ;
2924+ if let Some ( ( prev, _prev_version) ) = self . cx . npm_dependencies . get ( name) {
2925+ bail ! (
2926+ "dependency on NPM package `{}` specified in two `package.json` files, \
2927+ which at the time is not allowed:\n * {}\n * {}",
2928+ name,
2929+ path,
2930+ prev
2931+ )
2932+ }
2933+
2934+ self . cx
2935+ . npm_dependencies
2936+ . insert ( name. to_string ( ) , ( path, value. to_string ( ) ) ) ;
2937+ }
2938+
2939+ Ok ( ( ) )
2940+ }
28722941}
28732942
28742943#[ derive( Hash , Eq , PartialEq ) ]
0 commit comments