diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/compat/esm_resolver.rs | 13 | ||||
-rw-r--r-- | cli/compat/mod.rs | 107 | ||||
-rw-r--r-- | cli/deno_std.rs | 11 | ||||
-rw-r--r-- | cli/main.rs | 1 | ||||
-rw-r--r-- | cli/node/errors.rs (renamed from cli/compat/errors.rs) | 0 | ||||
-rw-r--r-- | cli/node/mod.rs | 225 | ||||
-rw-r--r-- | cli/proc_state.rs | 2 | ||||
-rw-r--r-- | cli/tools/init/mod.rs | 7 |
8 files changed, 255 insertions, 111 deletions
diff --git a/cli/compat/esm_resolver.rs b/cli/compat/esm_resolver.rs index 77d0fe47e..2a5da4fe1 100644 --- a/cli/compat/esm_resolver.rs +++ b/cli/compat/esm_resolver.rs @@ -1,6 +1,6 @@ // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. -use super::errors; +use crate::node::errors; use crate::resolver::ImportMapResolver; use deno_core::error::generic_error; use deno_core::error::AnyError; @@ -84,7 +84,7 @@ fn node_resolve( ) -> Result<ResolveResponse, AnyError> { // TODO(bartlomieju): skipped "policy" part as we don't plan to support it - if let Some(resolved) = crate::compat::try_resolve_builtin_module(specifier) { + if let Some(resolved) = crate::node::try_resolve_builtin_module(specifier) { return Ok(ResolveResponse::Esm(resolved)); } @@ -99,7 +99,7 @@ fn node_resolve( let split_specifier = url.as_str().split(':'); let specifier = split_specifier.skip(1).collect::<String>(); if let Some(resolved) = - crate::compat::try_resolve_builtin_module(&specifier) + crate::node::try_resolve_builtin_module(&specifier) { return Ok(ResolveResponse::Esm(resolved)); } else { @@ -1154,7 +1154,7 @@ fn legacy_main_resolve( #[cfg(test)] mod tests { use super::*; - use crate::compat::STD_URL_STR; + use crate::deno_std::CURRENT_STD_URL; fn testdir(name: &str) -> PathBuf { let c = PathBuf::from(env!("CARGO_MANIFEST_DIR")); @@ -1233,10 +1233,7 @@ mod tests { fn builtin_http() { let cwd = testdir("basic"); let main = Url::from_file_path(cwd.join("main.js")).unwrap(); - let expected = Url::parse(STD_URL_STR) - .unwrap() - .join("node/http.ts") - .unwrap(); + let expected = CURRENT_STD_URL.join("node/http.ts").unwrap(); let actual = node_resolve("http", main.as_str(), &cwd).unwrap(); assert!(matches!(actual, ResolveResponse::Esm(_))); diff --git a/cli/compat/mod.rs b/cli/compat/mod.rs index fb2f2628c..0581f208f 100644 --- a/cli/compat/mod.rs +++ b/cli/compat/mod.rs @@ -1,9 +1,10 @@ // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. -pub mod errors; mod esm_resolver; use crate::file_fetcher::FileFetcher; +use crate::node::NODE_COMPAT_URL; +use crate::node::SUPPORTED_MODULES; use deno_ast::MediaType; use deno_core::error::AnyError; use deno_core::located_script_name; @@ -15,101 +16,21 @@ use once_cell::sync::Lazy; pub use esm_resolver::check_if_should_use_esm_loader; pub use esm_resolver::NodeEsmResolver; -// WARNING: Ensure this is the only deno_std version reference as this -// is automatically updated by the version bump workflow. -pub(crate) static STD_URL_STR: &str = "https://deno.land/std@0.153.0/"; - -static SUPPORTED_MODULES: &[&str] = &[ - "assert", - "assert/strict", - "async_hooks", - "buffer", - "child_process", - "cluster", - "console", - "constants", - "crypto", - "dgram", - "dns", - "domain", - "events", - "fs", - "fs/promises", - "http", - "https", - "module", - "net", - "os", - "path", - "path/posix", - "path/win32", - "perf_hooks", - "process", - "querystring", - "readline", - "stream", - "stream/promises", - "stream/web", - "string_decoder", - "sys", - "timers", - "timers/promises", - "tls", - "tty", - "url", - "util", - "util/types", - "v8", - "vm", - "worker_threads", - "zlib", -]; - -static NODE_COMPAT_URL: Lazy<String> = Lazy::new(|| { - std::env::var("DENO_NODE_COMPAT_URL") - .map(String::into) - .ok() - .unwrap_or_else(|| STD_URL_STR.to_string()) -}); - -static GLOBAL_URL_STR: Lazy<String> = - Lazy::new(|| format!("{}node/global.ts", NODE_COMPAT_URL.as_str())); - pub static GLOBAL_URL: Lazy<Url> = - Lazy::new(|| Url::parse(&GLOBAL_URL_STR).unwrap()); - -static MODULE_URL_STR: Lazy<String> = - Lazy::new(|| format!("{}node/module.ts", NODE_COMPAT_URL.as_str())); - -pub static MODULE_ALL_URL: Lazy<Url> = - Lazy::new(|| Url::parse(&MODULE_ALL_URL_STR).unwrap()); - -static MODULE_ALL_URL_STR: Lazy<String> = - Lazy::new(|| format!("{}node/module_all.ts", NODE_COMPAT_URL.as_str())); + Lazy::new(|| NODE_COMPAT_URL.join("node/global.ts").unwrap()); pub static MODULE_URL: Lazy<Url> = - Lazy::new(|| Url::parse(&MODULE_URL_STR).unwrap()); + Lazy::new(|| NODE_COMPAT_URL.join("node/module.ts").unwrap()); static COMPAT_IMPORT_URL: Lazy<Url> = Lazy::new(|| Url::parse("flags:compat").unwrap()); /// Provide imports into a module graph when the compat flag is true. pub fn get_node_imports() -> Vec<(Url, Vec<String>)> { - vec![(COMPAT_IMPORT_URL.clone(), vec![GLOBAL_URL_STR.clone()])] -} - -pub fn try_resolve_builtin_module(specifier: &str) -> Option<Url> { - if SUPPORTED_MODULES.contains(&specifier) { - let ext = match specifier { - "stream/promises" => "mjs", - _ => "ts", - }; - let module_url = - format!("{}node/{}.{}", NODE_COMPAT_URL.as_str(), specifier, ext); - Some(Url::parse(&module_url).unwrap()) - } else { - None - } + vec![( + COMPAT_IMPORT_URL.clone(), + vec![GLOBAL_URL.as_str().to_owned()], + )] } pub fn load_cjs_module( @@ -122,7 +43,7 @@ pub fn load_cjs_module( const Module = await import("{module_loader}"); Module.default._load(module, null, {main}); }})('{module}');"#, - module_loader = MODULE_URL_STR.as_str(), + module_loader = MODULE_URL.as_str(), main = main, module = escape_for_single_quote_string(module), ); @@ -141,7 +62,7 @@ pub fn add_global_require( const require = Module.createRequire(main); globalThis.require = require; }})('{}');"#, - MODULE_URL_STR.as_str(), + MODULE_URL.as_str(), escape_for_single_quote_string(main_module), ); @@ -159,8 +80,12 @@ pub fn setup_builtin_modules( let mut script = String::new(); for module in SUPPORTED_MODULES { // skipping the modules that contains '/' as they are not available in NodeJS repl as well - if !module.contains('/') { - script = format!("{}const {} = require('{}');\n", script, module, module); + if !module.name.contains('/') { + script = format!( + "{}const {MODULE_NAME} = require('{MODULE_NAME}');\n", + script, + MODULE_NAME = module.name + ); } } diff --git a/cli/deno_std.rs b/cli/deno_std.rs new file mode 100644 index 000000000..6ba9f2244 --- /dev/null +++ b/cli/deno_std.rs @@ -0,0 +1,11 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. + +use deno_core::url::Url; +use once_cell::sync::Lazy; + +// WARNING: Ensure this is the only deno_std version reference as this +// is automatically updated by the version bump workflow. +static CURRENT_STD_URL_STR: &str = "https://deno.land/std@0.153.0/"; + +pub static CURRENT_STD_URL: Lazy<Url> = + Lazy::new(|| Url::parse(CURRENT_STD_URL_STR).unwrap()); diff --git a/cli/main.rs b/cli/main.rs index ead113697..79a806f0b 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -7,6 +7,7 @@ mod cdp; mod checksum; mod compat; mod deno_dir; +mod deno_std; mod diagnostics; mod diff; mod display; diff --git a/cli/compat/errors.rs b/cli/node/errors.rs index d7d1bbd05..d7d1bbd05 100644 --- a/cli/compat/errors.rs +++ b/cli/node/errors.rs diff --git a/cli/node/mod.rs b/cli/node/mod.rs index c19179d0c..71046b4b7 100644 --- a/cli/node/mod.rs +++ b/cli/node/mod.rs @@ -4,6 +4,7 @@ use std::collections::HashSet; use std::path::Path; use std::path::PathBuf; +use crate::deno_std::CURRENT_STD_URL; use deno_ast::MediaType; use deno_ast::ModuleSpecifier; use deno_core::anyhow::bail; @@ -27,7 +28,6 @@ use once_cell::sync::Lazy; use path_clean::PathClean; use regex::Regex; -use crate::compat; use crate::file_fetcher::FileFetcher; use crate::npm::GlobalNpmPackageResolver; use crate::npm::NpmPackageReference; @@ -35,9 +35,218 @@ use crate::npm::NpmPackageReq; use crate::npm::NpmPackageResolver; mod analyze; +pub mod errors; pub use analyze::esm_code_with_node_globals; +pub struct NodeModulePolyfill { + /// Name of the module like "assert" or "timers/promises" + pub name: &'static str, + + /// Specifier relative to the root of `deno_std` repo, like "node/asser.ts" + pub specifier: &'static str, +} + +pub(crate) static SUPPORTED_MODULES: &[NodeModulePolyfill] = &[ + NodeModulePolyfill { + name: "assert", + specifier: "node/assert.ts", + }, + NodeModulePolyfill { + name: "assert/strict", + specifier: "node/assert/strict.ts", + }, + NodeModulePolyfill { + name: "async_hooks", + specifier: "node/async_hooks.ts", + }, + NodeModulePolyfill { + name: "buffer", + specifier: "node/buffer.ts", + }, + NodeModulePolyfill { + name: "child_process", + specifier: "node/child_process.ts", + }, + NodeModulePolyfill { + name: "cluster", + specifier: "node/cluster.ts", + }, + NodeModulePolyfill { + name: "console", + specifier: "node/console.ts", + }, + NodeModulePolyfill { + name: "constants", + specifier: "node/constants.ts", + }, + NodeModulePolyfill { + name: "crypto", + specifier: "node/crypto.ts", + }, + NodeModulePolyfill { + name: "dgram", + specifier: "node/dgram.ts", + }, + NodeModulePolyfill { + name: "dns", + specifier: "node/dns.ts", + }, + NodeModulePolyfill { + name: "domain", + specifier: "node/domain.ts", + }, + NodeModulePolyfill { + name: "events", + specifier: "node/events.ts", + }, + NodeModulePolyfill { + name: "fs", + specifier: "node/fs.ts", + }, + NodeModulePolyfill { + name: "fs/promises", + specifier: "node/fs/promises.ts", + }, + NodeModulePolyfill { + name: "http", + specifier: "node/http.ts", + }, + NodeModulePolyfill { + name: "https", + specifier: "node/https.ts", + }, + NodeModulePolyfill { + name: "module", + specifier: "node/module.ts", + }, + NodeModulePolyfill { + name: "net", + specifier: "node/net.ts", + }, + NodeModulePolyfill { + name: "os", + specifier: "node/os.ts", + }, + NodeModulePolyfill { + name: "path", + specifier: "node/path.ts", + }, + NodeModulePolyfill { + name: "path/posix", + specifier: "node/path/posix.ts", + }, + NodeModulePolyfill { + name: "path/win32", + specifier: "node/path/win32.ts", + }, + NodeModulePolyfill { + name: "perf_hooks", + specifier: "node/perf_hooks.ts", + }, + NodeModulePolyfill { + name: "process", + specifier: "node/process.ts", + }, + NodeModulePolyfill { + name: "querystring", + specifier: "node/querystring.ts", + }, + NodeModulePolyfill { + name: "readline", + specifier: "node/readline.ts", + }, + NodeModulePolyfill { + name: "stream", + specifier: "node/stream.ts", + }, + NodeModulePolyfill { + name: "stream/promises", + specifier: "node/stream/promises.mjs", + }, + NodeModulePolyfill { + name: "stream/web", + specifier: "node/stream/web.ts", + }, + NodeModulePolyfill { + name: "string_decoder", + specifier: "node/string_decoder.ts", + }, + NodeModulePolyfill { + name: "sys", + specifier: "node/sys.ts", + }, + NodeModulePolyfill { + name: "timers", + specifier: "node/timers.ts", + }, + NodeModulePolyfill { + name: "timers/promises", + specifier: "node/timers/promises.ts", + }, + NodeModulePolyfill { + name: "tls", + specifier: "node/tls.ts", + }, + NodeModulePolyfill { + name: "tty", + specifier: "node/tty.ts", + }, + NodeModulePolyfill { + name: "url", + specifier: "node/url.ts", + }, + NodeModulePolyfill { + name: "util", + specifier: "node/util.ts", + }, + NodeModulePolyfill { + name: "util/types", + specifier: "node/util/types.ts", + }, + NodeModulePolyfill { + name: "v8", + specifier: "node/v8.ts", + }, + NodeModulePolyfill { + name: "vm", + specifier: "node/vm.ts", + }, + NodeModulePolyfill { + name: "worker_threads", + specifier: "node/worker_threads.ts", + }, + NodeModulePolyfill { + name: "zlib", + specifier: "node/zlib.ts", + }, +]; + +pub(crate) static NODE_COMPAT_URL: Lazy<Url> = Lazy::new(|| { + if let Ok(url_str) = std::env::var("DENO_NODE_COMPAT_URL") { + let url = Url::parse(&url_str).expect( + "Malformed DENO_NODE_COMPAT_URL value, make sure it's a file URL ending with a slash" + ); + return url; + } + + CURRENT_STD_URL.clone() +}); + +pub static MODULE_ALL_URL: Lazy<Url> = + Lazy::new(|| NODE_COMPAT_URL.join("node/module_all.ts").unwrap()); + +pub fn try_resolve_builtin_module(specifier: &str) -> Option<Url> { + for module in SUPPORTED_MODULES { + if module.name == specifier { + let module_url = NODE_COMPAT_URL.join(module.specifier).unwrap(); + return Some(module_url); + } + } + + None +} + static RESERVED_WORDS: Lazy<HashSet<&str>> = Lazy::new(|| { HashSet::from([ "break", @@ -96,7 +305,7 @@ pub async fn initialize_runtime( const moduleAll = await import(moduleAllUrl); Deno[Deno.internal].node.initialize(moduleAll.default); }})('{}');"#, - compat::MODULE_ALL_URL.as_str(), + MODULE_ALL_URL.as_str(), ); let value = @@ -142,7 +351,7 @@ pub fn node_resolve( Url::parse("node:module").unwrap(), ))); } - if let Some(resolved) = compat::try_resolve_builtin_module(specifier) { + if let Some(resolved) = try_resolve_builtin_module(specifier) { return Ok(Some(ResolveResponse::Esm(resolved))); } @@ -165,7 +374,7 @@ pub fn node_resolve( ))); } - if let Some(resolved) = compat::try_resolve_builtin_module(&specifier) { + if let Some(resolved) = try_resolve_builtin_module(&specifier) { return Ok(Some(ResolveResponse::Esm(resolved))); } else { return Err(generic_error(format!("Unknown module {}", specifier))); @@ -173,7 +382,7 @@ pub fn node_resolve( } if protocol != "file" && protocol != "data" { - return Err(compat::errors::err_unsupported_esm_url_scheme(&url)); + return Err(errors::err_unsupported_esm_url_scheme(&url)); } // todo(THIS PR): I think this is handled upstream so can be removed? @@ -410,7 +619,7 @@ fn finalize_resolution( let encoded_sep_re = Regex::new(r"%2F|%2C").unwrap(); if encoded_sep_re.is_match(resolved.path()) { - return Err(compat::errors::err_invalid_module_specifier( + return Err(errors::err_invalid_module_specifier( resolved.path(), "must not include encoded \"/\" or \"\\\\\" characters", Some(to_file_path_string(base)), @@ -437,12 +646,12 @@ fn finalize_resolution( (false, false) }; if is_dir { - return Err(compat::errors::err_unsupported_dir_import( + return Err(errors::err_unsupported_dir_import( resolved.as_str(), base.as_str(), )); } else if !is_file { - return Err(compat::errors::err_module_not_found( + return Err(errors::err_module_not_found( resolved.as_str(), base.as_str(), "module", diff --git a/cli/proc_state.rs b/cli/proc_state.rs index 123c9f262..806bb030b 100644 --- a/cli/proc_state.rs +++ b/cli/proc_state.rs @@ -491,7 +491,7 @@ impl ProcState { /// Add the builtin node modules to the graph data. pub async fn prepare_node_std_graph(&self) -> Result<(), AnyError> { let node_std_graph = self - .create_graph(vec![(compat::MODULE_ALL_URL.clone(), ModuleKind::Esm)]) + .create_graph(vec![(node::MODULE_ALL_URL.clone(), ModuleKind::Esm)]) .await?; self.graph_data.write().add_graph(&node_std_graph, false); Ok(()) diff --git a/cli/tools/init/mod.rs b/cli/tools/init/mod.rs index e47b88702..0966a9927 100644 --- a/cli/tools/init/mod.rs +++ b/cli/tools/init/mod.rs @@ -1,8 +1,9 @@ // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. use crate::args::InitFlags; -use crate::compat; -use deno_core::{anyhow::Context, error::AnyError}; +use crate::deno_std; +use deno_core::anyhow::Context; +use deno_core::error::AnyError; use std::io::Write; use std::path::Path; @@ -35,7 +36,7 @@ pub async fn init_project(init_flags: InitFlags) -> Result<(), AnyError> { create_file(&dir, "main.ts", main_ts)?; let main_test_ts = include_str!("./templates/main_test.ts") - .replace("{CURRENT_STD_URL}", compat::STD_URL_STR); + .replace("{CURRENT_STD_URL}", deno_std::CURRENT_STD_URL.as_str()); create_file(&dir, "main_test.ts", &main_test_ts)?; println!("✅ Project initialized"); |