diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/file_fetcher.rs | 2 | ||||
-rw-r--r-- | cli/standalone.rs | 41 | ||||
-rw-r--r-- | cli/tests/integration_tests.rs | 32 | ||||
-rw-r--r-- | cli/tests/standalone_import_datauri.ts | 4 |
4 files changed, 71 insertions, 8 deletions
diff --git a/cli/file_fetcher.rs b/cli/file_fetcher.rs index 4d3048750..8403c660d 100644 --- a/cli/file_fetcher.rs +++ b/cli/file_fetcher.rs @@ -191,7 +191,7 @@ pub fn map_content_type( } /// Remove shebangs from the start of source code strings -fn strip_shebang(mut value: String) -> String { +pub fn strip_shebang(mut value: String) -> String { if value.starts_with("#!") { if let Some(mid) = value.find('\n') { let (_, rest) = value.split_at(mid); diff --git a/cli/standalone.rs b/cli/standalone.rs index e69ca971b..60415c7e7 100644 --- a/cli/standalone.rs +++ b/cli/standalone.rs @@ -1,8 +1,12 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. use crate::colors; +use crate::file_fetcher::get_source_from_bytes; +use crate::file_fetcher::strip_shebang; use crate::version; +use data_url::DataUrl; use deno_core::error::type_error; +use deno_core::error::uri_error; use deno_core::error::AnyError; use deno_core::error::Context; use deno_core::futures::FutureExt; @@ -109,6 +113,19 @@ fn read_string_slice( Ok(string) } +fn get_source_from_data_url( + specifier: &ModuleSpecifier, +) -> Result<String, AnyError> { + let data_url = DataUrl::process(specifier.as_str()) + .map_err(|e| uri_error(format!("{:?}", e)))?; + let mime = data_url.mime_type(); + let charset = mime.get_parameter("charset").map(|v| v.to_string()); + let (bytes, _) = data_url + .decode_to_vec() + .map_err(|e| uri_error(format!("{:?}", e)))?; + Ok(strip_shebang(get_source_from_bytes(bytes, charset)?)) +} + const SPECIFIER: &str = "file://$deno$/bundle.js"; struct EmbeddedModuleLoader(String); @@ -121,12 +138,16 @@ impl ModuleLoader for EmbeddedModuleLoader { _referrer: &str, _is_main: bool, ) -> Result<ModuleSpecifier, AnyError> { - if specifier != SPECIFIER { - return Err(type_error( - "Self-contained binaries don't support module loading", - )); + if let Ok(module_specifier) = resolve_url(&specifier) { + if get_source_from_data_url(&module_specifier).is_ok() + || specifier == SPECIFIER + { + return Ok(module_specifier); + } } - Ok(resolve_url(specifier)?) + Err(type_error( + "Self-contained binaries don't support module loading", + )) } fn load( @@ -137,13 +158,19 @@ impl ModuleLoader for EmbeddedModuleLoader { _is_dynamic: bool, ) -> Pin<Box<deno_core::ModuleSourceFuture>> { let module_specifier = module_specifier.clone(); - let code = self.0.to_string(); + let is_data_uri = get_source_from_data_url(&module_specifier).ok(); + let code = if let Some(ref source) = is_data_uri { + source.to_string() + } else { + self.0.to_string() + }; async move { - if module_specifier.to_string() != SPECIFIER { + if is_data_uri.is_none() && module_specifier.to_string() != SPECIFIER { return Err(type_error( "Self-contained binaries don't support module loading", )); } + Ok(deno_core::ModuleSource { code, module_url_specified: module_specifier.to_string(), diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index 6c5626666..d58080210 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -5845,6 +5845,38 @@ console.log("finish"); } #[test] + fn standalone_load_datauri() { + let dir = TempDir::new().expect("tempdir fail"); + let exe = if cfg!(windows) { + dir.path().join("load_datauri.exe") + } else { + dir.path().join("load_datauri") + }; + let output = util::deno_cmd() + .current_dir(util::root_path()) + .arg("compile") + .arg("--unstable") + .arg("--output") + .arg(&exe) + .arg("./cli/tests/standalone_import_datauri.ts") + .stdout(std::process::Stdio::piped()) + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(output.status.success()); + let output = Command::new(exe) + .stdout(std::process::Stdio::piped()) + .stderr(std::process::Stdio::piped()) + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(output.status.success()); + assert_eq!(output.stdout, b"Hello Deno!\n"); + } + + #[test] fn compile_with_directory_exists_error() { let dir = TempDir::new().expect("tempdir fail"); let exe = if cfg!(windows) { diff --git a/cli/tests/standalone_import_datauri.ts b/cli/tests/standalone_import_datauri.ts new file mode 100644 index 000000000..68f348828 --- /dev/null +++ b/cli/tests/standalone_import_datauri.ts @@ -0,0 +1,4 @@ +const c = await import( + "data:text/javascript;base64,ZXhwb3J0IGRlZmF1bHQgJ0hlbGxvIERlbm8hJw==" +); +console.log(c.default); // Output: "Hello Deno!" |