0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-06 02:52:05 -05:00

Merge branch 'main' into lint_plugins

This commit is contained in:
Bartek Iwańczuk 2025-01-10 13:51:22 +01:00
commit 67f77579e8
No known key found for this signature in database
GPG key ID: 0C6BCDDC3B3AD750
72 changed files with 773 additions and 490 deletions

View file

@ -5,7 +5,7 @@ import { stringify } from "jsr:@std/yaml@^0.221/stringify";
// Bump this number when you want to purge the cache.
// Note: the tools/release/01_bump_crate_versions.ts script will update this version
// automatically via regex, so ensure that this line maintains this format.
const cacheVersion = 32;
const cacheVersion = 33;
const ubuntuX86Runner = "ubuntu-24.04";
const ubuntuX86XlRunner = "ubuntu-24.04-xl";

View file

@ -184,8 +184,8 @@ jobs:
~/.cargo/registry/index
~/.cargo/registry/cache
~/.cargo/git/db
key: '32-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-${{ hashFiles(''Cargo.lock'') }}'
restore-keys: '32-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-'
key: '33-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-${{ hashFiles(''Cargo.lock'') }}'
restore-keys: '33-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-'
if: '!(matrix.skip)'
- uses: dsherret/rust-toolchain-file@v1
if: '!(matrix.skip)'
@ -379,7 +379,7 @@ jobs:
!./target/*/*.zip
!./target/*/*.tar.gz
key: never_saved
restore-keys: '32-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-'
restore-keys: '33-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-'
- name: Apply and update mtime cache
if: '!(matrix.skip) && (!startsWith(github.ref, ''refs/tags/''))'
uses: ./.github/mtime_cache
@ -689,7 +689,7 @@ jobs:
!./target/*/gn_root
!./target/*/*.zip
!./target/*/*.tar.gz
key: '32-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-${{ github.sha }}'
key: '33-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-${{ github.sha }}'
publish-canary:
name: publish canary
runs-on: ubuntu-24.04

72
Cargo.lock generated
View file

@ -1244,7 +1244,7 @@ dependencies = [
[[package]]
name = "deno"
version = "2.1.4"
version = "2.1.5"
dependencies = [
"anstream",
"async-trait",
@ -1421,7 +1421,7 @@ dependencies = [
[[package]]
name = "deno_bench_util"
version = "0.178.0"
version = "0.179.0"
dependencies = [
"bencher",
"deno_core",
@ -1430,7 +1430,7 @@ dependencies = [
[[package]]
name = "deno_broadcast_channel"
version = "0.178.0"
version = "0.179.0"
dependencies = [
"async-trait",
"deno_core",
@ -1442,7 +1442,7 @@ dependencies = [
[[package]]
name = "deno_cache"
version = "0.116.0"
version = "0.117.0"
dependencies = [
"async-trait",
"deno_core",
@ -1485,7 +1485,7 @@ dependencies = [
[[package]]
name = "deno_canvas"
version = "0.53.0"
version = "0.54.0"
dependencies = [
"deno_core",
"deno_error",
@ -1523,7 +1523,7 @@ dependencies = [
[[package]]
name = "deno_console"
version = "0.184.0"
version = "0.185.0"
dependencies = [
"deno_core",
]
@ -1574,7 +1574,7 @@ checksum = "fe4dccb6147bb3f3ba0c7a48e993bfeb999d2c2e47a81badee80e2b370c8d695"
[[package]]
name = "deno_cron"
version = "0.64.0"
version = "0.65.0"
dependencies = [
"anyhow",
"async-trait",
@ -1588,7 +1588,7 @@ dependencies = [
[[package]]
name = "deno_crypto"
version = "0.198.0"
version = "0.199.0"
dependencies = [
"aes",
"aes-gcm",
@ -1681,7 +1681,7 @@ dependencies = [
[[package]]
name = "deno_fetch"
version = "0.208.0"
version = "0.209.0"
dependencies = [
"base64 0.21.7",
"bytes",
@ -1718,7 +1718,7 @@ dependencies = [
[[package]]
name = "deno_ffi"
version = "0.171.0"
version = "0.172.0"
dependencies = [
"deno_core",
"deno_error",
@ -1739,7 +1739,7 @@ dependencies = [
[[package]]
name = "deno_fs"
version = "0.94.0"
version = "0.95.0"
dependencies = [
"async-trait",
"base32",
@ -1797,7 +1797,7 @@ dependencies = [
[[package]]
name = "deno_http"
version = "0.182.0"
version = "0.183.0"
dependencies = [
"async-compression",
"async-trait",
@ -1837,7 +1837,7 @@ dependencies = [
[[package]]
name = "deno_io"
version = "0.94.0"
version = "0.95.0"
dependencies = [
"async-trait",
"deno_core",
@ -1859,7 +1859,7 @@ dependencies = [
[[package]]
name = "deno_kv"
version = "0.92.0"
version = "0.93.0"
dependencies = [
"anyhow",
"async-trait",
@ -1932,7 +1932,7 @@ dependencies = [
[[package]]
name = "deno_napi"
version = "0.115.0"
version = "0.116.0"
dependencies = [
"deno_core",
"deno_error",
@ -1961,7 +1961,7 @@ dependencies = [
[[package]]
name = "deno_net"
version = "0.176.0"
version = "0.177.0"
dependencies = [
"deno_core",
"deno_error",
@ -1980,7 +1980,7 @@ dependencies = [
[[package]]
name = "deno_node"
version = "0.122.0"
version = "0.123.0"
dependencies = [
"aead-gcm-stream",
"aes",
@ -2093,14 +2093,12 @@ dependencies = [
[[package]]
name = "deno_npm_cache"
version = "0.3.0"
version = "0.4.0"
dependencies = [
"anyhow",
"async-trait",
"base64 0.21.7",
"boxed_error",
"deno_cache_dir",
"deno_core",
"deno_error",
"deno_npm",
"deno_path_util",
@ -2173,7 +2171,7 @@ dependencies = [
[[package]]
name = "deno_permissions"
version = "0.43.0"
version = "0.44.0"
dependencies = [
"capacity_builder 0.5.0",
"deno_core",
@ -2193,19 +2191,23 @@ dependencies = [
[[package]]
name = "deno_resolver"
version = "0.15.0"
version = "0.16.0"
dependencies = [
"anyhow",
"async-trait",
"base32",
"boxed_error",
"dashmap",
"deno_cache_dir",
"deno_config",
"deno_error",
"deno_media_type",
"deno_npm",
"deno_package_json",
"deno_path_util",
"deno_semver",
"node_resolver",
"parking_lot",
"sys_traits",
"test_server",
"thiserror 2.0.3",
@ -2214,7 +2216,7 @@ dependencies = [
[[package]]
name = "deno_runtime"
version = "0.192.0"
version = "0.193.0"
dependencies = [
"color-print",
"deno_ast",
@ -2320,7 +2322,7 @@ dependencies = [
[[package]]
name = "deno_telemetry"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"async-trait",
"deno_core",
@ -2363,7 +2365,7 @@ dependencies = [
[[package]]
name = "deno_tls"
version = "0.171.0"
version = "0.172.0"
dependencies = [
"deno_core",
"deno_error",
@ -2414,7 +2416,7 @@ dependencies = [
[[package]]
name = "deno_url"
version = "0.184.0"
version = "0.185.0"
dependencies = [
"deno_bench_util",
"deno_console",
@ -2427,7 +2429,7 @@ dependencies = [
[[package]]
name = "deno_web"
version = "0.215.0"
version = "0.216.0"
dependencies = [
"async-trait",
"base64-simd 0.8.0",
@ -2450,7 +2452,7 @@ dependencies = [
[[package]]
name = "deno_webgpu"
version = "0.151.0"
version = "0.152.0"
dependencies = [
"deno_core",
"deno_error",
@ -2464,7 +2466,7 @@ dependencies = [
[[package]]
name = "deno_webidl"
version = "0.184.0"
version = "0.185.0"
dependencies = [
"deno_bench_util",
"deno_core",
@ -2472,7 +2474,7 @@ dependencies = [
[[package]]
name = "deno_websocket"
version = "0.189.0"
version = "0.190.0"
dependencies = [
"bytes",
"deno_core",
@ -2495,7 +2497,7 @@ dependencies = [
[[package]]
name = "deno_webstorage"
version = "0.179.0"
version = "0.180.0"
dependencies = [
"deno_core",
"deno_error",
@ -5067,7 +5069,7 @@ dependencies = [
[[package]]
name = "napi_sym"
version = "0.114.0"
version = "0.115.0"
dependencies = [
"quote",
"serde",
@ -5122,7 +5124,7 @@ dependencies = [
[[package]]
name = "node_resolver"
version = "0.22.0"
version = "0.23.0"
dependencies = [
"anyhow",
"async-trait",
@ -7759,9 +7761,9 @@ dependencies = [
[[package]]
name = "sys_traits"
version = "0.1.6"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1c12873696bde6de3aea3cd27de8e52897177c5b368a6a30987fd4926e30f85"
checksum = "5b46ac05dfbe9fd3a9703eff20e17f5b31e7b6a54daf27a421dcd56c7a27ecdd"
dependencies = [
"filetime",
"getrandom",

View file

@ -50,17 +50,17 @@ repository = "https://github.com/denoland/deno"
deno_ast = { version = "=0.44.0", features = ["transpiling"] }
deno_core = { version = "0.330.0" }
deno_bench_util = { version = "0.178.0", path = "./bench_util" }
deno_bench_util = { version = "0.179.0", path = "./bench_util" }
deno_config = { version = "=0.44.0", features = ["workspace", "sync"] }
deno_lockfile = "=0.24.0"
deno_media_type = { version = "0.2.3", features = ["module_specifier"] }
deno_npm = "=0.27.0"
deno_path_util = "=0.3.0"
deno_permissions = { version = "0.43.0", path = "./runtime/permissions" }
deno_runtime = { version = "0.192.0", path = "./runtime" }
deno_permissions = { version = "0.44.0", path = "./runtime/permissions" }
deno_runtime = { version = "0.193.0", path = "./runtime" }
deno_semver = "=0.7.1"
deno_terminal = "0.2.0"
napi_sym = { version = "0.114.0", path = "./ext/napi/sym" }
napi_sym = { version = "0.115.0", path = "./ext/napi/sym" }
test_util = { package = "test_server", path = "./tests/util/server" }
denokv_proto = "0.9.0"
@ -69,34 +69,34 @@ denokv_remote = "0.9.0"
denokv_sqlite = { default-features = false, version = "0.9.0" }
# exts
deno_broadcast_channel = { version = "0.178.0", path = "./ext/broadcast_channel" }
deno_cache = { version = "0.116.0", path = "./ext/cache" }
deno_canvas = { version = "0.53.0", path = "./ext/canvas" }
deno_console = { version = "0.184.0", path = "./ext/console" }
deno_cron = { version = "0.64.0", path = "./ext/cron" }
deno_crypto = { version = "0.198.0", path = "./ext/crypto" }
deno_fetch = { version = "0.208.0", path = "./ext/fetch" }
deno_ffi = { version = "0.171.0", path = "./ext/ffi" }
deno_fs = { version = "0.94.0", path = "./ext/fs" }
deno_http = { version = "0.182.0", path = "./ext/http" }
deno_io = { version = "0.94.0", path = "./ext/io" }
deno_kv = { version = "0.92.0", path = "./ext/kv" }
deno_napi = { version = "0.115.0", path = "./ext/napi" }
deno_net = { version = "0.176.0", path = "./ext/net" }
deno_node = { version = "0.122.0", path = "./ext/node" }
deno_telemetry = { version = "0.6.0", path = "./ext/telemetry" }
deno_tls = { version = "0.171.0", path = "./ext/tls" }
deno_url = { version = "0.184.0", path = "./ext/url" }
deno_web = { version = "0.215.0", path = "./ext/web" }
deno_webgpu = { version = "0.151.0", path = "./ext/webgpu" }
deno_webidl = { version = "0.184.0", path = "./ext/webidl" }
deno_websocket = { version = "0.189.0", path = "./ext/websocket" }
deno_webstorage = { version = "0.179.0", path = "./ext/webstorage" }
deno_broadcast_channel = { version = "0.179.0", path = "./ext/broadcast_channel" }
deno_cache = { version = "0.117.0", path = "./ext/cache" }
deno_canvas = { version = "0.54.0", path = "./ext/canvas" }
deno_console = { version = "0.185.0", path = "./ext/console" }
deno_cron = { version = "0.65.0", path = "./ext/cron" }
deno_crypto = { version = "0.199.0", path = "./ext/crypto" }
deno_fetch = { version = "0.209.0", path = "./ext/fetch" }
deno_ffi = { version = "0.172.0", path = "./ext/ffi" }
deno_fs = { version = "0.95.0", path = "./ext/fs" }
deno_http = { version = "0.183.0", path = "./ext/http" }
deno_io = { version = "0.95.0", path = "./ext/io" }
deno_kv = { version = "0.93.0", path = "./ext/kv" }
deno_napi = { version = "0.116.0", path = "./ext/napi" }
deno_net = { version = "0.177.0", path = "./ext/net" }
deno_node = { version = "0.123.0", path = "./ext/node" }
deno_telemetry = { version = "0.7.0", path = "./ext/telemetry" }
deno_tls = { version = "0.172.0", path = "./ext/tls" }
deno_url = { version = "0.185.0", path = "./ext/url" }
deno_web = { version = "0.216.0", path = "./ext/web" }
deno_webgpu = { version = "0.152.0", path = "./ext/webgpu" }
deno_webidl = { version = "0.185.0", path = "./ext/webidl" }
deno_websocket = { version = "0.190.0", path = "./ext/websocket" }
deno_webstorage = { version = "0.180.0", path = "./ext/webstorage" }
# resolvers
deno_npm_cache = { version = "0.3.0", path = "./resolvers/npm_cache" }
deno_resolver = { version = "0.15.0", path = "./resolvers/deno" }
node_resolver = { version = "0.22.0", path = "./resolvers/node" }
deno_npm_cache = { version = "0.4.0", path = "./resolvers/npm_cache" }
deno_resolver = { version = "0.16.0", path = "./resolvers/deno" }
node_resolver = { version = "0.23.0", path = "./resolvers/node" }
aes = "=0.8.3"
anyhow = "1.0.57"
@ -193,7 +193,7 @@ slab = "0.4"
smallvec = "1.8"
socket2 = { version = "0.5.3", features = ["all"] }
spki = "0.7.2"
sys_traits = "=0.1.6"
sys_traits = "=0.1.7"
tar = "=0.4.40"
tempfile = "3.4.0"
termcolor = "1.1.3"

View file

@ -6,6 +6,85 @@ https://github.com/denoland/deno/releases
We also have one-line install commands at:
https://github.com/denoland/deno_install
### 2.1.5 / 2025.01.09
- feat(unstable): implement QUIC (#21942)
- feat(unstable): add JS linting plugin infrastructure (#27416)
- feat(unstable): add OTEL MeterProvider (#27240)
- feat(unstable): no config npm:@opentelemetry/api integration (#27541)
- feat(unstable): replace SpanExporter with TracerProvider (#27473)
- feat(unstable): support selectors in JS lint plugins (#27452)
- fix(check): line-break between diagnostic message chain entries (#27543)
- fix(check): move module not found errors to typescript diagnostics (#27533)
- fix(compile): analyze modules in directory specified in --include (#27296)
- fix(compile): be more deterministic when compiling the same code in different
directories (#27395)
- fix(compile): display embedded file sizes and total (#27360)
- fix(compile): output contents of embedded file system (#27302)
- fix(ext/fetch): better error message when body resource is unavailable
(#27429)
- fix(ext/fetch): retry some http/2 errors (#27417)
- fix(ext/fs): do not throw for bigint ctime/mtime/atime (#27453)
- fix(ext/http): improve error message when underlying resource of request body
unavailable (#27463)
- fix(ext/net): update moka cache to avoid potential panic in `Deno.resolveDns`
on some laptops with Ryzen CPU (#27572)
- fix(ext/node): fix `fs.access`/`fs.promises.access` with `X_OK` mode parameter
on Windows (#27407)
- fix(ext/node): fix `os.cpus()` on Linux (#27592)
- fix(ext/node): RangeError timingSafeEqual with different byteLength (#27470)
- fix(ext/node): add `truncate` method to the `FileHandle` class (#27389)
- fix(ext/node): add support of any length IV for aes-(128|256)-gcm ciphers
(#27476)
- fix(ext/node): convert brotli chunks with proper byte offset (#27455)
- fix(ext/node): do not exit worker thread when there is pending async op
(#27378)
- fix(ext/node): have `process` global available in Node context (#27562)
- fix(ext/node): make getCiphers return supported ciphers (#27466)
- fix(ext/node): sort list of built-in modules alphabetically (#27410)
- fix(ext/node): support createConnection option in node:http.request() (#25470)
- fix(ext/node): support private key export in JWK format (#27325)
- fix(ext/web): add `[[ErrorData]]` slot to `DOMException` (#27342)
- fix(ext/websocket): Fix close code without reason (#27578)
- fix(jsr): Wasm imports fail to load (#27594)
- fix(kv): improve backoff error message and inline documentation (#27537)
- fix(lint): fix single char selectors being ignored (#27576)
- fix(lockfile): include dependencies listed in external import map in lockfile
(#27337)
- fix(lsp): css preprocessor formatting (#27526)
- fix(lsp): don't skip dirs with enabled subdirs (#27580)
- fix(lsp): include "node:" prefix for node builtin auto-imports (#27404)
- fix(lsp): respect "typescript.suggestionActions.enabled" setting (#27373)
- fix(lsp): rewrite imports for 'Move to a new file' action (#27427)
- fix(lsp): sql and component file formatting (#27350)
- fix(lsp): use verbatim specifier for URL auto-imports (#27605)
- fix(no-slow-types): handle rest param with internal assignments (#27581)
- fix(node/fs): add a chmod method to the FileHandle class (#27522)
- fix(node): add missing `inspector/promises` (#27491)
- fix(node): handle cjs exports with escaped chars (#27438)
- fix(npm): deterministically output tags to initialized file (#27514)
- fix(npm): search node_modules folder for package matching npm specifier
(#27345)
- fix(outdated): ensure "Latest" version is greater than "Update" version
(#27390)
- fix(outdated): support updating dependencies in external import maps (#27339)
- fix(permissions): implicit `--allow-import` when using `--cached-only`
(#27530)
- fix(publish): infer literal types in const contexts (#27425)
- fix(task): properly handle task name wildcards with --recursive (#27396)
- fix(task): support tasks without commands (#27191)
- fix(unstable): don't error on non-existing attrs or type attr (#27456)
- fix: FastString v8_string() should error when cannot allocated (#27375)
- fix: deno_resolver crate without 'sync' feature (#27403)
- fix: incorrect memory info free/available bytes on mac (#27460)
- fix: upgrade deno_doc to 0.161.3 (#27377)
- perf(fs/windows): stat - only open file once (#27487)
- perf(node/fs/copy): reduce metadata lookups copying directory (#27495)
- perf: don't store duplicate info for ops in the snapshot (#27430)
- perf: remove now needless canonicalization getting closest package.json
(#27437)
- perf: upgrade to deno_semver 0.7 (#27426)
### 2.1.4 / 2024.12.11
- feat(unstable): support caching npm dependencies only as they're needed

View file

@ -2,7 +2,7 @@
[package]
name = "deno_bench_util"
version = "0.178.0"
version = "0.179.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno"
version = "2.1.4"
version = "2.1.5"
authors.workspace = true
default-run = "deno"
edition.workspace = true

View file

@ -12,7 +12,10 @@ use deno_core::futures::FutureExt;
use deno_core::FeatureChecker;
use deno_error::JsErrorBox;
use deno_resolver::cjs::IsCjsResolutionMode;
use deno_resolver::npm::managed::ManagedInNpmPkgCheckerCreateOptions;
use deno_resolver::npm::CreateInNpmPkgCheckerOptions;
use deno_resolver::npm::NpmReqResolverOptions;
use deno_resolver::sloppy_imports::SloppyImportsCachedFs;
use deno_resolver::DenoResolverOptions;
use deno_resolver::NodeAndNpmReqResolver;
use deno_runtime::deno_fs;
@ -64,14 +67,11 @@ use crate::node::CliNodeCodeTranslator;
use crate::node::CliNodeResolver;
use crate::node::CliPackageJsonResolver;
use crate::npm::create_cli_npm_resolver;
use crate::npm::create_in_npm_pkg_checker;
use crate::npm::CliByonmNpmResolverCreateOptions;
use crate::npm::CliManagedInNpmPkgCheckerCreateOptions;
use crate::npm::CliManagedNpmResolverCreateOptions;
use crate::npm::CliNpmResolver;
use crate::npm::CliNpmResolverCreateOptions;
use crate::npm::CliNpmResolverManagedSnapshotOption;
use crate::npm::CreateInNpmPkgCheckerOptions;
use crate::npm::NpmRegistryReadPermissionChecker;
use crate::npm::NpmRegistryReadPermissionCheckerMode;
use crate::resolver::CjsTracker;
@ -81,7 +81,6 @@ use crate::resolver::CliResolver;
use crate::resolver::CliResolverOptions;
use crate::resolver::CliSloppyImportsResolver;
use crate::resolver::NpmModuleLoader;
use crate::resolver::SloppyImportsCachedFs;
use crate::standalone::binary::DenoCompileBinaryWriter;
use crate::sys::CliSys;
use crate::tools::check::TypeChecker;
@ -387,7 +386,7 @@ impl CliFactory {
CreateInNpmPkgCheckerOptions::Byonm
} else {
CreateInNpmPkgCheckerOptions::Managed(
CliManagedInNpmPkgCheckerCreateOptions {
ManagedInNpmPkgCheckerCreateOptions {
root_cache_dir_url: self.npm_cache_dir()?.root_dir_url(),
maybe_node_modules_path: cli_options
.node_modules_dir_path()
@ -395,7 +394,7 @@ impl CliFactory {
},
)
};
Ok(create_in_npm_pkg_checker(options))
Ok(deno_resolver::npm::create_in_npm_pkg_checker(options))
})
}

View file

@ -29,6 +29,7 @@ use deno_graph::ResolutionError;
use deno_graph::SpecifierError;
use deno_graph::WorkspaceFastCheckOption;
use deno_path_util::url_to_file_path;
use deno_resolver::sloppy_imports::SloppyImportsCachedFs;
use deno_resolver::sloppy_imports::SloppyImportsResolutionKind;
use deno_runtime::deno_node;
use deno_runtime::deno_permissions::PermissionsContainer;
@ -55,7 +56,6 @@ use crate::npm::CliNpmResolver;
use crate::resolver::CjsTracker;
use crate::resolver::CliResolver;
use crate::resolver::CliSloppyImportsResolver;
use crate::resolver::SloppyImportsCachedFs;
use crate::sys::CliSys;
use crate::tools::check;
use crate::tools::check::CheckError;

View file

@ -70,7 +70,7 @@ impl HttpClientProvider {
}
}
pub fn get_or_create(&self) -> Result<HttpClient, AnyError> {
pub fn get_or_create(&self) -> Result<HttpClient, JsErrorBox> {
use std::collections::hash_map::Entry;
let thread_id = std::thread::current().id();
let mut clients = self.clients_by_thread_id.lock();
@ -87,7 +87,8 @@ impl HttpClientProvider {
},
..self.options.clone()
},
)?;
)
.map_err(JsErrorBox::from_err)?;
entry.insert(client.clone());
Ok(HttpClient::new(client))
}

View file

@ -46,6 +46,7 @@ use deno_lint::linter::LintConfig as DenoLintConfig;
use deno_npm::npm_rc::ResolvedNpmRc;
use deno_package_json::PackageJsonCache;
use deno_path_util::url_to_file_path;
use deno_resolver::sloppy_imports::SloppyImportsCachedFs;
use deno_runtime::deno_node::PackageJson;
use indexmap::IndexSet;
use lsp_types::ClientCapabilities;
@ -65,7 +66,6 @@ use crate::cache::FastInsecureHasher;
use crate::file_fetcher::CliFileFetcher;
use crate::lsp::logging::lsp_warn;
use crate::resolver::CliSloppyImportsResolver;
use crate::resolver::SloppyImportsCachedFs;
use crate::sys::CliSys;
use crate::tools::lint::CliLinter;
use crate::tools::lint::CliLinterOptions;

View file

@ -26,6 +26,7 @@ use deno_graph::Resolution;
use deno_graph::ResolutionError;
use deno_graph::SpecifierError;
use deno_lint::linter::LintConfig as DenoLintConfig;
use deno_resolver::sloppy_imports::SloppyImportsCachedFs;
use deno_resolver::sloppy_imports::SloppyImportsResolution;
use deno_resolver::sloppy_imports::SloppyImportsResolutionKind;
use deno_runtime::deno_node;
@ -61,7 +62,6 @@ use crate::graph_util;
use crate::graph_util::enhanced_resolution_error_message;
use crate::lsp::lsp_custom::DiagnosticBatchNotificationParams;
use crate::resolver::CliSloppyImportsResolver;
use crate::resolver::SloppyImportsCachedFs;
use crate::sys::CliSys;
use crate::tools::lint::CliLinter;
use crate::tools::lint::CliLinterOptions;

View file

@ -23,6 +23,8 @@ use deno_graph::Range;
use deno_npm::NpmSystemInfo;
use deno_path_util::url_to_file_path;
use deno_resolver::cjs::IsCjsResolutionMode;
use deno_resolver::npm::managed::ManagedInNpmPkgCheckerCreateOptions;
use deno_resolver::npm::CreateInNpmPkgCheckerOptions;
use deno_resolver::npm::NpmReqResolverOptions;
use deno_resolver::DenoResolverOptions;
use deno_resolver::NodeAndNpmReqResolver;
@ -53,12 +55,10 @@ use crate::node::CliNodeResolver;
use crate::node::CliPackageJsonResolver;
use crate::npm::create_cli_npm_resolver_for_lsp;
use crate::npm::CliByonmNpmResolverCreateOptions;
use crate::npm::CliManagedInNpmPkgCheckerCreateOptions;
use crate::npm::CliManagedNpmResolverCreateOptions;
use crate::npm::CliNpmResolver;
use crate::npm::CliNpmResolverCreateOptions;
use crate::npm::CliNpmResolverManagedSnapshotOption;
use crate::npm::CreateInNpmPkgCheckerOptions;
use crate::npm::ManagedCliNpmResolver;
use crate::resolver::CliDenoResolver;
use crate::resolver::CliNpmReqResolver;
@ -736,14 +736,14 @@ impl<'a> ResolverFactory<'a> {
pub fn in_npm_pkg_checker(&self) -> &Arc<dyn InNpmPackageChecker> {
self.services.in_npm_pkg_checker.get_or_init(|| {
crate::npm::create_in_npm_pkg_checker(
deno_resolver::npm::create_in_npm_pkg_checker(
match self.services.npm_resolver.as_ref().map(|r| r.as_inner()) {
Some(crate::npm::InnerCliNpmResolverRef::Byonm(_)) | None => {
CreateInNpmPkgCheckerOptions::Byonm
}
Some(crate::npm::InnerCliNpmResolverRef::Managed(m)) => {
CreateInNpmPkgCheckerOptions::Managed(
CliManagedInNpmPkgCheckerCreateOptions {
ManagedInNpmPkgCheckerCreateOptions {
root_cache_dir_url: m.global_cache_root_url(),
maybe_node_modules_path: m.maybe_node_modules_path(),
},

View file

@ -3972,6 +3972,11 @@ impl CompletionEntry {
if let Some(mut new_specifier) = import_mapper
.check_specifier(&import_data.normalized, specifier)
.or_else(|| relative_specifier(specifier, &import_data.normalized))
.or_else(|| {
ModuleSpecifier::parse(&import_data.raw.module_specifier)
.is_ok()
.then(|| import_data.normalized.to_string())
})
{
if new_specifier.contains("/node_modules/") {
return None;

View file

@ -13,13 +13,13 @@ use deno_npm::resolution::AddPkgReqsOptions;
use deno_npm::resolution::NpmResolutionError;
use deno_npm::resolution::NpmResolutionSnapshot;
use deno_npm::NpmResolutionPackage;
use deno_resolver::npm::managed::NpmResolution;
use deno_semver::jsr::JsrDepPackageReq;
use deno_semver::package::PackageNv;
use deno_semver::package::PackageReq;
use deno_semver::SmallStackString;
use deno_semver::VersionReq;
use super::resolution::NpmResolution;
use crate::args::CliLockfile;
use crate::npm::CliNpmRegistryInfoProvider;
use crate::util::sync::TaskQueue;

View file

@ -11,8 +11,8 @@ use deno_core::futures::StreamExt;
use deno_error::JsErrorBox;
use deno_npm::NpmResolutionPackage;
use deno_npm::NpmSystemInfo;
use deno_resolver::npm::managed::NpmResolution;
use super::super::resolution::NpmResolution;
use super::common::lifecycle_scripts::LifecycleScriptsStrategy;
use super::common::NpmPackageFsInstaller;
use crate::args::LifecycleScriptsConfig;

View file

@ -24,19 +24,19 @@ use deno_npm::resolution::NpmResolutionSnapshot;
use deno_npm::NpmResolutionPackage;
use deno_npm::NpmSystemInfo;
use deno_path_util::fs::atomic_write_file_with_retries;
use deno_resolver::npm::get_package_folder_id_folder_name;
use deno_resolver::npm::managed::NpmResolution;
use deno_semver::package::PackageNv;
use deno_semver::StackString;
use serde::Deserialize;
use serde::Serialize;
use super::super::resolution::NpmResolution;
use super::common::bin_entries;
use super::common::NpmPackageFsInstaller;
use crate::args::LifecycleScriptsConfig;
use crate::args::NpmInstallDepsProvider;
use crate::cache::CACHE_PERM;
use crate::colors;
use crate::npm::managed::resolvers::get_package_folder_id_folder_name;
use crate::npm::managed::PackageCaching;
use crate::npm::CliNpmCache;
use crate::npm::CliNpmTarballCache;

View file

@ -4,11 +4,11 @@ use std::path::PathBuf;
use std::sync::Arc;
use deno_npm::NpmSystemInfo;
use deno_resolver::npm::managed::NpmResolution;
pub use self::common::NpmPackageFsInstaller;
use self::global::GlobalNpmPackageInstaller;
use self::local::LocalNpmPackageInstaller;
use super::resolution::NpmResolution;
use crate::args::LifecycleScriptsConfig;
use crate::args::NpmInstallDepsProvider;
use crate::npm::CliNpmCache;

View file

@ -23,6 +23,10 @@ use deno_npm::NpmResolutionPackage;
use deno_npm::NpmSystemInfo;
use deno_npm_cache::NpmCacheSetting;
use deno_path_util::fs::canonicalize_path_maybe_not_exists;
use deno_resolver::npm::managed::create_npm_fs_resolver;
use deno_resolver::npm::managed::NpmPackageFsResolver;
use deno_resolver::npm::managed::NpmPackageFsResolverPackageFolderError;
use deno_resolver::npm::managed::NpmResolution;
use deno_resolver::npm::CliNpmReqResolver;
use deno_runtime::colors;
use deno_runtime::ops::process::NpmProcessStateProvider;
@ -34,12 +38,8 @@ use installers::create_npm_fs_installer;
use installers::NpmPackageFsInstaller;
use node_resolver::errors::PackageFolderResolveError;
use node_resolver::errors::PackageFolderResolveIoError;
use node_resolver::InNpmPackageChecker;
use node_resolver::NpmPackageFolderResolver;
use self::resolution::NpmResolution;
use self::resolvers::create_npm_fs_resolver;
use self::resolvers::NpmPackageFsResolver;
use super::CliNpmCache;
use super::CliNpmCacheHttpClient;
use super::CliNpmRegistryInfoProvider;
@ -60,8 +60,6 @@ use crate::util::sync::AtomicFlag;
mod installer;
mod installers;
mod resolution;
mod resolvers;
pub enum CliNpmResolverManagedSnapshotOption {
ResolveFromLockfile(Arc<CliLockfile>),
@ -104,6 +102,7 @@ pub async fn create_managed_npm_resolver_for_lsp(
create_inner(
http_client,
npm_cache,
options.npm_cache_dir,
options.npm_install_deps_provider,
npm_api,
options.sys,
@ -133,6 +132,7 @@ pub async fn create_managed_npm_resolver(
Ok(create_inner(
http_client,
npm_cache,
options.npm_cache_dir,
options.npm_install_deps_provider,
api,
options.sys,
@ -150,6 +150,7 @@ pub async fn create_managed_npm_resolver(
fn create_inner(
http_client: Arc<CliNpmCacheHttpClient>,
npm_cache: Arc<CliNpmCache>,
npm_cache_dir: Arc<NpmCacheDir>,
npm_install_deps_provider: Arc<NpmInstallDepsProvider>,
registry_info_provider: Arc<CliNpmRegistryInfoProvider>,
sys: CliSys,
@ -181,7 +182,8 @@ fn create_inner(
lifecycle_scripts.clone(),
);
let fs_resolver = create_npm_fs_resolver(
npm_cache.clone(),
&npm_cache_dir,
&npm_rc,
resolution.clone(),
sys.clone(),
node_modules_dir_path,
@ -192,7 +194,9 @@ fn create_inner(
maybe_lockfile,
registry_info_provider,
npm_cache,
npm_cache_dir,
npm_install_deps_provider,
npm_rc,
resolution,
sys,
tarball_cache,
@ -271,35 +275,6 @@ async fn snapshot_from_lockfile(
Ok(snapshot)
}
#[derive(Debug)]
struct ManagedInNpmPackageChecker {
root_dir: Url,
}
impl InNpmPackageChecker for ManagedInNpmPackageChecker {
fn in_npm_package(&self, specifier: &Url) -> bool {
specifier.as_ref().starts_with(self.root_dir.as_str())
}
}
pub struct CliManagedInNpmPkgCheckerCreateOptions<'a> {
pub root_cache_dir_url: &'a Url,
pub maybe_node_modules_path: Option<&'a Path>,
}
pub fn create_managed_in_npm_pkg_checker(
options: CliManagedInNpmPkgCheckerCreateOptions,
) -> Arc<dyn InNpmPackageChecker> {
let root_dir = match options.maybe_node_modules_path {
Some(node_modules_folder) => {
deno_path_util::url_from_directory_path(node_modules_folder).unwrap()
}
None => options.root_cache_dir_url.clone(),
};
debug_assert!(root_dir.as_str().ends_with('/'));
Arc::new(ManagedInNpmPackageChecker { root_dir })
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PackageCaching<'a> {
Only(Cow<'a, [PackageReq]>),
@ -314,7 +289,9 @@ pub struct ManagedCliNpmResolver {
maybe_lockfile: Option<Arc<CliLockfile>>,
registry_info_provider: Arc<CliNpmRegistryInfoProvider>,
npm_cache: Arc<CliNpmCache>,
npm_cache_dir: Arc<NpmCacheDir>,
npm_install_deps_provider: Arc<NpmInstallDepsProvider>,
npm_rc: Arc<ResolvedNpmRc>,
sys: CliSys,
resolution: Arc<NpmResolution>,
resolution_installer: NpmResolutionInstaller,
@ -338,7 +315,7 @@ pub enum ResolvePkgFolderFromPkgIdError {
#[class(inherit)]
#[error("{0}")]
NpmPackageFsResolverPackageFolder(
#[from] resolvers::NpmPackageFsResolverPackageFolderError,
#[from] NpmPackageFsResolverPackageFolderError,
),
#[class(inherit)]
#[error("{0}")]
@ -363,7 +340,9 @@ impl ManagedCliNpmResolver {
maybe_lockfile: Option<Arc<CliLockfile>>,
registry_info_provider: Arc<CliNpmRegistryInfoProvider>,
npm_cache: Arc<CliNpmCache>,
npm_cache_dir: Arc<NpmCacheDir>,
npm_install_deps_provider: Arc<NpmInstallDepsProvider>,
npm_rc: Arc<ResolvedNpmRc>,
resolution: Arc<NpmResolution>,
sys: CliSys,
tarball_cache: Arc<CliNpmTarballCache>,
@ -382,7 +361,9 @@ impl ManagedCliNpmResolver {
maybe_lockfile,
registry_info_provider,
npm_cache,
npm_cache_dir,
npm_install_deps_provider,
npm_rc,
text_only_progress_bar,
resolution,
resolution_installer,
@ -671,11 +652,11 @@ impl ManagedCliNpmResolver {
}
pub fn global_cache_root_path(&self) -> &Path {
self.npm_cache.root_dir_path()
self.npm_cache_dir.root_dir()
}
pub fn global_cache_root_url(&self) -> &Url {
self.npm_cache.root_dir_url()
self.npm_cache_dir.root_dir_url()
}
}
@ -772,7 +753,8 @@ impl CliNpmResolver for ManagedCliNpmResolver {
self.lifecycle_scripts.clone(),
),
create_npm_fs_resolver(
self.npm_cache.clone(),
&self.npm_cache_dir,
&self.npm_rc,
npm_resolution.clone(),
self.sys.clone(),
self.root_node_modules_path().map(ToOwned::to_owned),
@ -780,7 +762,9 @@ impl CliNpmResolver for ManagedCliNpmResolver {
self.maybe_lockfile.clone(),
self.registry_info_provider.clone(),
self.npm_cache.clone(),
self.npm_cache_dir.clone(),
self.npm_install_deps_provider.clone(),
self.npm_rc.clone(),
npm_resolution,
self.sys.clone(),
self.tarball_cache.clone(),

View file

@ -1,33 +0,0 @@
// Copyright 2018-2025 the Deno authors. MIT license.
mod common;
mod global;
mod local;
use std::path::PathBuf;
use std::sync::Arc;
pub use self::common::NpmPackageFsResolver;
pub use self::common::NpmPackageFsResolverPackageFolderError;
use self::global::GlobalNpmPackageResolver;
pub use self::local::get_package_folder_id_folder_name;
use self::local::LocalNpmPackageResolver;
use super::resolution::NpmResolution;
use crate::npm::CliNpmCache;
use crate::sys::CliSys;
pub fn create_npm_fs_resolver(
npm_cache: Arc<CliNpmCache>,
resolution: Arc<NpmResolution>,
sys: CliSys,
maybe_node_modules_path: Option<PathBuf>,
) -> Arc<dyn NpmPackageFsResolver> {
match maybe_node_modules_path {
Some(node_modules_folder) => Arc::new(LocalNpmPackageResolver::new(
resolution,
sys,
node_modules_folder,
)),
None => Arc::new(GlobalNpmPackageResolver::new(npm_cache, resolution)),
}
}

View file

@ -11,9 +11,9 @@ use dashmap::DashMap;
use deno_core::error::AnyError;
use deno_core::serde_json;
use deno_core::url::Url;
use deno_error::JsErrorBox;
use deno_npm::npm_rc::ResolvedNpmRc;
use deno_npm::registry::NpmPackageInfo;
use deno_resolver::npm::ByonmInNpmPackageChecker;
use deno_resolver::npm::ByonmNpmResolver;
use deno_resolver::npm::CliNpmReqResolver;
use deno_resolver::npm::ResolvePkgFolderFromDenoReqError;
@ -22,13 +22,10 @@ use deno_semver::package::PackageNv;
use deno_semver::package::PackageReq;
use http::HeaderName;
use http::HeaderValue;
use managed::create_managed_in_npm_pkg_checker;
use node_resolver::InNpmPackageChecker;
use node_resolver::NpmPackageFolderResolver;
pub use self::byonm::CliByonmNpmResolver;
pub use self::byonm::CliByonmNpmResolverCreateOptions;
pub use self::managed::CliManagedInNpmPkgCheckerCreateOptions;
pub use self::managed::CliManagedNpmResolverCreateOptions;
pub use self::managed::CliNpmResolverManagedSnapshotOption;
pub use self::managed::ManagedCliNpmResolver;
@ -100,7 +97,7 @@ impl deno_npm_cache::NpmCacheHttpClient for CliNpmCacheHttpClient {
};
deno_npm_cache::DownloadError {
status_code,
error: err.into(),
error: JsErrorBox::from_err(err),
}
})
}
@ -133,29 +130,13 @@ pub async fn create_cli_npm_resolver(
}
}
pub enum CreateInNpmPkgCheckerOptions<'a> {
Managed(CliManagedInNpmPkgCheckerCreateOptions<'a>),
Byonm,
}
pub fn create_in_npm_pkg_checker(
options: CreateInNpmPkgCheckerOptions,
) -> Arc<dyn InNpmPackageChecker> {
match options {
CreateInNpmPkgCheckerOptions::Managed(options) => {
create_managed_in_npm_pkg_checker(options)
}
CreateInNpmPkgCheckerOptions::Byonm => Arc::new(ByonmInNpmPackageChecker),
}
}
pub enum InnerCliNpmResolverRef<'a> {
Managed(&'a ManagedCliNpmResolver),
#[allow(dead_code)]
Byonm(&'a CliByonmNpmResolver),
}
pub trait CliNpmResolver: NpmPackageFolderResolver + CliNpmReqResolver {
pub trait CliNpmResolver: CliNpmReqResolver {
fn into_npm_pkg_folder_resolver(
self: Arc<Self>,
) -> Arc<dyn NpmPackageFolderResolver>;

View file

@ -1,12 +1,9 @@
// Copyright 2018-2025 the Deno authors. MIT license.
use std::borrow::Cow;
use std::path::Path;
use std::path::PathBuf;
use std::sync::Arc;
use async_trait::async_trait;
use dashmap::DashMap;
use dashmap::DashSet;
use deno_ast::MediaType;
use deno_config::workspace::MappedResolutionDiagnostic;
@ -22,6 +19,7 @@ use deno_graph::source::UnknownBuiltInNodeModuleError;
use deno_graph::NpmLoadError;
use deno_graph::NpmResolvePkgReqsResult;
use deno_npm::resolution::NpmResolutionError;
use deno_resolver::sloppy_imports::SloppyImportsCachedFs;
use deno_resolver::sloppy_imports::SloppyImportsResolver;
use deno_runtime::colors;
use deno_runtime::deno_fs;
@ -30,8 +28,6 @@ use deno_runtime::deno_node::RealIsBuiltInNodeModuleChecker;
use deno_semver::package::PackageReq;
use node_resolver::NodeResolutionKind;
use node_resolver::ResolutionMode;
use sys_traits::FsMetadata;
use sys_traits::FsMetadataValue;
use thiserror::Error;
use crate::args::NpmCachingStrategy;
@ -45,11 +41,12 @@ use crate::util::text_encoding::from_utf8_lossy_cow;
pub type CjsTracker = deno_resolver::cjs::CjsTracker<CliSys>;
pub type IsCjsResolver = deno_resolver::cjs::IsCjsResolver<CliSys>;
pub type CliSloppyImportsCachedFs = SloppyImportsCachedFs<CliSys>;
pub type CliSloppyImportsResolver =
SloppyImportsResolver<SloppyImportsCachedFs>;
SloppyImportsResolver<CliSloppyImportsCachedFs>;
pub type CliDenoResolver = deno_resolver::DenoResolver<
RealIsBuiltInNodeModuleChecker,
SloppyImportsCachedFs,
CliSloppyImportsCachedFs,
CliSys,
>;
pub type CliNpmReqResolver =
@ -397,60 +394,3 @@ impl<'a> deno_graph::source::NpmResolver for WorkerCliNpmGraphResolver<'a> {
self.bare_node_builtins_enabled
}
}
#[derive(Debug)]
pub struct SloppyImportsCachedFs {
sys: CliSys,
cache: Option<
DashMap<
PathBuf,
Option<deno_resolver::sloppy_imports::SloppyImportsFsEntry>,
>,
>,
}
impl SloppyImportsCachedFs {
pub fn new(sys: CliSys) -> Self {
Self {
sys,
cache: Some(Default::default()),
}
}
pub fn new_without_stat_cache(fs: CliSys) -> Self {
Self {
sys: fs,
cache: None,
}
}
}
impl deno_resolver::sloppy_imports::SloppyImportResolverFs
for SloppyImportsCachedFs
{
fn stat_sync(
&self,
path: &Path,
) -> Option<deno_resolver::sloppy_imports::SloppyImportsFsEntry> {
if let Some(cache) = &self.cache {
if let Some(entry) = cache.get(path) {
return *entry;
}
}
let entry = self.sys.fs_metadata(path).ok().and_then(|stat| {
if stat.file_type().is_file() {
Some(deno_resolver::sloppy_imports::SloppyImportsFsEntry::File)
} else if stat.file_type().is_dir() {
Some(deno_resolver::sloppy_imports::SloppyImportsFsEntry::Dir)
} else {
None
}
});
if let Some(cache) = &self.cache {
cache.insert(path.to_owned(), entry);
}
entry
}
}

View file

@ -39,6 +39,9 @@ use deno_error::JsErrorBox;
use deno_npm::npm_rc::ResolvedNpmRc;
use deno_package_json::PackageJsonDepValue;
use deno_resolver::cjs::IsCjsResolutionMode;
use deno_resolver::npm::create_in_npm_pkg_checker;
use deno_resolver::npm::managed::ManagedInNpmPkgCheckerCreateOptions;
use deno_resolver::npm::CreateInNpmPkgCheckerOptions;
use deno_resolver::npm::NpmReqResolverOptions;
use deno_runtime::deno_fs;
use deno_runtime::deno_fs::FileSystem;
@ -81,14 +84,11 @@ use crate::node::CliNodeCodeTranslator;
use crate::node::CliNodeResolver;
use crate::node::CliPackageJsonResolver;
use crate::npm::create_cli_npm_resolver;
use crate::npm::create_in_npm_pkg_checker;
use crate::npm::CliByonmNpmResolverCreateOptions;
use crate::npm::CliManagedInNpmPkgCheckerCreateOptions;
use crate::npm::CliManagedNpmResolverCreateOptions;
use crate::npm::CliNpmResolver;
use crate::npm::CliNpmResolverCreateOptions;
use crate::npm::CliNpmResolverManagedSnapshotOption;
use crate::npm::CreateInNpmPkgCheckerOptions;
use crate::npm::NpmRegistryReadPermissionChecker;
use crate::npm::NpmRegistryReadPermissionCheckerMode;
use crate::resolver::CjsTracker;
@ -738,7 +738,7 @@ pub async fn run(
.map(|node_modules_dir| root_path.join(node_modules_dir));
let in_npm_pkg_checker =
create_in_npm_pkg_checker(CreateInNpmPkgCheckerOptions::Managed(
CliManagedInNpmPkgCheckerCreateOptions {
ManagedInNpmPkgCheckerCreateOptions {
root_cache_dir_url: npm_cache_dir.root_dir_url(),
maybe_node_modules_path: maybe_node_modules_path.as_deref(),
},
@ -796,7 +796,7 @@ pub async fn run(
));
let in_npm_pkg_checker =
create_in_npm_pkg_checker(CreateInNpmPkgCheckerOptions::Managed(
CliManagedInNpmPkgCheckerCreateOptions {
ManagedInNpmPkgCheckerCreateOptions {
root_cache_dir_url: npm_cache_dir.root_dir_url(),
maybe_node_modules_path: None,
},

View file

@ -660,6 +660,7 @@ mod tests {
use deno_config::workspace::ResolverWorkspaceJsrPackage;
use deno_core::serde_json::json;
use deno_core::url::Url;
use deno_resolver::sloppy_imports::SloppyImportsCachedFs;
use deno_runtime::deno_node::PackageJson;
use deno_semver::Version;
use import_map::ImportMapWithDiagnostics;
@ -668,7 +669,6 @@ mod tests {
use test_util::testdata_path;
use super::*;
use crate::resolver::SloppyImportsCachedFs;
use crate::sys::CliSys;
fn parse_ast(specifier: &Url, source_code: &str) -> ParsedSource {

View file

@ -83,8 +83,30 @@ declare var window: Window & typeof globalThis;
declare var self: Window & typeof globalThis;
/** @category Platform */
declare var closed: boolean;
/** @category Platform */
/**
* Exits the current Deno process.
*
* This function terminates the process by signaling the runtime to exit.
* Similar to exit(0) in posix. Its behavior is similar to the `window.close()`
* method in the browser, but specific to the Deno runtime.
*
* Note: Use this function cautiously, as it will stop the execution of the
* entire Deno program immediately.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/close
*
* @example
* ```ts
* console.log("About to close the Deno process.");
* close(); // The process will terminate here.
* console.log("This will not be logged."); // This line will never execute.
* ```
*
* @category Platform
*/
declare function close(): void;
/** @category Events */
declare var onerror: ((this: Window, ev: ErrorEvent) => any) | null;
/** @category Events */

