mirror of
https://github.com/denoland/deno.git
synced 2024-11-28 16:20:57 -05:00
feat(unstable): allow bare specifier for builtin node module (#20728)
closes #20566
This commit is contained in:
parent
8d9fef3b89
commit
fb73eb1e9d
17 changed files with 319 additions and 57 deletions
43
Cargo.lock
generated
43
Cargo.lock
generated
|
@ -995,7 +995,7 @@ dependencies = [
|
||||||
"deno_lockfile",
|
"deno_lockfile",
|
||||||
"deno_npm",
|
"deno_npm",
|
||||||
"deno_runtime",
|
"deno_runtime",
|
||||||
"deno_semver 0.5.1",
|
"deno_semver",
|
||||||
"deno_task_shell",
|
"deno_task_shell",
|
||||||
"dissimilar",
|
"dissimilar",
|
||||||
"dprint-plugin-json",
|
"dprint-plugin-json",
|
||||||
|
@ -1180,12 +1180,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_config"
|
name = "deno_config"
|
||||||
version = "0.3.1"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed5999e360fec39bbfee5d85bac82c5f557ed93a58660bc255026a90796138c6"
|
checksum = "fed704bc09eb4f88b26b16c75f87795d1ea1e658e26867fe684cef91c55543f1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"deno_semver 0.4.0",
|
|
||||||
"indexmap 2.0.0",
|
"indexmap 2.0.0",
|
||||||
"jsonc-parser",
|
"jsonc-parser",
|
||||||
"log",
|
"log",
|
||||||
|
@ -1266,9 +1265,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_doc"
|
name = "deno_doc"
|
||||||
version = "0.67.0"
|
version = "0.68.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2480971d683babc07eea6cdb37d1214675c25d084b0c819e2e52898634b044ce"
|
checksum = "b7f5649a3e8c8da3e73d27eff6306c522f1bb0c54e75fad5530f3a4746eea81f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"deno_ast",
|
"deno_ast",
|
||||||
|
@ -1284,9 +1283,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_emit"
|
name = "deno_emit"
|
||||||
version = "0.28.0"
|
version = "0.29.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ebc68365e2e5ce6dd11506a1a17aac6a10ea7787e084c45690f70c46a6662fd8"
|
checksum = "ac5e585450dbafc39a2161bc9c8f861409cec08c014c4f82c62fdbce5ae335c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64 0.13.1",
|
"base64 0.13.1",
|
||||||
|
@ -1351,16 +1350,17 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_graph"
|
name = "deno_graph"
|
||||||
version = "0.55.0"
|
version = "0.56.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f09c93dac12402a37be3ee24e0b6a691ddc5fdef13831b375b6c0950efc89e40"
|
checksum = "f02ddb53a0d3201895566ef3c1c5861c62d06df3b0fac6a7dcf826dd081eec27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"data-url",
|
"data-url",
|
||||||
"deno_ast",
|
"deno_ast",
|
||||||
"deno_semver 0.5.1",
|
"deno_semver",
|
||||||
"futures",
|
"futures",
|
||||||
|
"import_map",
|
||||||
"indexmap 2.0.0",
|
"indexmap 2.0.0",
|
||||||
"monch",
|
"monch",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
@ -1584,7 +1584,7 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"deno_lockfile",
|
"deno_lockfile",
|
||||||
"deno_semver 0.5.1",
|
"deno_semver",
|
||||||
"futures",
|
"futures",
|
||||||
"log",
|
"log",
|
||||||
"monch",
|
"monch",
|
||||||
|
@ -1667,19 +1667,6 @@ dependencies = [
|
||||||
"winres",
|
"winres",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "deno_semver"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6f739a9d90c47e2af7e2fcbae0976360f3fb5292f7288a084d035ed44d12a288"
|
|
||||||
dependencies = [
|
|
||||||
"monch",
|
|
||||||
"once_cell",
|
|
||||||
"serde",
|
|
||||||
"thiserror",
|
|
||||||
"url",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_semver"
|
name = "deno_semver"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
|
@ -2242,16 +2229,16 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "eszip"
|
name = "eszip"
|
||||||
version = "0.53.0"
|
version = "0.54.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf1763e61b99be49c961817d2211fbcef23b04159a60895b208e4608beb20ee0"
|
checksum = "4032916b1567b2588723ea4d1aa47537ae0f580f64a0aba5dedc8bf13e20c6e0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64 0.21.4",
|
"base64 0.21.4",
|
||||||
"deno_ast",
|
"deno_ast",
|
||||||
"deno_graph",
|
"deno_graph",
|
||||||
"deno_npm",
|
"deno_npm",
|
||||||
"deno_semver 0.5.1",
|
"deno_semver",
|
||||||
"futures",
|
"futures",
|
||||||
"hashlink",
|
"hashlink",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
|
@ -47,18 +47,18 @@ winres.workspace = true
|
||||||
[dependencies]
|
[dependencies]
|
||||||
deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "dep_graph", "module_specifier", "proposal", "react", "sourcemap", "transforms", "typescript", "view", "visit"] }
|
deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "dep_graph", "module_specifier", "proposal", "react", "sourcemap", "transforms", "typescript", "view", "visit"] }
|
||||||
deno_cache_dir = "=0.6.0"
|
deno_cache_dir = "=0.6.0"
|
||||||
deno_config = "=0.3.1"
|
deno_config = "=0.4.0"
|
||||||
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
||||||
deno_doc = "=0.67.0"
|
deno_doc = "=0.68.0"
|
||||||
deno_emit = "=0.28.0"
|
deno_emit = "=0.29.0"
|
||||||
deno_graph = "=0.55.0"
|
deno_graph = "=0.56.3"
|
||||||
deno_lint = { version = "=0.51.0", features = ["docs"] }
|
deno_lint = { version = "=0.51.0", features = ["docs"] }
|
||||||
deno_lockfile.workspace = true
|
deno_lockfile.workspace = true
|
||||||
deno_npm = "0.15.2"
|
deno_npm = "0.15.2"
|
||||||
deno_runtime = { workspace = true, features = ["dont_create_runtime_snapshot", "exclude_runtime_main_js", "include_js_files_for_snapshotting"] }
|
deno_runtime = { workspace = true, features = ["dont_create_runtime_snapshot", "exclude_runtime_main_js", "include_js_files_for_snapshotting"] }
|
||||||
deno_semver = "0.5.1"
|
deno_semver = "0.5.1"
|
||||||
deno_task_shell = "=0.13.2"
|
deno_task_shell = "=0.13.2"
|
||||||
eszip = "=0.53.0"
|
eszip = "=0.54.0"
|
||||||
napi_sym.workspace = true
|
napi_sym.workspace = true
|
||||||
|
|
||||||
async-trait.workspace = true
|
async-trait.workspace = true
|
||||||
|
@ -68,7 +68,7 @@ bincode = "=1.3.3"
|
||||||
bytes.workspace = true
|
bytes.workspace = true
|
||||||
cache_control.workspace = true
|
cache_control.workspace = true
|
||||||
chrono.workspace = true
|
chrono.workspace = true
|
||||||
clap = { version = "=4.3.3", features = ["string"] }
|
clap = { version = "=4.3.3", features = ["env", "string"] }
|
||||||
clap_complete = "=4.3.1"
|
clap_complete = "=4.3.1"
|
||||||
clap_complete_fig = "=4.3.1"
|
clap_complete_fig = "=4.3.1"
|
||||||
console_static_text.workspace = true
|
console_static_text.workspace = true
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
use clap::builder::FalseyValueParser;
|
||||||
use clap::value_parser;
|
use clap::value_parser;
|
||||||
use clap::Arg;
|
use clap::Arg;
|
||||||
use clap::ArgAction;
|
use clap::ArgAction;
|
||||||
|
@ -405,6 +406,7 @@ pub struct Flags {
|
||||||
pub reload: bool,
|
pub reload: bool,
|
||||||
pub seed: Option<u64>,
|
pub seed: Option<u64>,
|
||||||
pub unstable: bool,
|
pub unstable: bool,
|
||||||
|
pub unstable_bare_node_builtlins: bool,
|
||||||
pub unsafely_ignore_certificate_errors: Option<Vec<String>>,
|
pub unsafely_ignore_certificate_errors: Option<Vec<String>>,
|
||||||
pub v8_flags: Vec<String>,
|
pub v8_flags: Vec<String>,
|
||||||
}
|
}
|
||||||
|
@ -801,6 +803,10 @@ pub fn flags_from_vec(args: Vec<String>) -> clap::error::Result<Flags> {
|
||||||
flags.unstable = true;
|
flags.unstable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if matches.get_flag("unstable-bare-node-builtins") {
|
||||||
|
flags.unstable_bare_node_builtlins = true;
|
||||||
|
}
|
||||||
|
|
||||||
if matches.get_flag("quiet") {
|
if matches.get_flag("quiet") {
|
||||||
flags.log_level = Some(Level::Error);
|
flags.log_level = Some(Level::Error);
|
||||||
} else if let Some(log_level) = matches.get_one::<String>("log-level") {
|
} else if let Some(log_level) = matches.get_one::<String>("log-level") {
|
||||||
|
@ -896,6 +902,15 @@ fn clap_root() -> Command {
|
||||||
.action(ArgAction::SetTrue)
|
.action(ArgAction::SetTrue)
|
||||||
.global(true),
|
.global(true),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("unstable-bare-node-builtins")
|
||||||
|
.long("unstable-bare-node-builtins")
|
||||||
|
.help("Enable unstable bare node builtins feature")
|
||||||
|
.env("DENO_UNSTABLE_BARE_NODE_BUILTINS")
|
||||||
|
.value_parser(FalseyValueParser::new())
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
.global(true),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("log-level")
|
Arg::new("log-level")
|
||||||
.short('L')
|
.short('L')
|
||||||
|
|
|
@ -1216,6 +1216,15 @@ impl CliOptions {
|
||||||
self.flags.unstable
|
self.flags.unstable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unstable_bare_node_builtlins(&self) -> bool {
|
||||||
|
self.flags.unstable_bare_node_builtlins
|
||||||
|
|| self
|
||||||
|
.maybe_config_file()
|
||||||
|
.as_ref()
|
||||||
|
.map(|c| c.json.unstable.contains(&"bare-node-builtins".to_string()))
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn v8_flags(&self) -> &Vec<String> {
|
pub fn v8_flags(&self) -> &Vec<String> {
|
||||||
&self.flags.v8_flags
|
&self.flags.v8_flags
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
use deno_ast::Diagnostic;
|
use deno_ast::Diagnostic;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
use deno_graph::source::ResolveError;
|
||||||
use deno_graph::ModuleError;
|
use deno_graph::ModuleError;
|
||||||
use deno_graph::ModuleGraphError;
|
use deno_graph::ModuleGraphError;
|
||||||
use deno_graph::ResolutionError;
|
use deno_graph::ResolutionError;
|
||||||
|
@ -45,7 +46,11 @@ fn get_module_graph_error_class(err: &ModuleGraphError) -> &'static str {
|
||||||
fn get_resolution_error_class(err: &ResolutionError) -> &'static str {
|
fn get_resolution_error_class(err: &ResolutionError) -> &'static str {
|
||||||
match err {
|
match err {
|
||||||
ResolutionError::ResolverError { error, .. } => {
|
ResolutionError::ResolverError { error, .. } => {
|
||||||
get_error_class_name(error.as_ref())
|
use ResolveError::*;
|
||||||
|
match error.as_ref() {
|
||||||
|
Specifier(_) => "TypeError",
|
||||||
|
Other(e) => get_error_class_name(e),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => "TypeError",
|
_ => "TypeError",
|
||||||
}
|
}
|
||||||
|
|
|
@ -378,6 +378,9 @@ impl CliFactory {
|
||||||
.to_maybe_jsx_import_source_config()?,
|
.to_maybe_jsx_import_source_config()?,
|
||||||
maybe_import_map: self.maybe_import_map().await?.clone(),
|
maybe_import_map: self.maybe_import_map().await?.clone(),
|
||||||
maybe_vendor_dir: self.options.vendor_dir_path(),
|
maybe_vendor_dir: self.options.vendor_dir_path(),
|
||||||
|
bare_node_builtins_enabled: self
|
||||||
|
.options
|
||||||
|
.unstable_bare_node_builtlins(),
|
||||||
},
|
},
|
||||||
)))
|
)))
|
||||||
})
|
})
|
||||||
|
|
|
@ -24,6 +24,7 @@ use deno_core::parking_lot::Mutex;
|
||||||
use deno_core::parking_lot::RwLock;
|
use deno_core::parking_lot::RwLock;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
use deno_graph::source::Loader;
|
use deno_graph::source::Loader;
|
||||||
|
use deno_graph::source::ResolveError;
|
||||||
use deno_graph::GraphKind;
|
use deno_graph::GraphKind;
|
||||||
use deno_graph::Module;
|
use deno_graph::Module;
|
||||||
use deno_graph::ModuleError;
|
use deno_graph::ModuleError;
|
||||||
|
@ -487,10 +488,14 @@ fn get_resolution_error_bare_specifier(
|
||||||
{
|
{
|
||||||
Some(specifier.as_str())
|
Some(specifier.as_str())
|
||||||
} else if let ResolutionError::ResolverError { error, .. } = error {
|
} else if let ResolutionError::ResolverError { error, .. } = error {
|
||||||
if let Some(ImportMapError::UnmappedBareSpecifier(specifier, _)) =
|
if let ResolveError::Other(error) = (*error).as_ref() {
|
||||||
error.downcast_ref::<ImportMapError>()
|
if let Some(ImportMapError::UnmappedBareSpecifier(specifier, _)) =
|
||||||
{
|
error.downcast_ref::<ImportMapError>()
|
||||||
Some(specifier.as_str())
|
{
|
||||||
|
Some(specifier.as_str())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -679,6 +684,7 @@ mod test {
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use deno_ast::ModuleSpecifier;
|
use deno_ast::ModuleSpecifier;
|
||||||
|
use deno_graph::source::ResolveError;
|
||||||
use deno_graph::Position;
|
use deno_graph::Position;
|
||||||
use deno_graph::Range;
|
use deno_graph::Range;
|
||||||
use deno_graph::ResolutionError;
|
use deno_graph::ResolutionError;
|
||||||
|
@ -696,7 +702,7 @@ mod test {
|
||||||
let specifier = ModuleSpecifier::parse("file:///file.ts").unwrap();
|
let specifier = ModuleSpecifier::parse("file:///file.ts").unwrap();
|
||||||
let err = import_map.resolve(input, &specifier).err().unwrap();
|
let err = import_map.resolve(input, &specifier).err().unwrap();
|
||||||
let err = ResolutionError::ResolverError {
|
let err = ResolutionError::ResolverError {
|
||||||
error: Arc::new(err.into()),
|
error: Arc::new(ResolveError::Other(err.into())),
|
||||||
specifier: input.to_string(),
|
specifier: input.to_string(),
|
||||||
range: Range {
|
range: Range {
|
||||||
specifier,
|
specifier,
|
||||||
|
|
|
@ -970,6 +970,8 @@ pub enum DenoDiagnostic {
|
||||||
ResolutionError(deno_graph::ResolutionError),
|
ResolutionError(deno_graph::ResolutionError),
|
||||||
/// Invalid `node:` specifier.
|
/// Invalid `node:` specifier.
|
||||||
InvalidNodeSpecifier(ModuleSpecifier),
|
InvalidNodeSpecifier(ModuleSpecifier),
|
||||||
|
/// Bare specifier is used for `node:` specifier
|
||||||
|
BareNodeSpecifier(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DenoDiagnostic {
|
impl DenoDiagnostic {
|
||||||
|
@ -1003,6 +1005,7 @@ impl DenoDiagnostic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::InvalidNodeSpecifier(_) => "resolver-error",
|
Self::InvalidNodeSpecifier(_) => "resolver-error",
|
||||||
|
Self::BareNodeSpecifier(_) => "import-node-prefix-missing",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1174,6 +1177,7 @@ impl DenoDiagnostic {
|
||||||
.map(|specifier| json!({ "specifier": specifier }))
|
.map(|specifier| json!({ "specifier": specifier }))
|
||||||
),
|
),
|
||||||
Self::InvalidNodeSpecifier(specifier) => (lsp::DiagnosticSeverity::ERROR, format!("Unknown Node built-in module: {}", specifier.path()), None),
|
Self::InvalidNodeSpecifier(specifier) => (lsp::DiagnosticSeverity::ERROR, format!("Unknown Node built-in module: {}", specifier.path()), None),
|
||||||
|
Self::BareNodeSpecifier(specifier) => (lsp::DiagnosticSeverity::WARNING, format!("\"{}\" is resolved to \"node:{}\". If you want to use a built-in Node module, add a \"node:\" prefix.", specifier, specifier), Some(json!({ "specifier": specifier }))),
|
||||||
};
|
};
|
||||||
lsp::Diagnostic {
|
lsp::Diagnostic {
|
||||||
range: *range,
|
range: *range,
|
||||||
|
@ -1189,6 +1193,7 @@ impl DenoDiagnostic {
|
||||||
|
|
||||||
fn diagnose_resolution(
|
fn diagnose_resolution(
|
||||||
snapshot: &language_server::StateSnapshot,
|
snapshot: &language_server::StateSnapshot,
|
||||||
|
dependency_key: &str,
|
||||||
resolution: &Resolution,
|
resolution: &Resolution,
|
||||||
is_dynamic: bool,
|
is_dynamic: bool,
|
||||||
maybe_assert_type: Option<&str>,
|
maybe_assert_type: Option<&str>,
|
||||||
|
@ -1253,6 +1258,20 @@ fn diagnose_resolution(
|
||||||
if !deno_node::is_builtin_node_module(module_name) {
|
if !deno_node::is_builtin_node_module(module_name) {
|
||||||
diagnostics
|
diagnostics
|
||||||
.push(DenoDiagnostic::InvalidNodeSpecifier(specifier.clone()));
|
.push(DenoDiagnostic::InvalidNodeSpecifier(specifier.clone()));
|
||||||
|
} else if module_name == dependency_key {
|
||||||
|
let mut is_mapped = false;
|
||||||
|
if let Some(import_map) = &snapshot.maybe_import_map {
|
||||||
|
if let Resolution::Ok(resolved) = &resolution {
|
||||||
|
if import_map.resolve(module_name, &resolved.specifier).is_ok() {
|
||||||
|
is_mapped = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// show diagnostics for bare node specifiers that aren't mapped by import map
|
||||||
|
if !is_mapped {
|
||||||
|
diagnostics
|
||||||
|
.push(DenoDiagnostic::BareNodeSpecifier(module_name.to_string()));
|
||||||
|
}
|
||||||
} else if let Some(npm_resolver) = snapshot
|
} else if let Some(npm_resolver) = snapshot
|
||||||
.npm
|
.npm
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -1329,6 +1348,7 @@ fn diagnose_dependency(
|
||||||
diagnostics.extend(
|
diagnostics.extend(
|
||||||
diagnose_resolution(
|
diagnose_resolution(
|
||||||
snapshot,
|
snapshot,
|
||||||
|
dependency_key,
|
||||||
if dependency.maybe_code.is_none() {
|
if dependency.maybe_code.is_none() {
|
||||||
&dependency.maybe_type
|
&dependency.maybe_type
|
||||||
} else {
|
} else {
|
||||||
|
@ -1362,6 +1382,7 @@ fn diagnose_dependency(
|
||||||
diagnostics.extend(
|
diagnostics.extend(
|
||||||
diagnose_resolution(
|
diagnose_resolution(
|
||||||
snapshot,
|
snapshot,
|
||||||
|
dependency_key,
|
||||||
&dependency.maybe_type,
|
&dependency.maybe_type,
|
||||||
dependency.is_dynamic,
|
dependency.is_dynamic,
|
||||||
dependency.maybe_attribute_type.as_deref(),
|
dependency.maybe_attribute_type.as_deref(),
|
||||||
|
|
|
@ -365,6 +365,7 @@ impl Document {
|
||||||
maybe_headers: Option<HashMap<String, String>>,
|
maybe_headers: Option<HashMap<String, String>>,
|
||||||
text_info: SourceTextInfo,
|
text_info: SourceTextInfo,
|
||||||
resolver: &dyn deno_graph::source::Resolver,
|
resolver: &dyn deno_graph::source::Resolver,
|
||||||
|
npm_resolver: &dyn deno_graph::source::NpmResolver,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// we only ever do `Document::new` on on disk resources that are supposed to
|
// we only ever do `Document::new` on on disk resources that are supposed to
|
||||||
// be diagnosable, unlike `Document::open`, so it is safe to unconditionally
|
// be diagnosable, unlike `Document::open`, so it is safe to unconditionally
|
||||||
|
@ -374,6 +375,7 @@ impl Document {
|
||||||
text_info.clone(),
|
text_info.clone(),
|
||||||
maybe_headers.as_ref(),
|
maybe_headers.as_ref(),
|
||||||
resolver,
|
resolver,
|
||||||
|
npm_resolver,
|
||||||
);
|
);
|
||||||
let dependencies =
|
let dependencies =
|
||||||
Arc::new(DocumentDependencies::from_maybe_module(&maybe_module));
|
Arc::new(DocumentDependencies::from_maybe_module(&maybe_module));
|
||||||
|
@ -396,6 +398,7 @@ impl Document {
|
||||||
fn maybe_with_new_resolver(
|
fn maybe_with_new_resolver(
|
||||||
&self,
|
&self,
|
||||||
resolver: &dyn deno_graph::source::Resolver,
|
resolver: &dyn deno_graph::source::Resolver,
|
||||||
|
npm_resolver: &dyn deno_graph::source::NpmResolver,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
let parsed_source_result = match &self.0.maybe_parsed_source {
|
let parsed_source_result = match &self.0.maybe_parsed_source {
|
||||||
Some(parsed_source_result) => parsed_source_result.clone(),
|
Some(parsed_source_result) => parsed_source_result.clone(),
|
||||||
|
@ -406,6 +409,7 @@ impl Document {
|
||||||
&parsed_source_result,
|
&parsed_source_result,
|
||||||
self.0.maybe_headers.as_ref(),
|
self.0.maybe_headers.as_ref(),
|
||||||
resolver,
|
resolver,
|
||||||
|
npm_resolver,
|
||||||
));
|
));
|
||||||
let dependencies =
|
let dependencies =
|
||||||
Arc::new(DocumentDependencies::from_maybe_module(&maybe_module));
|
Arc::new(DocumentDependencies::from_maybe_module(&maybe_module));
|
||||||
|
@ -433,6 +437,7 @@ impl Document {
|
||||||
content: Arc<str>,
|
content: Arc<str>,
|
||||||
cache: &Arc<dyn HttpCache>,
|
cache: &Arc<dyn HttpCache>,
|
||||||
resolver: &dyn deno_graph::source::Resolver,
|
resolver: &dyn deno_graph::source::Resolver,
|
||||||
|
npm_resolver: &dyn deno_graph::source::NpmResolver,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let maybe_headers = language_id.as_headers();
|
let maybe_headers = language_id.as_headers();
|
||||||
let text_info = SourceTextInfo::new(content);
|
let text_info = SourceTextInfo::new(content);
|
||||||
|
@ -442,6 +447,7 @@ impl Document {
|
||||||
text_info.clone(),
|
text_info.clone(),
|
||||||
maybe_headers,
|
maybe_headers,
|
||||||
resolver,
|
resolver,
|
||||||
|
npm_resolver,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(None, None)
|
(None, None)
|
||||||
|
@ -470,6 +476,7 @@ impl Document {
|
||||||
version: i32,
|
version: i32,
|
||||||
changes: Vec<lsp::TextDocumentContentChangeEvent>,
|
changes: Vec<lsp::TextDocumentContentChangeEvent>,
|
||||||
resolver: &dyn deno_graph::source::Resolver,
|
resolver: &dyn deno_graph::source::Resolver,
|
||||||
|
npm_resolver: &dyn deno_graph::source::NpmResolver,
|
||||||
) -> Result<Document, AnyError> {
|
) -> Result<Document, AnyError> {
|
||||||
let mut content = self.0.text_info.text_str().to_string();
|
let mut content = self.0.text_info.text_str().to_string();
|
||||||
let mut line_index = self.0.line_index.clone();
|
let mut line_index = self.0.line_index.clone();
|
||||||
|
@ -505,6 +512,7 @@ impl Document {
|
||||||
text_info.clone(),
|
text_info.clone(),
|
||||||
maybe_headers,
|
maybe_headers,
|
||||||
resolver,
|
resolver,
|
||||||
|
npm_resolver,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(None, None)
|
(None, None)
|
||||||
|
@ -809,6 +817,7 @@ impl FileSystemDocuments {
|
||||||
cache: &Arc<dyn HttpCache>,
|
cache: &Arc<dyn HttpCache>,
|
||||||
resolver: &dyn deno_graph::source::Resolver,
|
resolver: &dyn deno_graph::source::Resolver,
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
|
npm_resolver: &dyn deno_graph::source::NpmResolver,
|
||||||
) -> Option<Document> {
|
) -> Option<Document> {
|
||||||
let fs_version = if specifier.scheme() == "data" {
|
let fs_version = if specifier.scheme() == "data" {
|
||||||
Some("1".to_string())
|
Some("1".to_string())
|
||||||
|
@ -818,7 +827,7 @@ impl FileSystemDocuments {
|
||||||
let file_system_doc = self.docs.get(specifier);
|
let file_system_doc = self.docs.get(specifier);
|
||||||
if file_system_doc.map(|d| d.fs_version().to_string()) != fs_version {
|
if file_system_doc.map(|d| d.fs_version().to_string()) != fs_version {
|
||||||
// attempt to update the file on the file system
|
// attempt to update the file on the file system
|
||||||
self.refresh_document(cache, resolver, specifier)
|
self.refresh_document(cache, resolver, specifier, npm_resolver)
|
||||||
} else {
|
} else {
|
||||||
file_system_doc.cloned()
|
file_system_doc.cloned()
|
||||||
}
|
}
|
||||||
|
@ -831,6 +840,7 @@ impl FileSystemDocuments {
|
||||||
cache: &Arc<dyn HttpCache>,
|
cache: &Arc<dyn HttpCache>,
|
||||||
resolver: &dyn deno_graph::source::Resolver,
|
resolver: &dyn deno_graph::source::Resolver,
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
|
npm_resolver: &dyn deno_graph::source::NpmResolver,
|
||||||
) -> Option<Document> {
|
) -> Option<Document> {
|
||||||
let doc = if specifier.scheme() == "file" {
|
let doc = if specifier.scheme() == "file" {
|
||||||
let path = specifier_to_file_path(specifier).ok()?;
|
let path = specifier_to_file_path(specifier).ok()?;
|
||||||
|
@ -845,6 +855,7 @@ impl FileSystemDocuments {
|
||||||
None,
|
None,
|
||||||
SourceTextInfo::from_string(content),
|
SourceTextInfo::from_string(content),
|
||||||
resolver,
|
resolver,
|
||||||
|
npm_resolver,
|
||||||
)
|
)
|
||||||
} else if specifier.scheme() == "data" {
|
} else if specifier.scheme() == "data" {
|
||||||
let (source, _) = get_source_from_data_url(specifier).ok()?;
|
let (source, _) = get_source_from_data_url(specifier).ok()?;
|
||||||
|
@ -854,6 +865,7 @@ impl FileSystemDocuments {
|
||||||
None,
|
None,
|
||||||
SourceTextInfo::from_string(source),
|
SourceTextInfo::from_string(source),
|
||||||
resolver,
|
resolver,
|
||||||
|
npm_resolver,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let fs_version = calculate_fs_version(cache, specifier)?;
|
let fs_version = calculate_fs_version(cache, specifier)?;
|
||||||
|
@ -870,6 +882,7 @@ impl FileSystemDocuments {
|
||||||
maybe_headers,
|
maybe_headers,
|
||||||
SourceTextInfo::from_string(content),
|
SourceTextInfo::from_string(content),
|
||||||
resolver,
|
resolver,
|
||||||
|
npm_resolver,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
|
@ -948,6 +961,7 @@ impl Documents {
|
||||||
maybe_jsx_import_source_config: None,
|
maybe_jsx_import_source_config: None,
|
||||||
maybe_import_map: None,
|
maybe_import_map: None,
|
||||||
maybe_vendor_dir: None,
|
maybe_vendor_dir: None,
|
||||||
|
bare_node_builtins_enabled: false,
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
npm_specifier_reqs: Default::default(),
|
npm_specifier_reqs: Default::default(),
|
||||||
|
@ -976,6 +990,7 @@ impl Documents {
|
||||||
content: Arc<str>,
|
content: Arc<str>,
|
||||||
) -> Document {
|
) -> Document {
|
||||||
let resolver = self.get_resolver();
|
let resolver = self.get_resolver();
|
||||||
|
let npm_resolver = self.get_npm_resolver();
|
||||||
let document = Document::open(
|
let document = Document::open(
|
||||||
specifier.clone(),
|
specifier.clone(),
|
||||||
version,
|
version,
|
||||||
|
@ -983,6 +998,7 @@ impl Documents {
|
||||||
content,
|
content,
|
||||||
&self.cache,
|
&self.cache,
|
||||||
resolver,
|
resolver,
|
||||||
|
npm_resolver,
|
||||||
);
|
);
|
||||||
let mut file_system_docs = self.file_system_docs.lock();
|
let mut file_system_docs = self.file_system_docs.lock();
|
||||||
file_system_docs.docs.remove(&specifier);
|
file_system_docs.docs.remove(&specifier);
|
||||||
|
@ -1015,7 +1031,12 @@ impl Documents {
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
let doc = doc.with_change(version, changes, self.get_resolver())?;
|
let doc = doc.with_change(
|
||||||
|
version,
|
||||||
|
changes,
|
||||||
|
self.get_resolver(),
|
||||||
|
self.get_npm_resolver(),
|
||||||
|
)?;
|
||||||
self.open_docs.insert(doc.specifier().clone(), doc.clone());
|
self.open_docs.insert(doc.specifier().clone(), doc.clone());
|
||||||
Ok(doc)
|
Ok(doc)
|
||||||
}
|
}
|
||||||
|
@ -1125,7 +1146,12 @@ impl Documents {
|
||||||
Some(document.clone())
|
Some(document.clone())
|
||||||
} else {
|
} else {
|
||||||
let mut file_system_docs = self.file_system_docs.lock();
|
let mut file_system_docs = self.file_system_docs.lock();
|
||||||
file_system_docs.get(&self.cache, self.get_resolver(), &specifier)
|
file_system_docs.get(
|
||||||
|
&self.cache,
|
||||||
|
self.get_resolver(),
|
||||||
|
&specifier,
|
||||||
|
self.get_npm_resolver(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1344,6 +1370,15 @@ impl Documents {
|
||||||
.maybe_config_file
|
.maybe_config_file
|
||||||
.and_then(|c| c.vendor_dir_path())
|
.and_then(|c| c.vendor_dir_path())
|
||||||
.as_ref(),
|
.as_ref(),
|
||||||
|
bare_node_builtins_enabled: options
|
||||||
|
.maybe_config_file
|
||||||
|
.map(|config| {
|
||||||
|
config
|
||||||
|
.json
|
||||||
|
.unstable
|
||||||
|
.contains(&"bare-node-builtins".to_string())
|
||||||
|
})
|
||||||
|
.unwrap_or(false),
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
self.imports = Arc::new(
|
self.imports = Arc::new(
|
||||||
|
@ -1353,8 +1388,12 @@ impl Documents {
|
||||||
imports
|
imports
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(referrer, imports)| {
|
.map(|(referrer, imports)| {
|
||||||
let graph_import =
|
let graph_import = GraphImport::new(
|
||||||
GraphImport::new(&referrer, imports, Some(self.get_resolver()));
|
&referrer,
|
||||||
|
imports,
|
||||||
|
Some(self.get_resolver()),
|
||||||
|
Some(self.get_npm_resolver()),
|
||||||
|
);
|
||||||
(referrer, graph_import)
|
(referrer, graph_import)
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
@ -1384,8 +1423,10 @@ impl Documents {
|
||||||
document_preload_limit: usize,
|
document_preload_limit: usize,
|
||||||
) {
|
) {
|
||||||
let resolver = self.resolver.as_graph_resolver();
|
let resolver = self.resolver.as_graph_resolver();
|
||||||
|
let npm_resolver = self.resolver.as_graph_npm_resolver();
|
||||||
for doc in self.open_docs.values_mut() {
|
for doc in self.open_docs.values_mut() {
|
||||||
if let Some(new_doc) = doc.maybe_with_new_resolver(resolver) {
|
if let Some(new_doc) = doc.maybe_with_new_resolver(resolver, npm_resolver)
|
||||||
|
{
|
||||||
*doc = new_doc;
|
*doc = new_doc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1411,11 +1452,18 @@ impl Documents {
|
||||||
if !open_docs.contains_key(&specifier)
|
if !open_docs.contains_key(&specifier)
|
||||||
&& !fs_docs.docs.contains_key(&specifier)
|
&& !fs_docs.docs.contains_key(&specifier)
|
||||||
{
|
{
|
||||||
fs_docs.refresh_document(&self.cache, resolver, &specifier);
|
fs_docs.refresh_document(
|
||||||
|
&self.cache,
|
||||||
|
resolver,
|
||||||
|
&specifier,
|
||||||
|
npm_resolver,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// update the existing entry to have the new resolver
|
// update the existing entry to have the new resolver
|
||||||
if let Some(doc) = fs_docs.docs.get_mut(&specifier) {
|
if let Some(doc) = fs_docs.docs.get_mut(&specifier) {
|
||||||
if let Some(new_doc) = doc.maybe_with_new_resolver(resolver) {
|
if let Some(new_doc) =
|
||||||
|
doc.maybe_with_new_resolver(resolver, npm_resolver)
|
||||||
|
{
|
||||||
*doc = new_doc;
|
*doc = new_doc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1436,7 +1484,9 @@ impl Documents {
|
||||||
// since we hit the limit, just update everything to use the new resolver
|
// since we hit the limit, just update everything to use the new resolver
|
||||||
for uri in not_found_docs {
|
for uri in not_found_docs {
|
||||||
if let Some(doc) = fs_docs.docs.get_mut(&uri) {
|
if let Some(doc) = fs_docs.docs.get_mut(&uri) {
|
||||||
if let Some(new_doc) = doc.maybe_with_new_resolver(resolver) {
|
if let Some(new_doc) =
|
||||||
|
doc.maybe_with_new_resolver(resolver, npm_resolver)
|
||||||
|
{
|
||||||
*doc = new_doc;
|
*doc = new_doc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1455,7 +1505,9 @@ impl Documents {
|
||||||
|
|
||||||
// just update to use the new resolver
|
// just update to use the new resolver
|
||||||
for doc in fs_docs.docs.values_mut() {
|
for doc in fs_docs.docs.values_mut() {
|
||||||
if let Some(new_doc) = doc.maybe_with_new_resolver(resolver) {
|
if let Some(new_doc) =
|
||||||
|
doc.maybe_with_new_resolver(resolver, npm_resolver)
|
||||||
|
{
|
||||||
*doc = new_doc;
|
*doc = new_doc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1528,11 +1580,12 @@ impl Documents {
|
||||||
}
|
}
|
||||||
|
|
||||||
let resolver = self.get_resolver();
|
let resolver = self.get_resolver();
|
||||||
|
let npm_resolver = self.get_npm_resolver();
|
||||||
while let Some(specifier) = doc_analyzer.pending_specifiers.pop_front() {
|
while let Some(specifier) = doc_analyzer.pending_specifiers.pop_front() {
|
||||||
if let Some(doc) = self.open_docs.get(&specifier) {
|
if let Some(doc) = self.open_docs.get(&specifier) {
|
||||||
doc_analyzer.analyze_doc(&specifier, doc);
|
doc_analyzer.analyze_doc(&specifier, doc);
|
||||||
} else if let Some(doc) =
|
} else if let Some(doc) =
|
||||||
file_system_docs.get(&self.cache, resolver, &specifier)
|
file_system_docs.get(&self.cache, resolver, &specifier, npm_resolver)
|
||||||
{
|
{
|
||||||
doc_analyzer.analyze_doc(&specifier, &doc);
|
doc_analyzer.analyze_doc(&specifier, &doc);
|
||||||
}
|
}
|
||||||
|
@ -1563,6 +1616,10 @@ impl Documents {
|
||||||
self.resolver.as_graph_resolver()
|
self.resolver.as_graph_resolver()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_npm_resolver(&self) -> &dyn deno_graph::source::NpmResolver {
|
||||||
|
self.resolver.as_graph_npm_resolver()
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_dependency(
|
fn resolve_dependency(
|
||||||
&self,
|
&self,
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
|
@ -1698,10 +1755,16 @@ fn parse_and_analyze_module(
|
||||||
text_info: SourceTextInfo,
|
text_info: SourceTextInfo,
|
||||||
maybe_headers: Option<&HashMap<String, String>>,
|
maybe_headers: Option<&HashMap<String, String>>,
|
||||||
resolver: &dyn deno_graph::source::Resolver,
|
resolver: &dyn deno_graph::source::Resolver,
|
||||||
|
npm_resolver: &dyn deno_graph::source::NpmResolver,
|
||||||
) -> (Option<ParsedSourceResult>, Option<ModuleResult>) {
|
) -> (Option<ParsedSourceResult>, Option<ModuleResult>) {
|
||||||
let parsed_source_result = parse_source(specifier, text_info, maybe_headers);
|
let parsed_source_result = parse_source(specifier, text_info, maybe_headers);
|
||||||
let module_result =
|
let module_result = analyze_module(
|
||||||
analyze_module(specifier, &parsed_source_result, maybe_headers, resolver);
|
specifier,
|
||||||
|
&parsed_source_result,
|
||||||
|
maybe_headers,
|
||||||
|
resolver,
|
||||||
|
npm_resolver,
|
||||||
|
);
|
||||||
(Some(parsed_source_result), Some(module_result))
|
(Some(parsed_source_result), Some(module_result))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1725,6 +1788,7 @@ fn analyze_module(
|
||||||
parsed_source_result: &ParsedSourceResult,
|
parsed_source_result: &ParsedSourceResult,
|
||||||
maybe_headers: Option<&HashMap<String, String>>,
|
maybe_headers: Option<&HashMap<String, String>>,
|
||||||
resolver: &dyn deno_graph::source::Resolver,
|
resolver: &dyn deno_graph::source::Resolver,
|
||||||
|
npm_resolver: &dyn deno_graph::source::NpmResolver,
|
||||||
) -> ModuleResult {
|
) -> ModuleResult {
|
||||||
match parsed_source_result {
|
match parsed_source_result {
|
||||||
Ok(parsed_source) => Ok(deno_graph::parse_module_from_ast(
|
Ok(parsed_source) => Ok(deno_graph::parse_module_from_ast(
|
||||||
|
@ -1732,6 +1796,7 @@ fn analyze_module(
|
||||||
maybe_headers,
|
maybe_headers,
|
||||||
parsed_source,
|
parsed_source,
|
||||||
Some(resolver),
|
Some(resolver),
|
||||||
|
Some(npm_resolver),
|
||||||
)),
|
)),
|
||||||
Err(err) => Err(deno_graph::ModuleGraphError::ModuleError(
|
Err(err) => Err(deno_graph::ModuleGraphError::ModuleError(
|
||||||
deno_graph::ModuleError::ParseErr(specifier.clone(), err.clone()),
|
deno_graph::ModuleError::ParseErr(specifier.clone(), err.clone()),
|
||||||
|
|
|
@ -570,7 +570,7 @@ impl ModuleLoader for CliModuleLoader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resolution
|
resolution.map_err(|err| err.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load(
|
fn load(
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
use deno_core::anyhow::anyhow;
|
use deno_core::anyhow::anyhow;
|
||||||
use deno_core::anyhow::bail;
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::futures::future;
|
use deno_core::futures::future;
|
||||||
use deno_core::futures::future::LocalBoxFuture;
|
use deno_core::futures::future::LocalBoxFuture;
|
||||||
|
@ -9,6 +8,7 @@ use deno_core::futures::FutureExt;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
use deno_graph::source::NpmPackageReqResolution;
|
use deno_graph::source::NpmPackageReqResolution;
|
||||||
use deno_graph::source::NpmResolver;
|
use deno_graph::source::NpmResolver;
|
||||||
|
use deno_graph::source::ResolveError;
|
||||||
use deno_graph::source::Resolver;
|
use deno_graph::source::Resolver;
|
||||||
use deno_graph::source::UnknownBuiltInNodeModuleError;
|
use deno_graph::source::UnknownBuiltInNodeModuleError;
|
||||||
use deno_graph::source::DEFAULT_JSX_IMPORT_SOURCE_MODULE;
|
use deno_graph::source::DEFAULT_JSX_IMPORT_SOURCE_MODULE;
|
||||||
|
@ -104,12 +104,14 @@ pub struct CliGraphResolver {
|
||||||
maybe_vendor_specifier: Option<ModuleSpecifier>,
|
maybe_vendor_specifier: Option<ModuleSpecifier>,
|
||||||
npm_resolver: Option<Arc<dyn CliNpmResolver>>,
|
npm_resolver: Option<Arc<dyn CliNpmResolver>>,
|
||||||
found_package_json_dep_flag: Arc<AtomicFlag>,
|
found_package_json_dep_flag: Arc<AtomicFlag>,
|
||||||
|
bare_node_builtins_enabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CliGraphResolverOptions<'a> {
|
pub struct CliGraphResolverOptions<'a> {
|
||||||
pub maybe_jsx_import_source_config: Option<JsxImportSourceConfig>,
|
pub maybe_jsx_import_source_config: Option<JsxImportSourceConfig>,
|
||||||
pub maybe_import_map: Option<Arc<ImportMap>>,
|
pub maybe_import_map: Option<Arc<ImportMap>>,
|
||||||
pub maybe_vendor_dir: Option<&'a PathBuf>,
|
pub maybe_vendor_dir: Option<&'a PathBuf>,
|
||||||
|
pub bare_node_builtins_enabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CliGraphResolver {
|
impl CliGraphResolver {
|
||||||
|
@ -135,6 +137,7 @@ impl CliGraphResolver {
|
||||||
.and_then(|v| ModuleSpecifier::from_directory_path(v).ok()),
|
.and_then(|v| ModuleSpecifier::from_directory_path(v).ok()),
|
||||||
npm_resolver,
|
npm_resolver,
|
||||||
found_package_json_dep_flag: Default::default(),
|
found_package_json_dep_flag: Default::default(),
|
||||||
|
bare_node_builtins_enabled: options.bare_node_builtins_enabled,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,7 +170,7 @@ impl Resolver for CliGraphResolver {
|
||||||
&self,
|
&self,
|
||||||
specifier: &str,
|
specifier: &str,
|
||||||
referrer: &ModuleSpecifier,
|
referrer: &ModuleSpecifier,
|
||||||
) -> Result<ModuleSpecifier, AnyError> {
|
) -> Result<ModuleSpecifier, ResolveError> {
|
||||||
let result = match self
|
let result = match self
|
||||||
.mapped_specifier_resolver
|
.mapped_specifier_resolver
|
||||||
.resolve(specifier, referrer)?
|
.resolve(specifier, referrer)?
|
||||||
|
@ -190,7 +193,7 @@ impl Resolver for CliGraphResolver {
|
||||||
if let Some(vendor_specifier) = &self.maybe_vendor_specifier {
|
if let Some(vendor_specifier) = &self.maybe_vendor_specifier {
|
||||||
if let Ok(specifier) = &result {
|
if let Ok(specifier) = &result {
|
||||||
if specifier.as_str().starts_with(vendor_specifier.as_str()) {
|
if specifier.as_str().starts_with(vendor_specifier.as_str()) {
|
||||||
bail!("Importing from the vendor directory is not permitted. Use a remote specifier instead or disable vendoring.");
|
return Err(ResolveError::Other(anyhow!("Importing from the vendor directory is not permitted. Use a remote specifier instead or disable vendoring.")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,6 +241,19 @@ impl NpmResolver for CliGraphResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_resolve_bare_builtin_node_module(
|
||||||
|
&self,
|
||||||
|
module_name: &str,
|
||||||
|
range: &deno_graph::Range,
|
||||||
|
) {
|
||||||
|
let deno_graph::Range {
|
||||||
|
start, specifier, ..
|
||||||
|
} = range;
|
||||||
|
let line = start.line + 1;
|
||||||
|
let column = start.character + 1;
|
||||||
|
log::warn!("Warning: Resolving \"{module_name}\" as \"node:{module_name}\" at {specifier}:{line}:{column}. If you want to use a built-in Node module, add a \"node:\" prefix.")
|
||||||
|
}
|
||||||
|
|
||||||
fn load_and_cache_npm_package_info(
|
fn load_and_cache_npm_package_info(
|
||||||
&self,
|
&self,
|
||||||
package_name: &str,
|
package_name: &str,
|
||||||
|
@ -276,6 +292,10 @@ impl NpmResolver for CliGraphResolver {
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn enables_bare_builtin_node_module(&self) -> bool {
|
||||||
|
self.bare_node_builtins_enabled
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -10419,3 +10419,92 @@ fn lsp_vendor_dir() {
|
||||||
|
|
||||||
client.shutdown();
|
client.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lsp_import_unstable_bare_node_builtins_auto_discovered() {
|
||||||
|
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||||
|
let temp_dir = context.temp_dir();
|
||||||
|
|
||||||
|
let contents = r#"import path from "path";"#;
|
||||||
|
temp_dir.write("main.ts", contents);
|
||||||
|
temp_dir.write("deno.json", r#"{ "unstable": ["bare-node-builtins"] }"#);
|
||||||
|
let main_script = temp_dir.uri().join("main.ts").unwrap();
|
||||||
|
|
||||||
|
let mut client = context.new_lsp_command().capture_stderr().build();
|
||||||
|
client.initialize_default();
|
||||||
|
let diagnostics = client.did_open(json!({
|
||||||
|
"textDocument": {
|
||||||
|
"uri": main_script,
|
||||||
|
"languageId": "typescript",
|
||||||
|
"version": 1,
|
||||||
|
"text": contents,
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
let diagnostics = diagnostics
|
||||||
|
.messages_with_file_and_source(main_script.as_ref(), "deno")
|
||||||
|
.diagnostics
|
||||||
|
.into_iter()
|
||||||
|
.filter(|d| {
|
||||||
|
d.code
|
||||||
|
== Some(lsp::NumberOrString::String(
|
||||||
|
"import-node-prefix-missing".to_string(),
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
// get the quick fixes
|
||||||
|
let res = client.write_request(
|
||||||
|
"textDocument/codeAction",
|
||||||
|
json!({
|
||||||
|
"textDocument": {
|
||||||
|
"uri": main_script
|
||||||
|
},
|
||||||
|
"range": {
|
||||||
|
"start": { "line": 0, "character": 16 },
|
||||||
|
"end": { "line": 0, "character": 18 },
|
||||||
|
},
|
||||||
|
"context": {
|
||||||
|
"diagnostics": json!(diagnostics),
|
||||||
|
"only": ["quickfix"]
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
res,
|
||||||
|
json!([{
|
||||||
|
"title": "Update specifier to node:path",
|
||||||
|
"kind": "quickfix",
|
||||||
|
"diagnostics": [
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "line": 0, "character": 17 },
|
||||||
|
"end": { "line": 0, "character": 23 }
|
||||||
|
},
|
||||||
|
"severity": 2,
|
||||||
|
"code": "import-node-prefix-missing",
|
||||||
|
"source": "deno",
|
||||||
|
"message": "\"path\" is resolved to \"node:path\". If you want to use a built-in Node module, add a \"node:\" prefix.",
|
||||||
|
"data": {
|
||||||
|
"specifier": "path"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"edit": {
|
||||||
|
"changes": {
|
||||||
|
main_script: [
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "line": 0, "character": 17 },
|
||||||
|
"end": { "line": 0, "character": 23 }
|
||||||
|
},
|
||||||
|
"newText": "\"node:path\""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}])
|
||||||
|
);
|
||||||
|
|
||||||
|
client.shutdown();
|
||||||
|
}
|
||||||
|
|
|
@ -4583,6 +4583,43 @@ itest!(node_prefix_missing {
|
||||||
exit_code: 1,
|
exit_code: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
itest!(node_prefix_missing_unstable_bare_node_builtins_enbaled {
|
||||||
|
args: "run --unstable-bare-node-builtins run/node_prefix_missing/main.ts",
|
||||||
|
output: "run/node_prefix_missing/main.ts.out_feature_enabled",
|
||||||
|
envs: env_vars_for_npm_tests(),
|
||||||
|
exit_code: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
itest!(
|
||||||
|
node_prefix_missing_unstable_bare_node_builtins_enbaled_by_env {
|
||||||
|
args: "run run/node_prefix_missing/main.ts",
|
||||||
|
output: "run/node_prefix_missing/main.ts.out_feature_enabled",
|
||||||
|
envs: [
|
||||||
|
env_vars_for_npm_tests(),
|
||||||
|
vec![(
|
||||||
|
"DENO_UNSTABLE_BARE_NODE_BUILTINS".to_string(),
|
||||||
|
"1".to_string()
|
||||||
|
)]
|
||||||
|
]
|
||||||
|
.concat(),
|
||||||
|
exit_code: 0,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
itest!(node_prefix_missing_unstable_bare_node_builtins_enbaled_by_config {
|
||||||
|
args: "run --config=run/node_prefix_missing/config.json run/node_prefix_missing/main.ts",
|
||||||
|
output: "run/node_prefix_missing/main.ts.out_feature_enabled",
|
||||||
|
envs: env_vars_for_npm_tests(),
|
||||||
|
exit_code: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
itest!(node_prefix_missing_unstable_bare_node_builtins_enbaled_with_import_map {
|
||||||
|
args: "run --unstable-bare-node-builtins --import-map run/node_prefix_missing/import_map.json run/node_prefix_missing/main.ts",
|
||||||
|
output: "run/node_prefix_missing/main.ts.out_feature_enabled",
|
||||||
|
envs: env_vars_for_npm_tests(),
|
||||||
|
exit_code: 0,
|
||||||
|
});
|
||||||
|
|
||||||
itest!(dynamic_import_syntax_error {
|
itest!(dynamic_import_syntax_error {
|
||||||
args: "run -A run/dynamic_import_syntax_error.js",
|
args: "run -A run/dynamic_import_syntax_error.js",
|
||||||
output: "run/dynamic_import_syntax_error.js.out",
|
output: "run/dynamic_import_syntax_error.js.out",
|
||||||
|
|
1
cli/tests/testdata/run/node_prefix_missing/config.json
vendored
Normal file
1
cli/tests/testdata/run/node_prefix_missing/config.json
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{ "unstable": ["bare-node-builtins"] }
|
1
cli/tests/testdata/run/node_prefix_missing/import_map.json
vendored
Normal file
1
cli/tests/testdata/run/node_prefix_missing/import_map.json
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{ "imports": {} }
|
2
cli/tests/testdata/run/node_prefix_missing/main.ts.out_feature_enabled
vendored
Normal file
2
cli/tests/testdata/run/node_prefix_missing/main.ts.out_feature_enabled
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[WILDCARD]Warning: Resolving "fs" as "node:fs" at file:///[WILDCARD]/cli/tests/testdata/run/node_prefix_missing/main.ts:1:16. If you want to use a built-in Node module, add a "node:" prefix.
|
||||||
|
[Function: writeFile]
|
1
cli/tools/vendor/test.rs
vendored
1
cli/tools/vendor/test.rs
vendored
|
@ -300,6 +300,7 @@ fn build_resolver(
|
||||||
maybe_jsx_import_source_config,
|
maybe_jsx_import_source_config,
|
||||||
maybe_import_map: original_import_map.map(Arc::new),
|
maybe_import_map: original_import_map.map(Arc::new),
|
||||||
maybe_vendor_dir: None,
|
maybe_vendor_dir: None,
|
||||||
|
bare_node_builtins_enabled: false,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue