mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
fix(byonm): resolve npm deps of jsr deps (#25399)
This allows using npm deps of jsr deps without having to add them to the root package.json. Works by taking the package requirement and scanning the `node_modules/.deno` directory for the best matching package, so it relies on deno's node_modules structure. Additionally to make the transition from package.json to deno.json easier, Deno now: 1. Installs npm deps in a deno.json at the same time as installing npm deps from a package.json. 2. Uses the alias in the import map for `node_modules/<alias>` for better package.json compatiblity.
This commit is contained in:
parent
13911eb8ef
commit
c6d1b0a1cc
49 changed files with 504 additions and 145 deletions
|
@ -44,7 +44,7 @@ pub use deno_config::deno_json::TsTypeLib;
|
||||||
pub use deno_config::glob::FilePatterns;
|
pub use deno_config::glob::FilePatterns;
|
||||||
pub use flags::*;
|
pub use flags::*;
|
||||||
pub use lockfile::CliLockfile;
|
pub use lockfile::CliLockfile;
|
||||||
pub use package_json::PackageJsonInstallDepsProvider;
|
pub use package_json::NpmInstallDepsProvider;
|
||||||
|
|
||||||
use deno_ast::ModuleSpecifier;
|
use deno_ast::ModuleSpecifier;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::bail;
|
||||||
|
|
|
@ -1,17 +1,20 @@
|
||||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
use std::collections::HashSet;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use deno_config::workspace::Workspace;
|
use deno_config::workspace::Workspace;
|
||||||
|
use deno_core::serde_json;
|
||||||
use deno_package_json::PackageJsonDepValue;
|
use deno_package_json::PackageJsonDepValue;
|
||||||
|
use deno_semver::npm::NpmPackageReqReference;
|
||||||
use deno_semver::package::PackageReq;
|
use deno_semver::package::PackageReq;
|
||||||
|
|
||||||
|
use crate::util::path::is_banned_path_char;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct InstallNpmRemotePkg {
|
pub struct InstallNpmRemotePkg {
|
||||||
pub alias: String,
|
pub alias: String,
|
||||||
// todo(24419): use this when setting up the node_modules dir
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub base_dir: PathBuf,
|
pub base_dir: PathBuf,
|
||||||
pub req: PackageReq,
|
pub req: PackageReq,
|
||||||
}
|
}
|
||||||
|
@ -19,74 +22,126 @@ pub struct InstallNpmRemotePkg {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct InstallNpmWorkspacePkg {
|
pub struct InstallNpmWorkspacePkg {
|
||||||
pub alias: String,
|
pub alias: String,
|
||||||
// todo(24419): use this when setting up the node_modules dir
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub base_dir: PathBuf,
|
|
||||||
pub target_dir: PathBuf,
|
pub target_dir: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct PackageJsonInstallDepsProvider {
|
pub struct NpmInstallDepsProvider {
|
||||||
remote_pkgs: Vec<InstallNpmRemotePkg>,
|
remote_pkgs: Vec<InstallNpmRemotePkg>,
|
||||||
workspace_pkgs: Vec<InstallNpmWorkspacePkg>,
|
workspace_pkgs: Vec<InstallNpmWorkspacePkg>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PackageJsonInstallDepsProvider {
|
impl NpmInstallDepsProvider {
|
||||||
pub fn empty() -> Self {
|
pub fn empty() -> Self {
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_workspace(workspace: &Arc<Workspace>) -> Self {
|
pub fn from_workspace(workspace: &Arc<Workspace>) -> Self {
|
||||||
|
// todo(dsherret): estimate capacity?
|
||||||
let mut workspace_pkgs = Vec::new();
|
let mut workspace_pkgs = Vec::new();
|
||||||
let mut remote_pkgs = Vec::new();
|
let mut remote_pkgs = Vec::new();
|
||||||
let workspace_npm_pkgs = workspace.npm_packages();
|
let workspace_npm_pkgs = workspace.npm_packages();
|
||||||
for pkg_json in workspace.package_jsons() {
|
|
||||||
let deps = pkg_json.resolve_local_package_json_deps();
|
for (_, folder) in workspace.config_folders() {
|
||||||
let mut pkg_pkgs = Vec::with_capacity(deps.len());
|
let mut deno_json_aliases = HashSet::new();
|
||||||
for (alias, dep) in deps {
|
|
||||||
let Ok(dep) = dep else {
|
// deal with the deno.json first because it takes precedence during resolution
|
||||||
continue;
|
if let Some(deno_json) = &folder.deno_json {
|
||||||
};
|
// don't bother with externally referenced import maps as users
|
||||||
match dep {
|
// should inline their import map to get this behaviour
|
||||||
PackageJsonDepValue::Req(pkg_req) => {
|
if let Some(serde_json::Value::Object(obj)) = &deno_json.json.imports {
|
||||||
let workspace_pkg = workspace_npm_pkgs.iter().find(|pkg| {
|
deno_json_aliases.reserve(obj.len());
|
||||||
pkg.matches_req(&pkg_req)
|
let mut pkg_pkgs = Vec::with_capacity(obj.len());
|
||||||
// do not resolve to the current package
|
for (alias, value) in obj {
|
||||||
&& pkg.pkg_json.path != pkg_json.path
|
let serde_json::Value::String(specifier) = value else {
|
||||||
});
|
continue;
|
||||||
|
};
|
||||||
|
let Ok(npm_req_ref) = NpmPackageReqReference::from_str(specifier)
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
// skip any aliases with banned characters
|
||||||
|
if alias.chars().any(|c| c == '\\' || is_banned_path_char(c)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
deno_json_aliases.insert(alias.to_lowercase());
|
||||||
|
let pkg_req = npm_req_ref.into_inner().req;
|
||||||
|
let workspace_pkg = workspace_npm_pkgs
|
||||||
|
.iter()
|
||||||
|
.find(|pkg| pkg.matches_req(&pkg_req));
|
||||||
|
|
||||||
if let Some(pkg) = workspace_pkg {
|
if let Some(pkg) = workspace_pkg {
|
||||||
workspace_pkgs.push(InstallNpmWorkspacePkg {
|
workspace_pkgs.push(InstallNpmWorkspacePkg {
|
||||||
alias,
|
alias: alias.to_string(),
|
||||||
base_dir: pkg_json.dir_path().to_path_buf(),
|
|
||||||
target_dir: pkg.pkg_json.dir_path().to_path_buf(),
|
target_dir: pkg.pkg_json.dir_path().to_path_buf(),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
pkg_pkgs.push(InstallNpmRemotePkg {
|
pkg_pkgs.push(InstallNpmRemotePkg {
|
||||||
alias,
|
alias: alias.to_string(),
|
||||||
base_dir: pkg_json.dir_path().to_path_buf(),
|
base_dir: deno_json.dir_path(),
|
||||||
req: pkg_req,
|
req: pkg_req,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PackageJsonDepValue::Workspace(version_req) => {
|
|
||||||
if let Some(pkg) = workspace_npm_pkgs.iter().find(|pkg| {
|
// sort within each package (more like npm resolution)
|
||||||
pkg.matches_name_and_version_req(&alias, &version_req)
|
pkg_pkgs.sort_by(|a, b| a.alias.cmp(&b.alias));
|
||||||
}) {
|
remote_pkgs.extend(pkg_pkgs);
|
||||||
workspace_pkgs.push(InstallNpmWorkspacePkg {
|
}
|
||||||
alias,
|
}
|
||||||
base_dir: pkg_json.dir_path().to_path_buf(),
|
|
||||||
target_dir: pkg.pkg_json.dir_path().to_path_buf(),
|
if let Some(pkg_json) = &folder.pkg_json {
|
||||||
|
let deps = pkg_json.resolve_local_package_json_deps();
|
||||||
|
let mut pkg_pkgs = Vec::with_capacity(deps.len());
|
||||||
|
for (alias, dep) in deps {
|
||||||
|
let Ok(dep) = dep else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if deno_json_aliases.contains(&alias.to_lowercase()) {
|
||||||
|
// aliases in deno.json take precedence over package.json, so
|
||||||
|
// since this can't be resolved don't bother installing it
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
match dep {
|
||||||
|
PackageJsonDepValue::Req(pkg_req) => {
|
||||||
|
let workspace_pkg = workspace_npm_pkgs.iter().find(|pkg| {
|
||||||
|
pkg.matches_req(&pkg_req)
|
||||||
|
// do not resolve to the current package
|
||||||
|
&& pkg.pkg_json.path != pkg_json.path
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if let Some(pkg) = workspace_pkg {
|
||||||
|
workspace_pkgs.push(InstallNpmWorkspacePkg {
|
||||||
|
alias,
|
||||||
|
target_dir: pkg.pkg_json.dir_path().to_path_buf(),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
pkg_pkgs.push(InstallNpmRemotePkg {
|
||||||
|
alias,
|
||||||
|
base_dir: pkg_json.dir_path().to_path_buf(),
|
||||||
|
req: pkg_req,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PackageJsonDepValue::Workspace(version_req) => {
|
||||||
|
if let Some(pkg) = workspace_npm_pkgs.iter().find(|pkg| {
|
||||||
|
pkg.matches_name_and_version_req(&alias, &version_req)
|
||||||
|
}) {
|
||||||
|
workspace_pkgs.push(InstallNpmWorkspacePkg {
|
||||||
|
alias,
|
||||||
|
target_dir: pkg.pkg_json.dir_path().to_path_buf(),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// sort within each package
|
|
||||||
pkg_pkgs.sort_by(|a, b| a.alias.cmp(&b.alias));
|
|
||||||
|
|
||||||
remote_pkgs.extend(pkg_pkgs);
|
// sort within each package as npm does
|
||||||
|
pkg_pkgs.sort_by(|a, b| a.alias.cmp(&b.alias));
|
||||||
|
remote_pkgs.extend(pkg_pkgs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
remote_pkgs.shrink_to_fit();
|
remote_pkgs.shrink_to_fit();
|
||||||
workspace_pkgs.shrink_to_fit();
|
workspace_pkgs.shrink_to_fit();
|
||||||
Self {
|
Self {
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::args::CaData;
|
||||||
use crate::args::CliOptions;
|
use crate::args::CliOptions;
|
||||||
use crate::args::DenoSubcommand;
|
use crate::args::DenoSubcommand;
|
||||||
use crate::args::Flags;
|
use crate::args::Flags;
|
||||||
use crate::args::PackageJsonInstallDepsProvider;
|
use crate::args::NpmInstallDepsProvider;
|
||||||
use crate::args::StorageKeyResolver;
|
use crate::args::StorageKeyResolver;
|
||||||
use crate::args::TsConfigType;
|
use crate::args::TsConfigType;
|
||||||
use crate::cache::Caches;
|
use crate::cache::Caches;
|
||||||
|
@ -386,9 +386,7 @@ impl CliFactory {
|
||||||
cache_setting: cli_options.cache_setting(),
|
cache_setting: cli_options.cache_setting(),
|
||||||
text_only_progress_bar: self.text_only_progress_bar().clone(),
|
text_only_progress_bar: self.text_only_progress_bar().clone(),
|
||||||
maybe_node_modules_path: cli_options.node_modules_dir_path().cloned(),
|
maybe_node_modules_path: cli_options.node_modules_dir_path().cloned(),
|
||||||
package_json_deps_provider: Arc::new(PackageJsonInstallDepsProvider::from_workspace(
|
npm_install_deps_provider: Arc::new(NpmInstallDepsProvider::from_workspace(cli_options.workspace())),
|
||||||
cli_options.workspace(),
|
|
||||||
)),
|
|
||||||
npm_system_info: cli_options.npm_system_info(),
|
npm_system_info: cli_options.npm_system_info(),
|
||||||
npmrc: cli_options.npmrc().clone(),
|
npmrc: cli_options.npmrc().clone(),
|
||||||
lifecycle_scripts: cli_options.lifecycle_scripts_config(),
|
lifecycle_scripts: cli_options.lifecycle_scripts_config(),
|
||||||
|
|
|
@ -1251,7 +1251,7 @@ impl Documents {
|
||||||
/// tsc when type checking.
|
/// tsc when type checking.
|
||||||
pub fn resolve(
|
pub fn resolve(
|
||||||
&self,
|
&self,
|
||||||
specifiers: &[String],
|
raw_specifiers: &[String],
|
||||||
referrer: &ModuleSpecifier,
|
referrer: &ModuleSpecifier,
|
||||||
file_referrer: Option<&ModuleSpecifier>,
|
file_referrer: Option<&ModuleSpecifier>,
|
||||||
) -> Vec<Option<(ModuleSpecifier, MediaType)>> {
|
) -> Vec<Option<(ModuleSpecifier, MediaType)>> {
|
||||||
|
@ -1262,16 +1262,16 @@ impl Documents {
|
||||||
.or(file_referrer);
|
.or(file_referrer);
|
||||||
let dependencies = document.as_ref().map(|d| d.dependencies());
|
let dependencies = document.as_ref().map(|d| d.dependencies());
|
||||||
let mut results = Vec::new();
|
let mut results = Vec::new();
|
||||||
for specifier in specifiers {
|
for raw_specifier in raw_specifiers {
|
||||||
if specifier.starts_with("asset:") {
|
if raw_specifier.starts_with("asset:") {
|
||||||
if let Ok(specifier) = ModuleSpecifier::parse(specifier) {
|
if let Ok(specifier) = ModuleSpecifier::parse(raw_specifier) {
|
||||||
let media_type = MediaType::from_specifier(&specifier);
|
let media_type = MediaType::from_specifier(&specifier);
|
||||||
results.push(Some((specifier, media_type)));
|
results.push(Some((specifier, media_type)));
|
||||||
} else {
|
} else {
|
||||||
results.push(None);
|
results.push(None);
|
||||||
}
|
}
|
||||||
} else if let Some(dep) =
|
} else if let Some(dep) =
|
||||||
dependencies.as_ref().and_then(|d| d.get(specifier))
|
dependencies.as_ref().and_then(|d| d.get(raw_specifier))
|
||||||
{
|
{
|
||||||
if let Some(specifier) = dep.maybe_type.maybe_specifier() {
|
if let Some(specifier) = dep.maybe_type.maybe_specifier() {
|
||||||
results.push(self.resolve_dependency(
|
results.push(self.resolve_dependency(
|
||||||
|
@ -1290,7 +1290,7 @@ impl Documents {
|
||||||
}
|
}
|
||||||
} else if let Ok(specifier) =
|
} else if let Ok(specifier) =
|
||||||
self.resolver.as_graph_resolver(file_referrer).resolve(
|
self.resolver.as_graph_resolver(file_referrer).resolve(
|
||||||
specifier,
|
raw_specifier,
|
||||||
&deno_graph::Range {
|
&deno_graph::Range {
|
||||||
specifier: referrer.clone(),
|
specifier: referrer.clone(),
|
||||||
start: deno_graph::Position::zeroed(),
|
start: deno_graph::Position::zeroed(),
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use crate::args::create_default_npmrc;
|
use crate::args::create_default_npmrc;
|
||||||
use crate::args::CacheSetting;
|
use crate::args::CacheSetting;
|
||||||
use crate::args::CliLockfile;
|
use crate::args::CliLockfile;
|
||||||
use crate::args::PackageJsonInstallDepsProvider;
|
use crate::args::NpmInstallDepsProvider;
|
||||||
use crate::graph_util::CliJsrUrlProvider;
|
use crate::graph_util::CliJsrUrlProvider;
|
||||||
use crate::http_util::HttpClientProvider;
|
use crate::http_util::HttpClientProvider;
|
||||||
use crate::lsp::config::Config;
|
use crate::lsp::config::Config;
|
||||||
|
@ -474,9 +474,7 @@ async fn create_npm_resolver(
|
||||||
maybe_node_modules_path: config_data
|
maybe_node_modules_path: config_data
|
||||||
.and_then(|d| d.node_modules_dir.clone()),
|
.and_then(|d| d.node_modules_dir.clone()),
|
||||||
// only used for top level install, so we can ignore this
|
// only used for top level install, so we can ignore this
|
||||||
package_json_deps_provider: Arc::new(
|
npm_install_deps_provider: Arc::new(NpmInstallDepsProvider::empty()),
|
||||||
PackageJsonInstallDepsProvider::empty(),
|
|
||||||
),
|
|
||||||
npmrc: config_data
|
npmrc: config_data
|
||||||
.and_then(|d| d.npmrc.clone())
|
.and_then(|d| d.npmrc.clone())
|
||||||
.unwrap_or_else(create_default_npmrc),
|
.unwrap_or_else(create_default_npmrc),
|
||||||
|
|
|
@ -401,7 +401,7 @@ impl<TGraphContainer: ModuleGraphContainer>
|
||||||
|
|
||||||
fn inner_resolve(
|
fn inner_resolve(
|
||||||
&self,
|
&self,
|
||||||
specifier: &str,
|
raw_specifier: &str,
|
||||||
referrer: &ModuleSpecifier,
|
referrer: &ModuleSpecifier,
|
||||||
) -> Result<ModuleSpecifier, AnyError> {
|
) -> Result<ModuleSpecifier, AnyError> {
|
||||||
if self.shared.node_resolver.in_npm_package(referrer) {
|
if self.shared.node_resolver.in_npm_package(referrer) {
|
||||||
|
@ -409,7 +409,7 @@ impl<TGraphContainer: ModuleGraphContainer>
|
||||||
self
|
self
|
||||||
.shared
|
.shared
|
||||||
.node_resolver
|
.node_resolver
|
||||||
.resolve(specifier, referrer, NodeResolutionMode::Execution)?
|
.resolve(raw_specifier, referrer, NodeResolutionMode::Execution)?
|
||||||
.into_url(),
|
.into_url(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -418,7 +418,7 @@ impl<TGraphContainer: ModuleGraphContainer>
|
||||||
let resolution = match graph.get(referrer) {
|
let resolution = match graph.get(referrer) {
|
||||||
Some(Module::Js(module)) => module
|
Some(Module::Js(module)) => module
|
||||||
.dependencies
|
.dependencies
|
||||||
.get(specifier)
|
.get(raw_specifier)
|
||||||
.map(|d| &d.maybe_code)
|
.map(|d| &d.maybe_code)
|
||||||
.unwrap_or(&Resolution::None),
|
.unwrap_or(&Resolution::None),
|
||||||
_ => &Resolution::None,
|
_ => &Resolution::None,
|
||||||
|
@ -433,7 +433,7 @@ impl<TGraphContainer: ModuleGraphContainer>
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Resolution::None => Cow::Owned(self.shared.resolver.resolve(
|
Resolution::None => Cow::Owned(self.shared.resolver.resolve(
|
||||||
specifier,
|
raw_specifier,
|
||||||
&deno_graph::Range {
|
&deno_graph::Range {
|
||||||
specifier: referrer.clone(),
|
specifier: referrer.clone(),
|
||||||
start: deno_graph::Position::zeroed(),
|
start: deno_graph::Position::zeroed(),
|
||||||
|
|
143
cli/npm/byonm.rs
143
cli/npm/byonm.rs
|
@ -17,6 +17,7 @@ use deno_runtime::deno_node::NodeRequireResolver;
|
||||||
use deno_runtime::deno_node::NpmProcessStateProvider;
|
use deno_runtime::deno_node::NpmProcessStateProvider;
|
||||||
use deno_runtime::deno_node::PackageJson;
|
use deno_runtime::deno_node::PackageJson;
|
||||||
use deno_semver::package::PackageReq;
|
use deno_semver::package::PackageReq;
|
||||||
|
use deno_semver::Version;
|
||||||
use node_resolver::errors::PackageFolderResolveError;
|
use node_resolver::errors::PackageFolderResolveError;
|
||||||
use node_resolver::errors::PackageFolderResolveIoError;
|
use node_resolver::errors::PackageFolderResolveIoError;
|
||||||
use node_resolver::errors::PackageJsonLoadError;
|
use node_resolver::errors::PackageJsonLoadError;
|
||||||
|
@ -29,6 +30,7 @@ use crate::args::NpmProcessStateKind;
|
||||||
use crate::util::fs::canonicalize_path_maybe_not_exists_with_fs;
|
use crate::util::fs::canonicalize_path_maybe_not_exists_with_fs;
|
||||||
use deno_runtime::fs_util::specifier_to_file_path;
|
use deno_runtime::fs_util::specifier_to_file_path;
|
||||||
|
|
||||||
|
use super::managed::normalize_pkg_name_for_node_modules_deno_folder;
|
||||||
use super::CliNpmResolver;
|
use super::CliNpmResolver;
|
||||||
use super::InnerCliNpmResolverRef;
|
use super::InnerCliNpmResolverRef;
|
||||||
|
|
||||||
|
@ -60,9 +62,7 @@ impl ByonmCliNpmResolver {
|
||||||
) -> Result<Option<Arc<PackageJson>>, PackageJsonLoadError> {
|
) -> Result<Option<Arc<PackageJson>>, PackageJsonLoadError> {
|
||||||
load_pkg_json(&DenoPkgJsonFsAdapter(self.fs.as_ref()), path)
|
load_pkg_json(&DenoPkgJsonFsAdapter(self.fs.as_ref()), path)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl ByonmCliNpmResolver {
|
|
||||||
/// Finds the ancestor package.json that contains the specified dependency.
|
/// Finds the ancestor package.json that contains the specified dependency.
|
||||||
pub fn find_ancestor_package_json_with_dep(
|
pub fn find_ancestor_package_json_with_dep(
|
||||||
&self,
|
&self,
|
||||||
|
@ -98,7 +98,7 @@ impl ByonmCliNpmResolver {
|
||||||
&self,
|
&self,
|
||||||
req: &PackageReq,
|
req: &PackageReq,
|
||||||
referrer: &ModuleSpecifier,
|
referrer: &ModuleSpecifier,
|
||||||
) -> Result<(Arc<PackageJson>, String), AnyError> {
|
) -> Result<Option<(Arc<PackageJson>, String)>, AnyError> {
|
||||||
fn resolve_alias_from_pkg_json(
|
fn resolve_alias_from_pkg_json(
|
||||||
req: &PackageReq,
|
req: &PackageReq,
|
||||||
pkg_json: &PackageJson,
|
pkg_json: &PackageJson,
|
||||||
|
@ -134,7 +134,7 @@ impl ByonmCliNpmResolver {
|
||||||
if let Some(alias) =
|
if let Some(alias) =
|
||||||
resolve_alias_from_pkg_json(req, pkg_json.as_ref())
|
resolve_alias_from_pkg_json(req, pkg_json.as_ref())
|
||||||
{
|
{
|
||||||
return Ok((pkg_json, alias));
|
return Ok(Some((pkg_json, alias)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current_path = dir_path;
|
current_path = dir_path;
|
||||||
|
@ -148,19 +148,65 @@ impl ByonmCliNpmResolver {
|
||||||
if let Some(pkg_json) = self.load_pkg_json(&root_pkg_json_path)? {
|
if let Some(pkg_json) = self.load_pkg_json(&root_pkg_json_path)? {
|
||||||
if let Some(alias) = resolve_alias_from_pkg_json(req, pkg_json.as_ref())
|
if let Some(alias) = resolve_alias_from_pkg_json(req, pkg_json.as_ref())
|
||||||
{
|
{
|
||||||
return Ok((pkg_json, alias));
|
return Ok(Some((pkg_json, alias)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bail!(
|
Ok(None)
|
||||||
concat!(
|
}
|
||||||
"Could not find a matching package for 'npm:{}' in a package.json file. ",
|
|
||||||
"You must specify this as a package.json dependency when the ",
|
fn resolve_folder_in_root_node_modules(
|
||||||
"node_modules folder is not managed by Deno.",
|
&self,
|
||||||
),
|
req: &PackageReq,
|
||||||
req,
|
) -> Option<PathBuf> {
|
||||||
|
// now check if node_modules/.deno/ matches this constraint
|
||||||
|
let root_node_modules_dir = self.root_node_modules_dir.as_ref()?;
|
||||||
|
let node_modules_deno_dir = root_node_modules_dir.join(".deno");
|
||||||
|
let Ok(entries) = self.fs.read_dir_sync(&node_modules_deno_dir) else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
let search_prefix = format!(
|
||||||
|
"{}@",
|
||||||
|
normalize_pkg_name_for_node_modules_deno_folder(&req.name)
|
||||||
);
|
);
|
||||||
|
let mut best_version = None;
|
||||||
|
|
||||||
|
// example entries:
|
||||||
|
// - @denotest+add@1.0.0
|
||||||
|
// - @denotest+add@1.0.0_1
|
||||||
|
for entry in entries {
|
||||||
|
if !entry.is_directory {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let Some(version_and_copy_idx) = entry.name.strip_prefix(&search_prefix)
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let version = version_and_copy_idx
|
||||||
|
.rsplit_once('_')
|
||||||
|
.map(|(v, _)| v)
|
||||||
|
.unwrap_or(version_and_copy_idx);
|
||||||
|
let Ok(version) = Version::parse_from_npm(version) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if req.version_req.matches(&version) {
|
||||||
|
if let Some((best_version_version, _)) = &best_version {
|
||||||
|
if version > *best_version_version {
|
||||||
|
best_version = Some((version, entry.name));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
best_version = Some((version, entry.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
best_version.map(|(_version, entry_name)| {
|
||||||
|
join_package_name(
|
||||||
|
&node_modules_deno_dir.join(entry_name).join("node_modules"),
|
||||||
|
&req.name,
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,29 +334,62 @@ impl CliNpmResolver for ByonmCliNpmResolver {
|
||||||
req: &PackageReq,
|
req: &PackageReq,
|
||||||
referrer: &ModuleSpecifier,
|
referrer: &ModuleSpecifier,
|
||||||
) -> Result<PathBuf, AnyError> {
|
) -> Result<PathBuf, AnyError> {
|
||||||
// resolve the pkg json and alias
|
fn node_resolve_dir(
|
||||||
let (pkg_json, alias) =
|
fs: &dyn FileSystem,
|
||||||
self.resolve_pkg_json_and_alias_for_req(req, referrer)?;
|
alias: &str,
|
||||||
// now try node resolution
|
start_dir: &Path,
|
||||||
for ancestor in pkg_json.path.parent().unwrap().ancestors() {
|
) -> Result<Option<PathBuf>, AnyError> {
|
||||||
let node_modules_folder = ancestor.join("node_modules");
|
for ancestor in start_dir.ancestors() {
|
||||||
let sub_dir = join_package_name(&node_modules_folder, &alias);
|
let node_modules_folder = ancestor.join("node_modules");
|
||||||
if self.fs.is_dir_sync(&sub_dir) {
|
let sub_dir = join_package_name(&node_modules_folder, alias);
|
||||||
return Ok(canonicalize_path_maybe_not_exists_with_fs(
|
if fs.is_dir_sync(&sub_dir) {
|
||||||
&sub_dir,
|
return Ok(Some(canonicalize_path_maybe_not_exists_with_fs(
|
||||||
self.fs.as_ref(),
|
&sub_dir, fs,
|
||||||
)?);
|
)?));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
bail!(
|
// now attempt to resolve if it's found in any package.json
|
||||||
concat!(
|
let maybe_pkg_json_and_alias =
|
||||||
"Could not find \"{}\" in a node_modules folder. ",
|
self.resolve_pkg_json_and_alias_for_req(req, referrer)?;
|
||||||
"Deno expects the node_modules/ directory to be up to date. ",
|
match maybe_pkg_json_and_alias {
|
||||||
"Did you forget to run `deno install`?"
|
Some((pkg_json, alias)) => {
|
||||||
),
|
// now try node resolution
|
||||||
alias,
|
if let Some(resolved) =
|
||||||
);
|
node_resolve_dir(self.fs.as_ref(), &alias, pkg_json.dir_path())?
|
||||||
|
{
|
||||||
|
return Ok(resolved);
|
||||||
|
}
|
||||||
|
|
||||||
|
bail!(
|
||||||
|
concat!(
|
||||||
|
"Could not find \"{}\" in a node_modules folder. ",
|
||||||
|
"Deno expects the node_modules/ directory to be up to date. ",
|
||||||
|
"Did you forget to run `deno install`?"
|
||||||
|
),
|
||||||
|
alias,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
// now check if node_modules/.deno/ matches this constraint
|
||||||
|
if let Some(folder) = self.resolve_folder_in_root_node_modules(req) {
|
||||||
|
return Ok(folder);
|
||||||
|
}
|
||||||
|
|
||||||
|
bail!(
|
||||||
|
concat!(
|
||||||
|
"Could not find a matching package for 'npm:{}' in the node_modules ",
|
||||||
|
"directory. Ensure you have all your JSR and npm dependencies listed ",
|
||||||
|
"in your deno.json or package.json, then run `deno install`. Alternatively, ",
|
||||||
|
r#"turn on auto-install by specifying `"nodeModulesDir": "auto"` in your "#,
|
||||||
|
"deno.json file."
|
||||||
|
),
|
||||||
|
req,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_state_hash(&self) -> Option<u64> {
|
fn check_state_hash(&self) -> Option<u64> {
|
||||||
|
|
|
@ -32,9 +32,9 @@ use resolution::AddPkgReqsResult;
|
||||||
|
|
||||||
use crate::args::CliLockfile;
|
use crate::args::CliLockfile;
|
||||||
use crate::args::LifecycleScriptsConfig;
|
use crate::args::LifecycleScriptsConfig;
|
||||||
|
use crate::args::NpmInstallDepsProvider;
|
||||||
use crate::args::NpmProcessState;
|
use crate::args::NpmProcessState;
|
||||||
use crate::args::NpmProcessStateKind;
|
use crate::args::NpmProcessStateKind;
|
||||||
use crate::args::PackageJsonInstallDepsProvider;
|
|
||||||
use crate::cache::FastInsecureHasher;
|
use crate::cache::FastInsecureHasher;
|
||||||
use crate::http_util::HttpClientProvider;
|
use crate::http_util::HttpClientProvider;
|
||||||
use crate::util::fs::canonicalize_path_maybe_not_exists_with_fs;
|
use crate::util::fs::canonicalize_path_maybe_not_exists_with_fs;
|
||||||
|
@ -45,6 +45,7 @@ use self::cache::NpmCache;
|
||||||
use self::registry::CliNpmRegistryApi;
|
use self::registry::CliNpmRegistryApi;
|
||||||
use self::resolution::NpmResolution;
|
use self::resolution::NpmResolution;
|
||||||
use self::resolvers::create_npm_fs_resolver;
|
use self::resolvers::create_npm_fs_resolver;
|
||||||
|
pub use self::resolvers::normalize_pkg_name_for_node_modules_deno_folder;
|
||||||
use self::resolvers::NpmPackageFsResolver;
|
use self::resolvers::NpmPackageFsResolver;
|
||||||
|
|
||||||
use super::CliNpmResolver;
|
use super::CliNpmResolver;
|
||||||
|
@ -71,7 +72,7 @@ pub struct CliNpmResolverManagedCreateOptions {
|
||||||
pub text_only_progress_bar: crate::util::progress_bar::ProgressBar,
|
pub text_only_progress_bar: crate::util::progress_bar::ProgressBar,
|
||||||
pub maybe_node_modules_path: Option<PathBuf>,
|
pub maybe_node_modules_path: Option<PathBuf>,
|
||||||
pub npm_system_info: NpmSystemInfo,
|
pub npm_system_info: NpmSystemInfo,
|
||||||
pub package_json_deps_provider: Arc<PackageJsonInstallDepsProvider>,
|
pub npm_install_deps_provider: Arc<NpmInstallDepsProvider>,
|
||||||
pub npmrc: Arc<ResolvedNpmRc>,
|
pub npmrc: Arc<ResolvedNpmRc>,
|
||||||
pub lifecycle_scripts: LifecycleScriptsConfig,
|
pub lifecycle_scripts: LifecycleScriptsConfig,
|
||||||
}
|
}
|
||||||
|
@ -97,7 +98,7 @@ pub async fn create_managed_npm_resolver_for_lsp(
|
||||||
npm_api,
|
npm_api,
|
||||||
npm_cache,
|
npm_cache,
|
||||||
options.npmrc,
|
options.npmrc,
|
||||||
options.package_json_deps_provider,
|
options.npm_install_deps_provider,
|
||||||
options.text_only_progress_bar,
|
options.text_only_progress_bar,
|
||||||
options.maybe_node_modules_path,
|
options.maybe_node_modules_path,
|
||||||
options.npm_system_info,
|
options.npm_system_info,
|
||||||
|
@ -122,7 +123,7 @@ pub async fn create_managed_npm_resolver(
|
||||||
npm_api,
|
npm_api,
|
||||||
npm_cache,
|
npm_cache,
|
||||||
options.npmrc,
|
options.npmrc,
|
||||||
options.package_json_deps_provider,
|
options.npm_install_deps_provider,
|
||||||
options.text_only_progress_bar,
|
options.text_only_progress_bar,
|
||||||
options.maybe_node_modules_path,
|
options.maybe_node_modules_path,
|
||||||
options.npm_system_info,
|
options.npm_system_info,
|
||||||
|
@ -139,7 +140,7 @@ fn create_inner(
|
||||||
npm_api: Arc<CliNpmRegistryApi>,
|
npm_api: Arc<CliNpmRegistryApi>,
|
||||||
npm_cache: Arc<NpmCache>,
|
npm_cache: Arc<NpmCache>,
|
||||||
npm_rc: Arc<ResolvedNpmRc>,
|
npm_rc: Arc<ResolvedNpmRc>,
|
||||||
package_json_deps_provider: Arc<PackageJsonInstallDepsProvider>,
|
npm_install_deps_provider: Arc<NpmInstallDepsProvider>,
|
||||||
text_only_progress_bar: crate::util::progress_bar::ProgressBar,
|
text_only_progress_bar: crate::util::progress_bar::ProgressBar,
|
||||||
node_modules_dir_path: Option<PathBuf>,
|
node_modules_dir_path: Option<PathBuf>,
|
||||||
npm_system_info: NpmSystemInfo,
|
npm_system_info: NpmSystemInfo,
|
||||||
|
@ -161,7 +162,7 @@ fn create_inner(
|
||||||
let fs_resolver = create_npm_fs_resolver(
|
let fs_resolver = create_npm_fs_resolver(
|
||||||
fs.clone(),
|
fs.clone(),
|
||||||
npm_cache.clone(),
|
npm_cache.clone(),
|
||||||
&package_json_deps_provider,
|
&npm_install_deps_provider,
|
||||||
&text_only_progress_bar,
|
&text_only_progress_bar,
|
||||||
resolution.clone(),
|
resolution.clone(),
|
||||||
tarball_cache.clone(),
|
tarball_cache.clone(),
|
||||||
|
@ -175,7 +176,7 @@ fn create_inner(
|
||||||
maybe_lockfile,
|
maybe_lockfile,
|
||||||
npm_api,
|
npm_api,
|
||||||
npm_cache,
|
npm_cache,
|
||||||
package_json_deps_provider,
|
npm_install_deps_provider,
|
||||||
resolution,
|
resolution,
|
||||||
tarball_cache,
|
tarball_cache,
|
||||||
text_only_progress_bar,
|
text_only_progress_bar,
|
||||||
|
@ -261,7 +262,7 @@ pub struct ManagedCliNpmResolver {
|
||||||
maybe_lockfile: Option<Arc<CliLockfile>>,
|
maybe_lockfile: Option<Arc<CliLockfile>>,
|
||||||
npm_api: Arc<CliNpmRegistryApi>,
|
npm_api: Arc<CliNpmRegistryApi>,
|
||||||
npm_cache: Arc<NpmCache>,
|
npm_cache: Arc<NpmCache>,
|
||||||
package_json_deps_provider: Arc<PackageJsonInstallDepsProvider>,
|
npm_install_deps_provider: Arc<NpmInstallDepsProvider>,
|
||||||
resolution: Arc<NpmResolution>,
|
resolution: Arc<NpmResolution>,
|
||||||
tarball_cache: Arc<TarballCache>,
|
tarball_cache: Arc<TarballCache>,
|
||||||
text_only_progress_bar: ProgressBar,
|
text_only_progress_bar: ProgressBar,
|
||||||
|
@ -286,7 +287,7 @@ impl ManagedCliNpmResolver {
|
||||||
maybe_lockfile: Option<Arc<CliLockfile>>,
|
maybe_lockfile: Option<Arc<CliLockfile>>,
|
||||||
npm_api: Arc<CliNpmRegistryApi>,
|
npm_api: Arc<CliNpmRegistryApi>,
|
||||||
npm_cache: Arc<NpmCache>,
|
npm_cache: Arc<NpmCache>,
|
||||||
package_json_deps_provider: Arc<PackageJsonInstallDepsProvider>,
|
npm_install_deps_provider: Arc<NpmInstallDepsProvider>,
|
||||||
resolution: Arc<NpmResolution>,
|
resolution: Arc<NpmResolution>,
|
||||||
tarball_cache: Arc<TarballCache>,
|
tarball_cache: Arc<TarballCache>,
|
||||||
text_only_progress_bar: ProgressBar,
|
text_only_progress_bar: ProgressBar,
|
||||||
|
@ -299,7 +300,7 @@ impl ManagedCliNpmResolver {
|
||||||
maybe_lockfile,
|
maybe_lockfile,
|
||||||
npm_api,
|
npm_api,
|
||||||
npm_cache,
|
npm_cache,
|
||||||
package_json_deps_provider,
|
npm_install_deps_provider,
|
||||||
text_only_progress_bar,
|
text_only_progress_bar,
|
||||||
resolution,
|
resolution,
|
||||||
tarball_cache,
|
tarball_cache,
|
||||||
|
@ -476,7 +477,7 @@ impl ManagedCliNpmResolver {
|
||||||
if !self.top_level_install_flag.raise() {
|
if !self.top_level_install_flag.raise() {
|
||||||
return Ok(false); // already did this
|
return Ok(false); // already did this
|
||||||
}
|
}
|
||||||
let pkg_json_remote_pkgs = self.package_json_deps_provider.remote_pkgs();
|
let pkg_json_remote_pkgs = self.npm_install_deps_provider.remote_pkgs();
|
||||||
if pkg_json_remote_pkgs.is_empty() {
|
if pkg_json_remote_pkgs.is_empty() {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
@ -605,7 +606,7 @@ impl CliNpmResolver for ManagedCliNpmResolver {
|
||||||
create_npm_fs_resolver(
|
create_npm_fs_resolver(
|
||||||
self.fs.clone(),
|
self.fs.clone(),
|
||||||
self.npm_cache.clone(),
|
self.npm_cache.clone(),
|
||||||
&self.package_json_deps_provider,
|
&self.npm_install_deps_provider,
|
||||||
&self.text_only_progress_bar,
|
&self.text_only_progress_bar,
|
||||||
npm_resolution.clone(),
|
npm_resolution.clone(),
|
||||||
self.tarball_cache.clone(),
|
self.tarball_cache.clone(),
|
||||||
|
@ -616,7 +617,7 @@ impl CliNpmResolver for ManagedCliNpmResolver {
|
||||||
self.maybe_lockfile.clone(),
|
self.maybe_lockfile.clone(),
|
||||||
self.npm_api.clone(),
|
self.npm_api.clone(),
|
||||||
self.npm_cache.clone(),
|
self.npm_cache.clone(),
|
||||||
self.package_json_deps_provider.clone(),
|
self.npm_install_deps_provider.clone(),
|
||||||
npm_resolution,
|
npm_resolution,
|
||||||
self.tarball_cache.clone(),
|
self.tarball_cache.clone(),
|
||||||
self.text_only_progress_bar.clone(),
|
self.text_only_progress_bar.clone(),
|
||||||
|
|
|
@ -41,7 +41,7 @@ use node_resolver::errors::ReferrerNotFoundError;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::args::PackageJsonInstallDepsProvider;
|
use crate::args::NpmInstallDepsProvider;
|
||||||
use crate::cache::CACHE_PERM;
|
use crate::cache::CACHE_PERM;
|
||||||
use crate::npm::cache_dir::mixed_case_package_name_decode;
|
use crate::npm::cache_dir::mixed_case_package_name_decode;
|
||||||
use crate::npm::cache_dir::mixed_case_package_name_encode;
|
use crate::npm::cache_dir::mixed_case_package_name_encode;
|
||||||
|
@ -65,7 +65,7 @@ use super::common::RegistryReadPermissionChecker;
|
||||||
pub struct LocalNpmPackageResolver {
|
pub struct LocalNpmPackageResolver {
|
||||||
cache: Arc<NpmCache>,
|
cache: Arc<NpmCache>,
|
||||||
fs: Arc<dyn deno_fs::FileSystem>,
|
fs: Arc<dyn deno_fs::FileSystem>,
|
||||||
pkg_json_deps_provider: Arc<PackageJsonInstallDepsProvider>,
|
npm_install_deps_provider: Arc<NpmInstallDepsProvider>,
|
||||||
progress_bar: ProgressBar,
|
progress_bar: ProgressBar,
|
||||||
resolution: Arc<NpmResolution>,
|
resolution: Arc<NpmResolution>,
|
||||||
tarball_cache: Arc<TarballCache>,
|
tarball_cache: Arc<TarballCache>,
|
||||||
|
@ -81,7 +81,7 @@ impl LocalNpmPackageResolver {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
cache: Arc<NpmCache>,
|
cache: Arc<NpmCache>,
|
||||||
fs: Arc<dyn deno_fs::FileSystem>,
|
fs: Arc<dyn deno_fs::FileSystem>,
|
||||||
pkg_json_deps_provider: Arc<PackageJsonInstallDepsProvider>,
|
npm_install_deps_provider: Arc<NpmInstallDepsProvider>,
|
||||||
progress_bar: ProgressBar,
|
progress_bar: ProgressBar,
|
||||||
resolution: Arc<NpmResolution>,
|
resolution: Arc<NpmResolution>,
|
||||||
tarball_cache: Arc<TarballCache>,
|
tarball_cache: Arc<TarballCache>,
|
||||||
|
@ -92,7 +92,7 @@ impl LocalNpmPackageResolver {
|
||||||
Self {
|
Self {
|
||||||
cache,
|
cache,
|
||||||
fs: fs.clone(),
|
fs: fs.clone(),
|
||||||
pkg_json_deps_provider,
|
npm_install_deps_provider,
|
||||||
progress_bar,
|
progress_bar,
|
||||||
resolution,
|
resolution,
|
||||||
tarball_cache,
|
tarball_cache,
|
||||||
|
@ -248,7 +248,7 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
|
||||||
sync_resolution_with_fs(
|
sync_resolution_with_fs(
|
||||||
&self.resolution.snapshot(),
|
&self.resolution.snapshot(),
|
||||||
&self.cache,
|
&self.cache,
|
||||||
&self.pkg_json_deps_provider,
|
&self.npm_install_deps_provider,
|
||||||
&self.progress_bar,
|
&self.progress_bar,
|
||||||
&self.tarball_cache,
|
&self.tarball_cache,
|
||||||
&self.root_node_modules_path,
|
&self.root_node_modules_path,
|
||||||
|
@ -412,14 +412,16 @@ fn has_lifecycle_scripts(
|
||||||
async fn sync_resolution_with_fs(
|
async fn sync_resolution_with_fs(
|
||||||
snapshot: &NpmResolutionSnapshot,
|
snapshot: &NpmResolutionSnapshot,
|
||||||
cache: &Arc<NpmCache>,
|
cache: &Arc<NpmCache>,
|
||||||
pkg_json_deps_provider: &PackageJsonInstallDepsProvider,
|
npm_install_deps_provider: &NpmInstallDepsProvider,
|
||||||
progress_bar: &ProgressBar,
|
progress_bar: &ProgressBar,
|
||||||
tarball_cache: &Arc<TarballCache>,
|
tarball_cache: &Arc<TarballCache>,
|
||||||
root_node_modules_dir_path: &Path,
|
root_node_modules_dir_path: &Path,
|
||||||
system_info: &NpmSystemInfo,
|
system_info: &NpmSystemInfo,
|
||||||
lifecycle_scripts: &LifecycleScriptsConfig,
|
lifecycle_scripts: &LifecycleScriptsConfig,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
if snapshot.is_empty() && pkg_json_deps_provider.workspace_pkgs().is_empty() {
|
if snapshot.is_empty()
|
||||||
|
&& npm_install_deps_provider.workspace_pkgs().is_empty()
|
||||||
|
{
|
||||||
return Ok(()); // don't create the directory
|
return Ok(()); // don't create the directory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -620,7 +622,7 @@ async fn sync_resolution_with_fs(
|
||||||
|
|
||||||
// 4. Create symlinks for package json dependencies
|
// 4. Create symlinks for package json dependencies
|
||||||
{
|
{
|
||||||
for remote in pkg_json_deps_provider.remote_pkgs() {
|
for remote in npm_install_deps_provider.remote_pkgs() {
|
||||||
let remote_pkg = if let Ok(remote_pkg) =
|
let remote_pkg = if let Ok(remote_pkg) =
|
||||||
snapshot.resolve_pkg_from_pkg_req(&remote.req)
|
snapshot.resolve_pkg_from_pkg_req(&remote.req)
|
||||||
{
|
{
|
||||||
|
@ -684,7 +686,7 @@ async fn sync_resolution_with_fs(
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Create symlinks for the remaining top level packages in the node_modules folder.
|
// 5. Create symlinks for the remaining top level packages in the node_modules folder.
|
||||||
// (These may be present if they are not in the package.json dependencies, such as )
|
// (These may be present if they are not in the package.json dependencies)
|
||||||
// Symlink node_modules/.deno/<package_id>/node_modules/<package_name> to
|
// Symlink node_modules/.deno/<package_id>/node_modules/<package_name> to
|
||||||
// node_modules/<package_name>
|
// node_modules/<package_name>
|
||||||
let mut ids = snapshot
|
let mut ids = snapshot
|
||||||
|
@ -757,10 +759,10 @@ async fn sync_resolution_with_fs(
|
||||||
|
|
||||||
// 8. Create symlinks for the workspace packages
|
// 8. Create symlinks for the workspace packages
|
||||||
{
|
{
|
||||||
// todo(#24419): this is not exactly correct because it should
|
// todo(dsherret): this is not exactly correct because it should
|
||||||
// install correctly for a workspace (potentially in sub directories),
|
// install correctly for a workspace (potentially in sub directories),
|
||||||
// but this is good enough for a first pass
|
// but this is good enough for a first pass
|
||||||
for workspace in pkg_json_deps_provider.workspace_pkgs() {
|
for workspace in npm_install_deps_provider.workspace_pkgs() {
|
||||||
symlink_package_dir(
|
symlink_package_dir(
|
||||||
&workspace.target_dir,
|
&workspace.target_dir,
|
||||||
&root_node_modules_dir_path.join(&workspace.alias),
|
&root_node_modules_dir_path.join(&workspace.alias),
|
||||||
|
@ -985,21 +987,31 @@ impl SetupCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Normalizes a package name for use at `node_modules/.deno/<pkg-name>@<version>[_<copy_index>]`
|
||||||
|
pub fn normalize_pkg_name_for_node_modules_deno_folder(name: &str) -> Cow<str> {
|
||||||
|
let name = if name.to_lowercase() == name {
|
||||||
|
Cow::Borrowed(name)
|
||||||
|
} else {
|
||||||
|
Cow::Owned(format!("_{}", mixed_case_package_name_encode(name)))
|
||||||
|
};
|
||||||
|
if name.starts_with('@') {
|
||||||
|
name.replace('/', "+").into()
|
||||||
|
} else {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_package_folder_id_folder_name(
|
fn get_package_folder_id_folder_name(
|
||||||
folder_id: &NpmPackageCacheFolderId,
|
folder_id: &NpmPackageCacheFolderId,
|
||||||
) -> String {
|
) -> String {
|
||||||
let copy_str = if folder_id.copy_index == 0 {
|
let copy_str = if folder_id.copy_index == 0 {
|
||||||
"".to_string()
|
Cow::Borrowed("")
|
||||||
} else {
|
} else {
|
||||||
format!("_{}", folder_id.copy_index)
|
Cow::Owned(format!("_{}", folder_id.copy_index))
|
||||||
};
|
};
|
||||||
let nv = &folder_id.nv;
|
let nv = &folder_id.nv;
|
||||||
let name = if nv.name.to_lowercase() == nv.name {
|
let name = normalize_pkg_name_for_node_modules_deno_folder(&nv.name);
|
||||||
Cow::Borrowed(&nv.name)
|
format!("{}@{}{}", name, nv.version, copy_str)
|
||||||
} else {
|
|
||||||
Cow::Owned(format!("_{}", mixed_case_package_name_encode(&nv.name)))
|
|
||||||
};
|
|
||||||
format!("{}@{}{}", name, nv.version, copy_str).replace('/', "+")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_package_folder_id_from_folder_name(
|
fn get_package_folder_id_from_folder_name(
|
||||||
|
|
|
@ -11,10 +11,11 @@ use deno_npm::NpmSystemInfo;
|
||||||
use deno_runtime::deno_fs::FileSystem;
|
use deno_runtime::deno_fs::FileSystem;
|
||||||
|
|
||||||
use crate::args::LifecycleScriptsConfig;
|
use crate::args::LifecycleScriptsConfig;
|
||||||
use crate::args::PackageJsonInstallDepsProvider;
|
use crate::args::NpmInstallDepsProvider;
|
||||||
use crate::util::progress_bar::ProgressBar;
|
use crate::util::progress_bar::ProgressBar;
|
||||||
|
|
||||||
pub use self::common::NpmPackageFsResolver;
|
pub use self::common::NpmPackageFsResolver;
|
||||||
|
pub use self::local::normalize_pkg_name_for_node_modules_deno_folder;
|
||||||
|
|
||||||
use self::global::GlobalNpmPackageResolver;
|
use self::global::GlobalNpmPackageResolver;
|
||||||
use self::local::LocalNpmPackageResolver;
|
use self::local::LocalNpmPackageResolver;
|
||||||
|
@ -27,7 +28,7 @@ use super::resolution::NpmResolution;
|
||||||
pub fn create_npm_fs_resolver(
|
pub fn create_npm_fs_resolver(
|
||||||
fs: Arc<dyn FileSystem>,
|
fs: Arc<dyn FileSystem>,
|
||||||
npm_cache: Arc<NpmCache>,
|
npm_cache: Arc<NpmCache>,
|
||||||
pkg_json_deps_provider: &Arc<PackageJsonInstallDepsProvider>,
|
npm_install_deps_provider: &Arc<NpmInstallDepsProvider>,
|
||||||
progress_bar: &ProgressBar,
|
progress_bar: &ProgressBar,
|
||||||
resolution: Arc<NpmResolution>,
|
resolution: Arc<NpmResolution>,
|
||||||
tarball_cache: Arc<TarballCache>,
|
tarball_cache: Arc<TarballCache>,
|
||||||
|
@ -39,7 +40,7 @@ pub fn create_npm_fs_resolver(
|
||||||
Some(node_modules_folder) => Arc::new(LocalNpmPackageResolver::new(
|
Some(node_modules_folder) => Arc::new(LocalNpmPackageResolver::new(
|
||||||
npm_cache,
|
npm_cache,
|
||||||
fs,
|
fs,
|
||||||
pkg_json_deps_provider.clone(),
|
npm_install_deps_provider.clone(),
|
||||||
progress_bar.clone(),
|
progress_bar.clone(),
|
||||||
resolution,
|
resolution,
|
||||||
tarball_cache,
|
tarball_cache,
|
||||||
|
|
|
@ -502,7 +502,7 @@ impl Resolver for CliGraphResolver {
|
||||||
|
|
||||||
fn resolve(
|
fn resolve(
|
||||||
&self,
|
&self,
|
||||||
specifier: &str,
|
raw_specifier: &str,
|
||||||
referrer_range: &deno_graph::Range,
|
referrer_range: &deno_graph::Range,
|
||||||
mode: ResolutionMode,
|
mode: ResolutionMode,
|
||||||
) -> Result<ModuleSpecifier, ResolveError> {
|
) -> Result<ModuleSpecifier, ResolveError> {
|
||||||
|
@ -519,7 +519,7 @@ impl Resolver for CliGraphResolver {
|
||||||
if let Some(node_resolver) = self.node_resolver.as_ref() {
|
if let Some(node_resolver) = self.node_resolver.as_ref() {
|
||||||
if referrer.scheme() == "file" && node_resolver.in_npm_package(referrer) {
|
if referrer.scheme() == "file" && node_resolver.in_npm_package(referrer) {
|
||||||
return node_resolver
|
return node_resolver
|
||||||
.resolve(specifier, referrer, to_node_mode(mode))
|
.resolve(raw_specifier, referrer, to_node_mode(mode))
|
||||||
.map(|res| res.into_url())
|
.map(|res| res.into_url())
|
||||||
.map_err(|e| ResolveError::Other(e.into()));
|
.map_err(|e| ResolveError::Other(e.into()));
|
||||||
}
|
}
|
||||||
|
@ -528,7 +528,7 @@ impl Resolver for CliGraphResolver {
|
||||||
// Attempt to resolve with the workspace resolver
|
// Attempt to resolve with the workspace resolver
|
||||||
let result: Result<_, ResolveError> = self
|
let result: Result<_, ResolveError> = self
|
||||||
.workspace_resolver
|
.workspace_resolver
|
||||||
.resolve(specifier, referrer)
|
.resolve(raw_specifier, referrer)
|
||||||
.map_err(|err| match err {
|
.map_err(|err| match err {
|
||||||
MappedResolutionError::Specifier(err) => ResolveError::Specifier(err),
|
MappedResolutionError::Specifier(err) => ResolveError::Specifier(err),
|
||||||
MappedResolutionError::ImportMap(err) => {
|
MappedResolutionError::ImportMap(err) => {
|
||||||
|
@ -700,7 +700,7 @@ impl Resolver for CliGraphResolver {
|
||||||
// If byonm, check if the bare specifier resolves to an npm package
|
// If byonm, check if the bare specifier resolves to an npm package
|
||||||
if is_byonm && referrer.scheme() == "file" {
|
if is_byonm && referrer.scheme() == "file" {
|
||||||
let maybe_resolution = node_resolver
|
let maybe_resolution = node_resolver
|
||||||
.resolve_if_for_npm_pkg(specifier, referrer, to_node_mode(mode))
|
.resolve_if_for_npm_pkg(raw_specifier, referrer, to_node_mode(mode))
|
||||||
.map_err(ResolveError::Other)?;
|
.map_err(ResolveError::Other)?;
|
||||||
if let Some(res) = maybe_resolution {
|
if let Some(res) = maybe_resolution {
|
||||||
return Ok(res.into_url());
|
return Ok(res.into_url());
|
||||||
|
|
|
@ -45,7 +45,7 @@ use serde::Serialize;
|
||||||
use crate::args::CaData;
|
use crate::args::CaData;
|
||||||
use crate::args::CliOptions;
|
use crate::args::CliOptions;
|
||||||
use crate::args::CompileFlags;
|
use crate::args::CompileFlags;
|
||||||
use crate::args::PackageJsonInstallDepsProvider;
|
use crate::args::NpmInstallDepsProvider;
|
||||||
use crate::args::PermissionFlags;
|
use crate::args::PermissionFlags;
|
||||||
use crate::args::UnstableConfig;
|
use crate::args::UnstableConfig;
|
||||||
use crate::cache::DenoDir;
|
use crate::cache::DenoDir;
|
||||||
|
|
|
@ -48,7 +48,7 @@ use crate::args::get_root_cert_store;
|
||||||
use crate::args::npm_pkg_req_ref_to_binary_command;
|
use crate::args::npm_pkg_req_ref_to_binary_command;
|
||||||
use crate::args::CaData;
|
use crate::args::CaData;
|
||||||
use crate::args::CacheSetting;
|
use crate::args::CacheSetting;
|
||||||
use crate::args::PackageJsonInstallDepsProvider;
|
use crate::args::NpmInstallDepsProvider;
|
||||||
use crate::args::StorageKeyResolver;
|
use crate::args::StorageKeyResolver;
|
||||||
use crate::cache::Caches;
|
use crate::cache::Caches;
|
||||||
use crate::cache::DenoDirProvider;
|
use crate::cache::DenoDirProvider;
|
||||||
|
@ -138,7 +138,7 @@ pub const UNSUPPORTED_SCHEME: &str = "Unsupported scheme";
|
||||||
impl ModuleLoader for EmbeddedModuleLoader {
|
impl ModuleLoader for EmbeddedModuleLoader {
|
||||||
fn resolve(
|
fn resolve(
|
||||||
&self,
|
&self,
|
||||||
specifier: &str,
|
raw_specifier: &str,
|
||||||
referrer: &str,
|
referrer: &str,
|
||||||
kind: ResolutionKind,
|
kind: ResolutionKind,
|
||||||
) -> Result<ModuleSpecifier, AnyError> {
|
) -> Result<ModuleSpecifier, AnyError> {
|
||||||
|
@ -162,13 +162,15 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
||||||
self
|
self
|
||||||
.shared
|
.shared
|
||||||
.node_resolver
|
.node_resolver
|
||||||
.resolve(specifier, &referrer, NodeResolutionMode::Execution)?
|
.resolve(raw_specifier, &referrer, NodeResolutionMode::Execution)?
|
||||||
.into_url(),
|
.into_url(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mapped_resolution =
|
let mapped_resolution = self
|
||||||
self.shared.workspace_resolver.resolve(specifier, &referrer);
|
.shared
|
||||||
|
.workspace_resolver
|
||||||
|
.resolve(raw_specifier, &referrer);
|
||||||
|
|
||||||
match mapped_resolution {
|
match mapped_resolution {
|
||||||
Ok(MappedResolution::WorkspaceJsrPackage { specifier, .. }) => {
|
Ok(MappedResolution::WorkspaceJsrPackage { specifier, .. }) => {
|
||||||
|
@ -262,7 +264,7 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
||||||
if err.is_unmapped_bare_specifier() && referrer.scheme() == "file" =>
|
if err.is_unmapped_bare_specifier() && referrer.scheme() == "file" =>
|
||||||
{
|
{
|
||||||
let maybe_res = self.shared.node_resolver.resolve_if_for_npm_pkg(
|
let maybe_res = self.shared.node_resolver.resolve_if_for_npm_pkg(
|
||||||
specifier,
|
raw_specifier,
|
||||||
&referrer,
|
&referrer,
|
||||||
NodeResolutionMode::Execution,
|
NodeResolutionMode::Execution,
|
||||||
)?;
|
)?;
|
||||||
|
@ -502,9 +504,9 @@ pub async fn run(
|
||||||
text_only_progress_bar: progress_bar,
|
text_only_progress_bar: progress_bar,
|
||||||
maybe_node_modules_path,
|
maybe_node_modules_path,
|
||||||
npm_system_info: Default::default(),
|
npm_system_info: Default::default(),
|
||||||
package_json_deps_provider: Arc::new(
|
npm_install_deps_provider: Arc::new(
|
||||||
// this is only used for installing packages, which isn't necessary with deno compile
|
// this is only used for installing packages, which isn't necessary with deno compile
|
||||||
PackageJsonInstallDepsProvider::empty(),
|
NpmInstallDepsProvider::empty(),
|
||||||
),
|
),
|
||||||
// create an npmrc that uses the fake npm_registry_url to resolve packages
|
// create an npmrc that uses the fake npm_registry_url to resolve packages
|
||||||
npmrc: Arc::new(ResolvedNpmRc {
|
npmrc: Arc::new(ResolvedNpmRc {
|
||||||
|
@ -554,9 +556,9 @@ pub async fn run(
|
||||||
text_only_progress_bar: progress_bar,
|
text_only_progress_bar: progress_bar,
|
||||||
maybe_node_modules_path: None,
|
maybe_node_modules_path: None,
|
||||||
npm_system_info: Default::default(),
|
npm_system_info: Default::default(),
|
||||||
package_json_deps_provider: Arc::new(
|
npm_install_deps_provider: Arc::new(
|
||||||
// this is only used for installing packages, which isn't necessary with deno compile
|
// this is only used for installing packages, which isn't necessary with deno compile
|
||||||
PackageJsonInstallDepsProvider::empty(),
|
NpmInstallDepsProvider::empty(),
|
||||||
),
|
),
|
||||||
// Packages from different registries are already inlined in the ESZip,
|
// Packages from different registries are already inlined in the ESZip,
|
||||||
// so no need to create actual `.npmrc` configuration.
|
// so no need to create actual `.npmrc` configuration.
|
||||||
|
|
|
@ -795,7 +795,7 @@ fn resolve_graph_specifier_types(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_non_graph_specifier_types(
|
fn resolve_non_graph_specifier_types(
|
||||||
specifier: &str,
|
raw_specifier: &str,
|
||||||
referrer: &ModuleSpecifier,
|
referrer: &ModuleSpecifier,
|
||||||
referrer_kind: NodeModuleKind,
|
referrer_kind: NodeModuleKind,
|
||||||
state: &State,
|
state: &State,
|
||||||
|
@ -810,14 +810,16 @@ fn resolve_non_graph_specifier_types(
|
||||||
Ok(Some(NodeResolution::into_specifier_and_media_type(
|
Ok(Some(NodeResolution::into_specifier_and_media_type(
|
||||||
node_resolver
|
node_resolver
|
||||||
.resolve(
|
.resolve(
|
||||||
specifier,
|
raw_specifier,
|
||||||
referrer,
|
referrer,
|
||||||
referrer_kind,
|
referrer_kind,
|
||||||
NodeResolutionMode::Types,
|
NodeResolutionMode::Types,
|
||||||
)
|
)
|
||||||
.ok(),
|
.ok(),
|
||||||
)))
|
)))
|
||||||
} else if let Ok(npm_req_ref) = NpmPackageReqReference::from_str(specifier) {
|
} else if let Ok(npm_req_ref) =
|
||||||
|
NpmPackageReqReference::from_str(raw_specifier)
|
||||||
|
{
|
||||||
debug_assert_eq!(referrer_kind, NodeModuleKind::Esm);
|
debug_assert_eq!(referrer_kind, NodeModuleKind::Esm);
|
||||||
// todo(dsherret): add support for injecting this in the graph so
|
// todo(dsherret): add support for injecting this in the graph so
|
||||||
// we don't need this special code here.
|
// we don't need this special code here.
|
||||||
|
|
|
@ -18,6 +18,7 @@ pub use npm::NpmResolverRc;
|
||||||
pub use package_json::load_pkg_json;
|
pub use package_json::load_pkg_json;
|
||||||
pub use package_json::PackageJsonThreadLocalCache;
|
pub use package_json::PackageJsonThreadLocalCache;
|
||||||
pub use path::PathClean;
|
pub use path::PathClean;
|
||||||
|
pub use resolution::parse_npm_pkg_name;
|
||||||
pub use resolution::NodeModuleKind;
|
pub use resolution::NodeModuleKind;
|
||||||
pub use resolution::NodeResolution;
|
pub use resolution::NodeResolution;
|
||||||
pub use resolution::NodeResolutionMode;
|
pub use resolution::NodeResolutionMode;
|
||||||
|
|
|
@ -14797,7 +14797,7 @@ fn lsp_byonm() {
|
||||||
"severity": 1,
|
"severity": 1,
|
||||||
"code": "resolver-error",
|
"code": "resolver-error",
|
||||||
"source": "deno",
|
"source": "deno",
|
||||||
"message": "Could not find a matching package for 'npm:chalk' in a package.json file. You must specify this as a package.json dependency when the node_modules folder is not managed by Deno.",
|
"message": "Could not find a matching package for 'npm:chalk' in the node_modules directory. Ensure you have all your JSR and npm dependencies listed in your deno.json or package.json, then run `deno install`. Alternatively, turn on auto-install by specifying `\"nodeModulesDir\": \"auto\"` in your deno.json file.",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"range": {
|
"range": {
|
||||||
|
@ -14842,7 +14842,7 @@ fn lsp_byonm() {
|
||||||
"severity": 1,
|
"severity": 1,
|
||||||
"code": "resolver-error",
|
"code": "resolver-error",
|
||||||
"source": "deno",
|
"source": "deno",
|
||||||
"message": "Could not find a matching package for 'npm:chalk' in a package.json file. You must specify this as a package.json dependency when the node_modules folder is not managed by Deno.",
|
"message": "Could not find a matching package for 'npm:chalk' in the node_modules directory. Ensure you have all your JSR and npm dependencies listed in your deno.json or package.json, then run `deno install`. Alternatively, turn on auto-install by specifying `\"nodeModulesDir\": \"auto\"` in your deno.json file.",
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
|
@ -2195,7 +2195,7 @@ console.log(getKind());
|
||||||
.args("run --allow-read chalk.ts")
|
.args("run --allow-read chalk.ts")
|
||||||
.run();
|
.run();
|
||||||
output.assert_matches_text(
|
output.assert_matches_text(
|
||||||
r#"error: Could not find a matching package for 'npm:chalk@5' in a package.json file. You must specify this as a package.json dependency when the node_modules folder is not managed by Deno.
|
r#"error: Could not find a matching package for 'npm:chalk@5' in the node_modules directory. Ensure you have all your JSR and npm dependencies listed in your deno.json or package.json, then run `deno install`. Alternatively, turn on auto-install by specifying `"nodeModulesDir": "auto"` in your deno.json file.
|
||||||
at file:///[WILDCARD]chalk.ts:1:19
|
at file:///[WILDCARD]chalk.ts:1:19
|
||||||
"#);
|
"#);
|
||||||
output.assert_exit_code(1);
|
output.assert_exit_code(1);
|
||||||
|
@ -2277,7 +2277,7 @@ console.log(getKind());
|
||||||
.args("run --allow-read chalk.ts")
|
.args("run --allow-read chalk.ts")
|
||||||
.run();
|
.run();
|
||||||
output.assert_matches_text(
|
output.assert_matches_text(
|
||||||
r#"error: Could not find a matching package for 'npm:chalk@5' in a package.json file. You must specify this as a package.json dependency when the node_modules folder is not managed by Deno.
|
r#"error: Could not find a matching package for 'npm:chalk@5' in the node_modules directory. Ensure you have all your JSR and npm dependencies listed in your deno.json or package.json, then run `deno install`. Alternatively, turn on auto-install by specifying `"nodeModulesDir": "auto"` in your deno.json file.
|
||||||
at file:///[WILDCARD]chalk.ts:1:19
|
at file:///[WILDCARD]chalk.ts:1:19
|
||||||
"#);
|
"#);
|
||||||
output.assert_exit_code(1);
|
output.assert_exit_code(1);
|
||||||
|
|
5
tests/registry/jsr/@denotest/npm-add/0.5.0/mod.ts
Normal file
5
tests/registry/jsr/@denotest/npm-add/0.5.0/mod.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import * as npmAdd from "npm:@denotest/add@0.5";
|
||||||
|
|
||||||
|
export function sum(a: number, b: number): number {
|
||||||
|
return npmAdd.sum(a, b);
|
||||||
|
}
|
5
tests/registry/jsr/@denotest/npm-add/0.5.0_meta.json
Normal file
5
tests/registry/jsr/@denotest/npm-add/0.5.0_meta.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"exports": {
|
||||||
|
".": "./mod.ts"
|
||||||
|
}
|
||||||
|
}
|
5
tests/registry/jsr/@denotest/npm-add/1.0.0/mod.ts
Normal file
5
tests/registry/jsr/@denotest/npm-add/1.0.0/mod.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import * as npmAdd from "npm:@denotest/add@1";
|
||||||
|
|
||||||
|
export function add(a: number, b: number): number {
|
||||||
|
return npmAdd.add(a, b);
|
||||||
|
}
|
5
tests/registry/jsr/@denotest/npm-add/1.0.0_meta.json
Normal file
5
tests/registry/jsr/@denotest/npm-add/1.0.0_meta.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"exports": {
|
||||||
|
".": "./mod.ts"
|
||||||
|
}
|
||||||
|
}
|
6
tests/registry/jsr/@denotest/npm-add/meta.json
Normal file
6
tests/registry/jsr/@denotest/npm-add/meta.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"versions": {
|
||||||
|
"0.5.0": {},
|
||||||
|
"1.0.0": {}
|
||||||
|
}
|
||||||
|
}
|
10
tests/specs/install/alias_deno_json/__test__.jsonc
Normal file
10
tests/specs/install/alias_deno_json/__test__.jsonc
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"tempDir": true,
|
||||||
|
"steps": [{
|
||||||
|
"args": "install",
|
||||||
|
"output": "[WILDCARD]"
|
||||||
|
}, {
|
||||||
|
"args": "run --allow-read=. verify.ts",
|
||||||
|
"output": "true\n"
|
||||||
|
}]
|
||||||
|
}
|
5
tests/specs/install/alias_deno_json/deno.json
Normal file
5
tests/specs/install/alias_deno_json/deno.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"imports": {
|
||||||
|
"alias": "npm:@denotest/add"
|
||||||
|
}
|
||||||
|
}
|
2
tests/specs/install/alias_deno_json/package.json
Normal file
2
tests/specs/install/alias_deno_json/package.json
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
{
|
||||||
|
}
|
2
tests/specs/install/alias_deno_json/verify.ts
Normal file
2
tests/specs/install/alias_deno_json/verify.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
const stat = Deno.statSync(new URL("./node_modules/alias", import.meta.url));
|
||||||
|
console.log(stat.isDirectory);
|
10
tests/specs/install/alias_invalid_path_char/__test__.jsonc
Normal file
10
tests/specs/install/alias_invalid_path_char/__test__.jsonc
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"tempDir": true,
|
||||||
|
"steps": [{
|
||||||
|
"args": "install",
|
||||||
|
"output": "[WILDCARD]"
|
||||||
|
}, {
|
||||||
|
"args": "run --allow-read=. verify.ts",
|
||||||
|
"output": ".bin\n.deno\n@denotest\n"
|
||||||
|
}]
|
||||||
|
}
|
7
tests/specs/install/alias_invalid_path_char/deno.jsonc
Normal file
7
tests/specs/install/alias_invalid_path_char/deno.jsonc
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"imports": {
|
||||||
|
// alias*test is an invalid path char on windows, so
|
||||||
|
// don't create an alias for this
|
||||||
|
"alias*test": "npm:@denotest/add"
|
||||||
|
}
|
||||||
|
}
|
2
tests/specs/install/alias_invalid_path_char/package.json
Normal file
2
tests/specs/install/alias_invalid_path_char/package.json
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
{
|
||||||
|
}
|
10
tests/specs/install/alias_invalid_path_char/verify.ts
Normal file
10
tests/specs/install/alias_invalid_path_char/verify.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
const entries = Array.from(
|
||||||
|
Deno.readDirSync(new URL("./node_modules", import.meta.url)),
|
||||||
|
);
|
||||||
|
const names = entries.map((entry) => entry.name);
|
||||||
|
names.sort();
|
||||||
|
|
||||||
|
// won't have the invalid path alias
|
||||||
|
for (const name of names) {
|
||||||
|
console.log(name);
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"tempDir": true,
|
||||||
|
"steps": [{
|
||||||
|
"args": "install",
|
||||||
|
"output": "[WILDCARD]"
|
||||||
|
}, {
|
||||||
|
"args": "run --allow-read=. verify.ts",
|
||||||
|
"output": "verify.out"
|
||||||
|
}]
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"imports": {
|
||||||
|
"alias": "jsr:@denotest/add"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"alias": "npm:@denotest/esm-basic"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
@denotest/esm-basic
|
||||||
|
[Module: null prototype] { add: [Function: add] }
|
|
@ -0,0 +1,13 @@
|
||||||
|
import * as mod from "alias";
|
||||||
|
|
||||||
|
const data = JSON.parse(
|
||||||
|
Deno.readTextFileSync(
|
||||||
|
new URL("./node_modules/alias/package.json", import.meta.url),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// this should just setup the npm package anyway, even though the alias
|
||||||
|
// will resolve to the jsr package
|
||||||
|
console.log(data.name);
|
||||||
|
|
||||||
|
console.log(mod);
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"tempDir": true,
|
||||||
|
"steps": [{
|
||||||
|
"args": "install",
|
||||||
|
"output": "[WILDCARD]"
|
||||||
|
}, {
|
||||||
|
"args": "run --allow-read=. verify.ts",
|
||||||
|
"output": "verify.out"
|
||||||
|
}]
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"imports": {
|
||||||
|
"alias": "npm:@denotest/add"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"alias": "npm:@denotest/esm-basic"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
@denotest/add
|
||||||
|
[Module: null prototype] {
|
||||||
|
add: [Function (anonymous)],
|
||||||
|
default: { add: [Function (anonymous)] }
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
import * as mod from "alias";
|
||||||
|
|
||||||
|
const data = JSON.parse(
|
||||||
|
Deno.readTextFileSync(
|
||||||
|
new URL("./node_modules/alias/package.json", import.meta.url),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(data.name);
|
||||||
|
console.log(mod);
|
10
tests/specs/install/byonm_jsr_npm_dep/__test__.jsonc
Normal file
10
tests/specs/install/byonm_jsr_npm_dep/__test__.jsonc
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"tempDir": true,
|
||||||
|
"steps": [{
|
||||||
|
"args": "install",
|
||||||
|
"output": "[WILDCARD]"
|
||||||
|
}, {
|
||||||
|
"args": "run main.ts",
|
||||||
|
"output": "3\n4\n"
|
||||||
|
}]
|
||||||
|
}
|
6
tests/specs/install/byonm_jsr_npm_dep/deno.json
Normal file
6
tests/specs/install/byonm_jsr_npm_dep/deno.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"imports": {
|
||||||
|
"@denotest/npm-add": "jsr:@denotest/npm-add@1",
|
||||||
|
"@denotest/npm-add-0-5": "jsr:@denotest/npm-add@0.5"
|
||||||
|
}
|
||||||
|
}
|
5
tests/specs/install/byonm_jsr_npm_dep/main.ts
Normal file
5
tests/specs/install/byonm_jsr_npm_dep/main.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import { add } from "@denotest/npm-add";
|
||||||
|
import { sum } from "@denotest/npm-add-0-5";
|
||||||
|
|
||||||
|
console.log(add(1, 2));
|
||||||
|
console.log(sum(2, 2));
|
2
tests/specs/install/byonm_jsr_npm_dep/package.json
Normal file
2
tests/specs/install/byonm_jsr_npm_dep/package.json
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"tempDir": true,
|
||||||
|
"steps": [{
|
||||||
|
"args": "install",
|
||||||
|
"output": "[WILDCARD]"
|
||||||
|
}, {
|
||||||
|
"args": "run --allow-read main.js",
|
||||||
|
"output": "4\n0.5.0\n"
|
||||||
|
}, {
|
||||||
|
"args": "run --allow-read member/main.js",
|
||||||
|
"output": "3\n1.0.0\n"
|
||||||
|
}]
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"nodeModulesDir": "manual",
|
||||||
|
"workspace": ["./member"],
|
||||||
|
"imports": {
|
||||||
|
"@denotest/add": "npm:@denotest/add@0.5"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { sum } from "@denotest/add";
|
||||||
|
|
||||||
|
console.log(sum(2, 2));
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
JSON.parse(Deno.readTextFileSync(
|
||||||
|
new URL("node_modules/@denotest/add/package.json", import.meta.url),
|
||||||
|
)).version,
|
||||||
|
);
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"imports": {
|
||||||
|
"@denotest/add": "npm:@denotest/add@1"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { add } from "@denotest/add";
|
||||||
|
|
||||||
|
console.log(add(1, 2));
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
JSON.parse(Deno.readTextFileSync(
|
||||||
|
new URL("node_modules/@denotest/add/package.json", import.meta.url),
|
||||||
|
)).version,
|
||||||
|
);
|
Loading…
Reference in a new issue