View file

@ -2,7 +2,7 @@
[package]
name = "deno_broadcast_channel"
version = "0.178.0"
version = "0.179.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_cache"
version = "0.116.0"
version = "0.117.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_canvas"
version = "0.53.0"
version = "0.54.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_console"
version = "0.184.0"
version = "0.185.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_cron"
version = "0.64.0"
version = "0.65.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_crypto"
version = "0.198.0"
version = "0.199.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_fetch"
version = "0.208.0"
version = "0.209.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_ffi"
version = "0.171.0"
version = "0.172.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_fs"
version = "0.94.0"
version = "0.95.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_http"
version = "0.182.0"
version = "0.183.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_io"
version = "0.94.0"
version = "0.95.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_kv"
version = "0.92.0"
version = "0.93.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_napi"
version = "0.115.0"
version = "0.116.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "napi_sym"
version = "0.114.0"
version = "0.115.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_net"
version = "0.176.0"
version = "0.177.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_node"
version = "0.122.0"
version = "0.123.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_telemetry"
version = "0.6.0"
version = "0.7.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_tls"
version = "0.171.0"
version = "0.172.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_url"
version = "0.184.0"
version = "0.185.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_web"
version = "0.215.0"
version = "0.216.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_webgpu"
version = "0.151.0"
version = "0.152.0"
authors = ["the Deno authors"]
edition.workspace = true
license = "MIT"

