summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2021-06-05 19:54:17 +0530
committerGitHub <noreply@github.com>2021-06-05 16:24:17 +0200
commite67010b5e2eaa5a5ddb756d7ddc2dd0194f09a0a (patch)
tree1c5abb176c12922ed5ed769972e4edae5f604ceb
parent4b3d55b449dd703aaa693410f0d37a2308bb0fd6 (diff)
feat(cli/compile): Support data uri dynamic imports in `deno compile` (#9936)
-rw-r--r--cli/file_fetcher.rs2
-rw-r--r--cli/standalone.rs41
-rw-r--r--cli/tests/integration_tests.rs32
-rw-r--r--cli/tests/standalone_import_datauri.ts4
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!"