View file

@ -2,7 +2,7 @@
[package]
name = "deno_webidl"
version = "0.184.0"
version = "0.185.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_websocket"
version = "0.189.0"
version = "0.190.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_webstorage"
version = "0.179.0"
version = "0.180.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_resolver"
version = "0.15.0"
version = "0.16.0"
authors.workspace = true
edition.workspace = true
license.workspace = true
@ -14,22 +14,24 @@ description = "Deno resolution algorithm"
path = "lib.rs"
[features]
sync = ["dashmap"]
sync = ["dashmap", "deno_package_json/sync", "node_resolver/sync"]
[dependencies]
anyhow.workspace = true
async-trait.workspace = true
base32.workspace = true
boxed_error.workspace = true
dashmap = { workspace = true, optional = true }
deno_cache_dir.workspace = true
deno_config.workspace = true
deno_error.workspace = true
deno_media_type.workspace = true
deno_npm.workspace = true
deno_package_json.workspace = true
deno_package_json.features = ["sync"]
deno_path_util.workspace = true
deno_semver.workspace = true
node_resolver.workspace = true
node_resolver.features = ["sync"]
parking_lot.workspace = true
sys_traits.workspace = true
thiserror.workspace = true
url.workspace = true

View file

@ -6,12 +6,14 @@
use std::path::PathBuf;
use boxed_error::Boxed;
use deno_cache_dir::npm::NpmCacheDir;
use deno_config::workspace::MappedResolution;
use deno_config::workspace::MappedResolutionDiagnostic;
use deno_config::workspace::MappedResolutionError;
use deno_config::workspace::WorkspaceResolvePkgJsonFolderError;
use deno_config::workspace::WorkspaceResolver;
use deno_error::JsError;
use deno_npm::npm_rc::ResolvedNpmRc;
use deno_package_json::PackageJsonDepValue;
use deno_package_json::PackageJsonDepValueParseError;
use deno_semver::npm::NpmPackageReqReference;
@ -47,6 +49,12 @@ mod sync;
#[allow(clippy::disallowed_types)]
pub type WorkspaceResolverRc = crate::sync::MaybeArc<WorkspaceResolver>;
#[allow(clippy::disallowed_types)]
pub(crate) type ResolvedNpmRcRc = crate::sync::MaybeArc<ResolvedNpmRc>;
#[allow(clippy::disallowed_types)]
pub(crate) type NpmCacheDirRc = crate::sync::MaybeArc<NpmCacheDir>;
#[derive(Debug, Clone)]
pub struct DenoResolution {
pub url: Url,

View file

@ -400,14 +400,14 @@ impl<
}
impl<
Sys: FsCanonicalize
TSys: FsCanonicalize
+ FsMetadata
+ FsRead
+ FsReadDir
+ Send
+ Sync
+ std::fmt::Debug,
> NpmPackageFolderResolver for ByonmNpmResolver<Sys>
> NpmPackageFolderResolver for ByonmNpmResolver<TSys>
{
fn resolve_package_folder_from_package(
&self,

View file

@ -2,6 +2,58 @@
use std::borrow::Cow;
use deno_cache_dir::npm::mixed_case_package_name_decode;
use deno_npm::NpmPackageCacheFolderId;
use deno_semver::package::PackageNv;
use deno_semver::StackString;
#[inline]
pub fn get_package_folder_id_folder_name(
folder_id: &NpmPackageCacheFolderId,
) -> String {
get_package_folder_id_folder_name_from_parts(
&folder_id.nv,
folder_id.copy_index,
)
}
pub fn get_package_folder_id_folder_name_from_parts(
nv: &PackageNv,
copy_index: u8,
) -> String {
let copy_str = if copy_index == 0 {
Cow::Borrowed("")
} else {
Cow::Owned(format!("_{}", copy_index))
};
let name = normalize_pkg_name_for_node_modules_deno_folder(&nv.name);
format!("{}@{}{}", name, nv.version, copy_str)
}
pub fn get_package_folder_id_from_folder_name(
folder_name: &str,
) -> Option<NpmPackageCacheFolderId> {
let folder_name = folder_name.replace('+', "/");
let (name, ending) = folder_name.rsplit_once('@')?;
let name: StackString = if let Some(encoded_name) = name.strip_prefix('_') {
StackString::from_string(mixed_case_package_name_decode(encoded_name)?)
} else {
name.into()
};
let (raw_version, copy_index) = match ending.split_once('_') {
Some((raw_version, copy_index)) => {
let copy_index = copy_index.parse::<u8>().ok()?;
(raw_version, copy_index)
}
None => (ending, 0),
};
let version = deno_semver::Version::parse_from_npm(raw_version).ok()?;
Some(NpmPackageCacheFolderId {
nv: PackageNv { name, version },
copy_index,
})
}
/// 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 {
@ -25,3 +77,36 @@ fn mixed_case_package_name_encode(name: &str) -> String {
)
.to_lowercase()
}
#[cfg(test)]
mod test {
use deno_npm::NpmPackageCacheFolderId;
use deno_semver::package::PackageNv;
use super::*;
#[test]
fn test_get_package_folder_id_folder_name() {
let cases = vec![
(
NpmPackageCacheFolderId {
nv: PackageNv::from_str("@types/foo@1.2.3").unwrap(),
copy_index: 1,
},
"@types+foo@1.2.3_1".to_string(),
),
(
NpmPackageCacheFolderId {
nv: PackageNv::from_str("JSON@3.2.1").unwrap(),
copy_index: 0,
},
"_jjju6tq@3.2.1".to_string(),
),
];
for (input, output) in cases {
assert_eq!(get_package_folder_id_folder_name(&input), output);
let folder_id = get_package_folder_id_from_folder_name(&output).unwrap();
assert_eq!(folder_id, input);
}
}
}

View file

@ -3,11 +3,17 @@
use std::path::Path;
use std::path::PathBuf;
use async_trait::async_trait;
use deno_ast::ModuleSpecifier;
use deno_npm::NpmPackageCacheFolderId;
use deno_npm::NpmPackageId;
use node_resolver::errors::PackageFolderResolveError;
use node_resolver::NpmPackageFolderResolver;
use url::Url;
use crate::sync::MaybeSend;
use crate::sync::MaybeSync;
#[allow(clippy::disallowed_types)]
pub(super) type NpmPackageFsResolverRc =
crate::sync::MaybeArc<dyn NpmPackageFsResolver>;
#[derive(Debug, thiserror::Error, deno_error::JsError)]
#[class(generic)]
@ -15,8 +21,9 @@ use node_resolver::errors::PackageFolderResolveError;
pub struct NpmPackageFsResolverPackageFolderError(deno_semver::StackString);
/// Part of the resolution that interacts with the file system.
#[async_trait(?Send)]
pub trait NpmPackageFsResolver: Send + Sync {
pub trait NpmPackageFsResolver:
NpmPackageFolderResolver + MaybeSend + MaybeSync
{
/// The local node_modules folder if it is applicable to the implementation.
fn node_modules_path(&self) -> Option<&Path>;
@ -31,14 +38,8 @@ pub trait NpmPackageFsResolver: Send + Sync {
})
}
fn resolve_package_folder_from_package(
&self,
name: &str,
referrer: &ModuleSpecifier,
) -> Result<PathBuf, PackageFolderResolveError>;
fn resolve_package_cache_folder_id_from_specifier(
&self,
specifier: &ModuleSpecifier,
specifier: &Url,
) -> Result<Option<NpmPackageCacheFolderId>, std::io::Error>;
}

View file

@ -4,55 +4,72 @@
use std::path::Path;
use std::path::PathBuf;
use std::sync::Arc;
use async_trait::async_trait;
use deno_ast::ModuleSpecifier;
use deno_npm::NpmPackageCacheFolderId;
use deno_npm::NpmPackageId;
use deno_semver::package::PackageNv;
use deno_semver::StackString;
use deno_semver::Version;
use node_resolver::errors::PackageFolderResolveError;
use node_resolver::errors::PackageNotFoundError;
use node_resolver::errors::ReferrerNotFoundError;
use node_resolver::NpmPackageFolderResolver;
use url::Url;
use super::super::resolution::NpmResolution;
use super::common::NpmPackageFsResolver;
use crate::npm::CliNpmCache;
use super::resolution::NpmResolutionRc;
use super::NpmCacheDirRc;
use super::NpmPackageFsResolver;
use crate::ResolvedNpmRcRc;
/// Resolves packages from the global npm cache.
#[derive(Debug)]
pub struct GlobalNpmPackageResolver {
cache: Arc<CliNpmCache>,
resolution: Arc<NpmResolution>,
cache: NpmCacheDirRc,
npm_rc: ResolvedNpmRcRc,
resolution: NpmResolutionRc,
}
impl GlobalNpmPackageResolver {
pub fn new(cache: Arc<CliNpmCache>, resolution: Arc<NpmResolution>) -> Self {
Self { cache, resolution }
pub fn new(
cache: NpmCacheDirRc,
npm_rc: ResolvedNpmRcRc,
resolution: NpmResolutionRc,
) -> Self {
Self {
cache,
npm_rc,
resolution,
}
}
#[async_trait(?Send)]
impl NpmPackageFsResolver for GlobalNpmPackageResolver {
fn node_modules_path(&self) -> Option<&Path> {
None
}
fn maybe_package_folder(&self, id: &NpmPackageId) -> Option<PathBuf> {
let folder_id = self
.resolution
.resolve_pkg_cache_folder_id_from_pkg_id(id)?;
Some(self.cache.package_folder_for_id(&folder_id))
fn resolve_package_cache_folder_id_from_specifier_inner(
&self,
specifier: &Url,
) -> Option<NpmPackageCacheFolderId> {
self
.cache
.resolve_package_folder_id_from_specifier(specifier)
.and_then(|cache_id| {
Some(NpmPackageCacheFolderId {
nv: PackageNv {
name: StackString::from_string(cache_id.name),
version: Version::parse_from_npm(&cache_id.version).ok()?,
},
copy_index: cache_id.copy_index,
})
})
}
}
impl NpmPackageFolderResolver for GlobalNpmPackageResolver {
fn resolve_package_folder_from_package(
&self,
name: &str,
referrer: &ModuleSpecifier,
referrer: &Url,
) -> Result<PathBuf, PackageFolderResolveError> {
use deno_npm::resolution::PackageNotFoundFromReferrerError;
let Some(referrer_cache_folder_id) = self
.cache
.resolve_package_folder_id_from_specifier(referrer)
let Some(referrer_cache_folder_id) =
self.resolve_package_cache_folder_id_from_specifier_inner(referrer)
else {
return Err(
ReferrerNotFoundError {
@ -103,15 +120,30 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver {
},
}
}
}
impl NpmPackageFsResolver for GlobalNpmPackageResolver {
fn node_modules_path(&self) -> Option<&Path> {
None
}
fn maybe_package_folder(&self, id: &NpmPackageId) -> Option<PathBuf> {
let folder_copy_index = self
.resolution
.resolve_pkg_cache_folder_copy_index_from_pkg_id(id)?;
let registry_url = self.npm_rc.get_registry_url(&id.nv.name);
Some(self.cache.package_folder_for_id(
&id.nv.name,
&id.nv.version.to_string(),
folder_copy_index,
registry_url,
))
}
fn resolve_package_cache_folder_id_from_specifier(
&self,
specifier: &ModuleSpecifier,
specifier: &Url,
) -> Result<Option<NpmPackageCacheFolderId>, std::io::Error> {
Ok(
self
.cache
.resolve_package_folder_id_from_specifier(specifier),
)
Ok(self.resolve_package_cache_folder_id_from_specifier_inner(specifier))
}
}

View file

@ -5,49 +5,50 @@
use std::borrow::Cow;
use std::path::Path;
use std::path::PathBuf;
use std::sync::Arc;
use async_trait::async_trait;
use deno_ast::ModuleSpecifier;
use deno_cache_dir::npm::mixed_case_package_name_decode;
use deno_core::url::Url;
use deno_npm::NpmPackageCacheFolderId;
use deno_npm::NpmPackageId;
use deno_path_util::fs::canonicalize_path_maybe_not_exists;
use deno_resolver::npm::normalize_pkg_name_for_node_modules_deno_folder;
use deno_semver::package::PackageNv;
use deno_semver::StackString;
use deno_path_util::url_from_directory_path;
use node_resolver::errors::PackageFolderResolveError;
use node_resolver::errors::PackageFolderResolveIoError;
use node_resolver::errors::PackageNotFoundError;
use node_resolver::errors::ReferrerNotFoundError;
use node_resolver::NpmPackageFolderResolver;
use sys_traits::FsCanonicalize;
use sys_traits::FsMetadata;
use url::Url;
use super::super::resolution::NpmResolution;
use super::common::NpmPackageFsResolver;
use crate::sys::CliSys;
use super::resolution::NpmResolutionRc;
use super::NpmPackageFsResolver;
use crate::npm::local::get_package_folder_id_folder_name_from_parts;
use crate::npm::local::get_package_folder_id_from_folder_name;
/// Resolver that creates a local node_modules directory
/// and resolves packages from it.
#[derive(Debug)]
pub struct LocalNpmPackageResolver {
resolution: Arc<NpmResolution>,
sys: CliSys,
pub struct LocalNpmPackageResolver<
TSys: FsCanonicalize + FsMetadata + Send + Sync,
> {
resolution: NpmResolutionRc,
sys: TSys,
root_node_modules_path: PathBuf,
root_node_modules_url: Url,
}
impl LocalNpmPackageResolver {
impl<TSys: FsCanonicalize + FsMetadata + Send + Sync>
LocalNpmPackageResolver<TSys>
{
#[allow(clippy::too_many_arguments)]
pub fn new(
resolution: Arc<NpmResolution>,
sys: CliSys,
resolution: NpmResolutionRc,
sys: TSys,
node_modules_folder: PathBuf,
) -> Self {
Self {
resolution,
sys,
root_node_modules_url: Url::from_directory_path(&node_modules_folder)
root_node_modules_url: url_from_directory_path(&node_modules_folder)
.unwrap(),
root_node_modules_path: node_modules_folder,
}
@ -67,7 +68,7 @@ impl LocalNpmPackageResolver {
fn resolve_folder_for_specifier(
&self,
specifier: &ModuleSpecifier,
specifier: &Url,
) -> Result<Option<PathBuf>, std::io::Error> {
let Some(relative_url) =
self.root_node_modules_url.make_relative(specifier)
@ -78,7 +79,7 @@ impl LocalNpmPackageResolver {
return Ok(None);
}
// it's within the directory, so use it
let Some(path) = specifier.to_file_path().ok() else {
let Some(path) = deno_path_util::url_to_file_path(specifier).ok() else {
return Ok(None);
};
// Canonicalize the path so it's not pointing to the symlinked directory
@ -88,7 +89,7 @@ impl LocalNpmPackageResolver {
fn resolve_package_folder_from_specifier(
&self,
specifier: &ModuleSpecifier,
specifier: &Url,
) -> Result<Option<PathBuf>, std::io::Error> {
let Some(local_path) = self.resolve_folder_for_specifier(specifier)? else {
return Ok(None);
@ -98,32 +99,13 @@ impl LocalNpmPackageResolver {
}
}
#[async_trait(?Send)]
impl NpmPackageFsResolver for LocalNpmPackageResolver {
fn node_modules_path(&self) -> Option<&Path> {
Some(self.root_node_modules_path.as_ref())
}
fn maybe_package_folder(&self, id: &NpmPackageId) -> Option<PathBuf> {
let cache_folder_id = self
.resolution
.resolve_pkg_cache_folder_id_from_pkg_id(id)?;
// package is stored at:
// node_modules/.deno/<package_cache_folder_id_folder_name>/node_modules/<package_name>
Some(
self
.root_node_modules_path
.join(".deno")
.join(get_package_folder_id_folder_name(&cache_folder_id))
.join("node_modules")
.join(&cache_folder_id.nv.name),
)
}
impl<TSys: FsCanonicalize + FsMetadata + Send + Sync + std::fmt::Debug>
NpmPackageFolderResolver for LocalNpmPackageResolver<TSys>
{
fn resolve_package_folder_from_package(
&self,
name: &str,
referrer: &ModuleSpecifier,
referrer: &Url,
) -> Result<PathBuf, PackageFolderResolveError> {
let maybe_local_path = self
.resolve_folder_for_specifier(referrer)
@ -153,7 +135,13 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
let sub_dir = join_package_name(&node_modules_folder, name);
if self.sys.fs_is_dir_no_err(&sub_dir) {
return Ok(sub_dir);
return Ok(self.sys.fs_canonicalize(&sub_dir).map_err(|err| {
PackageFolderResolveIoError {
package_name: name.to_string(),
referrer: referrer.clone(),
source: err,
}
})?);
}
if current_folder == self.root_node_modules_path {
@ -170,10 +158,37 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
.into(),
)
}
}
impl<TSys: FsCanonicalize + FsMetadata + Send + Sync + std::fmt::Debug>
NpmPackageFsResolver for LocalNpmPackageResolver<TSys>
{
fn node_modules_path(&self) -> Option<&Path> {
Some(self.root_node_modules_path.as_ref())
}
fn maybe_package_folder(&self, id: &NpmPackageId) -> Option<PathBuf> {
let folder_copy_index = self
.resolution
.resolve_pkg_cache_folder_copy_index_from_pkg_id(id)?;
// package is stored at:
// node_modules/.deno/<package_cache_folder_id_folder_name>/node_modules/<package_name>
Some(
self
.root_node_modules_path
.join(".deno")
.join(get_package_folder_id_folder_name_from_parts(
&id.nv,
folder_copy_index,
))
.join("node_modules")
.join(&id.nv.name),
)
}
fn resolve_package_cache_folder_id_from_specifier(
&self,
specifier: &ModuleSpecifier,
specifier: &Url,
) -> Result<Option<NpmPackageCacheFolderId>, std::io::Error> {
let Some(folder_path) =
self.resolve_package_folder_from_specifier(specifier)?
@ -198,43 +213,6 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
}
}
pub fn get_package_folder_id_folder_name(
folder_id: &NpmPackageCacheFolderId,
) -> String {
let copy_str = if folder_id.copy_index == 0 {
Cow::Borrowed("")
} else {
Cow::Owned(format!("_{}", folder_id.copy_index))
};
let nv = &folder_id.nv;
let name = normalize_pkg_name_for_node_modules_deno_folder(&nv.name);
format!("{}@{}{}", name, nv.version, copy_str)
}
fn get_package_folder_id_from_folder_name(
folder_name: &str,
) -> Option<NpmPackageCacheFolderId> {
let folder_name = folder_name.replace('+', "/");
let (name, ending) = folder_name.rsplit_once('@')?;
let name: StackString = if let Some(encoded_name) = name.strip_prefix('_') {
StackString::from_string(mixed_case_package_name_decode(encoded_name)?)
} else {
name.into()
};
let (raw_version, copy_index) = match ending.split_once('_') {
Some((raw_version, copy_index)) => {
let copy_index = copy_index.parse::<u8>().ok()?;
(raw_version, copy_index)
}
None => (ending, 0),
};
let version = deno_semver::Version::parse_from_npm(raw_version).ok()?;
Some(NpmPackageCacheFolderId {
nv: PackageNv { name, version },
copy_index,
})
}
fn join_package_name(path: &Path, package_name: &str) -> PathBuf {
let mut path = path.to_path_buf();
// ensure backslashes are used on windows
@ -243,36 +221,3 @@ fn join_package_name(path: &Path, package_name: &str) -> PathBuf {
}
path
}
#[cfg(test)]
mod test {
use deno_npm::NpmPackageCacheFolderId;
use deno_semver::package::PackageNv;
use super::*;
#[test]
fn test_get_package_folder_id_folder_name() {
let cases = vec![
(
NpmPackageCacheFolderId {
nv: PackageNv::from_str("@types/foo@1.2.3").unwrap(),
copy_index: 1,
},
"@types+foo@1.2.3_1".to_string(),
),
(
NpmPackageCacheFolderId {
nv: PackageNv::from_str("JSON@3.2.1").unwrap(),
copy_index: 0,
},
"_jjju6tq@3.2.1".to_string(),
),
];
for (input, output) in cases {
assert_eq!(get_package_folder_id_folder_name(&input), output);
let folder_id = get_package_folder_id_from_folder_name(&output).unwrap();
assert_eq!(folder_id, input);
}
}
}

View file

@ -0,0 +1,77 @@
// Copyright 2018-2025 the Deno authors. MIT license.
mod common;
mod global;
mod local;
mod resolution;
use std::path::Path;
use std::path::PathBuf;
use node_resolver::InNpmPackageChecker;
use sys_traits::FsCanonicalize;
use sys_traits::FsMetadata;
use url::Url;
pub use self::common::NpmPackageFsResolver;
pub use self::common::NpmPackageFsResolverPackageFolderError;
use self::common::NpmPackageFsResolverRc;
use self::global::GlobalNpmPackageResolver;
use self::local::LocalNpmPackageResolver;
pub use self::resolution::NpmResolution;
use self::resolution::NpmResolutionRc;
use crate::sync::new_rc;
use crate::NpmCacheDirRc;
use crate::ResolvedNpmRcRc;
pub fn create_npm_fs_resolver<
TSys: FsCanonicalize + FsMetadata + std::fmt::Debug + Send + Sync + 'static,
>(
npm_cache_dir: &NpmCacheDirRc,
npm_rc: &ResolvedNpmRcRc,
resolution: NpmResolutionRc,
sys: TSys,
maybe_node_modules_path: Option<PathBuf>,
) -> NpmPackageFsResolverRc {
match maybe_node_modules_path {
Some(node_modules_folder) => new_rc(LocalNpmPackageResolver::new(
resolution,
sys,
node_modules_folder,
)),
None => new_rc(GlobalNpmPackageResolver::new(
npm_cache_dir.clone(),
npm_rc.clone(),
resolution,
)),
}
}
#[derive(Debug)]
pub struct ManagedInNpmPackageChecker {
root_dir: Url,
}
impl InNpmPackageChecker for ManagedInNpmPackageChecker {
fn in_npm_package(&self, specifier: &Url) -> bool {
specifier.as_ref().starts_with(self.root_dir.as_str())
}
}
pub struct ManagedInNpmPkgCheckerCreateOptions<'a> {
pub root_cache_dir_url: &'a Url,
pub maybe_node_modules_path: Option<&'a Path>,
}
pub fn create_managed_in_npm_pkg_checker(
options: ManagedInNpmPkgCheckerCreateOptions,
) -> ManagedInNpmPackageChecker {
let root_dir = match options.maybe_node_modules_path {
Some(node_modules_folder) => {
deno_path_util::url_from_directory_path(node_modules_folder).unwrap()
}
None => options.root_cache_dir_url.clone(),
};
debug_assert!(root_dir.as_str().ends_with('/'));
ManagedInNpmPackageChecker { root_dir }
}

View file

@ -2,7 +2,6 @@
use std::collections::HashMap;
use deno_core::parking_lot::RwLock;
use deno_npm::resolution::NpmPackagesPartitioned;
use deno_npm::resolution::NpmResolutionSnapshot;
use deno_npm::resolution::PackageCacheFolderIdNotFoundError;
@ -16,10 +15,12 @@ use deno_npm::NpmResolutionPackage;
use deno_npm::NpmSystemInfo;
use deno_semver::package::PackageNv;
use deno_semver::package::PackageReq;
use parking_lot::RwLock;
/// Handles updating and storing npm resolution in memory where the underlying
/// snapshot can be updated concurrently. Additionally handles updating the lockfile
/// based on changes to the resolution.
#[allow(clippy::disallowed_types)]
pub(super) type NpmResolutionRc = crate::sync::MaybeArc<NpmResolution>;
/// Handles updating and storing npm resolution in memory.
///
/// This does not interact with the file system.
pub struct NpmResolution {
@ -50,15 +51,15 @@ impl NpmResolution {
}
}
pub fn resolve_pkg_cache_folder_id_from_pkg_id(
pub fn resolve_pkg_cache_folder_copy_index_from_pkg_id(
&self,
id: &NpmPackageId,
) -> Option<NpmPackageCacheFolderId> {
) -> Option<u8> {
self
.snapshot
.read()
.package_from_id(id)
.map(|p| p.get_package_cache_folder_id())
.map(|p| p.copy_index)
}
pub fn resolve_pkg_id_from_pkg_cache_folder_id(

View file

@ -4,15 +4,9 @@ use std::fmt::Debug;
use std::path::PathBuf;
use boxed_error::Boxed;
pub use byonm::ByonmInNpmPackageChecker;
pub use byonm::ByonmNpmResolver;
pub use byonm::ByonmNpmResolverCreateOptions;
pub use byonm::ByonmNpmResolverRc;
pub use byonm::ByonmResolvePkgFolderFromDenoReqError;
use deno_error::JsError;
use deno_semver::npm::NpmPackageReqReference;
use deno_semver::package::PackageReq;
pub use local::normalize_pkg_name_for_node_modules_deno_folder;
use node_resolver::errors::NodeResolveError;
use node_resolver::errors::NodeResolveErrorKind;
use node_resolver::errors::PackageFolderResolveErrorKind;
@ -33,8 +27,38 @@ use sys_traits::FsReadDir;
use thiserror::Error;
use url::Url;
pub use self::byonm::ByonmInNpmPackageChecker;
pub use self::byonm::ByonmNpmResolver;
pub use self::byonm::ByonmNpmResolverCreateOptions;
pub use self::byonm::ByonmNpmResolverRc;
pub use self::byonm::ByonmResolvePkgFolderFromDenoReqError;
pub use self::local::get_package_folder_id_folder_name;
pub use self::local::normalize_pkg_name_for_node_modules_deno_folder;
use self::managed::create_managed_in_npm_pkg_checker;
use self::managed::ManagedInNpmPkgCheckerCreateOptions;
use crate::sync::new_rc;
use crate::sync::MaybeSend;
use crate::sync::MaybeSync;
mod byonm;
mod local;
pub mod managed;
pub enum CreateInNpmPkgCheckerOptions<'a> {
Managed(ManagedInNpmPkgCheckerCreateOptions<'a>),
Byonm,
}
pub fn create_in_npm_pkg_checker(
options: CreateInNpmPkgCheckerOptions,
) -> InNpmPackageCheckerRc {
match options {
CreateInNpmPkgCheckerOptions::Managed(options) => {
new_rc(create_managed_in_npm_pkg_checker(options))
}
CreateInNpmPkgCheckerOptions::Byonm => new_rc(ByonmInNpmPackageChecker),
}
}
#[derive(Debug, Error, JsError)]
#[class(generic)]
@ -96,7 +120,7 @@ pub type CliNpmReqResolverRc = crate::sync::MaybeArc<dyn CliNpmReqResolver>;
// todo(dsherret): a temporary trait until we extract
// out the CLI npm resolver into here
pub trait CliNpmReqResolver: Debug + Send + Sync {
pub trait CliNpmReqResolver: Debug + MaybeSend + MaybeSync {
fn resolve_pkg_folder_from_deno_module_req(
&self,
req: &PackageReq,

View file

@ -7,8 +7,12 @@ use std::path::PathBuf;
use deno_media_type::MediaType;
use deno_path_util::url_from_file_path;
use deno_path_util::url_to_file_path;
use sys_traits::FsMetadata;
use sys_traits::FsMetadataValue;
use url::Url;
use crate::sync::MaybeDashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SloppyImportsFsEntry {
File,
@ -368,6 +372,50 @@ impl<Fs: SloppyImportResolverFs> SloppyImportsResolver<Fs> {
}
}
#[derive(Debug)]
pub struct SloppyImportsCachedFs<TSys: FsMetadata> {
sys: TSys,
cache: Option<MaybeDashMap<PathBuf, Option<SloppyImportsFsEntry>>>,
}
impl<TSys: FsMetadata> SloppyImportsCachedFs<TSys> {
pub fn new(sys: TSys) -> Self {
Self {
sys,
cache: Some(Default::default()),
}
}
pub fn new_without_stat_cache(sys: TSys) -> Self {
Self { sys, cache: None }
}
}
impl<TSys: FsMetadata> SloppyImportResolverFs for SloppyImportsCachedFs<TSys> {
fn stat_sync(&self, path: &Path) -> Option<SloppyImportsFsEntry> {
if let Some(cache) = &self.cache {
if let Some(entry) = cache.get(path) {
return *entry;
}
}
let entry = self.sys.fs_metadata(path).ok().and_then(|stat| {
if stat.file_type().is_file() {
Some(SloppyImportsFsEntry::File)
} else if stat.file_type().is_dir() {
Some(SloppyImportsFsEntry::Dir)
} else {
None
}
});
if let Some(cache) = &self.cache {
cache.insert(path.to_owned(), entry);
}
entry
}
}
#[cfg(test)]
mod test {
use test_util::TestContext;

View file

@ -6,6 +6,8 @@ pub use inner::*;
mod inner {
#![allow(clippy::disallowed_types)]
pub use core::marker::Send as MaybeSend;
pub use core::marker::Sync as MaybeSync;
pub use std::sync::Arc as MaybeArc;
pub use dashmap::DashMap as MaybeDashMap;
@ -21,6 +23,11 @@ mod inner {
use std::hash::RandomState;
pub use std::rc::Rc as MaybeArc;
pub trait MaybeSync {}
impl<T> MaybeSync for T where T: ?Sized {}
pub trait MaybeSend {}
impl<T> MaybeSend for T where T: ?Sized {}
// Wrapper struct that exposes a subset of `DashMap` API.
#[derive(Debug)]
pub struct MaybeDashMap<K, V, S = RandomState>(RefCell<HashMap<K, V, S>>);
@ -46,3 +53,9 @@ mod inner {
}
}
}
#[allow(clippy::disallowed_types)]
#[inline]
pub fn new_rc<T>(value: T) -> MaybeArc<T> {
MaybeArc::new(value)
}

View file

@ -2,7 +2,7 @@
[package]
name = "node_resolver"
version = "0.22.0"
version = "0.23.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_npm_cache"
version = "0.3.0"
version = "0.4.0"
authors.workspace = true
edition.workspace = true
license.workspace = true
@ -14,16 +14,11 @@ description = "Helpers for downloading and caching npm dependencies for Deno"
path = "lib.rs"
[dependencies]
# todo(dsherret): remove this dependency
anyhow.workspace = true
# todo(dsherret): remove this dependency
deno_core.workspace = true
async-trait.workspace = true
base64.workspace = true
boxed_error.workspace = true
deno_cache_dir.workspace = true
deno_error.workspace = true
deno_error = { workspace = true, features = ["serde", "serde_json", "tokio"] }
deno_npm.workspace = true
deno_path_util.workspace = true
deno_semver.workspace = true

View file

@ -6,7 +6,6 @@ use std::path::Path;
use std::path::PathBuf;
use std::sync::Arc;
use anyhow::Error as AnyError;
use deno_cache_dir::file_fetcher::CacheSetting;
use deno_cache_dir::npm::NpmCacheDir;
use deno_error::JsErrorBox;
@ -51,7 +50,7 @@ pub use tarball::TarballCache;
#[class(generic)]
pub struct DownloadError {
pub status_code: Option<StatusCode>,
pub error: AnyError,
pub error: JsErrorBox,
}
impl std::error::Error for DownloadError {
@ -312,15 +311,17 @@ impl<
&self,
name: &str,
package_info: &NpmPackageInfo,
) -> Result<(), AnyError> {
) -> Result<(), JsErrorBox> {
let file_cache_path = self.get_registry_package_info_file_cache_path(name);
let file_text = serde_json::to_string(&package_info)?;
let file_text =
serde_json::to_string(&package_info).map_err(JsErrorBox::from_err)?;
atomic_write_file_with_retries(
&self.sys,
&file_cache_path,
file_text.as_bytes(),
0o644,
)?;
)
.map_err(JsErrorBox::from_err)?;
Ok(())
}

View file

@ -5,11 +5,6 @@ use std::collections::HashSet;
use std::sync::Arc;
use async_trait::async_trait;
use deno_core::futures::future::LocalBoxFuture;
use deno_core::futures::FutureExt;
use deno_core::parking_lot::Mutex;
use deno_core::serde_json;
use deno_core::url::Url;
use deno_error::JsErrorBox;
use deno_npm::npm_rc::ResolvedNpmRc;
use deno_npm::registry::NpmPackageInfo;
@ -17,6 +12,9 @@ use deno_npm::registry::NpmRegistryApi;
use deno_npm::registry::NpmRegistryPackageInfoLoadError;
use deno_unsync::sync::AtomicFlag;
use deno_unsync::sync::MultiRuntimeAsyncValueCreator;
use futures::future::LocalBoxFuture;
use futures::FutureExt;
use parking_lot::Mutex;
use sys_traits::FsCreateDirAll;
use sys_traits::FsHardLink;
use sys_traits::FsMetadata;
@ -26,6 +24,7 @@ use sys_traits::FsRemoveFile;
use sys_traits::FsRename;
use sys_traits::SystemRandom;
use sys_traits::ThreadSleep;
use url::Url;
use crate::remote::maybe_auth_header_for_npm_registry;
use crate::NpmCache;

View file

@ -3,16 +3,15 @@
use std::collections::HashMap;
use std::sync::Arc;
use deno_core::futures::future::LocalBoxFuture;
use deno_core::futures::FutureExt;
use deno_core::parking_lot::Mutex;
use deno_core::url::Url;
use deno_error::JsErrorBox;
use deno_npm::npm_rc::ResolvedNpmRc;
use deno_npm::registry::NpmPackageVersionDistInfo;
use deno_semver::package::PackageNv;
use deno_unsync::sync::MultiRuntimeAsyncValueCreator;
use futures::future::LocalBoxFuture;
use futures::FutureExt;
use http::StatusCode;
use parking_lot::Mutex;
use sys_traits::FsCreateDirAll;
use sys_traits::FsHardLink;
use sys_traits::FsMetadata;
@ -22,6 +21,7 @@ use sys_traits::FsRemoveFile;
use sys_traits::FsRename;
use sys_traits::SystemRandom;
use sys_traits::ThreadSleep;
use url::Url;
use crate::remote::maybe_auth_header_for_npm_registry;
use crate::tarball_extract::verify_and_extract_tarball;

View file

@ -1,7 +1,5 @@
This crate is a work in progress:
1. Remove `deno_core` dependency.
1. Remove `anyhow` dependency.
1. Add a clippy.toml file that bans accessing the file system directory and
instead does it through a trait.
1. Make this crate work in Wasm.

View file

@ -2,7 +2,7 @@
[package]
name = "deno_runtime"
version = "0.192.0"
version = "0.193.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -2,7 +2,7 @@
[package]
name = "deno_permissions"
version = "0.43.0"
version = "0.44.0"
authors.workspace = true
edition.workspace = true
license.workspace = true

View file

@ -9937,6 +9937,74 @@ fn lsp_auto_imports_npm_auto() {
client.shutdown();
}
// Regression test for https://github.com/denoland/deno/issues/23869.
#[test]
fn lsp_auto_imports_remote_dts() {
let context = TestContextBuilder::new()
.use_http_server()
.use_temp_cwd()
.build();
let temp_dir = context.temp_dir();
let mut client = context.new_lsp_command().build();
client.initialize_default();
client.did_open(json!({
"textDocument": {
"uri": temp_dir.url().join("file.ts").unwrap(),
"languageId": "typescript",
"version": 1,
"text": r#"
import "http://localhost:4545/subdir/imports_declaration/imports_interface.ts";
const a: SomeInterface
"#,
},
}));
client.write_request(
"workspace/executeCommand",
json!({
"command": "deno.cache",
"arguments": [[], temp_dir.url().join("file.ts").unwrap()],
}),
);
let list = client.get_completion_list(
temp_dir.url().join("file.ts").unwrap(),
(2, 21),
json!({ "triggerKind": 2 }),
);
assert!(!list.is_incomplete);
let item = list
.items
.iter()
.find(|item| item.label == "SomeInterface")
.unwrap();
let res = client.write_request("completionItem/resolve", json!(item));
assert_eq!(
res,
json!({
"label": "SomeInterface",
"labelDetails": {
"description": "http://localhost:4545/subdir/imports_declaration/interface.d.ts",
},
"kind": 8,
"detail": "interface SomeInterface",
"documentation": {
"kind": "markdown",
"value": "",
},
"sortText": "￿16_1",
"additionalTextEdits": [
{
"range": {
"start": { "line": 2, "character": 0 },
"end": { "line": 2, "character": 0 },
},
"newText": " import { SomeInterface } from \"http://localhost:4545/subdir/imports_declaration/interface.d.ts\";\n",
},
],
}),
);
client.shutdown();
}
#[test]
fn lsp_npm_specifier_unopened_file() {
let context = TestContextBuilder::new()

View file

@ -0,0 +1,3 @@
import type { SomeInterface } from "./interface.d.ts";
export const someObject: SomeInterface = { someField: "someValue" };

View file

@ -0,0 +1,3 @@
export interface SomeInterface {
someField: string;
}