mirror of
https://github.com/denoland/deno.git
synced 2025-01-20 20:42:19 -05:00
Merge branch 'main' into sqlite_node_cppgc
This commit is contained in:
commit
fa2a41ef27
1332 changed files with 32424 additions and 17786 deletions
|
@ -13,7 +13,7 @@
|
|||
},
|
||||
"exec": {
|
||||
"commands": [{
|
||||
"command": "rustfmt --config imports_granularity=item",
|
||||
"command": "rustfmt --config imports_granularity=item --config group_imports=StdExternalCrate",
|
||||
"exts": ["rs"]
|
||||
}]
|
||||
},
|
||||
|
|
2
.github/mtime_cache/action.js
vendored
2
.github/mtime_cache/action.js
vendored
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
// This file contains the implementation of a Github Action. Github uses
|
||||
// Node.js v20.x to run actions, so this is Node code and not Deno code.
|
||||
|
||||
|
|
20
.github/workflows/ci.generate.ts
vendored
20
.github/workflows/ci.generate.ts
vendored
|
@ -1,11 +1,11 @@
|
|||
#!/usr/bin/env -S deno run --allow-write=. --lock=./tools/deno.lock.json
|
||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
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 = 36;
|
||||
|
||||
const ubuntuX86Runner = "ubuntu-24.04";
|
||||
const ubuntuX86XlRunner = "ubuntu-24.04-xl";
|
||||
|
@ -14,7 +14,7 @@ const windowsX86Runner = "windows-2022";
|
|||
const windowsX86XlRunner = "windows-2022-xl";
|
||||
const macosX86Runner = "macos-13";
|
||||
const macosArmRunner = "macos-14";
|
||||
const selfHostedMacosArmRunner = "self-hosted";
|
||||
const selfHostedMacosArmRunner = "ghcr.io/cirruslabs/macos-runner:sonoma";
|
||||
|
||||
const Runners = {
|
||||
linuxX86: {
|
||||
|
@ -41,8 +41,14 @@ const Runners = {
|
|||
macosArm: {
|
||||
os: "macos",
|
||||
arch: "aarch64",
|
||||
runner: macosArmRunner,
|
||||
},
|
||||
macosArmSelfHosted: {
|
||||
os: "macos",
|
||||
arch: "aarch64",
|
||||
// Actually use self-hosted runner only in denoland/deno on `main` branch and for tags (release) builds.
|
||||
runner:
|
||||
`\${{ github.repository == 'denoland/deno' && startsWith(github.ref, 'refs/tags/') && '${selfHostedMacosArmRunner}' || '${macosArmRunner}' }}`,
|
||||
`\${{ github.repository == 'denoland/deno' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')) && '${selfHostedMacosArmRunner}' || '${macosArmRunner}' }}`,
|
||||
},
|
||||
windowsX86: {
|
||||
os: "windows",
|
||||
|
@ -360,7 +366,7 @@ const ci = {
|
|||
needs: ["pre_build"],
|
||||
if: "${{ needs.pre_build.outputs.skip_build != 'true' }}",
|
||||
"runs-on": "${{ matrix.runner }}",
|
||||
"timeout-minutes": 180,
|
||||
"timeout-minutes": 240,
|
||||
defaults: {
|
||||
run: {
|
||||
// GH actions does not fail fast by default on
|
||||
|
@ -384,7 +390,7 @@ const ci = {
|
|||
job: "test",
|
||||
profile: "debug",
|
||||
}, {
|
||||
...Runners.macosArm,
|
||||
...Runners.macosArmSelfHosted,
|
||||
job: "test",
|
||||
profile: "release",
|
||||
skip_pr: true,
|
||||
|
@ -486,7 +492,7 @@ const ci = {
|
|||
},
|
||||
{
|
||||
name: "Cache Cargo home",
|
||||
uses: "actions/cache@v4",
|
||||
uses: "cirruslabs/cache@v4",
|
||||
with: {
|
||||
// See https://doc.rust-lang.org/cargo/guide/cargo-home.html#caching-the-cargo-home-in-ci
|
||||
// Note that with the new sparse registry format, we no longer have to cache a `.git` dir
|
||||
|
|
16
.github/workflows/ci.yml
vendored
16
.github/workflows/ci.yml
vendored
|
@ -48,7 +48,7 @@ jobs:
|
|||
- pre_build
|
||||
if: '${{ needs.pre_build.outputs.skip_build != ''true'' }}'
|
||||
runs-on: '${{ matrix.runner }}'
|
||||
timeout-minutes: 180
|
||||
timeout-minutes: 240
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
@ -68,12 +68,12 @@ jobs:
|
|||
skip: '${{ !contains(github.event.pull_request.labels.*.name, ''ci-full'') && (github.event_name == ''pull_request'') }}'
|
||||
- os: macos
|
||||
arch: aarch64
|
||||
runner: '${{ github.repository == ''denoland/deno'' && startsWith(github.ref, ''refs/tags/'') && ''self-hosted'' || ''macos-14'' }}'
|
||||
runner: macos-14
|
||||
job: test
|
||||
profile: debug
|
||||
- os: macos
|
||||
arch: aarch64
|
||||
runner: '${{ (!contains(github.event.pull_request.labels.*.name, ''ci-full'') && (github.event_name == ''pull_request'')) && ''ubuntu-24.04'' || github.repository == ''denoland/deno'' && startsWith(github.ref, ''refs/tags/'') && ''self-hosted'' || ''macos-14'' }}'
|
||||
runner: '${{ (!contains(github.event.pull_request.labels.*.name, ''ci-full'') && (github.event_name == ''pull_request'')) && ''ubuntu-24.04'' || github.repository == ''denoland/deno'' && (github.ref == ''refs/heads/main'' || startsWith(github.ref, ''refs/tags/'')) && ''ghcr.io/cirruslabs/macos-runner:sonoma'' || ''macos-14'' }}'
|
||||
job: test
|
||||
profile: release
|
||||
skip: '${{ !contains(github.event.pull_request.labels.*.name, ''ci-full'') && (github.event_name == ''pull_request'') }}'
|
||||
|
@ -175,7 +175,7 @@ jobs:
|
|||
tar --exclude=".git*" --exclude=target --exclude=third_party/prebuilt \
|
||||
-czvf target/release/deno_src.tar.gz -C .. deno
|
||||
- name: Cache Cargo home
|
||||
uses: actions/cache@v4
|
||||
uses: cirruslabs/cache@v4
|
||||
with:
|
||||
path: |-
|
||||
~/.cargo/.crates.toml
|
||||
|
@ -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: '36-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-${{ hashFiles(''Cargo.lock'') }}'
|
||||
restore-keys: '36-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: '36-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: '36-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-${{ github.sha }}'
|
||||
publish-canary:
|
||||
name: publish canary
|
||||
runs-on: ubuntu-24.04
|
||||
|
|
577
Cargo.lock
generated
577
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
90
Cargo.toml
90
Cargo.toml
|
@ -1,10 +1,11 @@
|
|||
# Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
# Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"bench_util",
|
||||
"cli",
|
||||
"cli/lib",
|
||||
"ext/broadcast_channel",
|
||||
"ext/cache",
|
||||
"ext/canvas",
|
||||
|
@ -48,55 +49,58 @@ repository = "https://github.com/denoland/deno"
|
|||
|
||||
[workspace.dependencies]
|
||||
deno_ast = { version = "=0.44.0", features = ["transpiling"] }
|
||||
deno_core = { version = "0.327.0" }
|
||||
deno_core = { version = "0.330.0" }
|
||||
|
||||
deno_bench_util = { version = "0.178.0", path = "./bench_util" }
|
||||
deno_config = { version = "=0.42.0", features = ["workspace", "sync"] }
|
||||
deno_bench_util = { version = "0.180.0", path = "./bench_util" }
|
||||
deno_config = { version = "=0.45.0", features = ["workspace", "sync"] }
|
||||
deno_lockfile = "=0.24.0"
|
||||
deno_media_type = { version = "0.2.0", features = ["module_specifier"] }
|
||||
deno_npm = "=0.27.0"
|
||||
deno_media_type = { version = "0.2.3", features = ["module_specifier"] }
|
||||
deno_npm = "=0.27.2"
|
||||
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.45.0", path = "./runtime/permissions" }
|
||||
deno_runtime = { version = "0.194.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.116.0", path = "./ext/napi/sym" }
|
||||
test_util = { package = "test_server", path = "./tests/util/server" }
|
||||
|
||||
denokv_proto = "0.8.4"
|
||||
denokv_remote = "0.8.4"
|
||||
denokv_proto = "0.9.0"
|
||||
denokv_remote = "0.9.0"
|
||||
# denokv_sqlite brings in bundled sqlite if we don't disable the default features
|
||||
denokv_sqlite = { default-features = false, version = "0.8.4" }
|
||||
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.180.0", path = "./ext/broadcast_channel" }
|
||||
deno_cache = { version = "0.118.0", path = "./ext/cache" }
|
||||
deno_canvas = { version = "0.55.0", path = "./ext/canvas" }
|
||||
deno_console = { version = "0.186.0", path = "./ext/console" }
|
||||
deno_cron = { version = "0.66.0", path = "./ext/cron" }
|
||||
deno_crypto = { version = "0.200.0", path = "./ext/crypto" }
|
||||
deno_fetch = { version = "0.210.0", path = "./ext/fetch" }
|
||||
deno_ffi = { version = "0.173.0", path = "./ext/ffi" }
|
||||
deno_fs = { version = "0.96.0", path = "./ext/fs" }
|
||||
deno_http = { version = "0.184.0", path = "./ext/http" }
|
||||
deno_io = { version = "0.96.0", path = "./ext/io" }
|
||||
deno_kv = { version = "0.94.0", path = "./ext/kv" }
|
||||
deno_napi = { version = "0.117.0", path = "./ext/napi" }
|
||||
deno_net = { version = "0.178.0", path = "./ext/net" }
|
||||
deno_node = { version = "0.124.0", path = "./ext/node" }
|
||||
deno_os = { version = "0.3.0", path = "./ext/os" }
|
||||
deno_process = { version = "0.1.0", path = "./ext/process" }
|
||||
deno_telemetry = { version = "0.8.0", path = "./ext/telemetry" }
|
||||
deno_tls = { version = "0.173.0", path = "./ext/tls" }
|
||||
deno_url = { version = "0.186.0", path = "./ext/url" }
|
||||
deno_web = { version = "0.217.0", path = "./ext/web" }
|
||||
deno_webgpu = { version = "0.153.0", path = "./ext/webgpu" }
|
||||
deno_webidl = { version = "0.186.0", path = "./ext/webidl" }
|
||||
deno_websocket = { version = "0.191.0", path = "./ext/websocket" }
|
||||
deno_webstorage = { version = "0.181.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" }
|
||||
# workspace libraries
|
||||
deno_lib = { version = "0.2.0", path = "./cli/lib" }
|
||||
deno_npm_cache = { version = "0.5.0", path = "./resolvers/npm_cache" }
|
||||
deno_resolver = { version = "0.17.0", path = "./resolvers/deno" }
|
||||
node_resolver = { version = "0.24.0", path = "./resolvers/node" }
|
||||
|
||||
aes = "=0.8.3"
|
||||
anyhow = "1.0.57"
|
||||
|
@ -119,7 +123,7 @@ dashmap = "5.5.3"
|
|||
data-encoding = "2.3.3"
|
||||
data-url = "=0.3.1"
|
||||
deno_cache_dir = "=0.16.0"
|
||||
deno_error = "=0.5.2"
|
||||
deno_error = "=0.5.3"
|
||||
deno_package_json = { version = "0.4.0", default-features = false }
|
||||
deno_unsync = "0.4.2"
|
||||
dlopen2 = "0.6.1"
|
||||
|
@ -193,7 +197,7 @@ slab = "0.4"
|
|||
smallvec = "1.8"
|
||||
socket2 = { version = "0.5.3", features = ["all"] }
|
||||
spki = "0.7.2"
|
||||
sys_traits = "=0.1.4"
|
||||
sys_traits = "=0.1.7"
|
||||
tar = "=0.4.40"
|
||||
tempfile = "3.4.0"
|
||||
termcolor = "1.1.3"
|
||||
|
@ -212,7 +216,7 @@ url = { version = "2.5", features = ["serde", "expose_internals"] }
|
|||
uuid = { version = "1.3.0", features = ["v4"] }
|
||||
webpki-root-certs = "0.26.5"
|
||||
webpki-roots = "0.26"
|
||||
which = "4.2.5"
|
||||
which = "6"
|
||||
yoke = { version = "0.7.4", features = ["derive"] }
|
||||
zeromq = { version = "=0.4.1", default-features = false, features = ["tcp-transport", "tokio-runtime"] }
|
||||
zstd = "=0.12.4"
|
||||
|
@ -240,7 +244,7 @@ syn = { version = "2", features = ["full", "extra-traits"] }
|
|||
nix = "=0.27.1"
|
||||
|
||||
# windows deps
|
||||
junction = "=0.2.0"
|
||||
junction = "=1.2.0"
|
||||
winapi = "=0.3.9"
|
||||
windows-sys = { version = "0.59.0", features = ["Win32_Foundation", "Win32_Media", "Win32_Storage_FileSystem", "Win32_System_IO", "Win32_System_WindowsProgramming", "Wdk", "Wdk_System", "Wdk_System_SystemInformation", "Win32_Security", "Win32_System_Pipes", "Wdk_Storage_FileSystem", "Win32_System_Registry", "Win32_System_Kernel", "Win32_System_Threading", "Win32_UI", "Win32_UI_Shell"] }
|
||||
winres = "=0.1.12"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright 2018-2024 the Deno authors
|
||||
Copyright 2018-2025 the Deno authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
|
105
Releases.md
105
Releases.md
|
@ -6,6 +6,111 @@ https://github.com/denoland/deno/releases
|
|||
We also have one-line install commands at:
|
||||
https://github.com/denoland/deno_install
|
||||
|
||||
### 2.1.6 / 2025.01.16
|
||||
|
||||
- fix(check/lsp): correctly resolve compilerOptions.types (#27686)
|
||||
- fix(check/lsp): fix bugs with tsc type resolution, allow npm packages to
|
||||
augment `ImportMeta` (#27690)
|
||||
- fix(compile): store embedded fs case sensitivity (#27653)
|
||||
- fix(compile/windows): better handling of deno_dir on different drive letter
|
||||
than code (#27654)
|
||||
- fix(ext/console): change Temporal color (#27684)
|
||||
- fix(ext/node): add `writev` method to `FileHandle` (#27563)
|
||||
- fix(ext/node): add chown method to FileHandle class (#27638)
|
||||
- fix(ext/node): apply `@npmcli/agent` workaround to `npm-check-updates`
|
||||
(#27639)
|
||||
- fix(ext/node): fix playwright http client (#27662)
|
||||
- fix(ext/node): show bare-node-builtin hint when using an import map (#27632)
|
||||
- fix(ext/node): use primordials in `ext/node/polyfills/_fs_common.ts` (#27589)
|
||||
- fix(lsp): handle pathless untitled URIs (#27637)
|
||||
- fix(lsp/check): don't resolve unknown media types to a `.js` extension
|
||||
(#27631)
|
||||
- fix(node): Prevent node:child_process from always inheriting the parent
|
||||
environment (#27343) (#27340)
|
||||
- fix(node/fs): add utimes method to the FileHandle class (#27582)
|
||||
- fix(outdated): Use `latest` tag even when it's the same as the current version
|
||||
(#27699)
|
||||
- fix(outdated): retain strict semver specifier when updating (#27701)
|
||||
|
||||
### 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
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
# Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
[package]
|
||||
name = "deno_bench_util"
|
||||
version = "0.178.0"
|
||||
version = "0.180.0"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
|
|
@ -7,7 +7,6 @@ use deno_bench_util::bench_js_sync;
|
|||
use deno_bench_util::bench_or_profile;
|
||||
use deno_bench_util::bencher::benchmark_group;
|
||||
use deno_bench_util::bencher::Bencher;
|
||||
|
||||
use deno_core::Extension;
|
||||
|
||||
#[op2]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use deno_bench_util::bench_js_sync_with;
|
||||
use deno_bench_util::bench_or_profile;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
use bencher::Bencher;
|
||||
use deno_core::v8;
|
||||
use deno_core::Extension;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
mod js_runtime;
|
||||
mod profiling;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
use bencher::DynBenchFn;
|
||||
use bencher::StaticBenchFn;
|
||||
use bencher::TestDescAndFn;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
# Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
[package]
|
||||
name = "deno"
|
||||
version = "2.1.4"
|
||||
version = "2.1.6"
|
||||
authors.workspace = true
|
||||
default-run = "deno"
|
||||
edition.workspace = true
|
||||
|
@ -62,6 +62,7 @@ serde_json.workspace = true
|
|||
zstd.workspace = true
|
||||
glibc_version = "0.1.2"
|
||||
flate2 = { workspace = true, features = ["default"] }
|
||||
deno_error.workspace = true
|
||||
|
||||
[target.'cfg(windows)'.build-dependencies]
|
||||
winapi.workspace = true
|
||||
|
@ -72,9 +73,10 @@ deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "proposa
|
|||
deno_cache_dir.workspace = true
|
||||
deno_config.workspace = true
|
||||
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
||||
deno_doc = { version = "=0.161.3", features = ["rust", "comrak"] }
|
||||
deno_doc = { version = "=0.164.0", features = ["rust", "comrak"] }
|
||||
deno_error.workspace = true
|
||||
deno_graph = { version = "=0.86.6" }
|
||||
deno_graph = { version = "=0.87.0" }
|
||||
deno_lib.workspace = true
|
||||
deno_lint = { version = "=0.68.2", features = ["docs"] }
|
||||
deno_lockfile.workspace = true
|
||||
deno_npm.workspace = true
|
||||
|
@ -124,7 +126,7 @@ http.workspace = true
|
|||
http-body.workspace = true
|
||||
http-body-util.workspace = true
|
||||
hyper-util.workspace = true
|
||||
import_map = { version = "=0.20.1", features = ["ext"] }
|
||||
import_map = { version = "=0.21.0", features = ["ext"] }
|
||||
indexmap.workspace = true
|
||||
jsonc-parser = { workspace = true, features = ["cst", "serde"] }
|
||||
jupyter_runtime = { package = "runtimelib", version = "=0.19.0", features = ["tokio-runtime"] }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashSet;
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
|
@ -34,7 +33,6 @@ use deno_core::url::Url;
|
|||
use deno_graph::GraphKind;
|
||||
use deno_path_util::normalize_path;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use deno_runtime::deno_permissions::PermissionsOptions;
|
||||
use deno_runtime::deno_permissions::SysDescriptor;
|
||||
use deno_telemetry::OtelConfig;
|
||||
use deno_telemetry::OtelConsoleConfig;
|
||||
|
@ -43,11 +41,8 @@ use log::Level;
|
|||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::args::resolve_no_prompt;
|
||||
use crate::util::fs::canonicalize_path;
|
||||
|
||||
use super::flags_net;
|
||||
use super::jsr_url;
|
||||
use crate::util::fs::canonicalize_path;
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||
pub enum ConfigFlag {
|
||||
|
@ -693,97 +688,6 @@ impl PermissionFlags {
|
|||
|| self.deny_write.is_some()
|
||||
|| self.allow_import.is_some()
|
||||
}
|
||||
|
||||
pub fn to_options(&self, cli_arg_urls: &[Cow<Url>]) -> PermissionsOptions {
|
||||
fn handle_allow<T: Default>(
|
||||
allow_all: bool,
|
||||
value: Option<T>,
|
||||
) -> Option<T> {
|
||||
if allow_all {
|
||||
assert!(value.is_none());
|
||||
Some(T::default())
|
||||
} else {
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_imports(
|
||||
cli_arg_urls: &[Cow<Url>],
|
||||
imports: Option<Vec<String>>,
|
||||
) -> Option<Vec<String>> {
|
||||
if imports.is_some() {
|
||||
return imports;
|
||||
}
|
||||
|
||||
let builtin_allowed_import_hosts = [
|
||||
"jsr.io:443",
|
||||
"deno.land:443",
|
||||
"esm.sh:443",
|
||||
"cdn.jsdelivr.net:443",
|
||||
"raw.githubusercontent.com:443",
|
||||
"gist.githubusercontent.com:443",
|
||||
];
|
||||
|
||||
let mut imports =
|
||||
Vec::with_capacity(builtin_allowed_import_hosts.len() + 1);
|
||||
imports
|
||||
.extend(builtin_allowed_import_hosts.iter().map(|s| s.to_string()));
|
||||
|
||||
// also add the JSR_URL env var
|
||||
if let Some(jsr_host) = allow_import_host_from_url(jsr_url()) {
|
||||
imports.push(jsr_host);
|
||||
}
|
||||
// include the cli arg urls
|
||||
for url in cli_arg_urls {
|
||||
if let Some(host) = allow_import_host_from_url(url) {
|
||||
imports.push(host);
|
||||
}
|
||||
}
|
||||
|
||||
Some(imports)
|
||||
}
|
||||
|
||||
PermissionsOptions {
|
||||
allow_all: self.allow_all,
|
||||
allow_env: handle_allow(self.allow_all, self.allow_env.clone()),
|
||||
deny_env: self.deny_env.clone(),
|
||||
allow_net: handle_allow(self.allow_all, self.allow_net.clone()),
|
||||
deny_net: self.deny_net.clone(),
|
||||
allow_ffi: handle_allow(self.allow_all, self.allow_ffi.clone()),
|
||||
deny_ffi: self.deny_ffi.clone(),
|
||||
allow_read: handle_allow(self.allow_all, self.allow_read.clone()),
|
||||
deny_read: self.deny_read.clone(),
|
||||
allow_run: handle_allow(self.allow_all, self.allow_run.clone()),
|
||||
deny_run: self.deny_run.clone(),
|
||||
allow_sys: handle_allow(self.allow_all, self.allow_sys.clone()),
|
||||
deny_sys: self.deny_sys.clone(),
|
||||
allow_write: handle_allow(self.allow_all, self.allow_write.clone()),
|
||||
deny_write: self.deny_write.clone(),
|
||||
allow_import: handle_imports(
|
||||
cli_arg_urls,
|
||||
handle_allow(self.allow_all, self.allow_import.clone()),
|
||||
),
|
||||
prompt: !resolve_no_prompt(self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the --allow-import host from the provided url
|
||||
fn allow_import_host_from_url(url: &Url) -> Option<String> {
|
||||
let host = url.host()?;
|
||||
if let Some(port) = url.port() {
|
||||
Some(format!("{}:{}", host, port))
|
||||
} else {
|
||||
use deno_core::url::Host::*;
|
||||
match host {
|
||||
Domain(domain) if domain == "jsr.io" && url.scheme() == "https" => None,
|
||||
_ => match url.scheme() {
|
||||
"https" => Some(format!("{}:443", host)),
|
||||
"http" => Some(format!("{}:80", host)),
|
||||
_ => None,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn join_paths(allowlist: &[String], d: &str) -> String {
|
||||
|
@ -6059,9 +5963,10 @@ pub fn resolve_urls(urls: Vec<String>) -> Vec<String> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use super::*;
|
||||
|
||||
/// Creates vector of strings, Vec<String>
|
||||
macro_rules! svec {
|
||||
($($x:expr),* $(,)?) => (vec![$($x.to_string().into()),*]);
|
||||
|
@ -11549,8 +11454,6 @@ mod tests {
|
|||
..Default::default()
|
||||
}
|
||||
);
|
||||
// just make sure this doesn't panic
|
||||
let _ = flags.permissions.to_options(&[]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -11626,29 +11529,6 @@ Usage: deno repl [OPTIONS] [-- [ARGS]...]\n"
|
|||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_allow_import_host_from_url() {
|
||||
fn parse(text: &str) -> Option<String> {
|
||||
allow_import_host_from_url(&Url::parse(text).unwrap())
|
||||
}
|
||||
|
||||
assert_eq!(parse("https://jsr.io"), None);
|
||||
assert_eq!(
|
||||
parse("http://127.0.0.1:4250"),
|
||||
Some("127.0.0.1:4250".to_string())
|
||||
);
|
||||
assert_eq!(parse("http://jsr.io"), Some("jsr.io:80".to_string()));
|
||||
assert_eq!(
|
||||
parse("https://example.com"),
|
||||
Some("example.com:443".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
parse("http://example.com"),
|
||||
Some("example.com:80".to_string())
|
||||
);
|
||||
assert_eq!(parse("file:///example.com"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn allow_all_conflicts_allow_perms() {
|
||||
let flags = [
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::net::IpAddr;
|
||||
use std::str::FromStr;
|
||||
|
||||
use deno_core::url::Url;
|
||||
use deno_runtime::deno_permissions::NetDescriptor;
|
||||
use std::net::IpAddr;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct ParsePortError(String);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::serde_json;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::path::PathBuf;
|
||||
|
@ -10,6 +10,8 @@ use deno_core::error::AnyError;
|
|||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::parking_lot::MutexGuard;
|
||||
use deno_core::serde_json;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_lockfile::Lockfile;
|
||||
use deno_lockfile::WorkspaceMemberConfig;
|
||||
use deno_package_json::PackageJsonDepValue;
|
||||
use deno_path_util::fs::atomic_write_file_with_retries;
|
||||
|
@ -17,15 +19,12 @@ use deno_runtime::deno_node::PackageJson;
|
|||
use deno_semver::jsr::JsrDepPackageReq;
|
||||
|
||||
use crate::args::deno_json::import_map_deps;
|
||||
use crate::args::DenoSubcommand;
|
||||
use crate::args::InstallFlags;
|
||||
use crate::cache;
|
||||
use crate::sys::CliSys;
|
||||
use crate::Flags;
|
||||
|
||||
use crate::args::DenoSubcommand;
|
||||
use crate::args::InstallFlags;
|
||||
|
||||
use deno_lockfile::Lockfile;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CliLockfileReadFromPathOptions {
|
||||
pub file_path: PathBuf,
|
||||
|
@ -61,6 +60,14 @@ impl<'a, T> std::ops::DerefMut for Guard<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
#[error("Failed writing lockfile")]
|
||||
#[class(inherit)]
|
||||
struct AtomicWriteFileWithRetriesError {
|
||||
#[source]
|
||||
source: std::io::Error,
|
||||
}
|
||||
|
||||
impl CliLockfile {
|
||||
/// Get the inner deno_lockfile::Lockfile.
|
||||
pub fn lock(&self) -> Guard<Lockfile> {
|
||||
|
@ -80,7 +87,7 @@ impl CliLockfile {
|
|||
self.lockfile.lock().overwrite
|
||||
}
|
||||
|
||||
pub fn write_if_changed(&self) -> Result<(), AnyError> {
|
||||
pub fn write_if_changed(&self) -> Result<(), JsErrorBox> {
|
||||
if self.skip_write {
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -98,7 +105,9 @@ impl CliLockfile {
|
|||
&bytes,
|
||||
cache::CACHE_PERM,
|
||||
)
|
||||
.context("Failed writing lockfile.")?;
|
||||
.map_err(|source| {
|
||||
JsErrorBox::from_err(AtomicWriteFileWithRetriesError { source })
|
||||
})?;
|
||||
lockfile.has_content_changed = false;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -257,7 +266,7 @@ impl CliLockfile {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn error_if_changed(&self) -> Result<(), AnyError> {
|
||||
pub fn error_if_changed(&self) -> Result<(), JsErrorBox> {
|
||||
if !self.frozen {
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -269,9 +278,7 @@ impl CliLockfile {
|
|||
let diff = crate::util::diff::diff(&contents, &new_contents);
|
||||
// has an extra newline at the end
|
||||
let diff = diff.trim_end();
|
||||
Err(deno_core::anyhow::anyhow!(
|
||||
"The lockfile is out of date. Run `deno install --frozen=false`, or rerun with `--frozen=false` to update it.\nchanges:\n{diff}"
|
||||
))
|
||||
Err(JsErrorBox::generic(format!("The lockfile is out of date. Run `deno install --frozen=false`, or rerun with `--frozen=false` to update it.\nchanges:\n{diff}")))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
|
413
cli/args/mod.rs
413
cli/args/mod.rs
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
pub mod deno_json;
|
||||
mod flags;
|
||||
|
@ -7,70 +7,6 @@ mod import_map;
|
|||
mod lockfile;
|
||||
mod package_json;
|
||||
|
||||
use deno_ast::MediaType;
|
||||
use deno_ast::SourceMapOption;
|
||||
use deno_cache_dir::file_fetcher::CacheSetting;
|
||||
use deno_config::deno_json::NodeModulesDirMode;
|
||||
use deno_config::workspace::CreateResolverOptions;
|
||||
use deno_config::workspace::FolderConfigs;
|
||||
use deno_config::workspace::PackageJsonDepResolution;
|
||||
use deno_config::workspace::VendorEnablement;
|
||||
use deno_config::workspace::Workspace;
|
||||
use deno_config::workspace::WorkspaceDirectory;
|
||||
use deno_config::workspace::WorkspaceDirectoryEmptyOptions;
|
||||
use deno_config::workspace::WorkspaceDiscoverOptions;
|
||||
use deno_config::workspace::WorkspaceDiscoverStart;
|
||||
use deno_config::workspace::WorkspaceLintConfig;
|
||||
use deno_config::workspace::WorkspaceResolver;
|
||||
use deno_core::resolve_url_or_path;
|
||||
use deno_graph::GraphKind;
|
||||
use deno_lint::linter::LintConfig as DenoLintConfig;
|
||||
use deno_npm::npm_rc::NpmRc;
|
||||
use deno_npm::npm_rc::ResolvedNpmRc;
|
||||
use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot;
|
||||
use deno_npm::NpmSystemInfo;
|
||||
use deno_path_util::normalize_path;
|
||||
use deno_semver::npm::NpmPackageReqReference;
|
||||
use deno_semver::StackString;
|
||||
use deno_telemetry::OtelConfig;
|
||||
use deno_telemetry::OtelRuntimeConfig;
|
||||
use import_map::resolve_import_map_value_from_specifier;
|
||||
|
||||
pub use deno_config::deno_json::BenchConfig;
|
||||
pub use deno_config::deno_json::ConfigFile;
|
||||
pub use deno_config::deno_json::FmtOptionsConfig;
|
||||
pub use deno_config::deno_json::LintRulesConfig;
|
||||
pub use deno_config::deno_json::ProseWrap;
|
||||
pub use deno_config::deno_json::TsConfig;
|
||||
pub use deno_config::deno_json::TsConfigForEmit;
|
||||
pub use deno_config::deno_json::TsConfigType;
|
||||
pub use deno_config::deno_json::TsTypeLib;
|
||||
pub use deno_config::glob::FilePatterns;
|
||||
pub use deno_json::check_warn_tsconfig;
|
||||
pub use flags::*;
|
||||
pub use lockfile::CliLockfile;
|
||||
pub use lockfile::CliLockfileReadFromPathOptions;
|
||||
pub use package_json::NpmInstallDepsProvider;
|
||||
pub use package_json::PackageJsonDepValueParseWithLocationError;
|
||||
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::url::Url;
|
||||
use deno_runtime::deno_permissions::PermissionsOptions;
|
||||
use deno_runtime::deno_tls::deno_native_certs::load_native_certs;
|
||||
use deno_runtime::deno_tls::rustls;
|
||||
use deno_runtime::deno_tls::rustls::RootCertStore;
|
||||
use deno_runtime::deno_tls::rustls_pemfile;
|
||||
use deno_runtime::deno_tls::webpki_roots;
|
||||
use deno_runtime::inspector_server::InspectorServer;
|
||||
use deno_terminal::colors;
|
||||
use dotenvy::from_filename;
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
|
@ -83,19 +19,84 @@ use std::num::NonZeroUsize;
|
|||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_ast::MediaType;
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_ast::SourceMapOption;
|
||||
use deno_cache_dir::file_fetcher::CacheSetting;
|
||||
pub use deno_config::deno_json::BenchConfig;
|
||||
pub use deno_config::deno_json::ConfigFile;
|
||||
use deno_config::deno_json::ConfigFileError;
|
||||
use deno_config::deno_json::FmtConfig;
|
||||
pub use deno_config::deno_json::FmtOptionsConfig;
|
||||
use deno_config::deno_json::LintConfig;
|
||||
pub use deno_config::deno_json::LintRulesConfig;
|
||||
use deno_config::deno_json::NodeModulesDirMode;
|
||||
pub use deno_config::deno_json::ProseWrap;
|
||||
use deno_config::deno_json::TestConfig;
|
||||
pub use deno_config::deno_json::TsConfig;
|
||||
pub use deno_config::deno_json::TsConfigForEmit;
|
||||
pub use deno_config::deno_json::TsConfigType;
|
||||
pub use deno_config::deno_json::TsTypeLib;
|
||||
pub use deno_config::glob::FilePatterns;
|
||||
use deno_config::workspace::CreateResolverOptions;
|
||||
use deno_config::workspace::FolderConfigs;
|
||||
use deno_config::workspace::PackageJsonDepResolution;
|
||||
use deno_config::workspace::VendorEnablement;
|
||||
use deno_config::workspace::Workspace;
|
||||
use deno_config::workspace::WorkspaceDirectory;
|
||||
use deno_config::workspace::WorkspaceDirectoryEmptyOptions;
|
||||
use deno_config::workspace::WorkspaceDiscoverOptions;
|
||||
use deno_config::workspace::WorkspaceDiscoverStart;
|
||||
use deno_config::workspace::WorkspaceLintConfig;
|
||||
use deno_config::workspace::WorkspaceResolver;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::resolve_url_or_path;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::url::Url;
|
||||
use deno_graph::GraphKind;
|
||||
pub use deno_json::check_warn_tsconfig;
|
||||
use deno_lib::cache::DenoDirProvider;
|
||||
use deno_lib::env::has_flag_env_var;
|
||||
use deno_lib::worker::StorageKeyResolver;
|
||||
use deno_lint::linter::LintConfig as DenoLintConfig;
|
||||
use deno_npm::npm_rc::NpmRc;
|
||||
use deno_npm::npm_rc::ResolvedNpmRc;
|
||||
use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot;
|
||||
use deno_npm::NpmSystemInfo;
|
||||
use deno_path_util::normalize_path;
|
||||
use deno_runtime::deno_permissions::PermissionsOptions;
|
||||
use deno_runtime::deno_tls::deno_native_certs::load_native_certs;
|
||||
use deno_runtime::deno_tls::rustls;
|
||||
use deno_runtime::deno_tls::rustls::RootCertStore;
|
||||
use deno_runtime::deno_tls::rustls_pemfile;
|
||||
use deno_runtime::deno_tls::webpki_roots;
|
||||
use deno_runtime::inspector_server::InspectorServer;
|
||||
use deno_semver::npm::NpmPackageReqReference;
|
||||
use deno_semver::StackString;
|
||||
use deno_telemetry::OtelConfig;
|
||||
use deno_telemetry::OtelRuntimeConfig;
|
||||
use deno_terminal::colors;
|
||||
use dotenvy::from_filename;
|
||||
pub use flags::*;
|
||||
use import_map::resolve_import_map_value_from_specifier;
|
||||
pub use lockfile::CliLockfile;
|
||||
pub use lockfile::CliLockfileReadFromPathOptions;
|
||||
use once_cell::sync::Lazy;
|
||||
pub use package_json::NpmInstallDepsProvider;
|
||||
pub use package_json::PackageJsonDepValueParseWithLocationError;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use sys_traits::EnvHomeDir;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::cache::DenoDirProvider;
|
||||
use crate::file_fetcher::CliFileFetcher;
|
||||
use crate::sys::CliSys;
|
||||
use crate::util::fs::canonicalize_path_maybe_not_exists;
|
||||
use crate::version;
|
||||
|
||||
use deno_config::deno_json::FmtConfig;
|
||||
use deno_config::deno_json::LintConfig;
|
||||
use deno_config::deno_json::TestConfig;
|
||||
|
||||
pub fn npm_registry_url() -> &'static Url {
|
||||
static NPM_REGISTRY_DEFAULT_URL: Lazy<Url> = Lazy::new(|| {
|
||||
let env_var_name = "NPM_CONFIG_REGISTRY";
|
||||
|
@ -606,7 +607,8 @@ pub fn create_default_npmrc() -> Arc<ResolvedNpmRc> {
|
|||
})
|
||||
}
|
||||
|
||||
#[derive(Error, Debug, Clone)]
|
||||
#[derive(Error, Debug, Clone, deno_error::JsError)]
|
||||
#[class(generic)]
|
||||
pub enum RootCertStoreLoadError {
|
||||
#[error(
|
||||
"Unknown certificate store \"{0}\" specified (allowed: \"system,mozilla\")"
|
||||
|
@ -717,7 +719,7 @@ pub enum NpmProcessStateKind {
|
|||
}
|
||||
|
||||
static NPM_PROCESS_STATE: Lazy<Option<NpmProcessState>> = Lazy::new(|| {
|
||||
use deno_runtime::ops::process::NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME;
|
||||
use deno_runtime::deno_process::NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME;
|
||||
let fd = std::env::var(NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME).ok()?;
|
||||
std::env::remove_var(NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME);
|
||||
let fd = fd.parse::<usize>().ok()?;
|
||||
|
@ -768,7 +770,7 @@ pub struct CliOptions {
|
|||
maybe_external_import_map: Option<(PathBuf, serde_json::Value)>,
|
||||
overrides: CliOptionOverrides,
|
||||
pub start_dir: Arc<WorkspaceDirectory>,
|
||||
pub deno_dir_provider: Arc<DenoDirProvider>,
|
||||
pub deno_dir_provider: Arc<DenoDirProvider<CliSys>>,
|
||||
}
|
||||
|
||||
impl CliOptions {
|
||||
|
@ -841,8 +843,6 @@ impl CliOptions {
|
|||
} else {
|
||||
&[]
|
||||
};
|
||||
let config_parse_options =
|
||||
deno_config::deno_json::ConfigParseOptions::default();
|
||||
let discover_pkg_json = flags.config_flag != ConfigFlag::Disabled
|
||||
&& !flags.no_npm
|
||||
&& !has_flag_env_var("DENO_NO_PACKAGE_JSON");
|
||||
|
@ -853,7 +853,6 @@ impl CliOptions {
|
|||
deno_json_cache: None,
|
||||
pkg_json_cache: Some(&node_resolver::PackageJsonThreadLocalCache),
|
||||
workspace_cache: None,
|
||||
config_parse_options,
|
||||
additional_config_file_names,
|
||||
discover_pkg_json,
|
||||
maybe_vendor_override,
|
||||
|
@ -1102,11 +1101,11 @@ impl CliOptions {
|
|||
}
|
||||
};
|
||||
Ok(self.workspace().create_resolver(
|
||||
&CliSys::default(),
|
||||
CreateResolverOptions {
|
||||
pkg_json_dep_resolution,
|
||||
specified_import_map: cli_arg_specified_import_map,
|
||||
},
|
||||
|path| Ok(std::fs::read_to_string(path)?),
|
||||
)?)
|
||||
}
|
||||
|
||||
|
@ -1230,6 +1229,16 @@ impl CliOptions {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn resolve_storage_key_resolver(&self) -> StorageKeyResolver {
|
||||
if let Some(location) = &self.flags.location {
|
||||
StorageKeyResolver::from_flag(location)
|
||||
} else if let Some(deno_json) = self.start_dir.maybe_deno_json() {
|
||||
StorageKeyResolver::from_config_file_url(&deno_json.specifier)
|
||||
} else {
|
||||
StorageKeyResolver::new_use_main_module()
|
||||
}
|
||||
}
|
||||
|
||||
// If the main module should be treated as being in an npm package.
|
||||
// This is triggered via a secret environment variable which is used
|
||||
// for functionality like child_process.fork. Users should NOT depend
|
||||
|
@ -1248,11 +1257,14 @@ impl CliOptions {
|
|||
|
||||
pub fn node_modules_dir(
|
||||
&self,
|
||||
) -> Result<Option<NodeModulesDirMode>, AnyError> {
|
||||
) -> Result<
|
||||
Option<NodeModulesDirMode>,
|
||||
deno_config::deno_json::NodeModulesDirParseError,
|
||||
> {
|
||||
if let Some(flag) = self.flags.node_modules_dir {
|
||||
return Ok(Some(flag));
|
||||
}
|
||||
self.workspace().node_modules_dir().map_err(Into::into)
|
||||
self.workspace().node_modules_dir()
|
||||
}
|
||||
|
||||
pub fn vendor_dir_path(&self) -> Option<&PathBuf> {
|
||||
|
@ -1262,7 +1274,7 @@ impl CliOptions {
|
|||
pub fn resolve_ts_config_for_emit(
|
||||
&self,
|
||||
config_type: TsConfigType,
|
||||
) -> Result<TsConfigForEmit, AnyError> {
|
||||
) -> Result<TsConfigForEmit, ConfigFileError> {
|
||||
self.workspace().resolve_ts_config_for_emit(config_type)
|
||||
}
|
||||
|
||||
|
@ -1291,7 +1303,7 @@ impl CliOptions {
|
|||
|
||||
pub fn to_compiler_option_types(
|
||||
&self,
|
||||
) -> Result<Vec<deno_graph::ReferrerImports>, AnyError> {
|
||||
) -> Result<Vec<deno_graph::ReferrerImports>, serde_json::Error> {
|
||||
self
|
||||
.workspace()
|
||||
.to_compiler_option_types()
|
||||
|
@ -1528,20 +1540,100 @@ impl CliOptions {
|
|||
self.flags.no_npm
|
||||
}
|
||||
|
||||
pub fn permission_flags(&self) -> &PermissionFlags {
|
||||
&self.flags.permissions
|
||||
}
|
||||
|
||||
pub fn permissions_options(&self) -> PermissionsOptions {
|
||||
fn files_to_urls(files: &[String]) -> Vec<Cow<'_, Url>> {
|
||||
files
|
||||
.iter()
|
||||
.filter_map(|f| Url::parse(f).ok().map(Cow::Owned))
|
||||
.collect()
|
||||
// bury this in here to ensure people use cli_options.permissions_options()
|
||||
fn flags_to_options(flags: &PermissionFlags) -> PermissionsOptions {
|
||||
fn handle_allow<T: Default>(
|
||||
allow_all: bool,
|
||||
value: Option<T>,
|
||||
) -> Option<T> {
|
||||
if allow_all {
|
||||
assert!(value.is_none());
|
||||
Some(T::default())
|
||||
} else {
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
PermissionsOptions {
|
||||
allow_all: flags.allow_all,
|
||||
allow_env: handle_allow(flags.allow_all, flags.allow_env.clone()),
|
||||
deny_env: flags.deny_env.clone(),
|
||||
allow_net: handle_allow(flags.allow_all, flags.allow_net.clone()),
|
||||
deny_net: flags.deny_net.clone(),
|
||||
allow_ffi: handle_allow(flags.allow_all, flags.allow_ffi.clone()),
|
||||
deny_ffi: flags.deny_ffi.clone(),
|
||||
allow_read: handle_allow(flags.allow_all, flags.allow_read.clone()),
|
||||
deny_read: flags.deny_read.clone(),
|
||||
allow_run: handle_allow(flags.allow_all, flags.allow_run.clone()),
|
||||
deny_run: flags.deny_run.clone(),
|
||||
allow_sys: handle_allow(flags.allow_all, flags.allow_sys.clone()),
|
||||
deny_sys: flags.deny_sys.clone(),
|
||||
allow_write: handle_allow(flags.allow_all, flags.allow_write.clone()),
|
||||
deny_write: flags.deny_write.clone(),
|
||||
allow_import: handle_allow(flags.allow_all, flags.allow_import.clone()),
|
||||
prompt: !resolve_no_prompt(flags),
|
||||
}
|
||||
}
|
||||
|
||||
// get a list of urls to imply for --allow-import
|
||||
let cli_arg_urls = self
|
||||
let mut permissions_options = flags_to_options(&self.flags.permissions);
|
||||
self.augment_import_permissions(&mut permissions_options);
|
||||
permissions_options
|
||||
}
|
||||
|
||||
fn augment_import_permissions(&self, options: &mut PermissionsOptions) {
|
||||
// do not add if the user specified --allow-all or --allow-import
|
||||
if !options.allow_all && options.allow_import.is_none() {
|
||||
options.allow_import = Some(self.implicit_allow_import());
|
||||
}
|
||||
}
|
||||
|
||||
fn implicit_allow_import(&self) -> Vec<String> {
|
||||
// allow importing from anywhere when using cached only
|
||||
if self.cache_setting() == CacheSetting::Only {
|
||||
vec![] // allow all imports
|
||||
} else {
|
||||
// implicitly allow some trusted hosts and the CLI arg urls
|
||||
let cli_arg_urls = self.get_cli_arg_urls();
|
||||
let builtin_allowed_import_hosts = [
|
||||
"jsr.io:443",
|
||||
"deno.land:443",
|
||||
"esm.sh:443",
|
||||
"cdn.jsdelivr.net:443",
|
||||
"raw.githubusercontent.com:443",
|
||||
"gist.githubusercontent.com:443",
|
||||
];
|
||||
let mut imports = Vec::with_capacity(
|
||||
builtin_allowed_import_hosts.len() + cli_arg_urls.len() + 1,
|
||||
);
|
||||
imports
|
||||
.extend(builtin_allowed_import_hosts.iter().map(|s| s.to_string()));
|
||||
// also add the JSR_URL env var
|
||||
if let Some(jsr_host) = allow_import_host_from_url(jsr_url()) {
|
||||
if jsr_host != "jsr.io:443" {
|
||||
imports.push(jsr_host);
|
||||
}
|
||||
}
|
||||
// include the cli arg urls
|
||||
for url in cli_arg_urls {
|
||||
if let Some(host) = allow_import_host_from_url(&url) {
|
||||
imports.push(host);
|
||||
}
|
||||
}
|
||||
imports
|
||||
}
|
||||
}
|
||||
|
||||
fn get_cli_arg_urls(&self) -> Vec<Cow<'_, Url>> {
|
||||
fn files_to_urls(files: &[String]) -> Vec<Cow<'_, Url>> {
|
||||
files.iter().filter_map(|f| file_to_url(f)).collect()
|
||||
}
|
||||
|
||||
fn file_to_url(file: &str) -> Option<Cow<'_, Url>> {
|
||||
Url::parse(file).ok().map(Cow::Owned)
|
||||
}
|
||||
|
||||
self
|
||||
.resolve_main_module()
|
||||
.ok()
|
||||
.map(|url| vec![Cow::Borrowed(url)])
|
||||
|
@ -1553,18 +1645,18 @@ impl CliOptions {
|
|||
Some(files_to_urls(&check_flags.files))
|
||||
}
|
||||
DenoSubcommand::Install(InstallFlags::Global(flags)) => {
|
||||
Url::parse(&flags.module_url)
|
||||
.ok()
|
||||
.map(|url| vec![Cow::Owned(url)])
|
||||
file_to_url(&flags.module_url).map(|url| vec![url])
|
||||
}
|
||||
DenoSubcommand::Doc(DocFlags {
|
||||
source_files: DocSourceFileFlag::Paths(paths),
|
||||
..
|
||||
}) => Some(files_to_urls(paths)),
|
||||
DenoSubcommand::Info(InfoFlags {
|
||||
file: Some(file), ..
|
||||
}) => file_to_url(file).map(|url| vec![url]),
|
||||
_ => None,
|
||||
})
|
||||
.unwrap_or_default();
|
||||
self.flags.permissions.to_options(&cli_arg_urls)
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn reload_flag(&self) -> bool {
|
||||
|
@ -1791,7 +1883,7 @@ fn resolve_node_modules_folder(
|
|||
cwd: &Path,
|
||||
flags: &Flags,
|
||||
workspace: &Workspace,
|
||||
deno_dir_provider: &Arc<DenoDirProvider>,
|
||||
deno_dir_provider: &Arc<DenoDirProvider<CliSys>>,
|
||||
) -> Result<Option<PathBuf>, AnyError> {
|
||||
fn resolve_from_root(root_folder: &FolderConfigs, cwd: &Path) -> PathBuf {
|
||||
root_folder
|
||||
|
@ -1895,63 +1987,11 @@ fn resolve_import_map_specifier(
|
|||
}
|
||||
}
|
||||
|
||||
pub struct StorageKeyResolver(Option<Option<String>>);
|
||||
|
||||
impl StorageKeyResolver {
|
||||
pub fn from_options(options: &CliOptions) -> Self {
|
||||
Self(if let Some(location) = &options.flags.location {
|
||||
// if a location is set, then the ascii serialization of the location is
|
||||
// used, unless the origin is opaque, and then no storage origin is set, as
|
||||
// we can't expect the origin to be reproducible
|
||||
let storage_origin = location.origin();
|
||||
if storage_origin.is_tuple() {
|
||||
Some(Some(storage_origin.ascii_serialization()))
|
||||
} else {
|
||||
Some(None)
|
||||
}
|
||||
} else {
|
||||
// otherwise we will use the path to the config file or None to
|
||||
// fall back to using the main module's path
|
||||
options
|
||||
.start_dir
|
||||
.maybe_deno_json()
|
||||
.map(|config_file| Some(config_file.specifier.to_string()))
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates a storage key resolver that will always resolve to being empty.
|
||||
pub fn empty() -> Self {
|
||||
Self(Some(None))
|
||||
}
|
||||
|
||||
/// Resolves the storage key to use based on the current flags, config, or main module.
|
||||
pub fn resolve_storage_key(
|
||||
&self,
|
||||
main_module: &ModuleSpecifier,
|
||||
) -> Option<String> {
|
||||
// use the stored value or fall back to using the path of the main module.
|
||||
if let Some(maybe_value) = &self.0 {
|
||||
maybe_value.clone()
|
||||
} else {
|
||||
Some(main_module.to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolves the no_prompt value based on the cli flags and environment.
|
||||
pub fn resolve_no_prompt(flags: &PermissionFlags) -> bool {
|
||||
flags.no_prompt || has_flag_env_var("DENO_NO_PROMPT")
|
||||
}
|
||||
|
||||
pub fn has_trace_permissions_enabled() -> bool {
|
||||
has_flag_env_var("DENO_TRACE_PERMISSIONS")
|
||||
}
|
||||
|
||||
pub fn has_flag_env_var(name: &str) -> bool {
|
||||
let value = env::var(name);
|
||||
matches!(value.as_ref().map(|s| s.as_str()), Ok("1"))
|
||||
}
|
||||
|
||||
pub fn npm_pkg_req_ref_to_binary_command(
|
||||
req_ref: &NpmPackageReqReference,
|
||||
) -> String {
|
||||
|
@ -2000,6 +2040,20 @@ fn load_env_variables_from_env_file(filename: Option<&Vec<String>>) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Gets the --allow-import host from the provided url
|
||||
fn allow_import_host_from_url(url: &Url) -> Option<String> {
|
||||
let host = url.host()?;
|
||||
if let Some(port) = url.port() {
|
||||
Some(format!("{}:{}", host, port))
|
||||
} else {
|
||||
match url.scheme() {
|
||||
"https" => Some(format!("{}:443", host)),
|
||||
"http" => Some(format!("{}:80", host)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum NpmCachingStrategy {
|
||||
Eager,
|
||||
|
@ -2007,7 +2061,7 @@ pub enum NpmCachingStrategy {
|
|||
Manual,
|
||||
}
|
||||
|
||||
pub(crate) fn otel_runtime_config() -> OtelRuntimeConfig {
|
||||
pub fn otel_runtime_config() -> OtelRuntimeConfig {
|
||||
OtelRuntimeConfig {
|
||||
runtime_name: Cow::Borrowed("deno"),
|
||||
runtime_version: Cow::Borrowed(crate::version::DENO_VERSION_INFO.deno),
|
||||
|
@ -2028,12 +2082,7 @@ mod test {
|
|||
let cwd = &std::env::current_dir().unwrap();
|
||||
let config_specifier =
|
||||
ModuleSpecifier::parse("file:///deno/deno.jsonc").unwrap();
|
||||
let config_file = ConfigFile::new(
|
||||
config_text,
|
||||
config_specifier,
|
||||
&deno_config::deno_json::ConfigParseOptions::default(),
|
||||
)
|
||||
.unwrap();
|
||||
let config_file = ConfigFile::new(config_text, config_specifier).unwrap();
|
||||
let actual = resolve_import_map_specifier(
|
||||
Some("import-map.json"),
|
||||
Some(&config_file),
|
||||
|
@ -2052,12 +2101,7 @@ mod test {
|
|||
let config_text = r#"{}"#;
|
||||
let config_specifier =
|
||||
ModuleSpecifier::parse("file:///deno/deno.jsonc").unwrap();
|
||||
let config_file = ConfigFile::new(
|
||||
config_text,
|
||||
config_specifier,
|
||||
&deno_config::deno_json::ConfigParseOptions::default(),
|
||||
)
|
||||
.unwrap();
|
||||
let config_file = ConfigFile::new(config_text, config_specifier).unwrap();
|
||||
let actual = resolve_import_map_specifier(
|
||||
None,
|
||||
Some(&config_file),
|
||||
|
@ -2076,27 +2120,6 @@ mod test {
|
|||
assert_eq!(actual, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn storage_key_resolver_test() {
|
||||
let resolver = StorageKeyResolver(None);
|
||||
let specifier = ModuleSpecifier::parse("file:///a.ts").unwrap();
|
||||
assert_eq!(
|
||||
resolver.resolve_storage_key(&specifier),
|
||||
Some(specifier.to_string())
|
||||
);
|
||||
let resolver = StorageKeyResolver(Some(None));
|
||||
assert_eq!(resolver.resolve_storage_key(&specifier), None);
|
||||
let resolver = StorageKeyResolver(Some(Some("value".to_string())));
|
||||
assert_eq!(
|
||||
resolver.resolve_storage_key(&specifier),
|
||||
Some("value".to_string())
|
||||
);
|
||||
|
||||
// test empty
|
||||
let resolver = StorageKeyResolver::empty();
|
||||
assert_eq!(resolver.resolve_storage_key(&specifier), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn jsr_urls() {
|
||||
let reg_url = jsr_url();
|
||||
|
@ -2104,4 +2127,26 @@ mod test {
|
|||
let reg_api_url = jsr_api_url();
|
||||
assert!(reg_api_url.as_str().ends_with('/'));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_allow_import_host_from_url() {
|
||||
fn parse(text: &str) -> Option<String> {
|
||||
allow_import_host_from_url(&Url::parse(text).unwrap())
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
parse("http://127.0.0.1:4250"),
|
||||
Some("127.0.0.1:4250".to_string())
|
||||
);
|
||||
assert_eq!(parse("http://jsr.io"), Some("jsr.io:80".to_string()));
|
||||
assert_eq!(
|
||||
parse("https://example.com"),
|
||||
Some("example.com:443".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
parse("http://example.com"),
|
||||
Some("example.com:80".to_string())
|
||||
);
|
||||
assert_eq!(parse("file:///example.com"), None);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
const cacheName = "cache-v1";
|
||||
const cache = await caches.open(cacheName);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
Deno.bench("echo deno", async () => {
|
||||
await new Deno.Command("echo", { args: ["deno"] }).output();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
// deno-lint-ignore-file no-console
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
// v8 builtin that's close to the upper bound non-NOPs
|
||||
Deno.bench("date_now", { n: 5e5 }, () => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
// deno-lint-ignore-file no-console no-process-globals
|
||||
|
||||
let [total, count] = typeof Deno !== "undefined"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
let total = 5;
|
||||
let current = "";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
/** @jsx h */
|
||||
import results from "./deno.json" assert { type: "json" };
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
// deno-lint-ignore-file no-console no-process-globals
|
||||
|
||||
let [total, count] = typeof Deno !== "undefined"
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
|
||||
use deno_core::serde::Deserialize;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_json::Value;
|
||||
use lsp_types::Uri;
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
use test_util::lsp::LspClientBuilder;
|
||||
use test_util::PathRef;
|
||||
use tower_lsp::lsp_types as lsp;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use deno_bench_util::bencher::benchmark_group;
|
||||
use deno_bench_util::bencher::benchmark_main;
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
#![allow(clippy::print_stdout)]
|
||||
#![allow(clippy::print_stderr)]
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::From;
|
||||
use std::env;
|
||||
|
@ -15,6 +12,10 @@ use std::path::PathBuf;
|
|||
use std::process::Command;
|
||||
use std::process::Stdio;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::Value;
|
||||
use test_util::PathRef;
|
||||
|
||||
mod lsp;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
import { loadTestLibrary } from "../../../tests/napi/common.js";
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
import { bench, run } from "mitata";
|
||||
import { createRequire } from "module";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
// deno-lint-ignore-file no-console no-process-globals
|
||||
|
||||
const queueMicrotask = globalThis.queueMicrotask || process.nextTick;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
// deno-lint-ignore-file no-console no-process-globals
|
||||
|
||||
let [total, count] = typeof Deno !== "undefined"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
// From https://github.com/just-js/benchmarks/tree/main/01-stdio
|
||||
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
//
|
||||
// From https://github.com/just-js/benchmarks/tree/main/01-stdio
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
const listener = Deno.listen({ port: 4500 });
|
||||
const response = new TextEncoder().encode(
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
// deno-lint-ignore-file no-console no-process-globals
|
||||
|
||||
const queueMicrotask = globalThis.queueMicrotask || process.nextTick;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
// deno-lint-ignore-file no-console no-process-globals
|
||||
|
||||
const queueMicrotask = globalThis.queueMicrotask || process.nextTick;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
// deno-lint-ignore-file no-console
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
// deno-lint-ignore-file no-console no-process-globals
|
||||
|
||||
const queueMicrotask = globalThis.queueMicrotask || process.nextTick;
|
||||
|
|
30
cli/build.rs
30
cli/build.rs
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
@ -8,17 +8,18 @@ use deno_runtime::*;
|
|||
mod shared;
|
||||
|
||||
mod ts {
|
||||
use super::*;
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op2;
|
||||
use deno_core::OpState;
|
||||
use serde::Serialize;
|
||||
use std::collections::HashMap;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use deno_core::op2;
|
||||
use deno_core::OpState;
|
||||
use deno_error::JsErrorBox;
|
||||
use serde::Serialize;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct BuildInfoResponse {
|
||||
|
@ -51,7 +52,7 @@ mod ts {
|
|||
fn op_script_version(
|
||||
_state: &mut OpState,
|
||||
#[string] _arg: &str,
|
||||
) -> Result<Option<String>, AnyError> {
|
||||
) -> Result<Option<String>, JsErrorBox> {
|
||||
Ok(Some("1".to_string()))
|
||||
}
|
||||
|
||||
|
@ -70,7 +71,7 @@ mod ts {
|
|||
fn op_load(
|
||||
state: &mut OpState,
|
||||
#[string] load_specifier: &str,
|
||||
) -> Result<LoadResponse, AnyError> {
|
||||
) -> Result<LoadResponse, JsErrorBox> {
|
||||
let op_crate_libs = state.borrow::<HashMap<&str, PathBuf>>();
|
||||
let path_dts = state.borrow::<PathBuf>();
|
||||
let re_asset = lazy_regex::regex!(r"asset:/{3}lib\.(\S+)\.d\.ts");
|
||||
|
@ -91,12 +92,15 @@ mod ts {
|
|||
// if it comes from an op crate, we were supplied with the path to the
|
||||
// file.
|
||||
let path = if let Some(op_crate_lib) = op_crate_libs.get(lib) {
|
||||
PathBuf::from(op_crate_lib).canonicalize()?
|
||||
PathBuf::from(op_crate_lib)
|
||||
.canonicalize()
|
||||
.map_err(JsErrorBox::from_err)?
|
||||
// otherwise we will generate the path ourself
|
||||
} else {
|
||||
path_dts.join(format!("lib.{lib}.d.ts"))
|
||||
};
|
||||
let data = std::fs::read_to_string(path)?;
|
||||
let data =
|
||||
std::fs::read_to_string(path).map_err(JsErrorBox::from_err)?;
|
||||
Ok(LoadResponse {
|
||||
data,
|
||||
version: "1".to_string(),
|
||||
|
@ -104,13 +108,13 @@ mod ts {
|
|||
script_kind: 3,
|
||||
})
|
||||
} else {
|
||||
Err(custom_error(
|
||||
Err(JsErrorBox::new(
|
||||
"InvalidSpecifier",
|
||||
format!("An invalid specifier was requested: {}", load_specifier),
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Err(custom_error(
|
||||
Err(JsErrorBox::new(
|
||||
"InvalidSpecifier",
|
||||
format!("An invalid specifier was requested: {}", load_specifier),
|
||||
))
|
||||
|
|
15
cli/cache/cache_db.rs
vendored
15
cli/cache/cache_db.rs
vendored
|
@ -1,4 +1,9 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::io::IsTerminal;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
|
@ -9,10 +14,6 @@ use deno_runtime::deno_webstorage::rusqlite::Connection;
|
|||
use deno_runtime::deno_webstorage::rusqlite::OptionalExtension;
|
||||
use deno_runtime::deno_webstorage::rusqlite::Params;
|
||||
use once_cell::sync::OnceCell;
|
||||
use std::io::IsTerminal;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::FastInsecureHasher;
|
||||
|
||||
|
@ -24,12 +25,12 @@ impl CacheDBHash {
|
|||
Self(hash)
|
||||
}
|
||||
|
||||
pub fn from_source(source: impl std::hash::Hash) -> Self {
|
||||
pub fn from_hashable(hashable: impl std::hash::Hash) -> Self {
|
||||
Self::new(
|
||||
// always write in the deno version just in case
|
||||
// the clearing on deno version change doesn't work
|
||||
FastInsecureHasher::new_deno_versioned()
|
||||
.write_hashable(source)
|
||||
.write_hashable(hashable)
|
||||
.finish(),
|
||||
)
|
||||
}
|
||||
|
|
9
cli/cache/caches.rs
vendored
9
cli/cache/caches.rs
vendored
|
@ -1,22 +1,23 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_lib::cache::DenoDirProvider;
|
||||
use once_cell::sync::OnceCell;
|
||||
|
||||
use super::cache_db::CacheDB;
|
||||
use super::cache_db::CacheDBConfiguration;
|
||||
use super::check::TYPE_CHECK_CACHE_DB;
|
||||
use super::code_cache::CODE_CACHE_DB;
|
||||
use super::deno_dir::DenoDirProvider;
|
||||
use super::fast_check::FAST_CHECK_CACHE_DB;
|
||||
use super::incremental::INCREMENTAL_CACHE_DB;
|
||||
use super::module_info::MODULE_INFO_CACHE_DB;
|
||||
use super::node::NODE_ANALYSIS_CACHE_DB;
|
||||
use crate::sys::CliSys;
|
||||
|
||||
pub struct Caches {
|
||||
dir_provider: Arc<DenoDirProvider>,
|
||||
dir_provider: Arc<DenoDirProvider<CliSys>>,
|
||||
fmt_incremental_cache_db: OnceCell<CacheDB>,
|
||||
lint_incremental_cache_db: OnceCell<CacheDB>,
|
||||
dep_analysis_db: OnceCell<CacheDB>,
|
||||
|
@ -27,7 +28,7 @@ pub struct Caches {
|
|||
}
|
||||
|
||||
impl Caches {
|
||||
pub fn new(dir: Arc<DenoDirProvider>) -> Self {
|
||||
pub fn new(dir: Arc<DenoDirProvider<CliSys>>) -> Self {
|
||||
Self {
|
||||
dir_provider: dir,
|
||||
fmt_incremental_cache_db: Default::default(),
|
||||
|
|
9
cli/cache/check.rs
vendored
9
cli/cache/check.rs
vendored
|
@ -1,12 +1,13 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_runtime::deno_webstorage::rusqlite::params;
|
||||
|
||||
use super::cache_db::CacheDB;
|
||||
use super::cache_db::CacheDBConfiguration;
|
||||
use super::cache_db::CacheDBHash;
|
||||
use super::cache_db::CacheFailure;
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_runtime::deno_webstorage::rusqlite::params;
|
||||
|
||||
pub static TYPE_CHECK_CACHE_DB: CacheDBConfiguration = CacheDBConfiguration {
|
||||
table_initializer: concat!(
|
||||
|
|
5
cli/cache/code_cache.rs
vendored
5
cli/cache/code_cache.rs
vendored
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -7,12 +7,11 @@ use deno_core::error::AnyError;
|
|||
use deno_runtime::code_cache;
|
||||
use deno_runtime::deno_webstorage::rusqlite::params;
|
||||
|
||||
use crate::worker::CliCodeCache;
|
||||
|
||||
use super::cache_db::CacheDB;
|
||||
use super::cache_db::CacheDBConfiguration;
|
||||
use super::cache_db::CacheDBHash;
|
||||
use super::cache_db::CacheFailure;
|
||||
use crate::worker::CliCodeCache;
|
||||
|
||||
pub static CODE_CACHE_DB: CacheDBConfiguration = CacheDBConfiguration {
|
||||
table_initializer: concat!(
|
||||
|
|
2
cli/cache/common.rs
vendored
2
cli/cache/common.rs
vendored
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::hash::Hasher;
|
||||
|
||||
|
|
12
cli/cache/emit.rs
vendored
12
cli/cache/emit.rs
vendored
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
|
@ -6,19 +6,20 @@ use deno_ast::ModuleSpecifier;
|
|||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::unsync::sync::AtomicFlag;
|
||||
use deno_lib::cache::DiskCache;
|
||||
|
||||
use super::DiskCache;
|
||||
use crate::sys::CliSys;
|
||||
|
||||
/// The cache that stores previously emitted files.
|
||||
#[derive(Debug)]
|
||||
pub struct EmitCache {
|
||||
disk_cache: DiskCache,
|
||||
disk_cache: DiskCache<CliSys>,
|
||||
emit_failed_flag: AtomicFlag,
|
||||
file_serializer: EmitFileSerializer,
|
||||
}
|
||||
|
||||
impl EmitCache {
|
||||
pub fn new(disk_cache: DiskCache) -> Self {
|
||||
pub fn new(disk_cache: DiskCache<CliSys>) -> Self {
|
||||
Self {
|
||||
disk_cache,
|
||||
emit_failed_flag: Default::default(),
|
||||
|
@ -159,9 +160,8 @@ impl EmitFileSerializer {
|
|||
mod test {
|
||||
use test_util::TempDir;
|
||||
|
||||
use crate::sys::CliSys;
|
||||
|
||||
use super::*;
|
||||
use crate::sys::CliSys;
|
||||
|
||||
#[test]
|
||||
pub fn emit_cache_general_use() {
|
||||
|
|
2
cli/cache/fast_check.rs
vendored
2
cli/cache/fast_check.rs
vendored
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_graph::FastCheckCacheItem;
|
||||
|
|
23
cli/cache/incremental.rs
vendored
23
cli/cache/incremental.rs
vendored
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
|
@ -34,12 +34,16 @@ pub static INCREMENTAL_CACHE_DB: CacheDBConfiguration = CacheDBConfiguration {
|
|||
pub struct IncrementalCache(IncrementalCacheInner);
|
||||
|
||||
impl IncrementalCache {
|
||||
pub fn new<TState: std::hash::Hash>(
|
||||
pub fn new(
|
||||
db: CacheDB,
|
||||
state: &TState,
|
||||
state_hash: CacheDBHash,
|
||||
initial_file_paths: &[PathBuf],
|
||||
) -> Self {
|
||||
IncrementalCache(IncrementalCacheInner::new(db, state, initial_file_paths))
|
||||
IncrementalCache(IncrementalCacheInner::new(
|
||||
db,
|
||||
state_hash,
|
||||
initial_file_paths,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn is_file_same(&self, file_path: &Path, file_text: &str) -> bool {
|
||||
|
@ -67,12 +71,11 @@ struct IncrementalCacheInner {
|
|||
}
|
||||
|
||||
impl IncrementalCacheInner {
|
||||
pub fn new<TState: std::hash::Hash>(
|
||||
pub fn new(
|
||||
db: CacheDB,
|
||||
state: &TState,
|
||||
state_hash: CacheDBHash,
|
||||
initial_file_paths: &[PathBuf],
|
||||
) -> Self {
|
||||
let state_hash = CacheDBHash::from_source(state);
|
||||
let sql_cache = SqlIncrementalCache::new(db, state_hash);
|
||||
Self::from_sql_incremental_cache(sql_cache, initial_file_paths)
|
||||
}
|
||||
|
@ -112,13 +115,13 @@ impl IncrementalCacheInner {
|
|||
|
||||
pub fn is_file_same(&self, file_path: &Path, file_text: &str) -> bool {
|
||||
match self.previous_hashes.get(file_path) {
|
||||
Some(hash) => *hash == CacheDBHash::from_source(file_text),
|
||||
Some(hash) => *hash == CacheDBHash::from_hashable(file_text),
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_file(&self, file_path: &Path, file_text: &str) {
|
||||
let hash = CacheDBHash::from_source(file_text);
|
||||
let hash = CacheDBHash::from_hashable(file_text);
|
||||
if let Some(previous_hash) = self.previous_hashes.get(file_path) {
|
||||
if *previous_hash == hash {
|
||||
return; // do not bother updating the db file because nothing has changed
|
||||
|
@ -262,7 +265,7 @@ mod test {
|
|||
let sql_cache = SqlIncrementalCache::new(conn, CacheDBHash::new(1));
|
||||
let file_path = PathBuf::from("/mod.ts");
|
||||
let file_text = "test";
|
||||
let file_hash = CacheDBHash::from_source(file_text);
|
||||
let file_hash = CacheDBHash::from_hashable(file_text);
|
||||
sql_cache.set_source_hash(&file_path, file_hash).unwrap();
|
||||
let cache = IncrementalCacheInner::from_sql_incremental_cache(
|
||||
sql_cache,
|
||||
|
|
71
cli/cache/mod.rs
vendored
71
cli/cache/mod.rs
vendored
|
@ -1,4 +1,23 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_ast::MediaType;
|
||||
use deno_cache_dir::file_fetcher::CacheSetting;
|
||||
use deno_cache_dir::file_fetcher::FetchNoFollowErrorKind;
|
||||
use deno_cache_dir::file_fetcher::FileOrRedirect;
|
||||
use deno_core::futures;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_graph::source::CacheInfo;
|
||||
use deno_graph::source::LoadFuture;
|
||||
use deno_graph::source::LoadResponse;
|
||||
use deno_graph::source::Loader;
|
||||
use deno_resolver::npm::DenoInNpmPackageChecker;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
use node_resolver::InNpmPackageChecker;
|
||||
|
||||
use crate::args::jsr_url;
|
||||
use crate::file_fetcher::CliFetchNoFollowErrorKind;
|
||||
|
@ -7,31 +26,11 @@ use crate::file_fetcher::FetchNoFollowOptions;
|
|||
use crate::file_fetcher::FetchPermissionsOptionRef;
|
||||
use crate::sys::CliSys;
|
||||
|
||||
use deno_ast::MediaType;
|
||||
use deno_cache_dir::file_fetcher::CacheSetting;
|
||||
use deno_cache_dir::file_fetcher::FetchNoFollowErrorKind;
|
||||
use deno_cache_dir::file_fetcher::FileOrRedirect;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_graph::source::CacheInfo;
|
||||
use deno_graph::source::LoadFuture;
|
||||
use deno_graph::source::LoadResponse;
|
||||
use deno_graph::source::Loader;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
use node_resolver::InNpmPackageChecker;
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
mod cache_db;
|
||||
mod caches;
|
||||
mod check;
|
||||
mod code_cache;
|
||||
mod common;
|
||||
mod deno_dir;
|
||||
mod disk_cache;
|
||||
mod emit;
|
||||
mod fast_check;
|
||||
mod incremental;
|
||||
|
@ -44,9 +43,8 @@ pub use caches::Caches;
|
|||
pub use check::TypeCheckCache;
|
||||
pub use code_cache::CodeCache;
|
||||
pub use common::FastInsecureHasher;
|
||||
pub use deno_dir::DenoDir;
|
||||
pub use deno_dir::DenoDirProvider;
|
||||
pub use disk_cache::DiskCache;
|
||||
/// Permissions used to save a file in the disk caches.
|
||||
pub use deno_cache_dir::CACHE_PERM;
|
||||
pub use emit::EmitCache;
|
||||
pub use fast_check::FastCheckCache;
|
||||
pub use incremental::IncrementalCache;
|
||||
|
@ -55,13 +53,11 @@ pub use node::NodeAnalysisCache;
|
|||
pub use parsed_source::LazyGraphSourceParser;
|
||||
pub use parsed_source::ParsedSourceCache;
|
||||
|
||||
/// Permissions used to save a file in the disk caches.
|
||||
pub use deno_cache_dir::CACHE_PERM;
|
||||
|
||||
pub type GlobalHttpCache = deno_cache_dir::GlobalHttpCache<CliSys>;
|
||||
pub type LocalHttpCache = deno_cache_dir::LocalHttpCache<CliSys>;
|
||||
pub type LocalLspHttpCache = deno_cache_dir::LocalLspHttpCache<CliSys>;
|
||||
pub use deno_cache_dir::HttpCache;
|
||||
use deno_error::JsErrorBox;
|
||||
|
||||
pub struct FetchCacherOptions {
|
||||
pub file_header_overrides: HashMap<ModuleSpecifier, HashMap<String, String>>,
|
||||
|
@ -76,7 +72,7 @@ pub struct FetchCacher {
|
|||
pub file_header_overrides: HashMap<ModuleSpecifier, HashMap<String, String>>,
|
||||
file_fetcher: Arc<CliFileFetcher>,
|
||||
global_http_cache: Arc<GlobalHttpCache>,
|
||||
in_npm_pkg_checker: Arc<dyn InNpmPackageChecker>,
|
||||
in_npm_pkg_checker: DenoInNpmPackageChecker,
|
||||
module_info_cache: Arc<ModuleInfoCache>,
|
||||
permissions: PermissionsContainer,
|
||||
sys: CliSys,
|
||||
|
@ -88,7 +84,7 @@ impl FetchCacher {
|
|||
pub fn new(
|
||||
file_fetcher: Arc<CliFileFetcher>,
|
||||
global_http_cache: Arc<GlobalHttpCache>,
|
||||
in_npm_pkg_checker: Arc<dyn InNpmPackageChecker>,
|
||||
in_npm_pkg_checker: DenoInNpmPackageChecker,
|
||||
module_info_cache: Arc<ModuleInfoCache>,
|
||||
sys: CliSys,
|
||||
options: FetchCacherOptions,
|
||||
|
@ -194,9 +190,9 @@ impl Loader for FetchCacher {
|
|||
LoaderCacheSetting::Use => None,
|
||||
LoaderCacheSetting::Reload => {
|
||||
if matches!(file_fetcher.cache_setting(), CacheSetting::Only) {
|
||||
return Err(deno_core::anyhow::anyhow!(
|
||||
return Err(deno_graph::source::LoadError::Other(Arc::new(JsErrorBox::generic(
|
||||
"Could not resolve version constraint using only cached data. Try running again without --cached-only"
|
||||
));
|
||||
))));
|
||||
}
|
||||
Some(CacheSetting::ReloadAll)
|
||||
}
|
||||
|
@ -262,28 +258,27 @@ impl Loader for FetchCacher {
|
|||
FetchNoFollowErrorKind::CacheSave { .. } |
|
||||
FetchNoFollowErrorKind::UnsupportedScheme { .. } |
|
||||
FetchNoFollowErrorKind::RedirectHeaderParse { .. } |
|
||||
FetchNoFollowErrorKind::InvalidHeader { .. } => Err(AnyError::from(err)),
|
||||
FetchNoFollowErrorKind::InvalidHeader { .. } => Err(deno_graph::source::LoadError::Other(Arc::new(JsErrorBox::from_err(err)))),
|
||||
FetchNoFollowErrorKind::NotCached { .. } => {
|
||||
if options.cache_setting == LoaderCacheSetting::Only {
|
||||
Ok(None)
|
||||
} else {
|
||||
Err(AnyError::from(err))
|
||||
Err(deno_graph::source::LoadError::Other(Arc::new(JsErrorBox::from_err(err))))
|
||||
}
|
||||
},
|
||||
FetchNoFollowErrorKind::ChecksumIntegrity(err) => {
|
||||
// convert to the equivalent deno_graph error so that it
|
||||
// enhances it if this is passed to deno_graph
|
||||
Err(
|
||||
deno_graph::source::ChecksumIntegrityError {
|
||||
deno_graph::source::LoadError::ChecksumIntegrity(deno_graph::source::ChecksumIntegrityError {
|
||||
actual: err.actual,
|
||||
expected: err.expected,
|
||||
}
|
||||
.into(),
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
CliFetchNoFollowErrorKind::PermissionCheck(permission_check_error) => Err(AnyError::from(permission_check_error)),
|
||||
CliFetchNoFollowErrorKind::PermissionCheck(permission_check_error) => Err(deno_graph::source::LoadError::Other(Arc::new(JsErrorBox::from_err(permission_check_error)))),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -298,7 +293,7 @@ impl Loader for FetchCacher {
|
|||
module_info: &deno_graph::ModuleInfo,
|
||||
) {
|
||||
log::debug!("Caching module info for {}", specifier);
|
||||
let source_hash = CacheDBHash::from_source(source);
|
||||
let source_hash = CacheDBHash::from_hashable(source);
|
||||
let result = self.module_info_cache.set_module_info(
|
||||
specifier,
|
||||
media_type,
|
||||
|
|
6
cli/cache/module_info.rs
vendored
6
cli/cache/module_info.rs
vendored
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -194,7 +194,7 @@ impl<'a> ModuleInfoCacheModuleAnalyzer<'a> {
|
|||
source: &Arc<str>,
|
||||
) -> Result<ModuleInfo, deno_ast::ParseDiagnostic> {
|
||||
// attempt to load from the cache
|
||||
let source_hash = CacheDBHash::from_source(source);
|
||||
let source_hash = CacheDBHash::from_hashable(source);
|
||||
if let Some(info) =
|
||||
self.load_cached_module_info(specifier, media_type, source_hash)
|
||||
{
|
||||
|
@ -228,7 +228,7 @@ impl<'a> deno_graph::ModuleAnalyzer for ModuleInfoCacheModuleAnalyzer<'a> {
|
|||
media_type: MediaType,
|
||||
) -> Result<ModuleInfo, deno_ast::ParseDiagnostic> {
|
||||
// attempt to load from the cache
|
||||
let source_hash = CacheDBHash::from_source(&source);
|
||||
let source_hash = CacheDBHash::from_hashable(&source);
|
||||
if let Some(info) =
|
||||
self.load_cached_module_info(specifier, media_type, source_hash)
|
||||
{
|
||||
|
|
5
cli/cache/node.rs
vendored
5
cli/cache/node.rs
vendored
|
@ -1,15 +1,14 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::serde_json;
|
||||
use deno_runtime::deno_webstorage::rusqlite::params;
|
||||
|
||||
use crate::node::CliCjsAnalysis;
|
||||
|
||||
use super::cache_db::CacheDB;
|
||||
use super::cache_db::CacheDBConfiguration;
|
||||
use super::cache_db::CacheFailure;
|
||||
use super::CacheDBHash;
|
||||
use crate::node::CliCjsAnalysis;
|
||||
|
||||
pub static NODE_ANALYSIS_CACHE_DB: CacheDBConfiguration =
|
||||
CacheDBConfiguration {
|
||||
|
|
2
cli/cache/parsed_source.rs
vendored
2
cli/cache/parsed_source.rs
vendored
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
/// <https://chromedevtools.github.io/devtools-protocol/tot/>
|
||||
use deno_core::serde_json::Value;
|
||||
|
|
65
cli/emit.rs
65
cli/emit.rs
|
@ -1,9 +1,6 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use crate::cache::EmitCache;
|
||||
use crate::cache::FastInsecureHasher;
|
||||
use crate::cache::ParsedSourceCache;
|
||||
use crate::resolver::CjsTracker;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_ast::EmittedSourceText;
|
||||
use deno_ast::ModuleKind;
|
||||
|
@ -14,18 +11,24 @@ use deno_ast::SourceRangedForSpanned;
|
|||
use deno_ast::TranspileModuleOptions;
|
||||
use deno_ast::TranspileResult;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::CoreError;
|
||||
use deno_core::futures::stream::FuturesUnordered;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::futures::StreamExt;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_graph::MediaType;
|
||||
use deno_graph::Module;
|
||||
use deno_graph::ModuleGraph;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::cache::EmitCache;
|
||||
use crate::cache::FastInsecureHasher;
|
||||
use crate::cache::ParsedSourceCache;
|
||||
use crate::resolver::CliCjsTracker;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Emitter {
|
||||
cjs_tracker: Arc<CjsTracker>,
|
||||
cjs_tracker: Arc<CliCjsTracker>,
|
||||
emit_cache: Arc<EmitCache>,
|
||||
parsed_source_cache: Arc<ParsedSourceCache>,
|
||||
transpile_and_emit_options:
|
||||
|
@ -36,7 +39,7 @@ pub struct Emitter {
|
|||
|
||||
impl Emitter {
|
||||
pub fn new(
|
||||
cjs_tracker: Arc<CjsTracker>,
|
||||
cjs_tracker: Arc<CliCjsTracker>,
|
||||
emit_cache: Arc<EmitCache>,
|
||||
parsed_source_cache: Arc<ParsedSourceCache>,
|
||||
transpile_options: deno_ast::TranspileOptions,
|
||||
|
@ -123,7 +126,7 @@ impl Emitter {
|
|||
let transpiled_source = deno_core::unsync::spawn_blocking({
|
||||
let specifier = specifier.clone();
|
||||
let source = source.clone();
|
||||
move || -> Result<_, AnyError> {
|
||||
move || {
|
||||
EmitParsedSourceHelper::transpile(
|
||||
&parsed_source_cache,
|
||||
&specifier,
|
||||
|
@ -154,7 +157,7 @@ impl Emitter {
|
|||
media_type: MediaType,
|
||||
module_kind: deno_ast::ModuleKind,
|
||||
source: &Arc<str>,
|
||||
) -> Result<String, AnyError> {
|
||||
) -> Result<String, EmitParsedSourceHelperError> {
|
||||
// Note: keep this in sync with the async version above
|
||||
let helper = EmitParsedSourceHelper(self);
|
||||
match helper.pre_emit_parsed_source(specifier, module_kind, source) {
|
||||
|
@ -209,7 +212,7 @@ impl Emitter {
|
|||
pub async fn load_and_emit_for_hmr(
|
||||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
) -> Result<String, AnyError> {
|
||||
) -> Result<String, CoreError> {
|
||||
let media_type = MediaType::from_specifier(specifier);
|
||||
let source_code = tokio::fs::read_to_string(
|
||||
ModuleSpecifier::to_file_path(specifier).unwrap(),
|
||||
|
@ -224,17 +227,21 @@ impl Emitter {
|
|||
let source_arc: Arc<str> = source_code.into();
|
||||
let parsed_source = self
|
||||
.parsed_source_cache
|
||||
.remove_or_parse_module(specifier, source_arc, media_type)?;
|
||||
.remove_or_parse_module(specifier, source_arc, media_type)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
// HMR doesn't work with embedded source maps for some reason, so set
|
||||
// the option to not use them (though you should test this out because
|
||||
// this statement is probably wrong)
|
||||
let mut options = self.transpile_and_emit_options.1.clone();
|
||||
options.source_map = SourceMapOption::None;
|
||||
let is_cjs = self.cjs_tracker.is_cjs_with_known_is_script(
|
||||
specifier,
|
||||
media_type,
|
||||
parsed_source.compute_is_script(),
|
||||
)?;
|
||||
let is_cjs = self
|
||||
.cjs_tracker
|
||||
.is_cjs_with_known_is_script(
|
||||
specifier,
|
||||
media_type,
|
||||
parsed_source.compute_is_script(),
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
let transpiled_source = parsed_source
|
||||
.transpile(
|
||||
&self.transpile_and_emit_options.0,
|
||||
|
@ -242,7 +249,8 @@ impl Emitter {
|
|||
module_kind: Some(ModuleKind::from_is_cjs(is_cjs)),
|
||||
},
|
||||
&options,
|
||||
)?
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)?
|
||||
.into_source();
|
||||
Ok(transpiled_source.text)
|
||||
}
|
||||
|
@ -281,6 +289,19 @@ enum PreEmitResult {
|
|||
NotCached { source_hash: u64 },
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum EmitParsedSourceHelperError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
ParseDiagnostic(#[from] deno_ast::ParseDiagnostic),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Transpile(#[from] deno_ast::TranspileError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Other(#[from] JsErrorBox),
|
||||
}
|
||||
|
||||
/// Helper to share code between async and sync emit_parsed_source methods.
|
||||
struct EmitParsedSourceHelper<'a>(&'a Emitter);
|
||||
|
||||
|
@ -310,7 +331,7 @@ impl<'a> EmitParsedSourceHelper<'a> {
|
|||
source: Arc<str>,
|
||||
transpile_options: &deno_ast::TranspileOptions,
|
||||
emit_options: &deno_ast::EmitOptions,
|
||||
) -> Result<EmittedSourceText, AnyError> {
|
||||
) -> Result<EmittedSourceText, EmitParsedSourceHelperError> {
|
||||
// nothing else needs the parsed source at this point, so remove from
|
||||
// the cache in order to not transpile owned
|
||||
let parsed_source = parsed_source_cache
|
||||
|
@ -350,7 +371,7 @@ impl<'a> EmitParsedSourceHelper<'a> {
|
|||
// todo(dsherret): this is a temporary measure until we have swc erroring for this
|
||||
fn ensure_no_import_assertion(
|
||||
parsed_source: &deno_ast::ParsedSource,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), JsErrorBox> {
|
||||
fn has_import_assertion(text: &str) -> bool {
|
||||
// good enough
|
||||
text.contains(" assert ") && !text.contains(" with ")
|
||||
|
@ -359,7 +380,7 @@ fn ensure_no_import_assertion(
|
|||
fn create_err(
|
||||
parsed_source: &deno_ast::ParsedSource,
|
||||
range: SourceRange,
|
||||
) -> AnyError {
|
||||
) -> JsErrorBox {
|
||||
let text_info = parsed_source.text_info_lazy();
|
||||
let loc = text_info.line_and_column_display(range.start);
|
||||
let mut msg = "Import assertions are deprecated. Use `with` keyword, instead of 'assert' keyword.".to_string();
|
||||
|
@ -372,7 +393,7 @@ fn ensure_no_import_assertion(
|
|||
loc.line_number,
|
||||
loc.column_number,
|
||||
));
|
||||
deno_core::anyhow::anyhow!("{}", msg)
|
||||
JsErrorBox::generic(msg)
|
||||
}
|
||||
|
||||
let deno_ast::ProgramRef::Module(module) = parsed_source.program_ref() else {
|
||||
|
|
119
cli/errors.rs
119
cli/errors.rs
|
@ -1,119 +0,0 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
//! There are many types of errors in Deno:
|
||||
//! - AnyError: a generic wrapper that can encapsulate any type of error.
|
||||
//! - JsError: a container for the error message and stack trace for exceptions
|
||||
//! thrown in JavaScript code. We use this to pretty-print stack traces.
|
||||
//! - Diagnostic: these are errors that originate in TypeScript's compiler.
|
||||
//! They're similar to JsError, in that they have line numbers. But
|
||||
//! Diagnostics are compile-time type errors, whereas JsErrors are runtime
|
||||
//! exceptions.
|
||||
|
||||
use deno_ast::ParseDiagnostic;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_graph::source::ResolveError;
|
||||
use deno_graph::ModuleError;
|
||||
use deno_graph::ModuleGraphError;
|
||||
use deno_graph::ModuleLoadError;
|
||||
use deno_graph::ResolutionError;
|
||||
use import_map::ImportMapError;
|
||||
|
||||
fn get_import_map_error_class(_: &ImportMapError) -> &'static str {
|
||||
"URIError"
|
||||
}
|
||||
|
||||
fn get_diagnostic_class(_: &ParseDiagnostic) -> &'static str {
|
||||
"SyntaxError"
|
||||
}
|
||||
|
||||
fn get_module_graph_error_class(err: &ModuleGraphError) -> &'static str {
|
||||
use deno_graph::JsrLoadError;
|
||||
use deno_graph::NpmLoadError;
|
||||
|
||||
match err {
|
||||
ModuleGraphError::ResolutionError(err)
|
||||
| ModuleGraphError::TypesResolutionError(err) => {
|
||||
get_resolution_error_class(err)
|
||||
}
|
||||
ModuleGraphError::ModuleError(err) => match err {
|
||||
ModuleError::InvalidTypeAssertion { .. } => "SyntaxError",
|
||||
ModuleError::ParseErr(_, diagnostic) => get_diagnostic_class(diagnostic),
|
||||
ModuleError::WasmParseErr(..) => "SyntaxError",
|
||||
ModuleError::UnsupportedMediaType { .. }
|
||||
| ModuleError::UnsupportedImportAttributeType { .. } => "TypeError",
|
||||
ModuleError::Missing(_, _) | ModuleError::MissingDynamic(_, _) => {
|
||||
"NotFound"
|
||||
}
|
||||
ModuleError::LoadingErr(_, _, err) => match err {
|
||||
ModuleLoadError::Loader(err) => get_error_class_name(err.as_ref()),
|
||||
ModuleLoadError::HttpsChecksumIntegrity(_)
|
||||
| ModuleLoadError::TooManyRedirects => "Error",
|
||||
ModuleLoadError::NodeUnknownBuiltinModule(_) => "NotFound",
|
||||
ModuleLoadError::Decode(_) => "TypeError",
|
||||
ModuleLoadError::Npm(err) => match err {
|
||||
NpmLoadError::NotSupportedEnvironment
|
||||
| NpmLoadError::PackageReqResolution(_)
|
||||
| NpmLoadError::RegistryInfo(_) => "Error",
|
||||
NpmLoadError::PackageReqReferenceParse(_) => "TypeError",
|
||||
},
|
||||
ModuleLoadError::Jsr(err) => match err {
|
||||
JsrLoadError::UnsupportedManifestChecksum
|
||||
| JsrLoadError::PackageFormat(_) => "TypeError",
|
||||
JsrLoadError::ContentLoadExternalSpecifier
|
||||
| JsrLoadError::ContentLoad(_)
|
||||
| JsrLoadError::ContentChecksumIntegrity(_)
|
||||
| JsrLoadError::PackageManifestLoad(_, _)
|
||||
| JsrLoadError::PackageVersionManifestChecksumIntegrity(..)
|
||||
| JsrLoadError::PackageVersionManifestLoad(_, _)
|
||||
| JsrLoadError::RedirectInPackage(_) => "Error",
|
||||
JsrLoadError::PackageNotFound(_)
|
||||
| JsrLoadError::PackageReqNotFound(_)
|
||||
| JsrLoadError::PackageVersionNotFound(_)
|
||||
| JsrLoadError::UnknownExport { .. } => "NotFound",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn get_resolution_error_class(err: &ResolutionError) -> &'static str {
|
||||
match err {
|
||||
ResolutionError::ResolverError { error, .. } => {
|
||||
use ResolveError::*;
|
||||
match error.as_ref() {
|
||||
Specifier(_) => "TypeError",
|
||||
Other(e) => get_error_class_name(e),
|
||||
}
|
||||
}
|
||||
_ => "TypeError",
|
||||
}
|
||||
}
|
||||
|
||||
fn get_try_from_int_error_class(_: &std::num::TryFromIntError) -> &'static str {
|
||||
"TypeError"
|
||||
}
|
||||
|
||||
pub fn get_error_class_name(e: &AnyError) -> &'static str {
|
||||
deno_runtime::errors::get_error_class_name(e)
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<ImportMapError>()
|
||||
.map(get_import_map_error_class)
|
||||
})
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<ParseDiagnostic>()
|
||||
.map(get_diagnostic_class)
|
||||
})
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<ModuleGraphError>()
|
||||
.map(get_module_graph_error_class)
|
||||
})
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<ResolutionError>()
|
||||
.map(get_resolution_error_class)
|
||||
})
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<std::num::TryFromIntError>()
|
||||
.map(get_try_from_int_error_class)
|
||||
})
|
||||
.unwrap_or("Error")
|
||||
}
|
511
cli/factory.rs
511
cli/factory.rs
|
@ -1,4 +1,45 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::future::Future;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_cache_dir::npm::NpmCacheDir;
|
||||
use deno_config::workspace::PackageJsonDepResolution;
|
||||
use deno_config::workspace::WorkspaceResolver;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::FeatureChecker;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_lib::cache::DenoDir;
|
||||
use deno_lib::cache::DenoDirProvider;
|
||||
use deno_lib::npm::NpmRegistryReadPermissionChecker;
|
||||
use deno_lib::npm::NpmRegistryReadPermissionCheckerMode;
|
||||
use deno_lib::worker::LibMainWorkerFactory;
|
||||
use deno_lib::worker::LibMainWorkerOptions;
|
||||
use deno_npm_cache::NpmCacheSetting;
|
||||
use deno_resolver::cjs::IsCjsResolutionMode;
|
||||
use deno_resolver::npm::managed::ManagedInNpmPkgCheckerCreateOptions;
|
||||
use deno_resolver::npm::managed::NpmResolutionCell;
|
||||
use deno_resolver::npm::CreateInNpmPkgCheckerOptions;
|
||||
use deno_resolver::npm::DenoInNpmPackageChecker;
|
||||
use deno_resolver::npm::NpmReqResolverOptions;
|
||||
use deno_resolver::sloppy_imports::SloppyImportsCachedFs;
|
||||
use deno_resolver::DenoResolverOptions;
|
||||
use deno_resolver::NodeAndNpmReqResolver;
|
||||
use deno_runtime::deno_fs;
|
||||
use deno_runtime::deno_fs::RealFs;
|
||||
use deno_runtime::deno_node::RealIsBuiltInNodeModuleChecker;
|
||||
use deno_runtime::deno_permissions::Permissions;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
use deno_runtime::deno_tls::rustls::RootCertStore;
|
||||
use deno_runtime::deno_tls::RootCertStoreProvider;
|
||||
use deno_runtime::deno_web::BlobStore;
|
||||
use deno_runtime::inspector_server::InspectorServer;
|
||||
use deno_runtime::permissions::RuntimePermissionDescriptorParser;
|
||||
use log::warn;
|
||||
use node_resolver::analyze::NodeCodeTranslator;
|
||||
use once_cell::sync::OnceCell;
|
||||
|
||||
use crate::args::check_warn_tsconfig;
|
||||
use crate::args::get_root_cert_store;
|
||||
|
@ -7,12 +48,9 @@ use crate::args::CliOptions;
|
|||
use crate::args::DenoSubcommand;
|
||||
use crate::args::Flags;
|
||||
use crate::args::NpmInstallDepsProvider;
|
||||
use crate::args::StorageKeyResolver;
|
||||
use crate::args::TsConfigType;
|
||||
use crate::cache::Caches;
|
||||
use crate::cache::CodeCache;
|
||||
use crate::cache::DenoDir;
|
||||
use crate::cache::DenoDirProvider;
|
||||
use crate::cache::EmitCache;
|
||||
use crate::cache::GlobalHttpCache;
|
||||
use crate::cache::HttpCache;
|
||||
|
@ -33,23 +71,27 @@ use crate::node::CliCjsCodeAnalyzer;
|
|||
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::create_npm_process_state_provider;
|
||||
use crate::npm::installer::NpmInstaller;
|
||||
use crate::npm::installer::NpmResolutionInstaller;
|
||||
use crate::npm::CliByonmNpmResolverCreateOptions;
|
||||
use crate::npm::CliManagedInNpmPkgCheckerCreateOptions;
|
||||
use crate::npm::CliManagedNpmResolverCreateOptions;
|
||||
use crate::npm::CliNpmCache;
|
||||
use crate::npm::CliNpmCacheHttpClient;
|
||||
use crate::npm::CliNpmRegistryInfoProvider;
|
||||
use crate::npm::CliNpmResolver;
|
||||
use crate::npm::CliNpmResolverCreateOptions;
|
||||
use crate::npm::CliNpmResolverManagedSnapshotOption;
|
||||
use crate::npm::CreateInNpmPkgCheckerOptions;
|
||||
use crate::resolver::CjsTracker;
|
||||
use crate::npm::CliNpmTarballCache;
|
||||
use crate::npm::NpmResolutionInitializer;
|
||||
use crate::resolver::CliCjsTracker;
|
||||
use crate::resolver::CliDenoResolver;
|
||||
use crate::resolver::CliNpmGraphResolver;
|
||||
use crate::resolver::CliNpmReqResolver;
|
||||
use crate::resolver::CliResolver;
|
||||
use crate::resolver::CliResolverOptions;
|
||||
use crate::resolver::CliSloppyImportsResolver;
|
||||
use crate::resolver::FoundPackageJsonDepFlag;
|
||||
use crate::resolver::NpmModuleLoader;
|
||||
use crate::resolver::SloppyImportsCachedFs;
|
||||
use crate::standalone::binary::DenoCompileBinaryWriter;
|
||||
use crate::sys::CliSys;
|
||||
use crate::tools::check::TypeChecker;
|
||||
|
@ -63,35 +105,6 @@ use crate::util::progress_bar::ProgressBar;
|
|||
use crate::util::progress_bar::ProgressBarStyle;
|
||||
use crate::worker::CliMainWorkerFactory;
|
||||
use crate::worker::CliMainWorkerOptions;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use deno_cache_dir::npm::NpmCacheDir;
|
||||
use deno_config::workspace::PackageJsonDepResolution;
|
||||
use deno_config::workspace::WorkspaceResolver;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::FeatureChecker;
|
||||
|
||||
use deno_resolver::cjs::IsCjsResolutionMode;
|
||||
use deno_resolver::npm::NpmReqResolverOptions;
|
||||
use deno_resolver::DenoResolverOptions;
|
||||
use deno_resolver::NodeAndNpmReqResolver;
|
||||
use deno_runtime::deno_fs;
|
||||
use deno_runtime::deno_fs::RealFs;
|
||||
use deno_runtime::deno_node::RealIsBuiltInNodeModuleChecker;
|
||||
use deno_runtime::deno_permissions::Permissions;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
use deno_runtime::deno_tls::rustls::RootCertStore;
|
||||
use deno_runtime::deno_tls::RootCertStoreProvider;
|
||||
use deno_runtime::deno_web::BlobStore;
|
||||
use deno_runtime::inspector_server::InspectorServer;
|
||||
use deno_runtime::permissions::RuntimePermissionDescriptorParser;
|
||||
use log::warn;
|
||||
use node_resolver::analyze::NodeCodeTranslator;
|
||||
use node_resolver::InNpmPackageChecker;
|
||||
use once_cell::sync::OnceCell;
|
||||
use std::future::Future;
|
||||
use std::sync::Arc;
|
||||
|
||||
struct CliRootCertStoreProvider {
|
||||
cell: OnceCell<RootCertStore>,
|
||||
|
@ -116,7 +129,7 @@ impl CliRootCertStoreProvider {
|
|||
}
|
||||
|
||||
impl RootCertStoreProvider for CliRootCertStoreProvider {
|
||||
fn get_or_try_init(&self) -> Result<&RootCertStore, AnyError> {
|
||||
fn get_or_try_init(&self) -> Result<&RootCertStore, JsErrorBox> {
|
||||
self
|
||||
.cell
|
||||
.get_or_try_init(|| {
|
||||
|
@ -126,7 +139,7 @@ impl RootCertStoreProvider for CliRootCertStoreProvider {
|
|||
self.maybe_ca_data.clone(),
|
||||
)
|
||||
})
|
||||
.map_err(|e| e.into())
|
||||
.map_err(JsErrorBox::from_err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,7 +191,7 @@ impl<T> Deferred<T> {
|
|||
struct CliFactoryServices {
|
||||
blob_store: Deferred<Arc<BlobStore>>,
|
||||
caches: Deferred<Arc<Caches>>,
|
||||
cjs_tracker: Deferred<Arc<CjsTracker>>,
|
||||
cjs_tracker: Deferred<Arc<CliCjsTracker>>,
|
||||
cli_options: Deferred<Arc<CliOptions>>,
|
||||
code_cache: Deferred<Arc<CodeCache>>,
|
||||
deno_resolver: Deferred<Arc<CliDenoResolver>>,
|
||||
|
@ -186,11 +199,12 @@ struct CliFactoryServices {
|
|||
emitter: Deferred<Arc<Emitter>>,
|
||||
feature_checker: Deferred<Arc<FeatureChecker>>,
|
||||
file_fetcher: Deferred<Arc<CliFileFetcher>>,
|
||||
found_pkg_json_dep_flag: Arc<FoundPackageJsonDepFlag>,
|
||||
fs: Deferred<Arc<dyn deno_fs::FileSystem>>,
|
||||
global_http_cache: Deferred<Arc<GlobalHttpCache>>,
|
||||
http_cache: Deferred<Arc<dyn HttpCache>>,
|
||||
http_client_provider: Deferred<Arc<HttpClientProvider>>,
|
||||
in_npm_pkg_checker: Deferred<Arc<dyn InNpmPackageChecker>>,
|
||||
in_npm_pkg_checker: Deferred<DenoInNpmPackageChecker>,
|
||||
main_graph_container: Deferred<Arc<MainModuleGraphContainer>>,
|
||||
maybe_file_watcher_reporter: Deferred<Option<FileWatcherReporter>>,
|
||||
maybe_inspector_server: Deferred<Option<Arc<InspectorServer>>>,
|
||||
|
@ -200,9 +214,18 @@ struct CliFactoryServices {
|
|||
module_load_preparer: Deferred<Arc<ModuleLoadPreparer>>,
|
||||
node_code_translator: Deferred<Arc<CliNodeCodeTranslator>>,
|
||||
node_resolver: Deferred<Arc<CliNodeResolver>>,
|
||||
npm_cache: Deferred<Arc<CliNpmCache>>,
|
||||
npm_cache_dir: Deferred<Arc<NpmCacheDir>>,
|
||||
npm_cache_http_client: Deferred<Arc<CliNpmCacheHttpClient>>,
|
||||
npm_graph_resolver: Deferred<Arc<CliNpmGraphResolver>>,
|
||||
npm_installer: Deferred<Arc<NpmInstaller>>,
|
||||
npm_registry_info_provider: Deferred<Arc<CliNpmRegistryInfoProvider>>,
|
||||
npm_req_resolver: Deferred<Arc<CliNpmReqResolver>>,
|
||||
npm_resolver: Deferred<Arc<dyn CliNpmResolver>>,
|
||||
npm_resolution: Arc<NpmResolutionCell>,
|
||||
npm_resolution_initializer: Deferred<Arc<NpmResolutionInitializer>>,
|
||||
npm_resolution_installer: Deferred<Arc<NpmResolutionInstaller>>,
|
||||
npm_resolver: Deferred<CliNpmResolver>,
|
||||
npm_tarball_cache: Deferred<Arc<CliNpmTarballCache>>,
|
||||
parsed_source_cache: Deferred<Arc<ParsedSourceCache>>,
|
||||
permission_desc_parser:
|
||||
Deferred<Arc<RuntimePermissionDescriptorParser<CliSys>>>,
|
||||
|
@ -260,11 +283,13 @@ impl CliFactory {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn deno_dir_provider(&self) -> Result<&Arc<DenoDirProvider>, AnyError> {
|
||||
pub fn deno_dir_provider(
|
||||
&self,
|
||||
) -> Result<&Arc<DenoDirProvider<CliSys>>, AnyError> {
|
||||
Ok(&self.cli_options()?.deno_dir_provider)
|
||||
}
|
||||
|
||||
pub fn deno_dir(&self) -> Result<&DenoDir, AnyError> {
|
||||
pub fn deno_dir(&self) -> Result<&DenoDir<CliSys>, AnyError> {
|
||||
Ok(self.deno_dir_provider()?.get_or_create()?)
|
||||
}
|
||||
|
||||
|
@ -377,14 +402,14 @@ impl CliFactory {
|
|||
|
||||
pub fn in_npm_pkg_checker(
|
||||
&self,
|
||||
) -> Result<&Arc<dyn InNpmPackageChecker>, AnyError> {
|
||||
) -> Result<&DenoInNpmPackageChecker, AnyError> {
|
||||
self.services.in_npm_pkg_checker.get_or_try_init(|| {
|
||||
let cli_options = self.cli_options()?;
|
||||
let options = if cli_options.use_byonm() {
|
||||
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()
|
||||
|
@ -392,7 +417,19 @@ impl CliFactory {
|
|||
},
|
||||
)
|
||||
};
|
||||
Ok(create_in_npm_pkg_checker(options))
|
||||
Ok(DenoInNpmPackageChecker::new(options))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn npm_cache(&self) -> Result<&Arc<CliNpmCache>, AnyError> {
|
||||
self.services.npm_cache.get_or_try_init(|| {
|
||||
let cli_options = self.cli_options()?;
|
||||
Ok(Arc::new(CliNpmCache::new(
|
||||
self.npm_cache_dir()?.clone(),
|
||||
self.sys(),
|
||||
NpmCacheSetting::from_cache_setting(&cli_options.cache_setting()),
|
||||
cli_options.npmrc().clone(),
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -408,16 +445,131 @@ impl CliFactory {
|
|||
})
|
||||
}
|
||||
|
||||
pub async fn npm_resolver(
|
||||
pub fn npm_cache_http_client(&self) -> &Arc<CliNpmCacheHttpClient> {
|
||||
self.services.npm_cache_http_client.get_or_init(|| {
|
||||
Arc::new(CliNpmCacheHttpClient::new(
|
||||
self.http_client_provider().clone(),
|
||||
self.text_only_progress_bar().clone(),
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn npm_graph_resolver(
|
||||
&self,
|
||||
) -> Result<&Arc<dyn CliNpmResolver>, AnyError> {
|
||||
) -> Result<&Arc<CliNpmGraphResolver>, AnyError> {
|
||||
self.services.npm_graph_resolver.get_or_try_init(|| {
|
||||
let cli_options = self.cli_options()?;
|
||||
Ok(Arc::new(CliNpmGraphResolver::new(
|
||||
self.npm_installer_if_managed()?.cloned(),
|
||||
self.services.found_pkg_json_dep_flag.clone(),
|
||||
cli_options.unstable_bare_node_builtins(),
|
||||
cli_options.default_npm_caching_strategy(),
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn npm_installer_if_managed(
|
||||
&self,
|
||||
) -> Result<Option<&Arc<NpmInstaller>>, AnyError> {
|
||||
let options = self.cli_options()?;
|
||||
if options.use_byonm() || options.no_npm() {
|
||||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(self.npm_installer()?))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn npm_installer(&self) -> Result<&Arc<NpmInstaller>, AnyError> {
|
||||
self.services.npm_installer.get_or_try_init(|| {
|
||||
let cli_options = self.cli_options()?;
|
||||
Ok(Arc::new(NpmInstaller::new(
|
||||
self.npm_cache()?.clone(),
|
||||
Arc::new(NpmInstallDepsProvider::from_workspace(
|
||||
cli_options.workspace(),
|
||||
)),
|
||||
self.npm_resolution().clone(),
|
||||
self.npm_resolution_initializer()?.clone(),
|
||||
self.npm_resolution_installer()?.clone(),
|
||||
self.text_only_progress_bar(),
|
||||
self.sys(),
|
||||
self.npm_tarball_cache()?.clone(),
|
||||
cli_options.maybe_lockfile().cloned(),
|
||||
cli_options.node_modules_dir_path().cloned(),
|
||||
cli_options.lifecycle_scripts_config(),
|
||||
cli_options.npm_system_info(),
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn npm_registry_info_provider(
|
||||
&self,
|
||||
) -> Result<&Arc<CliNpmRegistryInfoProvider>, AnyError> {
|
||||
self
|
||||
.services
|
||||
.npm_registry_info_provider
|
||||
.get_or_try_init(|| {
|
||||
let cli_options = self.cli_options()?;
|
||||
Ok(Arc::new(CliNpmRegistryInfoProvider::new(
|
||||
self.npm_cache()?.clone(),
|
||||
self.npm_cache_http_client().clone(),
|
||||
cli_options.npmrc().clone(),
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn npm_resolution(&self) -> &Arc<NpmResolutionCell> {
|
||||
&self.services.npm_resolution
|
||||
}
|
||||
|
||||
pub fn npm_resolution_initializer(
|
||||
&self,
|
||||
) -> Result<&Arc<NpmResolutionInitializer>, AnyError> {
|
||||
self
|
||||
.services
|
||||
.npm_resolution_initializer
|
||||
.get_or_try_init(|| {
|
||||
let cli_options = self.cli_options()?;
|
||||
Ok(Arc::new(NpmResolutionInitializer::new(
|
||||
self.npm_registry_info_provider()?.clone(),
|
||||
self.npm_resolution().clone(),
|
||||
match cli_options.resolve_npm_resolution_snapshot()? {
|
||||
Some(snapshot) => {
|
||||
CliNpmResolverManagedSnapshotOption::Specified(Some(snapshot))
|
||||
}
|
||||
None => match cli_options.maybe_lockfile() {
|
||||
Some(lockfile) => {
|
||||
CliNpmResolverManagedSnapshotOption::ResolveFromLockfile(
|
||||
lockfile.clone(),
|
||||
)
|
||||
}
|
||||
None => CliNpmResolverManagedSnapshotOption::Specified(None),
|
||||
},
|
||||
},
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn npm_resolution_installer(
|
||||
&self,
|
||||
) -> Result<&Arc<NpmResolutionInstaller>, AnyError> {
|
||||
self.services.npm_resolution_installer.get_or_try_init(|| {
|
||||
let cli_options = self.cli_options()?;
|
||||
Ok(Arc::new(NpmResolutionInstaller::new(
|
||||
self.npm_registry_info_provider()?.clone(),
|
||||
self.npm_resolution().clone(),
|
||||
cli_options.maybe_lockfile().cloned(),
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn npm_resolver(&self) -> Result<&CliNpmResolver, AnyError> {
|
||||
self
|
||||
.services
|
||||
.npm_resolver
|
||||
.get_or_try_init_async(
|
||||
async {
|
||||
let cli_options = self.cli_options()?;
|
||||
create_cli_npm_resolver(if cli_options.use_byonm() {
|
||||
Ok(CliNpmResolver::new(if cli_options.use_byonm() {
|
||||
CliNpmResolverCreateOptions::Byonm(
|
||||
CliByonmNpmResolverCreateOptions {
|
||||
sys: self.sys(),
|
||||
|
@ -436,52 +588,43 @@ impl CliFactory {
|
|||
},
|
||||
)
|
||||
} else {
|
||||
self
|
||||
.npm_resolution_initializer()?
|
||||
.ensure_initialized()
|
||||
.await?;
|
||||
CliNpmResolverCreateOptions::Managed(
|
||||
CliManagedNpmResolverCreateOptions {
|
||||
http_client_provider: self.http_client_provider().clone(),
|
||||
npm_install_deps_provider: Arc::new(
|
||||
NpmInstallDepsProvider::from_workspace(
|
||||
cli_options.workspace(),
|
||||
),
|
||||
),
|
||||
sys: self.sys(),
|
||||
snapshot: match cli_options.resolve_npm_resolution_snapshot()? {
|
||||
Some(snapshot) => {
|
||||
CliNpmResolverManagedSnapshotOption::Specified(Some(
|
||||
snapshot,
|
||||
))
|
||||
}
|
||||
None => match cli_options.maybe_lockfile() {
|
||||
Some(lockfile) => {
|
||||
CliNpmResolverManagedSnapshotOption::ResolveFromLockfile(
|
||||
lockfile.clone(),
|
||||
)
|
||||
}
|
||||
None => {
|
||||
CliNpmResolverManagedSnapshotOption::Specified(None)
|
||||
}
|
||||
},
|
||||
},
|
||||
maybe_lockfile: cli_options.maybe_lockfile().cloned(),
|
||||
npm_resolution: self.npm_resolution().clone(),
|
||||
npm_cache_dir: self.npm_cache_dir()?.clone(),
|
||||
cache_setting: cli_options.cache_setting(),
|
||||
text_only_progress_bar: self.text_only_progress_bar().clone(),
|
||||
maybe_node_modules_path: cli_options
|
||||
.node_modules_dir_path()
|
||||
.cloned(),
|
||||
npm_system_info: cli_options.npm_system_info(),
|
||||
npmrc: cli_options.npmrc().clone(),
|
||||
lifecycle_scripts: cli_options.lifecycle_scripts_config(),
|
||||
},
|
||||
)
|
||||
})
|
||||
.await
|
||||
}))
|
||||
}
|
||||
.boxed_local(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub fn npm_tarball_cache(
|
||||
&self,
|
||||
) -> Result<&Arc<CliNpmTarballCache>, AnyError> {
|
||||
self.services.npm_tarball_cache.get_or_try_init(|| {
|
||||
let cli_options = self.cli_options()?;
|
||||
Ok(Arc::new(CliNpmTarballCache::new(
|
||||
self.npm_cache()?.clone(),
|
||||
self.npm_cache_http_client().clone(),
|
||||
self.sys(),
|
||||
cli_options.npmrc().clone(),
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn sloppy_imports_resolver(
|
||||
&self,
|
||||
) -> Result<Option<&Arc<CliSloppyImportsResolver>>, AnyError> {
|
||||
|
@ -569,17 +712,10 @@ impl CliFactory {
|
|||
.resolver
|
||||
.get_or_try_init_async(
|
||||
async {
|
||||
let cli_options = self.cli_options()?;
|
||||
Ok(Arc::new(CliResolver::new(CliResolverOptions {
|
||||
npm_resolver: if cli_options.no_npm() {
|
||||
None
|
||||
} else {
|
||||
Some(self.npm_resolver().await?.clone())
|
||||
},
|
||||
bare_node_builtins_enabled: cli_options
|
||||
.unstable_bare_node_builtins(),
|
||||
deno_resolver: self.deno_resolver().await?.clone(),
|
||||
})))
|
||||
Ok(Arc::new(CliResolver::new(
|
||||
self.deno_resolver().await?.clone(),
|
||||
self.services.found_pkg_json_dep_flag.clone(),
|
||||
)))
|
||||
}
|
||||
.boxed_local(),
|
||||
)
|
||||
|
@ -661,13 +797,10 @@ impl CliFactory {
|
|||
Ok(Arc::new(CliNodeResolver::new(
|
||||
self.in_npm_pkg_checker()?.clone(),
|
||||
RealIsBuiltInNodeModuleChecker,
|
||||
self
|
||||
.npm_resolver()
|
||||
.await?
|
||||
.clone()
|
||||
.into_npm_pkg_folder_resolver(),
|
||||
self.npm_resolver().await?.clone(),
|
||||
self.pkg_json_resolver().clone(),
|
||||
self.sys(),
|
||||
node_resolver::ConditionsFromResolutionMode::default(),
|
||||
)))
|
||||
}
|
||||
.boxed_local(),
|
||||
|
@ -697,11 +830,7 @@ impl CliFactory {
|
|||
cjs_esm_analyzer,
|
||||
self.in_npm_pkg_checker()?.clone(),
|
||||
node_resolver,
|
||||
self
|
||||
.npm_resolver()
|
||||
.await?
|
||||
.clone()
|
||||
.into_npm_pkg_folder_resolver(),
|
||||
self.npm_resolver().await?.clone(),
|
||||
self.pkg_json_resolver().clone(),
|
||||
self.sys(),
|
||||
)))
|
||||
|
@ -718,11 +847,10 @@ impl CliFactory {
|
|||
.get_or_try_init_async(async {
|
||||
let npm_resolver = self.npm_resolver().await?;
|
||||
Ok(Arc::new(CliNpmReqResolver::new(NpmReqResolverOptions {
|
||||
byonm_resolver: (npm_resolver.clone()).into_maybe_byonm(),
|
||||
sys: self.sys(),
|
||||
in_npm_pkg_checker: self.in_npm_pkg_checker()?.clone(),
|
||||
node_resolver: self.node_resolver().await?.clone(),
|
||||
npm_req_resolver: npm_resolver.clone().into_npm_req_resolver(),
|
||||
npm_resolver: npm_resolver.clone(),
|
||||
})))
|
||||
})
|
||||
.await
|
||||
|
@ -750,7 +878,9 @@ impl CliFactory {
|
|||
cli_options.clone(),
|
||||
self.module_graph_builder().await?.clone(),
|
||||
self.node_resolver().await?.clone(),
|
||||
self.npm_installer_if_managed()?.cloned(),
|
||||
self.npm_resolver().await?.clone(),
|
||||
self.sys(),
|
||||
)))
|
||||
})
|
||||
.await
|
||||
|
@ -774,6 +904,8 @@ impl CliFactory {
|
|||
cli_options.maybe_lockfile().cloned(),
|
||||
self.maybe_file_watcher_reporter().clone(),
|
||||
self.module_info_cache()?.clone(),
|
||||
self.npm_graph_resolver()?.clone(),
|
||||
self.npm_installer_if_managed()?.cloned(),
|
||||
self.npm_resolver().await?.clone(),
|
||||
self.parsed_source_cache().clone(),
|
||||
self.resolver().await?.clone(),
|
||||
|
@ -794,7 +926,7 @@ impl CliFactory {
|
|||
let cli_options = self.cli_options()?;
|
||||
Ok(Arc::new(ModuleGraphCreator::new(
|
||||
cli_options.clone(),
|
||||
self.npm_resolver().await?.clone(),
|
||||
self.npm_installer_if_managed()?.cloned(),
|
||||
self.module_graph_builder().await?.clone(),
|
||||
self.type_checker().await?.clone(),
|
||||
)))
|
||||
|
@ -849,10 +981,10 @@ impl CliFactory {
|
|||
.await
|
||||
}
|
||||
|
||||
pub fn cjs_tracker(&self) -> Result<&Arc<CjsTracker>, AnyError> {
|
||||
pub fn cjs_tracker(&self) -> Result<&Arc<CliCjsTracker>, AnyError> {
|
||||
self.services.cjs_tracker.get_or_try_init(|| {
|
||||
let options = self.cli_options()?;
|
||||
Ok(Arc::new(CjsTracker::new(
|
||||
Ok(Arc::new(CliCjsTracker::new(
|
||||
self.in_npm_pkg_checker()?.clone(),
|
||||
self.pkg_json_resolver().clone(),
|
||||
if options.is_node_main() || options.unstable_detect_cjs() {
|
||||
|
@ -901,7 +1033,7 @@ impl CliFactory {
|
|||
self.emitter()?,
|
||||
self.file_fetcher()?,
|
||||
self.http_client_provider(),
|
||||
self.npm_resolver().await?.as_ref(),
|
||||
self.npm_resolver().await?,
|
||||
self.workspace_resolver().await?.as_ref(),
|
||||
cli_options.npm_system_info(),
|
||||
))
|
||||
|
@ -941,8 +1073,48 @@ impl CliFactory {
|
|||
let cjs_tracker = self.cjs_tracker()?.clone();
|
||||
let pkg_json_resolver = self.pkg_json_resolver().clone();
|
||||
let npm_req_resolver = self.npm_req_resolver().await?;
|
||||
let npm_registry_permission_checker = {
|
||||
let mode = if cli_options.use_byonm() {
|
||||
NpmRegistryReadPermissionCheckerMode::Byonm
|
||||
} else if let Some(node_modules_dir) = cli_options.node_modules_dir_path()
|
||||
{
|
||||
NpmRegistryReadPermissionCheckerMode::Local(node_modules_dir.clone())
|
||||
} else {
|
||||
NpmRegistryReadPermissionCheckerMode::Global(
|
||||
self.npm_cache_dir()?.root_dir().to_path_buf(),
|
||||
)
|
||||
};
|
||||
Arc::new(NpmRegistryReadPermissionChecker::new(self.sys(), mode))
|
||||
};
|
||||
|
||||
Ok(CliMainWorkerFactory::new(
|
||||
let module_loader_factory = CliModuleLoaderFactory::new(
|
||||
cli_options,
|
||||
cjs_tracker,
|
||||
if cli_options.code_cache_enabled() {
|
||||
Some(self.code_cache()?.clone())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
self.emitter()?.clone(),
|
||||
in_npm_pkg_checker.clone(),
|
||||
self.main_module_graph_container().await?.clone(),
|
||||
self.module_load_preparer().await?.clone(),
|
||||
node_code_translator.clone(),
|
||||
node_resolver.clone(),
|
||||
NpmModuleLoader::new(
|
||||
self.cjs_tracker()?.clone(),
|
||||
fs.clone(),
|
||||
node_code_translator.clone(),
|
||||
),
|
||||
npm_registry_permission_checker,
|
||||
npm_req_resolver.clone(),
|
||||
cli_npm_resolver.clone(),
|
||||
self.parsed_source_cache().clone(),
|
||||
self.resolver().await?.clone(),
|
||||
self.sys(),
|
||||
);
|
||||
|
||||
let lib_main_worker_factory = LibMainWorkerFactory::new(
|
||||
self.blob_store().clone(),
|
||||
if cli_options.code_cache_enabled() {
|
||||
Some(self.code_cache()?.clone())
|
||||
|
@ -951,48 +1123,70 @@ impl CliFactory {
|
|||
},
|
||||
self.feature_checker()?.clone(),
|
||||
fs.clone(),
|
||||
maybe_file_watcher_communicator,
|
||||
self.maybe_inspector_server()?.clone(),
|
||||
cli_options.maybe_lockfile().cloned(),
|
||||
Box::new(CliModuleLoaderFactory::new(
|
||||
cli_options,
|
||||
cjs_tracker,
|
||||
if cli_options.code_cache_enabled() {
|
||||
Some(self.code_cache()?.clone())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
self.emitter()?.clone(),
|
||||
in_npm_pkg_checker.clone(),
|
||||
self.main_module_graph_container().await?.clone(),
|
||||
self.module_load_preparer().await?.clone(),
|
||||
node_code_translator.clone(),
|
||||
node_resolver.clone(),
|
||||
npm_req_resolver.clone(),
|
||||
cli_npm_resolver.clone(),
|
||||
NpmModuleLoader::new(
|
||||
self.cjs_tracker()?.clone(),
|
||||
fs.clone(),
|
||||
node_code_translator.clone(),
|
||||
),
|
||||
self.parsed_source_cache().clone(),
|
||||
self.resolver().await?.clone(),
|
||||
self.sys(),
|
||||
)),
|
||||
Box::new(module_loader_factory),
|
||||
node_resolver.clone(),
|
||||
npm_resolver.clone(),
|
||||
create_npm_process_state_provider(npm_resolver),
|
||||
pkg_json_resolver,
|
||||
self.root_cert_store_provider().clone(),
|
||||
self.root_permissions_container()?.clone(),
|
||||
StorageKeyResolver::from_options(cli_options),
|
||||
cli_options.resolve_storage_key_resolver(),
|
||||
self.sys(),
|
||||
self.create_lib_main_worker_options()?,
|
||||
);
|
||||
|
||||
Ok(CliMainWorkerFactory::new(
|
||||
lib_main_worker_factory,
|
||||
maybe_file_watcher_communicator,
|
||||
cli_options.maybe_lockfile().cloned(),
|
||||
node_resolver.clone(),
|
||||
self.npm_installer_if_managed()?.cloned(),
|
||||
npm_resolver.clone(),
|
||||
self.sys(),
|
||||
cli_options.sub_command().clone(),
|
||||
self.create_cli_main_worker_options()?,
|
||||
self.cli_options()?.otel_config(),
|
||||
self.cli_options()?.default_npm_caching_strategy(),
|
||||
self.root_permissions_container()?.clone(),
|
||||
))
|
||||
}
|
||||
|
||||
fn create_lib_main_worker_options(
|
||||
&self,
|
||||
) -> Result<LibMainWorkerOptions, AnyError> {
|
||||
let cli_options = self.cli_options()?;
|
||||
Ok(LibMainWorkerOptions {
|
||||
argv: cli_options.argv().clone(),
|
||||
// This optimization is only available for "run" subcommand
|
||||
// because we need to register new ops for testing and jupyter
|
||||
// integration.
|
||||
skip_op_registration: cli_options.sub_command().is_run(),
|
||||
log_level: cli_options.log_level().unwrap_or(log::Level::Info).into(),
|
||||
enable_op_summary_metrics: cli_options.enable_op_summary_metrics(),
|
||||
enable_testing_features: cli_options.enable_testing_features(),
|
||||
has_node_modules_dir: cli_options.has_node_modules_dir(),
|
||||
inspect_brk: cli_options.inspect_brk().is_some(),
|
||||
inspect_wait: cli_options.inspect_wait().is_some(),
|
||||
strace_ops: cli_options.strace_ops().clone(),
|
||||
is_inspecting: cli_options.is_inspecting(),
|
||||
location: cli_options.location_flag().clone(),
|
||||
// if the user ran a binary command, we'll need to set process.argv[0]
|
||||
// to be the name of the binary command instead of deno
|
||||
argv0: cli_options
|
||||
.take_binary_npm_command_name()
|
||||
.or(std::env::args().next()),
|
||||
node_debug: std::env::var("NODE_DEBUG").ok(),
|
||||
origin_data_folder_path: Some(self.deno_dir()?.origin_data_folder_path()),
|
||||
seed: cli_options.seed(),
|
||||
unsafely_ignore_certificate_errors: cli_options
|
||||
.unsafely_ignore_certificate_errors()
|
||||
.clone(),
|
||||
node_ipc: cli_options.node_ipc_fd(),
|
||||
serve_port: cli_options.serve_port(),
|
||||
serve_host: cli_options.serve_host(),
|
||||
deno_version: crate::version::DENO_VERSION_INFO.deno,
|
||||
deno_user_agent: crate::version::DENO_VERSION_INFO.user_agent,
|
||||
otel_config: self.cli_options()?.otel_config(),
|
||||
startup_snapshot: crate::js::deno_isolate_init(),
|
||||
})
|
||||
}
|
||||
|
||||
fn create_cli_main_worker_options(
|
||||
&self,
|
||||
) -> Result<CliMainWorkerOptions, AnyError> {
|
||||
|
@ -1024,37 +1218,10 @@ impl CliFactory {
|
|||
};
|
||||
|
||||
Ok(CliMainWorkerOptions {
|
||||
argv: cli_options.argv().clone(),
|
||||
// This optimization is only available for "run" subcommand
|
||||
// because we need to register new ops for testing and jupyter
|
||||
// integration.
|
||||
skip_op_registration: cli_options.sub_command().is_run(),
|
||||
log_level: cli_options.log_level().unwrap_or(log::Level::Info).into(),
|
||||
enable_op_summary_metrics: cli_options.enable_op_summary_metrics(),
|
||||
enable_testing_features: cli_options.enable_testing_features(),
|
||||
has_node_modules_dir: cli_options.has_node_modules_dir(),
|
||||
hmr: cli_options.has_hmr(),
|
||||
inspect_brk: cli_options.inspect_brk().is_some(),
|
||||
inspect_wait: cli_options.inspect_wait().is_some(),
|
||||
strace_ops: cli_options.strace_ops().clone(),
|
||||
is_inspecting: cli_options.is_inspecting(),
|
||||
location: cli_options.location_flag().clone(),
|
||||
// if the user ran a binary command, we'll need to set process.argv[0]
|
||||
// to be the name of the binary command instead of deno
|
||||
argv0: cli_options
|
||||
.take_binary_npm_command_name()
|
||||
.or(std::env::args().next()),
|
||||
node_debug: std::env::var("NODE_DEBUG").ok(),
|
||||
origin_data_folder_path: Some(self.deno_dir()?.origin_data_folder_path()),
|
||||
seed: cli_options.seed(),
|
||||
unsafely_ignore_certificate_errors: cli_options
|
||||
.unsafely_ignore_certificate_errors()
|
||||
.clone(),
|
||||
needs_test_modules: cli_options.sub_command().needs_test(),
|
||||
create_hmr_runner,
|
||||
create_coverage_collector,
|
||||
node_ipc: cli_options.node_ipc_fd(),
|
||||
serve_port: cli_options.serve_port(),
|
||||
serve_host: cli_options.serve_host(),
|
||||
default_npm_caching_strategy: cli_options.default_npm_caching_strategy(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
|
@ -498,10 +498,6 @@ fn validate_scheme(specifier: &Url) -> Result<(), UnsupportedSchemeError> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::cache::GlobalHttpCache;
|
||||
use crate::http_util::HttpClientProvider;
|
||||
|
||||
use super::*;
|
||||
use deno_cache_dir::file_fetcher::FetchNoFollowErrorKind;
|
||||
use deno_cache_dir::file_fetcher::HttpClient;
|
||||
use deno_core::resolve_url;
|
||||
|
@ -509,6 +505,10 @@ mod tests {
|
|||
use deno_runtime::deno_web::InMemoryBlobPart;
|
||||
use test_util::TempDir;
|
||||
|
||||
use super::*;
|
||||
use crate::cache::GlobalHttpCache;
|
||||
use crate::http_util::HttpClientProvider;
|
||||
|
||||
fn setup(
|
||||
cache_setting: CacheSetting,
|
||||
maybe_temp_dir: Option<TempDir>,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::error::Error;
|
||||
use std::ops::Deref;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_config::deno_json;
|
||||
use deno_config::deno_json::JsxImportSourceConfig;
|
||||
use deno_config::deno_json::NodeModulesDirMode;
|
||||
use deno_config::workspace::JsrPackageConfig;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_error::JsErrorClass;
|
||||
use deno_graph::source::Loader;
|
||||
use deno_graph::source::LoaderChecksum;
|
||||
use deno_graph::source::ResolutionKind;
|
||||
|
@ -28,14 +30,14 @@ use deno_graph::ResolutionError;
|
|||
use deno_graph::SpecifierError;
|
||||
use deno_graph::WorkspaceFastCheckOption;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use deno_resolver::npm::DenoInNpmPackageChecker;
|
||||
use deno_resolver::sloppy_imports::SloppyImportsCachedFs;
|
||||
use deno_resolver::sloppy_imports::SloppyImportsResolutionKind;
|
||||
use deno_runtime::deno_node;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
use deno_semver::jsr::JsrDepPackageReq;
|
||||
use deno_semver::package::PackageNv;
|
||||
use deno_semver::SmallStackString;
|
||||
use import_map::ImportMapError;
|
||||
use node_resolver::InNpmPackageChecker;
|
||||
|
||||
use crate::args::config_to_deno_graph_workspace_member;
|
||||
use crate::args::jsr_url;
|
||||
|
@ -49,15 +51,17 @@ use crate::cache::GlobalHttpCache;
|
|||
use crate::cache::ModuleInfoCache;
|
||||
use crate::cache::ParsedSourceCache;
|
||||
use crate::colors;
|
||||
use crate::errors::get_error_class_name;
|
||||
use crate::file_fetcher::CliFileFetcher;
|
||||
use crate::npm::installer::NpmInstaller;
|
||||
use crate::npm::installer::PackageCaching;
|
||||
use crate::npm::CliNpmResolver;
|
||||
use crate::resolver::CjsTracker;
|
||||
use crate::resolver::CliCjsTracker;
|
||||
use crate::resolver::CliNpmGraphResolver;
|
||||
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;
|
||||
use crate::tools::check::TypeChecker;
|
||||
use crate::util::file_watcher::WatcherCommunicator;
|
||||
use crate::util::fs::canonicalize_path;
|
||||
|
@ -84,7 +88,7 @@ pub fn graph_valid(
|
|||
sys: &CliSys,
|
||||
roots: &[ModuleSpecifier],
|
||||
options: GraphValidOptions,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), JsErrorBox> {
|
||||
if options.exit_integrity_errors {
|
||||
graph_exit_integrity_errors(graph);
|
||||
}
|
||||
|
@ -103,9 +107,9 @@ pub fn graph_valid(
|
|||
} else {
|
||||
// finally surface the npm resolution result
|
||||
if let Err(err) = &graph.npm_dep_graph_result {
|
||||
return Err(custom_error(
|
||||
get_error_class_name(err),
|
||||
format_deno_graph_error(err.as_ref().deref()),
|
||||
return Err(JsErrorBox::new(
|
||||
err.get_class(),
|
||||
format_deno_graph_error(err),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
|
@ -144,7 +148,7 @@ pub fn graph_walk_errors<'a>(
|
|||
sys: &'a CliSys,
|
||||
roots: &'a [ModuleSpecifier],
|
||||
options: GraphWalkErrorsOptions,
|
||||
) -> impl Iterator<Item = AnyError> + 'a {
|
||||
) -> impl Iterator<Item = JsErrorBox> + 'a {
|
||||
graph
|
||||
.walk(
|
||||
roots.iter(),
|
||||
|
@ -164,29 +168,15 @@ pub fn graph_walk_errors<'a>(
|
|||
roots.contains(error.specifier())
|
||||
}
|
||||
};
|
||||
let mut message = match &error {
|
||||
ModuleGraphError::ResolutionError(resolution_error) => {
|
||||
enhanced_resolution_error_message(resolution_error)
|
||||
}
|
||||
ModuleGraphError::TypesResolutionError(resolution_error) => {
|
||||
format!(
|
||||
"Failed resolving types. {}",
|
||||
enhanced_resolution_error_message(resolution_error)
|
||||
)
|
||||
}
|
||||
ModuleGraphError::ModuleError(error) => {
|
||||
enhanced_integrity_error_message(error)
|
||||
.or_else(|| enhanced_sloppy_imports_error_message(sys, error))
|
||||
.unwrap_or_else(|| format_deno_graph_error(error))
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(range) = error.maybe_range() {
|
||||
if !is_root && !range.specifier.as_str().contains("/$deno$eval") {
|
||||
message.push_str("\n at ");
|
||||
message.push_str(&format_range_with_colors(range));
|
||||
}
|
||||
}
|
||||
let message = enhance_graph_error(
|
||||
sys,
|
||||
&error,
|
||||
if is_root {
|
||||
EnhanceGraphErrorMode::HideRange
|
||||
} else {
|
||||
EnhanceGraphErrorMode::ShowRange
|
||||
},
|
||||
);
|
||||
|
||||
if graph.graph_kind() == GraphKind::TypesOnly
|
||||
&& matches!(
|
||||
|
@ -198,10 +188,61 @@ pub fn graph_walk_errors<'a>(
|
|||
return None;
|
||||
}
|
||||
|
||||
Some(custom_error(get_error_class_name(&error.into()), message))
|
||||
if graph.graph_kind().include_types()
|
||||
&& (message.contains(RUN_WITH_SLOPPY_IMPORTS_MSG)
|
||||
|| matches!(
|
||||
error,
|
||||
ModuleGraphError::ModuleError(ModuleError::Missing(..))
|
||||
))
|
||||
{
|
||||
// ignore and let typescript surface this as a diagnostic instead
|
||||
log::debug!("Ignoring: {}", message);
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(JsErrorBox::new(error.get_class(), message))
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum EnhanceGraphErrorMode {
|
||||
ShowRange,
|
||||
HideRange,
|
||||
}
|
||||
|
||||
pub fn enhance_graph_error(
|
||||
sys: &CliSys,
|
||||
error: &ModuleGraphError,
|
||||
mode: EnhanceGraphErrorMode,
|
||||
) -> String {
|
||||
let mut message = match &error {
|
||||
ModuleGraphError::ResolutionError(resolution_error) => {
|
||||
enhanced_resolution_error_message(resolution_error)
|
||||
}
|
||||
ModuleGraphError::TypesResolutionError(resolution_error) => {
|
||||
format!(
|
||||
"Failed resolving types. {}",
|
||||
enhanced_resolution_error_message(resolution_error)
|
||||
)
|
||||
}
|
||||
ModuleGraphError::ModuleError(error) => {
|
||||
enhanced_integrity_error_message(error)
|
||||
.or_else(|| enhanced_sloppy_imports_error_message(sys, error))
|
||||
.unwrap_or_else(|| format_deno_graph_error(error))
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(range) = error.maybe_range() {
|
||||
if mode == EnhanceGraphErrorMode::ShowRange
|
||||
&& !range.specifier.as_str().contains("/$deno$eval")
|
||||
{
|
||||
message.push_str("\n at ");
|
||||
message.push_str(&format_range_with_colors(range));
|
||||
}
|
||||
}
|
||||
message
|
||||
}
|
||||
|
||||
pub fn graph_exit_integrity_errors(graph: &ModuleGraph) {
|
||||
for error in graph.module_errors() {
|
||||
exit_for_integrity_error(error);
|
||||
|
@ -226,7 +267,7 @@ pub struct CreateGraphOptions<'a> {
|
|||
|
||||
pub struct ModuleGraphCreator {
|
||||
options: Arc<CliOptions>,
|
||||
npm_resolver: Arc<dyn CliNpmResolver>,
|
||||
npm_installer: Option<Arc<NpmInstaller>>,
|
||||
module_graph_builder: Arc<ModuleGraphBuilder>,
|
||||
type_checker: Arc<TypeChecker>,
|
||||
}
|
||||
|
@ -234,13 +275,13 @@ pub struct ModuleGraphCreator {
|
|||
impl ModuleGraphCreator {
|
||||
pub fn new(
|
||||
options: Arc<CliOptions>,
|
||||
npm_resolver: Arc<dyn CliNpmResolver>,
|
||||
npm_installer: Option<Arc<NpmInstaller>>,
|
||||
module_graph_builder: Arc<ModuleGraphBuilder>,
|
||||
type_checker: Arc<TypeChecker>,
|
||||
) -> Self {
|
||||
Self {
|
||||
options,
|
||||
npm_resolver,
|
||||
npm_installer,
|
||||
module_graph_builder,
|
||||
type_checker,
|
||||
}
|
||||
|
@ -363,9 +404,9 @@ impl ModuleGraphCreator {
|
|||
.build_graph_with_npm_resolution(&mut graph, options)
|
||||
.await?;
|
||||
|
||||
if let Some(npm_resolver) = self.npm_resolver.as_managed() {
|
||||
if let Some(npm_installer) = &self.npm_installer {
|
||||
if graph.has_node_specifier && self.options.type_check_mode().is_true() {
|
||||
npm_resolver.inject_synthetic_types_node_package().await?;
|
||||
npm_installer.inject_synthetic_types_node_package().await?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -399,14 +440,14 @@ impl ModuleGraphCreator {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn graph_valid(&self, graph: &ModuleGraph) -> Result<(), AnyError> {
|
||||
pub fn graph_valid(&self, graph: &ModuleGraph) -> Result<(), JsErrorBox> {
|
||||
self.module_graph_builder.graph_valid(graph)
|
||||
}
|
||||
|
||||
async fn type_check_graph(
|
||||
&self,
|
||||
graph: ModuleGraph,
|
||||
) -> Result<Arc<ModuleGraph>, AnyError> {
|
||||
) -> Result<Arc<ModuleGraph>, CheckError> {
|
||||
self
|
||||
.type_checker
|
||||
.check(
|
||||
|
@ -429,17 +470,40 @@ pub struct BuildFastCheckGraphOptions<'a> {
|
|||
pub workspace_fast_check: deno_graph::WorkspaceFastCheckOption<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum BuildGraphWithNpmResolutionError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
SerdeJson(#[from] serde_json::Error),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
ToMaybeJsxImportSourceConfig(
|
||||
#[from] deno_json::ToMaybeJsxImportSourceConfigError,
|
||||
),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
NodeModulesDirParse(#[from] deno_json::NodeModulesDirParseError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Other(#[from] JsErrorBox),
|
||||
#[class(generic)]
|
||||
#[error("Resolving npm specifier entrypoints this way is currently not supported with \"nodeModules\": \"manual\". In the meantime, try with --node-modules-dir=auto instead")]
|
||||
UnsupportedNpmSpecifierEntrypointResolutionWay,
|
||||
}
|
||||
|
||||
pub struct ModuleGraphBuilder {
|
||||
caches: Arc<cache::Caches>,
|
||||
cjs_tracker: Arc<CjsTracker>,
|
||||
cjs_tracker: Arc<CliCjsTracker>,
|
||||
cli_options: Arc<CliOptions>,
|
||||
file_fetcher: Arc<CliFileFetcher>,
|
||||
global_http_cache: Arc<GlobalHttpCache>,
|
||||
in_npm_pkg_checker: Arc<dyn InNpmPackageChecker>,
|
||||
in_npm_pkg_checker: DenoInNpmPackageChecker,
|
||||
lockfile: Option<Arc<CliLockfile>>,
|
||||
maybe_file_watcher_reporter: Option<FileWatcherReporter>,
|
||||
module_info_cache: Arc<ModuleInfoCache>,
|
||||
npm_resolver: Arc<dyn CliNpmResolver>,
|
||||
npm_graph_resolver: Arc<CliNpmGraphResolver>,
|
||||
npm_installer: Option<Arc<NpmInstaller>>,
|
||||
npm_resolver: CliNpmResolver,
|
||||
parsed_source_cache: Arc<ParsedSourceCache>,
|
||||
resolver: Arc<CliResolver>,
|
||||
root_permissions_container: PermissionsContainer,
|
||||
|
@ -450,15 +514,17 @@ impl ModuleGraphBuilder {
|
|||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
caches: Arc<cache::Caches>,
|
||||
cjs_tracker: Arc<CjsTracker>,
|
||||
cjs_tracker: Arc<CliCjsTracker>,
|
||||
cli_options: Arc<CliOptions>,
|
||||
file_fetcher: Arc<CliFileFetcher>,
|
||||
global_http_cache: Arc<GlobalHttpCache>,
|
||||
in_npm_pkg_checker: Arc<dyn InNpmPackageChecker>,
|
||||
in_npm_pkg_checker: DenoInNpmPackageChecker,
|
||||
lockfile: Option<Arc<CliLockfile>>,
|
||||
maybe_file_watcher_reporter: Option<FileWatcherReporter>,
|
||||
module_info_cache: Arc<ModuleInfoCache>,
|
||||
npm_resolver: Arc<dyn CliNpmResolver>,
|
||||
npm_graph_resolver: Arc<CliNpmGraphResolver>,
|
||||
npm_installer: Option<Arc<NpmInstaller>>,
|
||||
npm_resolver: CliNpmResolver,
|
||||
parsed_source_cache: Arc<ParsedSourceCache>,
|
||||
resolver: Arc<CliResolver>,
|
||||
root_permissions_container: PermissionsContainer,
|
||||
|
@ -474,6 +540,8 @@ impl ModuleGraphBuilder {
|
|||
lockfile,
|
||||
maybe_file_watcher_reporter,
|
||||
module_info_cache,
|
||||
npm_graph_resolver,
|
||||
npm_installer,
|
||||
npm_resolver,
|
||||
parsed_source_cache,
|
||||
resolver,
|
||||
|
@ -486,7 +554,7 @@ impl ModuleGraphBuilder {
|
|||
&self,
|
||||
graph: &mut ModuleGraph,
|
||||
options: CreateGraphOptions<'a>,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), BuildGraphWithNpmResolutionError> {
|
||||
enum MutLoaderRef<'a> {
|
||||
Borrowed(&'a mut dyn Loader),
|
||||
Owned(cache::FetchCacher),
|
||||
|
@ -572,10 +640,7 @@ impl ModuleGraphBuilder {
|
|||
Some(loader) => MutLoaderRef::Borrowed(loader),
|
||||
None => MutLoaderRef::Owned(self.create_graph_loader()),
|
||||
};
|
||||
let cli_resolver = &self.resolver;
|
||||
let graph_resolver = self.create_graph_resolver()?;
|
||||
let graph_npm_resolver =
|
||||
cli_resolver.create_graph_npm_resolver(options.npm_caching);
|
||||
let maybe_file_watcher_reporter = self
|
||||
.maybe_file_watcher_reporter
|
||||
.as_ref()
|
||||
|
@ -596,7 +661,7 @@ impl ModuleGraphBuilder {
|
|||
executor: Default::default(),
|
||||
file_system: &self.sys,
|
||||
jsr_url_provider: &CliJsrUrlProvider,
|
||||
npm_resolver: Some(&graph_npm_resolver),
|
||||
npm_resolver: Some(self.npm_graph_resolver.as_ref()),
|
||||
module_analyzer: &analyzer,
|
||||
reporter: maybe_file_watcher_reporter,
|
||||
resolver: Some(&graph_resolver),
|
||||
|
@ -614,22 +679,21 @@ impl ModuleGraphBuilder {
|
|||
loader: &'a mut dyn deno_graph::source::Loader,
|
||||
options: deno_graph::BuildOptions<'a>,
|
||||
npm_caching: NpmCachingStrategy,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), BuildGraphWithNpmResolutionError> {
|
||||
// ensure an "npm install" is done if the user has explicitly
|
||||
// opted into using a node_modules directory
|
||||
if self
|
||||
.cli_options
|
||||
.node_modules_dir()?
|
||||
.map(|m| m.uses_node_modules_dir())
|
||||
.map(|m| m == NodeModulesDirMode::Auto)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
if let Some(npm_resolver) = self.npm_resolver.as_managed() {
|
||||
let already_done =
|
||||
npm_resolver.ensure_top_level_package_json_install().await?;
|
||||
if let Some(npm_installer) = &self.npm_installer {
|
||||
let already_done = npm_installer
|
||||
.ensure_top_level_package_json_install()
|
||||
.await?;
|
||||
if !already_done && matches!(npm_caching, NpmCachingStrategy::Eager) {
|
||||
npm_resolver
|
||||
.cache_packages(crate::npm::PackageCaching::All)
|
||||
.await?;
|
||||
npm_installer.cache_packages(PackageCaching::All).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -648,10 +712,9 @@ impl ModuleGraphBuilder {
|
|||
let initial_package_deps_len = graph.packages.package_deps_sum();
|
||||
let initial_package_mappings_len = graph.packages.mappings().len();
|
||||
|
||||
if roots.iter().any(|r| r.scheme() == "npm")
|
||||
&& self.npm_resolver.as_byonm().is_some()
|
||||
if roots.iter().any(|r| r.scheme() == "npm") && self.npm_resolver.is_byonm()
|
||||
{
|
||||
bail!("Resolving npm specifier entrypoints this way is currently not supported with \"nodeModules\": \"manual\". In the meantime, try with --node-modules-dir=auto instead");
|
||||
return Err(BuildGraphWithNpmResolutionError::UnsupportedNpmSpecifierEntrypointResolutionWay);
|
||||
}
|
||||
|
||||
graph.build(roots, loader, options).await;
|
||||
|
@ -702,7 +765,7 @@ impl ModuleGraphBuilder {
|
|||
&self,
|
||||
graph: &mut ModuleGraph,
|
||||
options: BuildFastCheckGraphOptions,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), deno_json::ToMaybeJsxImportSourceConfigError> {
|
||||
if !graph.graph_kind().include_types() {
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -717,11 +780,7 @@ impl ModuleGraphBuilder {
|
|||
None
|
||||
};
|
||||
let parser = self.parsed_source_cache.as_capturing_parser();
|
||||
let cli_resolver = &self.resolver;
|
||||
let graph_resolver = self.create_graph_resolver()?;
|
||||
let graph_npm_resolver = cli_resolver.create_graph_npm_resolver(
|
||||
self.cli_options.default_npm_caching_strategy(),
|
||||
);
|
||||
|
||||
graph.build_fast_check_type_graph(
|
||||
deno_graph::BuildFastCheckTypeGraphOptions {
|
||||
|
@ -730,7 +789,7 @@ impl ModuleGraphBuilder {
|
|||
fast_check_dts: false,
|
||||
jsr_url_provider: &CliJsrUrlProvider,
|
||||
resolver: Some(&graph_resolver),
|
||||
npm_resolver: Some(&graph_npm_resolver),
|
||||
npm_resolver: Some(self.npm_graph_resolver.as_ref()),
|
||||
workspace_fast_check: options.workspace_fast_check,
|
||||
},
|
||||
);
|
||||
|
@ -766,7 +825,7 @@ impl ModuleGraphBuilder {
|
|||
/// Check if `roots` and their deps are available. Returns `Ok(())` if
|
||||
/// so. Returns `Err(_)` if there is a known module graph or resolution
|
||||
/// error statically reachable from `roots` and not a dynamic import.
|
||||
pub fn graph_valid(&self, graph: &ModuleGraph) -> Result<(), AnyError> {
|
||||
pub fn graph_valid(&self, graph: &ModuleGraph) -> Result<(), JsErrorBox> {
|
||||
self.graph_roots_valid(
|
||||
graph,
|
||||
&graph.roots.iter().cloned().collect::<Vec<_>>(),
|
||||
|
@ -777,7 +836,7 @@ impl ModuleGraphBuilder {
|
|||
&self,
|
||||
graph: &ModuleGraph,
|
||||
roots: &[ModuleSpecifier],
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), JsErrorBox> {
|
||||
graph_valid(
|
||||
graph,
|
||||
&self.sys,
|
||||
|
@ -794,7 +853,10 @@ impl ModuleGraphBuilder {
|
|||
)
|
||||
}
|
||||
|
||||
fn create_graph_resolver(&self) -> Result<CliGraphResolver, AnyError> {
|
||||
fn create_graph_resolver(
|
||||
&self,
|
||||
) -> Result<CliGraphResolver, deno_json::ToMaybeJsxImportSourceConfigError>
|
||||
{
|
||||
let jsx_import_source_config = self
|
||||
.cli_options
|
||||
.workspace()
|
||||
|
@ -835,6 +897,9 @@ pub fn enhanced_resolution_error_message(error: &ResolutionError) -> String {
|
|||
message
|
||||
}
|
||||
|
||||
static RUN_WITH_SLOPPY_IMPORTS_MSG: &str =
|
||||
"or run with --unstable-sloppy-imports";
|
||||
|
||||
fn enhanced_sloppy_imports_error_message(
|
||||
sys: &CliSys,
|
||||
error: &ModuleError,
|
||||
|
@ -842,11 +907,9 @@ fn enhanced_sloppy_imports_error_message(
|
|||
match error {
|
||||
ModuleError::LoadingErr(specifier, _, ModuleLoadError::Loader(_)) // ex. "Is a directory" error
|
||||
| ModuleError::Missing(specifier, _) => {
|
||||
let additional_message = CliSloppyImportsResolver::new(SloppyImportsCachedFs::new(sys.clone()))
|
||||
.resolve(specifier, SloppyImportsResolutionKind::Execution)?
|
||||
.as_suggestion_message();
|
||||
let additional_message = maybe_additional_sloppy_imports_message(sys, specifier)?;
|
||||
Some(format!(
|
||||
"{} {} or run with --unstable-sloppy-imports",
|
||||
"{} {}",
|
||||
error,
|
||||
additional_message,
|
||||
))
|
||||
|
@ -855,6 +918,19 @@ fn enhanced_sloppy_imports_error_message(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn maybe_additional_sloppy_imports_message(
|
||||
sys: &CliSys,
|
||||
specifier: &ModuleSpecifier,
|
||||
) -> Option<String> {
|
||||
Some(format!(
|
||||
"{} {}",
|
||||
CliSloppyImportsResolver::new(SloppyImportsCachedFs::new(sys.clone()))
|
||||
.resolve(specifier, SloppyImportsResolutionKind::Execution)?
|
||||
.as_suggestion_message(),
|
||||
RUN_WITH_SLOPPY_IMPORTS_MSG
|
||||
))
|
||||
}
|
||||
|
||||
fn enhanced_integrity_error_message(err: &ModuleError) -> Option<String> {
|
||||
match err {
|
||||
ModuleError::LoadingErr(
|
||||
|
@ -948,9 +1024,11 @@ fn get_resolution_error_bare_specifier(
|
|||
{
|
||||
Some(specifier.as_str())
|
||||
} else if let ResolutionError::ResolverError { error, .. } = error {
|
||||
if let ResolveError::Other(error) = (*error).as_ref() {
|
||||
if let Some(ImportMapError::UnmappedBareSpecifier(specifier, _)) =
|
||||
error.downcast_ref::<ImportMapError>()
|
||||
if let ResolveError::ImportMap(error) = (*error).as_ref() {
|
||||
if let import_map::ImportMapErrorKind::UnmappedBareSpecifier(
|
||||
specifier,
|
||||
_,
|
||||
) = error.as_kind()
|
||||
{
|
||||
Some(specifier.as_str())
|
||||
} else {
|
||||
|
@ -987,11 +1065,12 @@ fn get_import_prefix_missing_error(error: &ResolutionError) -> Option<&str> {
|
|||
ResolveError::Other(other_error) => {
|
||||
if let Some(SpecifierError::ImportPrefixMissing {
|
||||
specifier, ..
|
||||
}) = other_error.downcast_ref::<SpecifierError>()
|
||||
}) = other_error.as_any().downcast_ref::<SpecifierError>()
|
||||
{
|
||||
maybe_specifier = Some(specifier);
|
||||
}
|
||||
}
|
||||
ResolveError::ImportMap(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1146,7 +1225,7 @@ fn format_deno_graph_error(err: &dyn Error) -> String {
|
|||
|
||||
#[derive(Debug)]
|
||||
struct CliGraphResolver<'a> {
|
||||
cjs_tracker: &'a CjsTracker,
|
||||
cjs_tracker: &'a CliCjsTracker,
|
||||
resolver: &'a CliResolver,
|
||||
jsx_import_source_config: Option<JsxImportSourceConfig>,
|
||||
}
|
||||
|
@ -1242,7 +1321,7 @@ mod test {
|
|||
let specifier = ModuleSpecifier::parse("file:///file.ts").unwrap();
|
||||
let err = import_map.resolve(input, &specifier).err().unwrap();
|
||||
let err = ResolutionError::ResolverError {
|
||||
error: Arc::new(ResolveError::Other(err.into())),
|
||||
error: Arc::new(ResolveError::ImportMap(err)),
|
||||
specifier: input.to_string(),
|
||||
range: Range {
|
||||
specifier,
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use crate::util::progress_bar::UpdateGuard;
|
||||
use crate::version;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::thread::ThreadId;
|
||||
|
||||
use boxed_error::Boxed;
|
||||
use deno_cache_dir::file_fetcher::RedirectHeaderParseError;
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::StreamExt;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::serde;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::url::Url;
|
||||
use deno_error::JsError;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_runtime::deno_fetch;
|
||||
use deno_runtime::deno_fetch::create_http_client;
|
||||
use deno_runtime::deno_fetch::CreateHttpClientOptions;
|
||||
|
@ -23,12 +25,11 @@ use http::header::CONTENT_LENGTH;
|
|||
use http::HeaderMap;
|
||||
use http::StatusCode;
|
||||
use http_body_util::BodyExt;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::thread::ThreadId;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::util::progress_bar::UpdateGuard;
|
||||
use crate::version;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SendError {
|
||||
#[error(transparent)]
|
||||
|
@ -69,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();
|
||||
|
@ -86,7 +87,8 @@ impl HttpClientProvider {
|
|||
},
|
||||
..self.options.clone()
|
||||
},
|
||||
)?;
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
entry.insert(client.clone());
|
||||
Ok(HttpClient::new(client))
|
||||
}
|
||||
|
@ -94,34 +96,49 @@ impl HttpClientProvider {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
#[derive(Debug, Error, JsError)]
|
||||
#[class(type)]
|
||||
#[error("Bad response: {:?}{}", .status_code, .response_text.as_ref().map(|s| format!("\n\n{}", s)).unwrap_or_else(String::new))]
|
||||
pub struct BadResponseError {
|
||||
pub status_code: StatusCode,
|
||||
pub response_text: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Boxed)]
|
||||
#[derive(Debug, Boxed, JsError)]
|
||||
pub struct DownloadError(pub Box<DownloadErrorKind>);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
#[derive(Debug, Error, JsError)]
|
||||
pub enum DownloadErrorKind {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Fetch(AnyError),
|
||||
Fetch(deno_fetch::ClientSendError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
UrlParse(#[from] deno_core::url::ParseError),
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
HttpParse(#[from] http::Error),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Json(#[from] serde_json::Error),
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
ToStr(#[from] http::header::ToStrError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
RedirectHeaderParse(RedirectHeaderParseError),
|
||||
#[class(type)]
|
||||
#[error("Too many redirects.")]
|
||||
TooManyRedirects,
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
BadResponse(#[from] BadResponseError),
|
||||
#[class("Http")]
|
||||
#[error("Not Found.")]
|
||||
NotFound,
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Other(JsErrorBox),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -208,11 +225,11 @@ impl HttpClient {
|
|||
Ok(String::from_utf8(bytes)?)
|
||||
}
|
||||
|
||||
pub async fn download(&self, url: Url) -> Result<Vec<u8>, AnyError> {
|
||||
pub async fn download(&self, url: Url) -> Result<Vec<u8>, DownloadError> {
|
||||
let maybe_bytes = self.download_inner(url, None, None).await?;
|
||||
match maybe_bytes {
|
||||
Some(bytes) => Ok(bytes),
|
||||
None => Err(custom_error("Http", "Not found.")),
|
||||
None => Err(DownloadErrorKind::NotFound.into_box()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -276,7 +293,7 @@ impl HttpClient {
|
|||
get_response_body_with_progress(response, progress_guard)
|
||||
.await
|
||||
.map(|(_, body)| Some(body))
|
||||
.map_err(|err| DownloadErrorKind::Fetch(err).into_box())
|
||||
.map_err(|err| DownloadErrorKind::Other(err).into_box())
|
||||
}
|
||||
|
||||
async fn get_redirected_response(
|
||||
|
@ -293,7 +310,7 @@ impl HttpClient {
|
|||
.clone()
|
||||
.send(req)
|
||||
.await
|
||||
.map_err(|e| DownloadErrorKind::Fetch(e.into()).into_box())?;
|
||||
.map_err(|e| DownloadErrorKind::Fetch(e).into_box())?;
|
||||
let status = response.status();
|
||||
if status.is_redirection() {
|
||||
for _ in 0..5 {
|
||||
|
@ -313,7 +330,7 @@ impl HttpClient {
|
|||
.clone()
|
||||
.send(req)
|
||||
.await
|
||||
.map_err(|e| DownloadErrorKind::Fetch(e.into()).into_box())?;
|
||||
.map_err(|e| DownloadErrorKind::Fetch(e).into_box())?;
|
||||
let status = new_response.status();
|
||||
if status.is_redirection() {
|
||||
response = new_response;
|
||||
|
@ -332,7 +349,7 @@ impl HttpClient {
|
|||
pub async fn get_response_body_with_progress(
|
||||
response: http::Response<deno_fetch::ResBody>,
|
||||
progress_guard: Option<&UpdateGuard>,
|
||||
) -> Result<(HeaderMap, Vec<u8>), AnyError> {
|
||||
) -> Result<(HeaderMap, Vec<u8>), JsErrorBox> {
|
||||
use http_body::Body as _;
|
||||
if let Some(progress_guard) = progress_guard {
|
||||
let mut total_size = response.body().size_hint().exact();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
pub fn main() {
|
||||
let mut args = vec!["cargo", "test", "-p", "cli_tests", "--features", "run"];
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use log::debug;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
// deno-lint-ignore-file
|
||||
|
||||
import { core, primordials } from "ext:core/mod.js";
|
||||
|
@ -8,7 +8,7 @@ import {
|
|||
restorePermissions,
|
||||
} from "ext:cli/40_test_common.js";
|
||||
import { Console } from "ext:deno_console/01_console.js";
|
||||
import { setExitHandler } from "ext:runtime/30_os.js";
|
||||
import { setExitHandler } from "ext:deno_os/30_os.js";
|
||||
const {
|
||||
op_register_bench,
|
||||
op_bench_get_origin,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
// deno-lint-ignore-file
|
||||
|
||||
/*
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
// @ts-check
|
||||
|
||||
|
@ -406,8 +406,9 @@ export function splitSelectors(input) {
|
|||
}
|
||||
}
|
||||
|
||||
if (last < input.length - 1) {
|
||||
out.push(input.slice(last).trim());
|
||||
const remaining = input.slice(last).trim();
|
||||
if (remaining.length > 0) {
|
||||
out.push(remaining);
|
||||
}
|
||||
|
||||
return out;
|
||||
|
@ -743,8 +744,7 @@ export function compileSelector(selector) {
|
|||
fn = matchNthChild(node, fn);
|
||||
break;
|
||||
case PSEUDO_HAS:
|
||||
// FIXME
|
||||
// fn = matchIs(part, fn);
|
||||
// TODO(@marvinhagemeister)
|
||||
throw new Error("TODO: :has");
|
||||
case PSEUDO_NOT:
|
||||
fn = matchNot(node.selectors, fn);
|
||||
|
@ -766,8 +766,7 @@ export function compileSelector(selector) {
|
|||
*/
|
||||
function matchFirstChild(next) {
|
||||
return (ctx, id) => {
|
||||
const parent = ctx.getParent(id);
|
||||
const first = ctx.getFirstChild(parent);
|
||||
const first = ctx.getFirstChild(id);
|
||||
return first === id && next(ctx, first);
|
||||
};
|
||||
}
|
||||
|
@ -778,8 +777,7 @@ function matchFirstChild(next) {
|
|||
*/
|
||||
function matchLastChild(next) {
|
||||
return (ctx, id) => {
|
||||
const parent = ctx.getParent(id);
|
||||
const last = ctx.getLastChild(parent);
|
||||
const last = ctx.getLastChild(id);
|
||||
return last === id && next(ctx, id);
|
||||
};
|
||||
}
|
||||
|
@ -954,7 +952,9 @@ function matchElem(part, next) {
|
|||
else if (part.elem === 0) return false;
|
||||
|
||||
const type = ctx.getType(id);
|
||||
if (type > 0 && type === part.elem) return next(ctx, id);
|
||||
if (type > 0 && type === part.elem) {
|
||||
return next(ctx, id);
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
@ -967,7 +967,16 @@ function matchElem(part, next) {
|
|||
*/
|
||||
function matchAttrExists(attr, next) {
|
||||
return (ctx, id) => {
|
||||
return ctx.hasAttrPath(id, attr.prop, 0) ? next(ctx, id) : false;
|
||||
try {
|
||||
ctx.getAttrPathValue(id, attr.prop, 0);
|
||||
return next(ctx, id);
|
||||
} catch (err) {
|
||||
if (err === -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -978,9 +987,15 @@ function matchAttrExists(attr, next) {
|
|||
*/
|
||||
function matchAttrBin(attr, next) {
|
||||
return (ctx, id) => {
|
||||
if (!ctx.hasAttrPath(id, attr.prop, 0)) return false;
|
||||
const value = ctx.getAttrPathValue(id, attr.prop, 0);
|
||||
if (!matchAttrValue(attr, value)) return false;
|
||||
try {
|
||||
const value = ctx.getAttrPathValue(id, attr.prop, 0);
|
||||
if (!matchAttrValue(attr, value)) return false;
|
||||
} catch (err) {
|
||||
if (err === -1) {
|
||||
return false;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
return next(ctx, id);
|
||||
};
|
||||
}
|
||||
|
|
11
cli/js/40_lint_types.d.ts
vendored
11
cli/js/40_lint_types.d.ts
vendored
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
export interface NodeFacade {
|
||||
type: string;
|
||||
|
@ -12,6 +12,8 @@ export interface AstContext {
|
|||
strTableOffset: number;
|
||||
rootOffset: number;
|
||||
nodes: Map<number, NodeFacade>;
|
||||
spansOffset: number;
|
||||
propsOffset: number;
|
||||
strByType: number[];
|
||||
strByProp: number[];
|
||||
typeByStr: Map<string, number>;
|
||||
|
@ -19,6 +21,12 @@ export interface AstContext {
|
|||
matcher: MatchContext;
|
||||
}
|
||||
|
||||
export interface Node {
|
||||
range: Range;
|
||||
}
|
||||
|
||||
export type Range = [number, number];
|
||||
|
||||
// TODO(@marvinhagemeister) Remove once we land "official" types
|
||||
export interface RuleContext {
|
||||
id: string;
|
||||
|
@ -121,7 +129,6 @@ export interface MatchContext {
|
|||
getSiblings(id: number): number[];
|
||||
getParent(id: number): number;
|
||||
getType(id: number): number;
|
||||
hasAttrPath(id: number, propIds: number[], idx: number): boolean;
|
||||
getAttrPathValue(id: number, propIds: number[], idx: number): unknown;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
import { core, primordials } from "ext:core/mod.js";
|
||||
import { escapeName, withPermissions } from "ext:cli/40_test_common.js";
|
||||
|
@ -26,7 +26,7 @@ const {
|
|||
TypeError,
|
||||
} = primordials;
|
||||
|
||||
import { setExitHandler } from "ext:runtime/30_os.js";
|
||||
import { setExitHandler } from "ext:deno_os/30_os.js";
|
||||
|
||||
// Capture `Deno` global so that users deleting or mangling it, won't
|
||||
// have impact on our sanitizers.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
import { core, primordials } from "ext:core/mod.js";
|
||||
import { serializePermissions } from "ext:runtime/10_permissions.js";
|
||||
const ops = core.ops;
|
||||
|
|
10
cli/jsr.rs
10
cli/jsr.rs
|
@ -1,14 +1,16 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::args::jsr_url;
|
||||
use crate::file_fetcher::CliFileFetcher;
|
||||
use dashmap::DashMap;
|
||||
use deno_core::serde_json;
|
||||
use deno_graph::packages::JsrPackageInfo;
|
||||
use deno_graph::packages::JsrPackageVersionInfo;
|
||||
use deno_semver::package::PackageNv;
|
||||
use deno_semver::package::PackageReq;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::args::jsr_url;
|
||||
use crate::file_fetcher::CliFileFetcher;
|
||||
|
||||
/// This is similar to a subset of `JsrCacheResolver` which fetches rather than
|
||||
/// just reads the cache. Keep in sync!
|
||||
|
|
37
cli/lib/Cargo.toml
Normal file
37
cli/lib/Cargo.toml
Normal file
|
@ -0,0 +1,37 @@
|
|||
# Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
[package]
|
||||
name = "deno_lib"
|
||||
version = "0.2.0"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
readme = "README.md"
|
||||
repository.workspace = true
|
||||
description = "Shared code between the Deno CLI and denort"
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
deno_cache_dir.workspace = true
|
||||
deno_error.workspace = true
|
||||
deno_fs = { workspace = true, features = ["sync_fs"] }
|
||||
deno_node = { workspace = true, features = ["sync_fs"] }
|
||||
deno_path_util.workspace = true
|
||||
deno_resolver = { workspace = true, features = ["sync"] }
|
||||
deno_runtime.workspace = true
|
||||
deno_terminal.workspace = true
|
||||
faster-hex.workspace = true
|
||||
log.workspace = true
|
||||
node_resolver = { workspace = true, features = ["sync"] }
|
||||
parking_lot.workspace = true
|
||||
ring.workspace = true
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
sys_traits = { workspace = true, features = ["getrandom"] }
|
||||
thiserror.workspace = true
|
||||
tokio.workspace = true
|
||||
url.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
test_util.workspace = true
|
4
cli/lib/README.md
Normal file
4
cli/lib/README.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
# deno_lib
|
||||
|
||||
This crate contains the shared code between the Deno CLI and denort. It is
|
||||
highly unstable.
|
|
@ -1,25 +1,23 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_cache_dir::DenoDirResolutionError;
|
||||
use once_cell::sync::OnceCell;
|
||||
|
||||
use crate::sys::CliSys;
|
||||
|
||||
use super::DiskCache;
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use deno_cache_dir::DenoDirResolutionError;
|
||||
|
||||
use super::DiskCache;
|
||||
use crate::sys::DenoLibSys;
|
||||
|
||||
/// Lazily creates the deno dir which might be useful in scenarios
|
||||
/// where functionality wants to continue if the DENO_DIR can't be created.
|
||||
pub struct DenoDirProvider {
|
||||
sys: CliSys,
|
||||
pub struct DenoDirProvider<TSys: DenoLibSys> {
|
||||
sys: TSys,
|
||||
maybe_custom_root: Option<PathBuf>,
|
||||
deno_dir: OnceCell<Result<DenoDir, DenoDirResolutionError>>,
|
||||
deno_dir: std::sync::OnceLock<Result<DenoDir<TSys>, DenoDirResolutionError>>,
|
||||
}
|
||||
|
||||
impl DenoDirProvider {
|
||||
pub fn new(sys: CliSys, maybe_custom_root: Option<PathBuf>) -> Self {
|
||||
impl<TSys: DenoLibSys> DenoDirProvider<TSys> {
|
||||
pub fn new(sys: TSys, maybe_custom_root: Option<PathBuf>) -> Self {
|
||||
Self {
|
||||
sys,
|
||||
maybe_custom_root,
|
||||
|
@ -27,7 +25,9 @@ impl DenoDirProvider {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_or_create(&self) -> Result<&DenoDir, DenoDirResolutionError> {
|
||||
pub fn get_or_create(
|
||||
&self,
|
||||
) -> Result<&DenoDir<TSys>, DenoDirResolutionError> {
|
||||
self
|
||||
.deno_dir
|
||||
.get_or_init(|| {
|
||||
|
@ -50,16 +50,16 @@ impl DenoDirProvider {
|
|||
/// `DenoDir` serves as coordinator for multiple `DiskCache`s containing them
|
||||
/// in single directory that can be controlled with `$DENO_DIR` env variable.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DenoDir {
|
||||
pub struct DenoDir<TSys: DenoLibSys> {
|
||||
/// Example: /Users/rld/.deno/
|
||||
pub root: PathBuf,
|
||||
/// Used by TsCompiler to cache compiler output.
|
||||
pub gen_cache: DiskCache,
|
||||
pub gen_cache: DiskCache<TSys>,
|
||||
}
|
||||
|
||||
impl DenoDir {
|
||||
impl<TSys: DenoLibSys> DenoDir<TSys> {
|
||||
pub fn new(
|
||||
sys: CliSys,
|
||||
sys: TSys,
|
||||
maybe_custom_root: Option<PathBuf>,
|
||||
) -> Result<Self, deno_cache_dir::DenoDirResolutionError> {
|
||||
let root = deno_cache_dir::resolve_deno_dir(
|
|
@ -1,13 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use crate::sys::CliSys;
|
||||
|
||||
use super::CACHE_PERM;
|
||||
|
||||
use deno_cache_dir::url_to_filename;
|
||||
use deno_core::url::Host;
|
||||
use deno_core::url::Url;
|
||||
use deno_path_util::fs::atomic_write_file_with_retries;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs;
|
||||
use std::path::Component;
|
||||
|
@ -16,15 +8,23 @@ use std::path::PathBuf;
|
|||
use std::path::Prefix;
|
||||
use std::str;
|
||||
|
||||
use deno_cache_dir::url_to_filename;
|
||||
use deno_cache_dir::CACHE_PERM;
|
||||
use deno_path_util::fs::atomic_write_file_with_retries;
|
||||
use url::Host;
|
||||
use url::Url;
|
||||
|
||||
use crate::sys::DenoLibSys;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DiskCache {
|
||||
sys: CliSys,
|
||||
pub struct DiskCache<TSys: DenoLibSys> {
|
||||
sys: TSys,
|
||||
pub location: PathBuf,
|
||||
}
|
||||
|
||||
impl DiskCache {
|
||||
impl<TSys: DenoLibSys> DiskCache<TSys> {
|
||||
/// `location` must be an absolute path.
|
||||
pub fn new(sys: CliSys, location: &Path) -> Self {
|
||||
pub fn new(sys: TSys, location: &Path) -> Self {
|
||||
assert!(location.is_absolute());
|
||||
Self {
|
||||
sys,
|
||||
|
@ -130,14 +130,18 @@ impl DiskCache {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
// ok, testing
|
||||
#[allow(clippy::disallowed_types)]
|
||||
use sys_traits::impls::RealSys;
|
||||
use test_util::TempDir;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_set_get_cache_file() {
|
||||
let temp_dir = TempDir::new();
|
||||
let sub_dir = temp_dir.path().join("sub_dir");
|
||||
let cache = DiskCache::new(CliSys::default(), &sub_dir.to_path_buf());
|
||||
let cache = DiskCache::new(RealSys, &sub_dir.to_path_buf());
|
||||
let path = PathBuf::from("foo/bar.txt");
|
||||
cache.set(&path, b"hello").unwrap();
|
||||
assert_eq!(cache.get(&path).unwrap(), b"hello");
|
||||
|
@ -151,7 +155,7 @@ mod tests {
|
|||
PathBuf::from("/deno_dir/")
|
||||
};
|
||||
|
||||
let cache = DiskCache::new(CliSys::default(), &cache_location);
|
||||
let cache = DiskCache::new(RealSys, &cache_location);
|
||||
|
||||
let mut test_cases = vec![
|
||||
(
|
||||
|
@ -207,7 +211,7 @@ mod tests {
|
|||
} else {
|
||||
"/foo"
|
||||
};
|
||||
let cache = DiskCache::new(CliSys::default(), &PathBuf::from(p));
|
||||
let cache = DiskCache::new(RealSys, &PathBuf::from(p));
|
||||
|
||||
let mut test_cases = vec![
|
||||
(
|
||||
|
@ -255,7 +259,7 @@ mod tests {
|
|||
PathBuf::from("/deno_dir/")
|
||||
};
|
||||
|
||||
let cache = DiskCache::new(CliSys::default(), &cache_location);
|
||||
let cache = DiskCache::new(RealSys, &cache_location);
|
||||
|
||||
let mut test_cases = vec!["unknown://localhost/test.ts"];
|
||||
|
8
cli/lib/cache/mod.rs
vendored
Normal file
8
cli/lib/cache/mod.rs
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
pub use deno_dir::DenoDir;
|
||||
pub use deno_dir::DenoDirProvider;
|
||||
pub use disk_cache::DiskCache;
|
||||
|
||||
mod deno_dir;
|
||||
mod disk_cache;
|
10
cli/lib/env.rs
Normal file
10
cli/lib/env.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
pub fn has_trace_permissions_enabled() -> bool {
|
||||
has_flag_env_var("DENO_TRACE_PERMISSIONS")
|
||||
}
|
||||
|
||||
pub fn has_flag_env_var(name: &str) -> bool {
|
||||
let value = std::env::var(name);
|
||||
matches!(value.as_ref().map(|s| s.as_str()), Ok("1"))
|
||||
}
|
9
cli/lib/lib.rs
Normal file
9
cli/lib/lib.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
pub mod cache;
|
||||
pub mod env;
|
||||
pub mod npm;
|
||||
pub mod standalone;
|
||||
pub mod sys;
|
||||
pub mod util;
|
||||
pub mod worker;
|
6
cli/lib/npm/mod.rs
Normal file
6
cli/lib/npm/mod.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
mod permission_checker;
|
||||
|
||||
pub use permission_checker::NpmRegistryReadPermissionChecker;
|
||||
pub use permission_checker::NpmRegistryReadPermissionCheckerMode;
|
120
cli/lib/npm/permission_checker.rs
Normal file
120
cli/lib/npm/permission_checker.rs
Normal file
|
@ -0,0 +1,120 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::io::ErrorKind;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_runtime::deno_node::NodePermissions;
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use crate::sys::DenoLibSys;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum NpmRegistryReadPermissionCheckerMode {
|
||||
Byonm,
|
||||
Global(PathBuf),
|
||||
Local(PathBuf),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct NpmRegistryReadPermissionChecker<TSys: DenoLibSys> {
|
||||
sys: TSys,
|
||||
cache: Mutex<HashMap<PathBuf, PathBuf>>,
|
||||
mode: NpmRegistryReadPermissionCheckerMode,
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
#[class(inherit)]
|
||||
#[error("failed canonicalizing '{path}'")]
|
||||
struct EnsureRegistryReadPermissionError {
|
||||
path: PathBuf,
|
||||
#[source]
|
||||
#[inherit]
|
||||
source: std::io::Error,
|
||||
}
|
||||
|
||||
impl<TSys: DenoLibSys> NpmRegistryReadPermissionChecker<TSys> {
|
||||
pub fn new(sys: TSys, mode: NpmRegistryReadPermissionCheckerMode) -> Self {
|
||||
Self {
|
||||
sys,
|
||||
cache: Default::default(),
|
||||
mode,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
|
||||
pub fn ensure_read_permission<'a>(
|
||||
&self,
|
||||
permissions: &mut dyn NodePermissions,
|
||||
path: &'a Path,
|
||||
) -> Result<Cow<'a, Path>, JsErrorBox> {
|
||||
if permissions.query_read_all() {
|
||||
return Ok(Cow::Borrowed(path)); // skip permissions checks below
|
||||
}
|
||||
|
||||
match &self.mode {
|
||||
NpmRegistryReadPermissionCheckerMode::Byonm => {
|
||||
if path.components().any(|c| c.as_os_str() == "node_modules") {
|
||||
Ok(Cow::Borrowed(path))
|
||||
} else {
|
||||
permissions
|
||||
.check_read_path(path)
|
||||
.map_err(JsErrorBox::from_err)
|
||||
}
|
||||
}
|
||||
NpmRegistryReadPermissionCheckerMode::Global(registry_path)
|
||||
| NpmRegistryReadPermissionCheckerMode::Local(registry_path) => {
|
||||
// allow reading if it's in the node_modules
|
||||
let is_path_in_node_modules = path.starts_with(registry_path)
|
||||
&& path
|
||||
.components()
|
||||
.all(|c| !matches!(c, std::path::Component::ParentDir));
|
||||
|
||||
if is_path_in_node_modules {
|
||||
let mut cache = self.cache.lock();
|
||||
let mut canonicalize =
|
||||
|path: &Path| -> Result<Option<PathBuf>, JsErrorBox> {
|
||||
match cache.get(path) {
|
||||
Some(canon) => Ok(Some(canon.clone())),
|
||||
None => match self.sys.fs_canonicalize(path) {
|
||||
Ok(canon) => {
|
||||
cache.insert(path.to_path_buf(), canon.clone());
|
||||
Ok(Some(canon))
|
||||
}
|
||||
Err(e) => {
|
||||
if e.kind() == ErrorKind::NotFound {
|
||||
return Ok(None);
|
||||
}
|
||||
Err(JsErrorBox::from_err(
|
||||
EnsureRegistryReadPermissionError {
|
||||
path: path.to_path_buf(),
|
||||
source: e,
|
||||
},
|
||||
))
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
if let Some(registry_path_canon) = canonicalize(registry_path)? {
|
||||
if let Some(path_canon) = canonicalize(path)? {
|
||||
if path_canon.starts_with(registry_path_canon) {
|
||||
return Ok(Cow::Owned(path_canon));
|
||||
}
|
||||
} else if path.starts_with(registry_path_canon)
|
||||
|| path.starts_with(registry_path)
|
||||
{
|
||||
return Ok(Cow::Borrowed(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
permissions
|
||||
.check_read_path(path)
|
||||
.map_err(JsErrorBox::from_err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3
cli/lib/standalone/mod.rs
Normal file
3
cli/lib/standalone/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
pub mod virtual_fs;
|
296
cli/lib/standalone/virtual_fs.rs
Normal file
296
cli/lib/standalone/virtual_fs.rs
Normal file
|
@ -0,0 +1,296 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum VfsFileSubDataKind {
|
||||
/// Raw bytes of the file.
|
||||
Raw,
|
||||
/// Bytes to use for module loading. For example, for TypeScript
|
||||
/// files this will be the transpiled JavaScript source.
|
||||
ModuleGraph,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum WindowsSystemRootablePath {
|
||||
/// The root of the system above any drive letters.
|
||||
WindowSystemRoot,
|
||||
Path(PathBuf),
|
||||
}
|
||||
|
||||
impl WindowsSystemRootablePath {
|
||||
pub fn join(&self, name_component: &str) -> PathBuf {
|
||||
// this method doesn't handle multiple components
|
||||
debug_assert!(
|
||||
!name_component.contains('\\'),
|
||||
"Invalid component: {}",
|
||||
name_component
|
||||
);
|
||||
debug_assert!(
|
||||
!name_component.contains('/'),
|
||||
"Invalid component: {}",
|
||||
name_component
|
||||
);
|
||||
|
||||
match self {
|
||||
WindowsSystemRootablePath::WindowSystemRoot => {
|
||||
// windows drive letter
|
||||
PathBuf::from(&format!("{}\\", name_component))
|
||||
}
|
||||
WindowsSystemRootablePath::Path(path) => path.join(name_component),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
|
||||
pub enum FileSystemCaseSensitivity {
|
||||
#[serde(rename = "s")]
|
||||
Sensitive,
|
||||
#[serde(rename = "i")]
|
||||
Insensitive,
|
||||
}
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
pub struct VirtualDirectoryEntries(Vec<VfsEntry>);
|
||||
|
||||
impl VirtualDirectoryEntries {
|
||||
pub fn new(mut entries: Vec<VfsEntry>) -> Self {
|
||||
// needs to be sorted by name
|
||||
entries.sort_by(|a, b| a.name().cmp(b.name()));
|
||||
Self(entries)
|
||||
}
|
||||
|
||||
pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, VfsEntry> {
|
||||
self.0.iter_mut()
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> std::slice::Iter<'_, VfsEntry> {
|
||||
self.0.iter()
|
||||
}
|
||||
|
||||
pub fn take_inner(&mut self) -> Vec<VfsEntry> {
|
||||
std::mem::take(&mut self.0)
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
pub fn get_by_name(
|
||||
&self,
|
||||
name: &str,
|
||||
case_sensitivity: FileSystemCaseSensitivity,
|
||||
) -> Option<&VfsEntry> {
|
||||
self
|
||||
.binary_search(name, case_sensitivity)
|
||||
.ok()
|
||||
.map(|index| &self.0[index])
|
||||
}
|
||||
|
||||
pub fn get_mut_by_name(
|
||||
&mut self,
|
||||
name: &str,
|
||||
case_sensitivity: FileSystemCaseSensitivity,
|
||||
) -> Option<&mut VfsEntry> {
|
||||
self
|
||||
.binary_search(name, case_sensitivity)
|
||||
.ok()
|
||||
.map(|index| &mut self.0[index])
|
||||
}
|
||||
|
||||
pub fn get_mut_by_index(&mut self, index: usize) -> Option<&mut VfsEntry> {
|
||||
self.0.get_mut(index)
|
||||
}
|
||||
|
||||
pub fn binary_search(
|
||||
&self,
|
||||
name: &str,
|
||||
case_sensitivity: FileSystemCaseSensitivity,
|
||||
) -> Result<usize, usize> {
|
||||
match case_sensitivity {
|
||||
FileSystemCaseSensitivity::Sensitive => {
|
||||
self.0.binary_search_by(|e| e.name().cmp(name))
|
||||
}
|
||||
FileSystemCaseSensitivity::Insensitive => self.0.binary_search_by(|e| {
|
||||
e.name()
|
||||
.chars()
|
||||
.zip(name.chars())
|
||||
.map(|(a, b)| a.to_ascii_lowercase().cmp(&b.to_ascii_lowercase()))
|
||||
.find(|&ord| ord != Ordering::Equal)
|
||||
.unwrap_or_else(|| e.name().len().cmp(&name.len()))
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert(
|
||||
&mut self,
|
||||
entry: VfsEntry,
|
||||
case_sensitivity: FileSystemCaseSensitivity,
|
||||
) -> usize {
|
||||
match self.binary_search(entry.name(), case_sensitivity) {
|
||||
Ok(index) => {
|
||||
self.0[index] = entry;
|
||||
index
|
||||
}
|
||||
Err(insert_index) => {
|
||||
self.0.insert(insert_index, entry);
|
||||
insert_index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_or_modify(
|
||||
&mut self,
|
||||
name: &str,
|
||||
case_sensitivity: FileSystemCaseSensitivity,
|
||||
on_insert: impl FnOnce() -> VfsEntry,
|
||||
on_modify: impl FnOnce(&mut VfsEntry),
|
||||
) -> usize {
|
||||
match self.binary_search(name, case_sensitivity) {
|
||||
Ok(index) => {
|
||||
on_modify(&mut self.0[index]);
|
||||
index
|
||||
}
|
||||
Err(insert_index) => {
|
||||
self.0.insert(insert_index, on_insert());
|
||||
insert_index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, index: usize) -> VfsEntry {
|
||||
self.0.remove(index)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct VirtualDirectory {
|
||||
#[serde(rename = "n")]
|
||||
pub name: String,
|
||||
// should be sorted by name
|
||||
#[serde(rename = "e")]
|
||||
pub entries: VirtualDirectoryEntries,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
pub struct OffsetWithLength {
|
||||
#[serde(rename = "o")]
|
||||
pub offset: u64,
|
||||
#[serde(rename = "l")]
|
||||
pub len: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct VirtualFile {
|
||||
#[serde(rename = "n")]
|
||||
pub name: String,
|
||||
#[serde(rename = "o")]
|
||||
pub offset: OffsetWithLength,
|
||||
/// Offset file to use for module loading when it differs from the
|
||||
/// raw file. Often this will be the same offset as above for data
|
||||
/// such as JavaScript files, but for TypeScript files the `offset`
|
||||
/// will be the original raw bytes when included as an asset and this
|
||||
/// offset will be to the transpiled JavaScript source.
|
||||
#[serde(rename = "m")]
|
||||
pub module_graph_offset: OffsetWithLength,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct VirtualSymlinkParts(Vec<String>);
|
||||
|
||||
impl VirtualSymlinkParts {
|
||||
pub fn from_path(path: &Path) -> Self {
|
||||
Self(
|
||||
path
|
||||
.components()
|
||||
.filter(|c| !matches!(c, std::path::Component::RootDir))
|
||||
.map(|c| c.as_os_str().to_string_lossy().to_string())
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn take_parts(&mut self) -> Vec<String> {
|
||||
std::mem::take(&mut self.0)
|
||||
}
|
||||
|
||||
pub fn parts(&self) -> &[String] {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn set_parts(&mut self, parts: Vec<String>) {
|
||||
self.0 = parts;
|
||||
}
|
||||
|
||||
pub fn display(&self) -> String {
|
||||
self.0.join("/")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct VirtualSymlink {
|
||||
#[serde(rename = "n")]
|
||||
pub name: String,
|
||||
#[serde(rename = "p")]
|
||||
pub dest_parts: VirtualSymlinkParts,
|
||||
}
|
||||
|
||||
impl VirtualSymlink {
|
||||
pub fn resolve_dest_from_root(&self, root: &Path) -> PathBuf {
|
||||
let mut dest = root.to_path_buf();
|
||||
for part in &self.dest_parts.0 {
|
||||
dest.push(part);
|
||||
}
|
||||
dest
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum VfsEntryRef<'a> {
|
||||
Dir(&'a VirtualDirectory),
|
||||
File(&'a VirtualFile),
|
||||
Symlink(&'a VirtualSymlink),
|
||||
}
|
||||
|
||||
impl VfsEntryRef<'_> {
|
||||
pub fn name(&self) -> &str {
|
||||
match self {
|
||||
Self::Dir(dir) => &dir.name,
|
||||
Self::File(file) => &file.name,
|
||||
Self::Symlink(symlink) => &symlink.name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// todo(dsherret): we should store this more efficiently in the binary
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum VfsEntry {
|
||||
Dir(VirtualDirectory),
|
||||
File(VirtualFile),
|
||||
Symlink(VirtualSymlink),
|
||||
}
|
||||
|
||||
impl VfsEntry {
|
||||
pub fn name(&self) -> &str {
|
||||
match self {
|
||||
Self::Dir(dir) => &dir.name,
|
||||
Self::File(file) => &file.name,
|
||||
Self::Symlink(symlink) => &symlink.name,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_ref(&self) -> VfsEntryRef {
|
||||
match self {
|
||||
VfsEntry::Dir(dir) => VfsEntryRef::Dir(dir),
|
||||
VfsEntry::File(file) => VfsEntryRef::File(file),
|
||||
VfsEntry::Symlink(symlink) => VfsEntryRef::Symlink(symlink),
|
||||
}
|
||||
}
|
||||
}
|
37
cli/lib/sys.rs
Normal file
37
cli/lib/sys.rs
Normal file
|
@ -0,0 +1,37 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use deno_node::ExtNodeSys;
|
||||
use sys_traits::FsCanonicalize;
|
||||
use sys_traits::FsCreateDirAll;
|
||||
use sys_traits::FsMetadata;
|
||||
use sys_traits::FsOpen;
|
||||
use sys_traits::FsRead;
|
||||
use sys_traits::FsReadDir;
|
||||
use sys_traits::FsRemoveFile;
|
||||
use sys_traits::FsRename;
|
||||
use sys_traits::SystemRandom;
|
||||
use sys_traits::ThreadSleep;
|
||||
|
||||
pub trait DenoLibSys:
|
||||
FsCanonicalize
|
||||
+ FsCreateDirAll
|
||||
+ FsReadDir
|
||||
+ FsMetadata
|
||||
+ FsOpen
|
||||
+ FsRemoveFile
|
||||
+ FsRename
|
||||
+ FsRead
|
||||
+ ThreadSleep
|
||||
+ SystemRandom
|
||||
+ ExtNodeSys
|
||||
+ Clone
|
||||
+ Send
|
||||
+ Sync
|
||||
+ std::fmt::Debug
|
||||
+ 'static
|
||||
{
|
||||
}
|
||||
|
||||
// ok, implementation
|
||||
#[allow(clippy::disallowed_types)]
|
||||
impl DenoLibSys for sys_traits::impls::RealSys {}
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use ring::digest::Context;
|
||||
use ring::digest::SHA256;
|
3
cli/lib/util/mod.rs
Normal file
3
cli/lib/util/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
pub mod checksum;
|
581
cli/lib/worker.rs
Normal file
581
cli/lib/worker.rs
Normal file
|
@ -0,0 +1,581 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_core::error::JsError;
|
||||
use deno_node::NodeRequireLoaderRc;
|
||||
use deno_resolver::npm::DenoInNpmPackageChecker;
|
||||
use deno_resolver::npm::NpmResolver;
|
||||
use deno_runtime::colors;
|
||||
use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel;
|
||||
use deno_runtime::deno_core;
|
||||
use deno_runtime::deno_core::error::CoreError;
|
||||
use deno_runtime::deno_core::v8;
|
||||
use deno_runtime::deno_core::CompiledWasmModuleStore;
|
||||
use deno_runtime::deno_core::Extension;
|
||||
use deno_runtime::deno_core::FeatureChecker;
|
||||
use deno_runtime::deno_core::JsRuntime;
|
||||
use deno_runtime::deno_core::LocalInspectorSession;
|
||||
use deno_runtime::deno_core::ModuleLoader;
|
||||
use deno_runtime::deno_core::SharedArrayBufferStore;
|
||||
use deno_runtime::deno_fs;
|
||||
use deno_runtime::deno_node::NodeExtInitServices;
|
||||
use deno_runtime::deno_node::NodeRequireLoader;
|
||||
use deno_runtime::deno_node::NodeResolver;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
use deno_runtime::deno_process::NpmProcessStateProviderRc;
|
||||
use deno_runtime::deno_telemetry::OtelConfig;
|
||||
use deno_runtime::deno_tls::RootCertStoreProvider;
|
||||
use deno_runtime::deno_web::BlobStore;
|
||||
use deno_runtime::fmt_errors::format_js_error;
|
||||
use deno_runtime::inspector_server::InspectorServer;
|
||||
use deno_runtime::ops::worker_host::CreateWebWorkerCb;
|
||||
use deno_runtime::web_worker::WebWorker;
|
||||
use deno_runtime::web_worker::WebWorkerOptions;
|
||||
use deno_runtime::web_worker::WebWorkerServiceOptions;
|
||||
use deno_runtime::worker::MainWorker;
|
||||
use deno_runtime::worker::WorkerOptions;
|
||||
use deno_runtime::worker::WorkerServiceOptions;
|
||||
use deno_runtime::BootstrapOptions;
|
||||
use deno_runtime::WorkerExecutionMode;
|
||||
use deno_runtime::WorkerLogLevel;
|
||||
use deno_runtime::UNSTABLE_GRANULAR_FLAGS;
|
||||
use url::Url;
|
||||
|
||||
use crate::env::has_trace_permissions_enabled;
|
||||
use crate::sys::DenoLibSys;
|
||||
use crate::util::checksum;
|
||||
|
||||
pub struct CreateModuleLoaderResult {
|
||||
pub module_loader: Rc<dyn ModuleLoader>,
|
||||
pub node_require_loader: Rc<dyn NodeRequireLoader>,
|
||||
}
|
||||
|
||||
pub trait ModuleLoaderFactory: Send + Sync {
|
||||
fn create_for_main(
|
||||
&self,
|
||||
root_permissions: PermissionsContainer,
|
||||
) -> CreateModuleLoaderResult;
|
||||
|
||||
fn create_for_worker(
|
||||
&self,
|
||||
parent_permissions: PermissionsContainer,
|
||||
permissions: PermissionsContainer,
|
||||
) -> CreateModuleLoaderResult;
|
||||
}
|
||||
|
||||
enum StorageKeyResolverStrategy {
|
||||
Specified(Option<String>),
|
||||
UseMainModule,
|
||||
}
|
||||
|
||||
pub struct StorageKeyResolver(StorageKeyResolverStrategy);
|
||||
|
||||
impl StorageKeyResolver {
|
||||
pub fn from_flag(location: &Url) -> Self {
|
||||
// if a location is set, then the ascii serialization of the location is
|
||||
// used, unless the origin is opaque, and then no storage origin is set, as
|
||||
// we can't expect the origin to be reproducible
|
||||
let storage_origin = location.origin();
|
||||
Self(StorageKeyResolverStrategy::Specified(
|
||||
if storage_origin.is_tuple() {
|
||||
Some(storage_origin.ascii_serialization())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn from_config_file_url(url: &Url) -> Self {
|
||||
Self(StorageKeyResolverStrategy::Specified(Some(url.to_string())))
|
||||
}
|
||||
|
||||
pub fn new_use_main_module() -> Self {
|
||||
Self(StorageKeyResolverStrategy::UseMainModule)
|
||||
}
|
||||
|
||||
/// Creates a storage key resolver that will always resolve to being empty.
|
||||
pub fn empty() -> Self {
|
||||
Self(StorageKeyResolverStrategy::Specified(None))
|
||||
}
|
||||
|
||||
/// Resolves the storage key to use based on the current flags, config, or main module.
|
||||
pub fn resolve_storage_key(&self, main_module: &Url) -> Option<String> {
|
||||
// use the stored value or fall back to using the path of the main module.
|
||||
match &self.0 {
|
||||
StorageKeyResolverStrategy::Specified(value) => value.clone(),
|
||||
StorageKeyResolverStrategy::UseMainModule => {
|
||||
Some(main_module.to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(bartlomieju): this should be moved to some other place, added to avoid string
|
||||
// duplication between worker setups and `deno info` output.
|
||||
pub fn get_cache_storage_dir() -> PathBuf {
|
||||
// Note: we currently use temp_dir() to avoid managing storage size.
|
||||
std::env::temp_dir().join("deno_cache")
|
||||
}
|
||||
|
||||
/// By default V8 uses 1.4Gb heap limit which is meant for browser tabs.
|
||||
/// Instead probe for the total memory on the system and use it instead
|
||||
/// as a default.
|
||||
pub fn create_isolate_create_params() -> Option<v8::CreateParams> {
|
||||
let maybe_mem_info = deno_runtime::deno_os::sys_info::mem_info();
|
||||
maybe_mem_info.map(|mem_info| {
|
||||
v8::CreateParams::default()
|
||||
.heap_limits_from_system_memory(mem_info.total, 0)
|
||||
})
|
||||
}
|
||||
|
||||
pub struct LibMainWorkerOptions {
|
||||
pub argv: Vec<String>,
|
||||
pub deno_version: &'static str,
|
||||
pub deno_user_agent: &'static str,
|
||||
pub log_level: WorkerLogLevel,
|
||||
pub enable_op_summary_metrics: bool,
|
||||
pub enable_testing_features: bool,
|
||||
pub has_node_modules_dir: bool,
|
||||
pub inspect_brk: bool,
|
||||
pub inspect_wait: bool,
|
||||
pub strace_ops: Option<Vec<String>>,
|
||||
pub is_inspecting: bool,
|
||||
pub location: Option<Url>,
|
||||
pub argv0: Option<String>,
|
||||
pub node_debug: Option<String>,
|
||||
pub otel_config: OtelConfig,
|
||||
pub origin_data_folder_path: Option<PathBuf>,
|
||||
pub seed: Option<u64>,
|
||||
pub unsafely_ignore_certificate_errors: Option<Vec<String>>,
|
||||
pub skip_op_registration: bool,
|
||||
pub node_ipc: Option<i64>,
|
||||
pub startup_snapshot: Option<&'static [u8]>,
|
||||
pub serve_port: Option<u16>,
|
||||
pub serve_host: Option<String>,
|
||||
}
|
||||
|
||||
struct LibWorkerFactorySharedState<TSys: DenoLibSys> {
|
||||
blob_store: Arc<BlobStore>,
|
||||
broadcast_channel: InMemoryBroadcastChannel,
|
||||
code_cache: Option<Arc<dyn deno_runtime::code_cache::CodeCache>>,
|
||||
compiled_wasm_module_store: CompiledWasmModuleStore,
|
||||
feature_checker: Arc<FeatureChecker>,
|
||||
fs: Arc<dyn deno_fs::FileSystem>,
|
||||
maybe_inspector_server: Option<Arc<InspectorServer>>,
|
||||
module_loader_factory: Box<dyn ModuleLoaderFactory>,
|
||||
node_resolver:
|
||||
Arc<NodeResolver<DenoInNpmPackageChecker, NpmResolver<TSys>, TSys>>,
|
||||
npm_process_state_provider: NpmProcessStateProviderRc,
|
||||
pkg_json_resolver: Arc<node_resolver::PackageJsonResolver<TSys>>,
|
||||
root_cert_store_provider: Arc<dyn RootCertStoreProvider>,
|
||||
shared_array_buffer_store: SharedArrayBufferStore,
|
||||
storage_key_resolver: StorageKeyResolver,
|
||||
sys: TSys,
|
||||
options: LibMainWorkerOptions,
|
||||
}
|
||||
|
||||
impl<TSys: DenoLibSys> LibWorkerFactorySharedState<TSys> {
|
||||
fn resolve_unstable_features(
|
||||
&self,
|
||||
feature_checker: &FeatureChecker,
|
||||
) -> Vec<i32> {
|
||||
let mut unstable_features =
|
||||
Vec::with_capacity(UNSTABLE_GRANULAR_FLAGS.len());
|
||||
for granular_flag in UNSTABLE_GRANULAR_FLAGS {
|
||||
if feature_checker.check(granular_flag.name) {
|
||||
unstable_features.push(granular_flag.id);
|
||||
}
|
||||
}
|
||||
unstable_features
|
||||
}
|
||||
|
||||
fn create_node_init_services(
|
||||
&self,
|
||||
node_require_loader: NodeRequireLoaderRc,
|
||||
) -> NodeExtInitServices<DenoInNpmPackageChecker, NpmResolver<TSys>, TSys> {
|
||||
NodeExtInitServices {
|
||||
node_require_loader,
|
||||
node_resolver: self.node_resolver.clone(),
|
||||
pkg_json_resolver: self.pkg_json_resolver.clone(),
|
||||
sys: self.sys.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn create_web_worker_callback(
|
||||
self: &Arc<Self>,
|
||||
stdio: deno_runtime::deno_io::Stdio,
|
||||
) -> Arc<CreateWebWorkerCb> {
|
||||
let shared = self.clone();
|
||||
Arc::new(move |args| {
|
||||
let maybe_inspector_server = shared.maybe_inspector_server.clone();
|
||||
|
||||
let CreateModuleLoaderResult {
|
||||
module_loader,
|
||||
node_require_loader,
|
||||
} = shared.module_loader_factory.create_for_worker(
|
||||
args.parent_permissions.clone(),
|
||||
args.permissions.clone(),
|
||||
);
|
||||
let create_web_worker_cb =
|
||||
shared.create_web_worker_callback(stdio.clone());
|
||||
|
||||
let maybe_storage_key = shared
|
||||
.storage_key_resolver
|
||||
.resolve_storage_key(&args.main_module);
|
||||
let cache_storage_dir = maybe_storage_key.map(|key| {
|
||||
// TODO(@satyarohith): storage quota management
|
||||
get_cache_storage_dir().join(checksum::gen(&[key.as_bytes()]))
|
||||
});
|
||||
|
||||
// TODO(bartlomieju): this is cruft, update FeatureChecker to spit out
|
||||
// list of enabled features.
|
||||
let feature_checker = shared.feature_checker.clone();
|
||||
let unstable_features =
|
||||
shared.resolve_unstable_features(feature_checker.as_ref());
|
||||
|
||||
let services = WebWorkerServiceOptions {
|
||||
root_cert_store_provider: Some(shared.root_cert_store_provider.clone()),
|
||||
module_loader,
|
||||
fs: shared.fs.clone(),
|
||||
node_services: Some(
|
||||
shared.create_node_init_services(node_require_loader),
|
||||
),
|
||||
blob_store: shared.blob_store.clone(),
|
||||
broadcast_channel: shared.broadcast_channel.clone(),
|
||||
shared_array_buffer_store: Some(
|
||||
shared.shared_array_buffer_store.clone(),
|
||||
),
|
||||
compiled_wasm_module_store: Some(
|
||||
shared.compiled_wasm_module_store.clone(),
|
||||
),
|
||||
maybe_inspector_server,
|
||||
feature_checker,
|
||||
npm_process_state_provider: Some(
|
||||
shared.npm_process_state_provider.clone(),
|
||||
),
|
||||
permissions: args.permissions,
|
||||
};
|
||||
let options = WebWorkerOptions {
|
||||
name: args.name,
|
||||
main_module: args.main_module.clone(),
|
||||
worker_id: args.worker_id,
|
||||
bootstrap: BootstrapOptions {
|
||||
deno_version: shared.options.deno_version.to_string(),
|
||||
args: shared.options.argv.clone(),
|
||||
cpu_count: std::thread::available_parallelism()
|
||||
.map(|p| p.get())
|
||||
.unwrap_or(1),
|
||||
log_level: shared.options.log_level,
|
||||
enable_op_summary_metrics: shared.options.enable_op_summary_metrics,
|
||||
enable_testing_features: shared.options.enable_testing_features,
|
||||
locale: deno_core::v8::icu::get_language_tag(),
|
||||
location: Some(args.main_module),
|
||||
no_color: !colors::use_color(),
|
||||
color_level: colors::get_color_level(),
|
||||
is_stdout_tty: deno_terminal::is_stdout_tty(),
|
||||
is_stderr_tty: deno_terminal::is_stderr_tty(),
|
||||
unstable_features,
|
||||
user_agent: shared.options.deno_user_agent.to_string(),
|
||||
inspect: shared.options.is_inspecting,
|
||||
has_node_modules_dir: shared.options.has_node_modules_dir,
|
||||
argv0: shared.options.argv0.clone(),
|
||||
node_debug: shared.options.node_debug.clone(),
|
||||
node_ipc_fd: None,
|
||||
mode: WorkerExecutionMode::Worker,
|
||||
serve_port: shared.options.serve_port,
|
||||
serve_host: shared.options.serve_host.clone(),
|
||||
otel_config: shared.options.otel_config.clone(),
|
||||
close_on_idle: args.close_on_idle,
|
||||
},
|
||||
extensions: vec![],
|
||||
startup_snapshot: shared.options.startup_snapshot,
|
||||
create_params: create_isolate_create_params(),
|
||||
unsafely_ignore_certificate_errors: shared
|
||||
.options
|
||||
.unsafely_ignore_certificate_errors
|
||||
.clone(),
|
||||
seed: shared.options.seed,
|
||||
create_web_worker_cb,
|
||||
format_js_error_fn: Some(Arc::new(format_js_error)),
|
||||
worker_type: args.worker_type,
|
||||
stdio: stdio.clone(),
|
||||
cache_storage_dir,
|
||||
strace_ops: shared.options.strace_ops.clone(),
|
||||
close_on_idle: args.close_on_idle,
|
||||
maybe_worker_metadata: args.maybe_worker_metadata,
|
||||
enable_stack_trace_arg_in_ops: has_trace_permissions_enabled(),
|
||||
};
|
||||
|
||||
WebWorker::bootstrap_from_options(services, options)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LibMainWorkerFactory<TSys: DenoLibSys> {
|
||||
shared: Arc<LibWorkerFactorySharedState<TSys>>,
|
||||
}
|
||||
|
||||
impl<TSys: DenoLibSys> LibMainWorkerFactory<TSys> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
blob_store: Arc<BlobStore>,
|
||||
code_cache: Option<Arc<dyn deno_runtime::code_cache::CodeCache>>,
|
||||
feature_checker: Arc<FeatureChecker>,
|
||||
fs: Arc<dyn deno_fs::FileSystem>,
|
||||
maybe_inspector_server: Option<Arc<InspectorServer>>,
|
||||
module_loader_factory: Box<dyn ModuleLoaderFactory>,
|
||||
node_resolver: Arc<
|
||||
NodeResolver<DenoInNpmPackageChecker, NpmResolver<TSys>, TSys>,
|
||||
>,
|
||||
npm_process_state_provider: NpmProcessStateProviderRc,
|
||||
pkg_json_resolver: Arc<node_resolver::PackageJsonResolver<TSys>>,
|
||||
root_cert_store_provider: Arc<dyn RootCertStoreProvider>,
|
||||
storage_key_resolver: StorageKeyResolver,
|
||||
sys: TSys,
|
||||
options: LibMainWorkerOptions,
|
||||
) -> Self {
|
||||
Self {
|
||||
shared: Arc::new(LibWorkerFactorySharedState {
|
||||
blob_store,
|
||||
broadcast_channel: Default::default(),
|
||||
code_cache,
|
||||
compiled_wasm_module_store: Default::default(),
|
||||
feature_checker,
|
||||
fs,
|
||||
maybe_inspector_server,
|
||||
module_loader_factory,
|
||||
node_resolver,
|
||||
npm_process_state_provider,
|
||||
pkg_json_resolver,
|
||||
root_cert_store_provider,
|
||||
shared_array_buffer_store: Default::default(),
|
||||
storage_key_resolver,
|
||||
sys,
|
||||
options,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_custom_worker(
|
||||
&self,
|
||||
mode: WorkerExecutionMode,
|
||||
main_module: Url,
|
||||
permissions: PermissionsContainer,
|
||||
custom_extensions: Vec<Extension>,
|
||||
stdio: deno_runtime::deno_io::Stdio,
|
||||
) -> Result<LibMainWorker, CoreError> {
|
||||
let shared = &self.shared;
|
||||
let CreateModuleLoaderResult {
|
||||
module_loader,
|
||||
node_require_loader,
|
||||
} = shared
|
||||
.module_loader_factory
|
||||
.create_for_main(permissions.clone());
|
||||
|
||||
// TODO(bartlomieju): this is cruft, update FeatureChecker to spit out
|
||||
// list of enabled features.
|
||||
let feature_checker = shared.feature_checker.clone();
|
||||
let unstable_features =
|
||||
shared.resolve_unstable_features(feature_checker.as_ref());
|
||||
let maybe_storage_key = shared
|
||||
.storage_key_resolver
|
||||
.resolve_storage_key(&main_module);
|
||||
let origin_storage_dir = maybe_storage_key.as_ref().map(|key| {
|
||||
shared
|
||||
.options
|
||||
.origin_data_folder_path
|
||||
.as_ref()
|
||||
.unwrap() // must be set if storage key resolver returns a value
|
||||
.join(checksum::gen(&[key.as_bytes()]))
|
||||
});
|
||||
let cache_storage_dir = maybe_storage_key.map(|key| {
|
||||
// TODO(@satyarohith): storage quota management
|
||||
get_cache_storage_dir().join(checksum::gen(&[key.as_bytes()]))
|
||||
});
|
||||
|
||||
let services = WorkerServiceOptions {
|
||||
root_cert_store_provider: Some(shared.root_cert_store_provider.clone()),
|
||||
module_loader,
|
||||
fs: shared.fs.clone(),
|
||||
node_services: Some(
|
||||
shared.create_node_init_services(node_require_loader),
|
||||
),
|
||||
npm_process_state_provider: Some(
|
||||
shared.npm_process_state_provider.clone(),
|
||||
),
|
||||
blob_store: shared.blob_store.clone(),
|
||||
broadcast_channel: shared.broadcast_channel.clone(),
|
||||
fetch_dns_resolver: Default::default(),
|
||||
shared_array_buffer_store: Some(shared.shared_array_buffer_store.clone()),
|
||||
compiled_wasm_module_store: Some(
|
||||
shared.compiled_wasm_module_store.clone(),
|
||||
),
|
||||
feature_checker,
|
||||
permissions,
|
||||
v8_code_cache: shared.code_cache.clone(),
|
||||
};
|
||||
|
||||
let options = WorkerOptions {
|
||||
bootstrap: BootstrapOptions {
|
||||
deno_version: shared.options.deno_version.to_string(),
|
||||
args: shared.options.argv.clone(),
|
||||
cpu_count: std::thread::available_parallelism()
|
||||
.map(|p| p.get())
|
||||
.unwrap_or(1),
|
||||
log_level: shared.options.log_level,
|
||||
enable_op_summary_metrics: shared.options.enable_op_summary_metrics,
|
||||
enable_testing_features: shared.options.enable_testing_features,
|
||||
locale: deno_core::v8::icu::get_language_tag(),
|
||||
location: shared.options.location.clone(),
|
||||
no_color: !colors::use_color(),
|
||||
is_stdout_tty: deno_terminal::is_stdout_tty(),
|
||||
is_stderr_tty: deno_terminal::is_stderr_tty(),
|
||||
color_level: colors::get_color_level(),
|
||||
unstable_features,
|
||||
user_agent: shared.options.deno_user_agent.to_string(),
|
||||
inspect: shared.options.is_inspecting,
|
||||
has_node_modules_dir: shared.options.has_node_modules_dir,
|
||||
argv0: shared.options.argv0.clone(),
|
||||
node_debug: shared.options.node_debug.clone(),
|
||||
node_ipc_fd: shared.options.node_ipc,
|
||||
mode,
|
||||
serve_port: shared.options.serve_port,
|
||||
serve_host: shared.options.serve_host.clone(),
|
||||
otel_config: shared.options.otel_config.clone(),
|
||||
close_on_idle: true,
|
||||
},
|
||||
extensions: custom_extensions,
|
||||
startup_snapshot: shared.options.startup_snapshot,
|
||||
create_params: create_isolate_create_params(),
|
||||
unsafely_ignore_certificate_errors: shared
|
||||
.options
|
||||
.unsafely_ignore_certificate_errors
|
||||
.clone(),
|
||||
seed: shared.options.seed,
|
||||
format_js_error_fn: Some(Arc::new(format_js_error)),
|
||||
create_web_worker_cb: shared.create_web_worker_callback(stdio.clone()),
|
||||
maybe_inspector_server: shared.maybe_inspector_server.clone(),
|
||||
should_break_on_first_statement: shared.options.inspect_brk,
|
||||
should_wait_for_inspector_session: shared.options.inspect_wait,
|
||||
strace_ops: shared.options.strace_ops.clone(),
|
||||
cache_storage_dir,
|
||||
origin_storage_dir,
|
||||
stdio,
|
||||
skip_op_registration: shared.options.skip_op_registration,
|
||||
enable_stack_trace_arg_in_ops: has_trace_permissions_enabled(),
|
||||
};
|
||||
|
||||
let worker =
|
||||
MainWorker::bootstrap_from_options(&main_module, services, options);
|
||||
|
||||
Ok(LibMainWorker {
|
||||
main_module,
|
||||
worker,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LibMainWorker {
|
||||
main_module: Url,
|
||||
worker: MainWorker,
|
||||
}
|
||||
|
||||
impl LibMainWorker {
|
||||
pub fn into_main_worker(self) -> MainWorker {
|
||||
self.worker
|
||||
}
|
||||
|
||||
pub fn main_module(&self) -> &Url {
|
||||
&self.main_module
|
||||
}
|
||||
|
||||
pub fn js_runtime(&mut self) -> &mut JsRuntime {
|
||||
&mut self.worker.js_runtime
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn create_inspector_session(&mut self) -> LocalInspectorSession {
|
||||
self.worker.create_inspector_session()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn dispatch_load_event(&mut self) -> Result<(), JsError> {
|
||||
self.worker.dispatch_load_event()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn dispatch_beforeunload_event(&mut self) -> Result<bool, JsError> {
|
||||
self.worker.dispatch_beforeunload_event()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn dispatch_process_beforeexit_event(&mut self) -> Result<bool, JsError> {
|
||||
self.worker.dispatch_process_beforeexit_event()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn dispatch_unload_event(&mut self) -> Result<(), JsError> {
|
||||
self.worker.dispatch_unload_event()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn dispatch_process_exit_event(&mut self) -> Result<(), JsError> {
|
||||
self.worker.dispatch_process_exit_event()
|
||||
}
|
||||
|
||||
pub async fn execute_main_module(&mut self) -> Result<(), CoreError> {
|
||||
let id = self.worker.preload_main_module(&self.main_module).await?;
|
||||
self.worker.evaluate_module(id).await
|
||||
}
|
||||
|
||||
pub async fn execute_side_module(&mut self) -> Result<(), CoreError> {
|
||||
let id = self.worker.preload_side_module(&self.main_module).await?;
|
||||
self.worker.evaluate_module(id).await
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn run_event_loop(
|
||||
&mut self,
|
||||
wait_for_inspector: bool,
|
||||
) -> Result<(), CoreError> {
|
||||
self.worker.run_event_loop(wait_for_inspector).await
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn exit_code(&self) -> i32 {
|
||||
self.worker.exit_code()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn storage_key_resolver_test() {
|
||||
let resolver =
|
||||
StorageKeyResolver(StorageKeyResolverStrategy::UseMainModule);
|
||||
let specifier = Url::parse("file:///a.ts").unwrap();
|
||||
assert_eq!(
|
||||
resolver.resolve_storage_key(&specifier),
|
||||
Some(specifier.to_string())
|
||||
);
|
||||
let resolver =
|
||||
StorageKeyResolver(StorageKeyResolverStrategy::Specified(None));
|
||||
assert_eq!(resolver.resolve_storage_key(&specifier), None);
|
||||
let resolver = StorageKeyResolver(StorageKeyResolverStrategy::Specified(
|
||||
Some("value".to_string()),
|
||||
));
|
||||
assert_eq!(
|
||||
resolver.resolve_storage_key(&specifier),
|
||||
Some("value".to_string())
|
||||
);
|
||||
|
||||
// test empty
|
||||
let resolver = StorageKeyResolver::empty();
|
||||
assert_eq!(resolver.resolve_storage_key(&specifier), None);
|
||||
}
|
||||
}
|
|
@ -1,33 +1,25 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use super::diagnostics::DenoDiagnostic;
|
||||
use super::diagnostics::DiagnosticSource;
|
||||
use super::documents::Document;
|
||||
use super::documents::Documents;
|
||||
use super::language_server;
|
||||
use super::resolver::LspResolver;
|
||||
use super::tsc;
|
||||
use super::urls::url_to_uri;
|
||||
|
||||
use crate::args::jsr_url;
|
||||
use crate::lsp::logging::lsp_warn;
|
||||
use crate::lsp::search::PackageSearchApi;
|
||||
use crate::tools::lint::CliLinter;
|
||||
use crate::util::path::relative_specifier;
|
||||
use deno_config::workspace::MappedResolution;
|
||||
use deno_lint::diagnostic::LintDiagnosticRange;
|
||||
use std::borrow::Cow;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::path::Path;
|
||||
|
||||
use deno_ast::SourceRange;
|
||||
use deno_ast::SourceRangedForSpanned;
|
||||
use deno_ast::SourceTextInfo;
|
||||
use deno_core::error::custom_error;
|
||||
use deno_config::workspace::MappedResolution;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::serde::Deserialize;
|
||||
use deno_core::serde::Serialize;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_lint::diagnostic::LintDiagnosticRange;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use deno_resolver::npm::managed::NpmResolutionCell;
|
||||
use deno_runtime::deno_node::PathClean;
|
||||
use deno_semver::jsr::JsrPackageNvReference;
|
||||
use deno_semver::jsr::JsrPackageReqReference;
|
||||
|
@ -40,20 +32,30 @@ use deno_semver::SmallStackString;
|
|||
use deno_semver::StackString;
|
||||
use deno_semver::Version;
|
||||
use import_map::ImportMap;
|
||||
use node_resolver::InNpmPackageChecker;
|
||||
use node_resolver::NodeResolutionKind;
|
||||
use node_resolver::ResolutionMode;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use std::borrow::Cow;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::path::Path;
|
||||
use text_lines::LineAndColumnIndex;
|
||||
use tower_lsp::lsp_types as lsp;
|
||||
use tower_lsp::lsp_types::Position;
|
||||
use tower_lsp::lsp_types::Range;
|
||||
|
||||
use super::diagnostics::DenoDiagnostic;
|
||||
use super::diagnostics::DiagnosticSource;
|
||||
use super::documents::Document;
|
||||
use super::documents::Documents;
|
||||
use super::language_server;
|
||||
use super::resolver::LspResolver;
|
||||
use super::tsc;
|
||||
use super::urls::url_to_uri;
|
||||
use crate::args::jsr_url;
|
||||
use crate::lsp::logging::lsp_warn;
|
||||
use crate::lsp::search::PackageSearchApi;
|
||||
use crate::tools::lint::CliLinter;
|
||||
use crate::util::path::relative_specifier;
|
||||
|
||||
/// Diagnostic error codes which actually are the same, and so when grouping
|
||||
/// fixes we treat them the same.
|
||||
static FIX_ALL_ERROR_CODES: Lazy<HashMap<&'static str, &'static str>> =
|
||||
|
@ -365,7 +367,9 @@ impl<'a> TsResponseImportMapper<'a> {
|
|||
if let Ok(Some(pkg_id)) =
|
||||
npm_resolver.resolve_pkg_id_from_specifier(specifier)
|
||||
{
|
||||
let pkg_reqs = npm_resolver.resolve_pkg_reqs_from_pkg_id(&pkg_id);
|
||||
let pkg_reqs = npm_resolver
|
||||
.resolution()
|
||||
.resolve_pkg_reqs_from_pkg_id(&pkg_id);
|
||||
// check if any pkg reqs match what is found in an import map
|
||||
if !pkg_reqs.is_empty() {
|
||||
let sub_path = npm_resolver
|
||||
|
@ -1070,10 +1074,13 @@ impl CodeActionCollection {
|
|||
// we wrap tsc, we can't handle the asynchronous response, so it is
|
||||
// actually easier to return errors if we ever encounter one of these,
|
||||
// which we really wouldn't expect from the Deno lsp.
|
||||
return Err(custom_error(
|
||||
"UnsupportedFix",
|
||||
"The action returned from TypeScript is unsupported.",
|
||||
));
|
||||
return Err(
|
||||
JsErrorBox::new(
|
||||
"UnsupportedFix",
|
||||
"The action returned from TypeScript is unsupported.",
|
||||
)
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
let Some(action) =
|
||||
fix_ts_import_action(specifier, resolution_mode, action, language_server)
|
||||
|
@ -1292,6 +1299,19 @@ impl CodeActionCollection {
|
|||
range: &lsp::Range,
|
||||
language_server: &language_server::Inner,
|
||||
) -> Option<lsp::CodeAction> {
|
||||
fn top_package_req_for_name(
|
||||
resolution: &NpmResolutionCell,
|
||||
name: &str,
|
||||
) -> Option<PackageReq> {
|
||||
let package_reqs = resolution.package_reqs();
|
||||
let mut entries = package_reqs
|
||||
.into_iter()
|
||||
.filter(|(_, nv)| nv.name == name)
|
||||
.collect::<Vec<_>>();
|
||||
entries.sort_by(|a, b| a.1.version.cmp(&b.1.version));
|
||||
Some(entries.pop()?.0)
|
||||
}
|
||||
|
||||
let (dep_key, dependency, _) =
|
||||
document.get_maybe_dependency(&range.end)?;
|
||||
if dependency.maybe_deno_types_specifier.is_some() {
|
||||
|
@ -1379,9 +1399,10 @@ impl CodeActionCollection {
|
|||
.and_then(|versions| versions.first().cloned())?;
|
||||
let types_specifier_text =
|
||||
if let Some(npm_resolver) = managed_npm_resolver {
|
||||
let mut specifier_text = if let Some(req) =
|
||||
npm_resolver.top_package_req_for_name(&types_package_name)
|
||||
{
|
||||
let mut specifier_text = if let Some(req) = top_package_req_for_name(
|
||||
npm_resolver.resolution(),
|
||||
&types_package_name,
|
||||
) {
|
||||
format!("npm:{req}")
|
||||
} else {
|
||||
format!("npm:{}@^{}", &types_package_name, types_package_version)
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use deno_core::url::Url;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_lib::cache::DenoDir;
|
||||
use deno_path_util::url_to_file_path;
|
||||
|
||||
use crate::cache::DenoDir;
|
||||
use crate::cache::GlobalHttpCache;
|
||||
use crate::cache::HttpCache;
|
||||
use crate::cache::LocalLspHttpCache;
|
||||
|
@ -9,15 +19,6 @@ use crate::lsp::logging::lsp_log;
|
|||
use crate::lsp::logging::lsp_warn;
|
||||
use crate::sys::CliSys;
|
||||
|
||||
use deno_core::url::Url;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::time::SystemTime;
|
||||
|
||||
pub fn calculate_fs_version(
|
||||
cache: &LspCache,
|
||||
specifier: &ModuleSpecifier,
|
||||
|
@ -69,7 +70,7 @@ fn calculate_fs_version_in_cache(
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LspCache {
|
||||
deno_dir: DenoDir,
|
||||
deno_dir: DenoDir<CliSys>,
|
||||
global: Arc<GlobalHttpCache>,
|
||||
vendors_by_scope: BTreeMap<ModuleSpecifier, Option<Arc<LocalLspHttpCache>>>,
|
||||
}
|
||||
|
@ -120,7 +121,7 @@ impl LspCache {
|
|||
.collect();
|
||||
}
|
||||
|
||||
pub fn deno_dir(&self) -> &DenoDir {
|
||||
pub fn deno_dir(&self) -> &DenoDir<CliSys> {
|
||||
&self.deno_dir
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
//!
|
||||
//! Provides information about what capabilities that are supported by the
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -12,12 +12,11 @@ use lsp_types::Uri;
|
|||
use tower_lsp::lsp_types as lsp;
|
||||
use tower_lsp::lsp_types::ConfigurationItem;
|
||||
|
||||
use crate::lsp::repl::get_repl_workspace_settings;
|
||||
|
||||
use super::config::WorkspaceSettings;
|
||||
use super::config::SETTINGS_SECTION;
|
||||
use super::lsp_custom;
|
||||
use super::testing::lsp_custom as testing_lsp_custom;
|
||||
use crate::lsp::repl::get_repl_workspace_settings;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TestingNotification {
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use crate::lsp::logging::lsp_warn;
|
||||
|
||||
use super::analysis::source_range_to_lsp_range;
|
||||
use super::config::CodeLensSettings;
|
||||
use super::language_server;
|
||||
use super::text::LineIndex;
|
||||
use super::tsc;
|
||||
use super::tsc::NavigationTree;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashSet;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_ast::swc::ast;
|
||||
use deno_ast::swc::visit::Visit;
|
||||
|
@ -25,13 +21,17 @@ use deno_core::ModuleSpecifier;
|
|||
use lazy_regex::lazy_regex;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashSet;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use tower_lsp::jsonrpc::Error as LspError;
|
||||
use tower_lsp::lsp_types as lsp;
|
||||
|
||||
use super::analysis::source_range_to_lsp_range;
|
||||
use super::config::CodeLensSettings;
|
||||
use super::language_server;
|
||||
use super::text::LineIndex;
|
||||
use super::tsc;
|
||||
use super::tsc::NavigationTree;
|
||||
use crate::lsp::logging::lsp_warn;
|
||||
|
||||
static ABSTRACT_MODIFIER: Lazy<Regex> = lazy_regex!(r"\babstract\b");
|
||||
|
||||
static EXPORT_MODIFIER: Lazy<Regex> = lazy_regex!(r"\bexport\b");
|
||||
|
|
|
@ -1,4 +1,26 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use deno_ast::LineAndColumnIndex;
|
||||
use deno_ast::SourceTextInfo;
|
||||
use deno_core::resolve_path;
|
||||
use deno_core::resolve_url;
|
||||
use deno_core::serde::Deserialize;
|
||||
use deno_core::serde::Serialize;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::url::Position;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use deno_runtime::deno_node::SUPPORTED_BUILTIN_NODE_MODULES;
|
||||
use deno_semver::jsr::JsrPackageReqReference;
|
||||
use deno_semver::package::PackageNv;
|
||||
use import_map::ImportMap;
|
||||
use indexmap::IndexSet;
|
||||
use lsp_types::CompletionList;
|
||||
use node_resolver::NodeResolutionKind;
|
||||
use node_resolver::ResolutionMode;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use tower_lsp::lsp_types as lsp;
|
||||
|
||||
use super::client::Client;
|
||||
use super::config::Config;
|
||||
|
@ -12,33 +34,10 @@ use super::registries::ModuleRegistry;
|
|||
use super::resolver::LspResolver;
|
||||
use super::search::PackageSearchApi;
|
||||
use super::tsc;
|
||||
|
||||
use crate::graph_util::to_node_resolution_mode;
|
||||
use crate::jsr::JsrFetchResolver;
|
||||
use crate::util::path::is_importable_ext;
|
||||
use crate::util::path::relative_specifier;
|
||||
use deno_runtime::deno_node::SUPPORTED_BUILTIN_NODE_MODULES;
|
||||
|
||||
use deno_ast::LineAndColumnIndex;
|
||||
use deno_ast::SourceTextInfo;
|
||||
use deno_core::resolve_path;
|
||||
use deno_core::resolve_url;
|
||||
use deno_core::serde::Deserialize;
|
||||
use deno_core::serde::Serialize;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::url::Position;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use deno_semver::jsr::JsrPackageReqReference;
|
||||
use deno_semver::package::PackageNv;
|
||||
use import_map::ImportMap;
|
||||
use indexmap::IndexSet;
|
||||
use lsp_types::CompletionList;
|
||||
use node_resolver::NodeResolutionKind;
|
||||
use node_resolver::ResolutionMode;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use tower_lsp::lsp_types as lsp;
|
||||
|
||||
static FILE_PROTO_RE: Lazy<Regex> =
|
||||
lazy_regex::lazy_regex!(r#"^file:/{2}(?:/[A-Za-z]:)?"#);
|
||||
|
@ -822,16 +821,18 @@ fn get_workspace_completions(
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::collections::HashMap;
|
||||
|
||||
use deno_core::resolve_url;
|
||||
use pretty_assertions::assert_eq;
|
||||
use test_util::TempDir;
|
||||
|
||||
use super::*;
|
||||
use crate::cache::HttpCache;
|
||||
use crate::lsp::cache::LspCache;
|
||||
use crate::lsp::documents::Documents;
|
||||
use crate::lsp::documents::LanguageId;
|
||||
use crate::lsp::search::tests::TestPackageSearchApi;
|
||||
use deno_core::resolve_url;
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::collections::HashMap;
|
||||
use test_util::TempDir;
|
||||
|
||||
fn setup(
|
||||
open_sources: &[(&str, &str, i32, LanguageId)],
|
||||
|
|
|
@ -1,4 +1,13 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Deref;
|
||||
use std::ops::DerefMut;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_ast::MediaType;
|
||||
use deno_config::deno_json::DenoJsonCache;
|
||||
|
@ -32,28 +41,21 @@ use deno_core::serde_json::json;
|
|||
use deno_core::serde_json::Value;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_lib::env::has_flag_env_var;
|
||||
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;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Deref;
|
||||
use std::ops::DerefMut;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use tower_lsp::lsp_types as lsp;
|
||||
|
||||
use super::logging::lsp_log;
|
||||
use super::lsp_custom;
|
||||
use super::urls::url_to_uri;
|
||||
use crate::args::discover_npmrc_from_workspace;
|
||||
use crate::args::has_flag_env_var;
|
||||
use crate::args::CliLockfile;
|
||||
use crate::args::CliLockfileReadFromPathOptions;
|
||||
use crate::args::ConfigFile;
|
||||
|
@ -63,7 +65,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;
|
||||
|
@ -852,7 +853,8 @@ impl Settings {
|
|||
Some(false)
|
||||
} else if let Some(enable_paths) = &enable_paths {
|
||||
for enable_path in enable_paths {
|
||||
if path.starts_with(enable_path) {
|
||||
// Also enable if the checked path is a dir containing an enabled path.
|
||||
if path.starts_with(enable_path) || enable_path.starts_with(&path) {
|
||||
return Some(true);
|
||||
}
|
||||
}
|
||||
|
@ -1244,7 +1246,6 @@ impl ConfigData {
|
|||
pkg_json_cache: Some(pkg_json_cache),
|
||||
workspace_cache: Some(workspace_cache),
|
||||
discover_pkg_json: !has_flag_env_var("DENO_NO_PACKAGE_JSON"),
|
||||
config_parse_options: Default::default(),
|
||||
maybe_vendor_override: None,
|
||||
},
|
||||
)
|
||||
|
@ -1569,11 +1570,11 @@ impl ConfigData {
|
|||
let resolver = member_dir
|
||||
.workspace
|
||||
.create_resolver(
|
||||
&CliSys::default(),
|
||||
CreateResolverOptions {
|
||||
pkg_json_dep_resolution,
|
||||
specified_import_map,
|
||||
},
|
||||
|path| Ok(std::fs::read_to_string(path)?),
|
||||
)
|
||||
.inspect_err(|err| {
|
||||
lsp_warn!(
|
||||
|
@ -2075,7 +2076,6 @@ impl deno_config::workspace::WorkspaceCache for WorkspaceMemCache {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use deno_config::deno_json::ConfigParseOptions;
|
||||
use deno_core::resolve_url;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
|
@ -2349,12 +2349,7 @@ mod tests {
|
|||
config
|
||||
.tree
|
||||
.inject_config_file(
|
||||
ConfigFile::new(
|
||||
"{}",
|
||||
root_uri.join("deno.json").unwrap(),
|
||||
&ConfigParseOptions::default(),
|
||||
)
|
||||
.unwrap(),
|
||||
ConfigFile::new("{}", root_uri.join("deno.json").unwrap()).unwrap(),
|
||||
)
|
||||
.await;
|
||||
assert!(config.specifier_enabled(&root_uri));
|
||||
|
@ -2410,7 +2405,6 @@ mod tests {
|
|||
})
|
||||
.to_string(),
|
||||
root_uri.join("deno.json").unwrap(),
|
||||
&ConfigParseOptions::default(),
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
|
@ -2436,7 +2430,6 @@ mod tests {
|
|||
})
|
||||
.to_string(),
|
||||
root_uri.join("deno.json").unwrap(),
|
||||
&ConfigParseOptions::default(),
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
|
@ -2454,7 +2447,6 @@ mod tests {
|
|||
})
|
||||
.to_string(),
|
||||
root_uri.join("deno.json").unwrap(),
|
||||
&ConfigParseOptions::default(),
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
|
|
|
@ -1,32 +1,11 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use super::analysis;
|
||||
use super::client::Client;
|
||||
use super::config::Config;
|
||||
use super::documents;
|
||||
use super::documents::Document;
|
||||
use super::documents::Documents;
|
||||
use super::documents::DocumentsFilter;
|
||||
use super::language_server;
|
||||
use super::language_server::StateSnapshot;
|
||||
use super::performance::Performance;
|
||||
use super::tsc;
|
||||
use super::tsc::TsServer;
|
||||
use super::urls::uri_parse_unencoded;
|
||||
use super::urls::url_to_uri;
|
||||
use super::urls::LspUrlMap;
|
||||
|
||||
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;
|
||||
use crate::tools::lint::LintRuleProvider;
|
||||
use crate::tsc::DiagnosticCategory;
|
||||
use crate::util::path::to_percent_decoded_str;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
|
||||
use deno_ast::MediaType;
|
||||
use deno_config::deno_json::LintConfig;
|
||||
|
@ -47,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;
|
||||
|
@ -55,20 +35,40 @@ use deno_semver::jsr::JsrPackageReqReference;
|
|||
use deno_semver::npm::NpmPackageReqReference;
|
||||
use deno_semver::package::PackageReq;
|
||||
use import_map::ImportMap;
|
||||
use import_map::ImportMapError;
|
||||
use import_map::ImportMapErrorKind;
|
||||
use log::error;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::sync::Mutex;
|
||||
use tokio::time::Duration;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tower_lsp::lsp_types as lsp;
|
||||
|
||||
use super::analysis;
|
||||
use super::client::Client;
|
||||
use super::config::Config;
|
||||
use super::documents;
|
||||
use super::documents::Document;
|
||||
use super::documents::Documents;
|
||||
use super::documents::DocumentsFilter;
|
||||
use super::language_server;
|
||||
use super::language_server::StateSnapshot;
|
||||
use super::performance::Performance;
|
||||
use super::tsc;
|
||||
use super::tsc::TsServer;
|
||||
use super::urls::uri_parse_unencoded;
|
||||
use super::urls::url_to_uri;
|
||||
use super::urls::LspUrlMap;
|
||||
use crate::graph_util;
|
||||
use crate::graph_util::enhanced_resolution_error_message;
|
||||
use crate::lsp::lsp_custom::DiagnosticBatchNotificationParams;
|
||||
use crate::resolver::CliSloppyImportsResolver;
|
||||
use crate::sys::CliSys;
|
||||
use crate::tools::lint::CliLinter;
|
||||
use crate::tools::lint::CliLinterOptions;
|
||||
use crate::tools::lint::LintRuleProvider;
|
||||
use crate::tsc::DiagnosticCategory;
|
||||
use crate::util::path::to_percent_decoded_str;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DiagnosticServerUpdateMessage {
|
||||
pub snapshot: Arc<StateSnapshot>,
|
||||
|
@ -265,7 +265,7 @@ impl TsDiagnosticsStore {
|
|||
}
|
||||
|
||||
pub fn should_send_diagnostic_batch_index_notifications() -> bool {
|
||||
crate::args::has_flag_env_var(
|
||||
deno_lib::env::has_flag_env_var(
|
||||
"DENO_DONT_USE_INTERNAL_LSP_DIAGNOSTIC_SYNC_FLAG",
|
||||
)
|
||||
}
|
||||
|
@ -1297,8 +1297,8 @@ impl DenoDiagnostic {
|
|||
let mut message;
|
||||
message = enhanced_resolution_error_message(err);
|
||||
if let deno_graph::ResolutionError::ResolverError {error, ..} = err{
|
||||
if let ResolveError::Other(resolve_error, ..) = (*error).as_ref() {
|
||||
if let Some(ImportMapError::UnmappedBareSpecifier(specifier, _)) = resolve_error.downcast_ref::<ImportMapError>() {
|
||||
if let ResolveError::ImportMap(importmap) = (*error).as_ref() {
|
||||
if let ImportMapErrorKind::UnmappedBareSpecifier(specifier, _) = &**importmap {
|
||||
if specifier.chars().next().unwrap_or('\0') == '@'{
|
||||
let hint = format!("\nHint: Use [deno add {}] to add the dependency.", specifier);
|
||||
message.push_str(hint.as_str());
|
||||
|
@ -1646,6 +1646,12 @@ fn generate_deno_diagnostics(
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_config::deno_json::ConfigFile;
|
||||
use pretty_assertions::assert_eq;
|
||||
use test_util::TempDir;
|
||||
|
||||
use super::*;
|
||||
use crate::lsp::cache::LspCache;
|
||||
use crate::lsp::config::Config;
|
||||
|
@ -1656,11 +1662,6 @@ mod tests {
|
|||
use crate::lsp::language_server::StateSnapshot;
|
||||
use crate::lsp::resolver::LspResolver;
|
||||
|
||||
use deno_config::deno_json::ConfigFile;
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::sync::Arc;
|
||||
use test_util::TempDir;
|
||||
|
||||
fn mock_config() -> Config {
|
||||
let root_url = resolve_url("file:///").unwrap();
|
||||
let root_uri = url_to_uri(&root_url).unwrap();
|
||||
|
@ -1694,12 +1695,7 @@ mod tests {
|
|||
let mut config = Config::new_with_roots([root_uri.clone()]);
|
||||
if let Some((relative_path, json_string)) = maybe_import_map {
|
||||
let base_url = root_uri.join(relative_path).unwrap();
|
||||
let config_file = ConfigFile::new(
|
||||
json_string,
|
||||
base_url,
|
||||
&deno_config::deno_json::ConfigParseOptions::default(),
|
||||
)
|
||||
.unwrap();
|
||||
let config_file = ConfigFile::new(json_string, base_url).unwrap();
|
||||
config.tree.inject_config_file(config_file).await;
|
||||
}
|
||||
let resolver =
|
||||
|
|
|
@ -1,41 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use super::cache::calculate_fs_version;
|
||||
use super::cache::LspCache;
|
||||
use super::config::Config;
|
||||
use super::resolver::LspResolver;
|
||||
use super::resolver::ScopeDepInfo;
|
||||
use super::resolver::SingleReferrerGraphResolver;
|
||||
use super::testing::TestCollector;
|
||||
use super::testing::TestModule;
|
||||
use super::text::LineIndex;
|
||||
use super::tsc;
|
||||
use super::tsc::AssetDocument;
|
||||
|
||||
use crate::graph_util::CliJsrUrlProvider;
|
||||
|
||||
use dashmap::DashMap;
|
||||
use deno_ast::swc::visit::VisitWith;
|
||||
use deno_ast::MediaType;
|
||||
use deno_ast::ParsedSource;
|
||||
use deno_ast::SourceTextInfo;
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::future;
|
||||
use deno_core::futures::future::Shared;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_graph::Resolution;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use deno_runtime::deno_node;
|
||||
use deno_semver::jsr::JsrPackageReqReference;
|
||||
use deno_semver::npm::NpmPackageReqReference;
|
||||
use deno_semver::package::PackageReq;
|
||||
use indexmap::IndexMap;
|
||||
use indexmap::IndexSet;
|
||||
use node_resolver::NodeResolutionKind;
|
||||
use node_resolver::ResolutionMode;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashMap;
|
||||
|
@ -48,8 +12,44 @@ use std::str::FromStr;
|
|||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::sync::Arc;
|
||||
|
||||
use dashmap::DashMap;
|
||||
use deno_ast::swc::visit::VisitWith;
|
||||
use deno_ast::MediaType;
|
||||
use deno_ast::ParsedSource;
|
||||
use deno_ast::SourceTextInfo;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::future;
|
||||
use deno_core::futures::future::Shared;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_graph::Resolution;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use deno_runtime::deno_node;
|
||||
use deno_semver::jsr::JsrPackageReqReference;
|
||||
use deno_semver::npm::NpmPackageReqReference;
|
||||
use deno_semver::package::PackageReq;
|
||||
use indexmap::IndexMap;
|
||||
use indexmap::IndexSet;
|
||||
use node_resolver::NodeResolutionKind;
|
||||
use node_resolver::ResolutionMode;
|
||||
use tower_lsp::lsp_types as lsp;
|
||||
|
||||
use super::cache::calculate_fs_version;
|
||||
use super::cache::LspCache;
|
||||
use super::config::Config;
|
||||
use super::resolver::LspResolver;
|
||||
use super::resolver::ScopeDepInfo;
|
||||
use super::resolver::SingleReferrerGraphResolver;
|
||||
use super::testing::TestCollector;
|
||||
use super::testing::TestModule;
|
||||
use super::text::LineIndex;
|
||||
use super::tsc;
|
||||
use super::tsc::AssetDocument;
|
||||
use crate::graph_util::CliJsrUrlProvider;
|
||||
|
||||
pub const DOCUMENT_SCHEMES: [&str; 5] =
|
||||
["data", "blob", "file", "http", "https"];
|
||||
|
||||
|
@ -64,6 +64,9 @@ pub enum LanguageId {
|
|||
Markdown,
|
||||
Html,
|
||||
Css,
|
||||
Scss,
|
||||
Sass,
|
||||
Less,
|
||||
Yaml,
|
||||
Sql,
|
||||
Svelte,
|
||||
|
@ -86,6 +89,9 @@ impl LanguageId {
|
|||
LanguageId::Markdown => Some("md"),
|
||||
LanguageId::Html => Some("html"),
|
||||
LanguageId::Css => Some("css"),
|
||||
LanguageId::Scss => Some("scss"),
|
||||
LanguageId::Sass => Some("sass"),
|
||||
LanguageId::Less => Some("less"),
|
||||
LanguageId::Yaml => Some("yaml"),
|
||||
LanguageId::Sql => Some("sql"),
|
||||
LanguageId::Svelte => Some("svelte"),
|
||||
|
@ -107,6 +113,9 @@ impl LanguageId {
|
|||
LanguageId::Markdown => Some("text/markdown"),
|
||||
LanguageId::Html => Some("text/html"),
|
||||
LanguageId::Css => Some("text/css"),
|
||||
LanguageId::Scss => None,
|
||||
LanguageId::Sass => None,
|
||||
LanguageId::Less => None,
|
||||
LanguageId::Yaml => Some("application/yaml"),
|
||||
LanguageId::Sql => None,
|
||||
LanguageId::Svelte => None,
|
||||
|
@ -140,6 +149,9 @@ impl FromStr for LanguageId {
|
|||
"markdown" => Ok(Self::Markdown),
|
||||
"html" => Ok(Self::Html),
|
||||
"css" => Ok(Self::Css),
|
||||
"scss" => Ok(Self::Scss),
|
||||
"sass" => Ok(Self::Sass),
|
||||
"less" => Ok(Self::Less),
|
||||
"yaml" => Ok(Self::Yaml),
|
||||
"sql" => Ok(Self::Sql),
|
||||
"svelte" => Ok(Self::Svelte),
|
||||
|
@ -468,7 +480,7 @@ impl Document {
|
|||
let is_cjs_resolver =
|
||||
resolver.as_is_cjs_resolver(self.file_referrer.as_ref());
|
||||
let npm_resolver =
|
||||
resolver.create_graph_npm_resolver(self.file_referrer.as_ref());
|
||||
resolver.as_graph_npm_resolver(self.file_referrer.as_ref());
|
||||
let config_data = resolver.as_config_data(self.file_referrer.as_ref());
|
||||
let jsx_import_source_config =
|
||||
config_data.and_then(|d| d.maybe_jsx_import_source_config());
|
||||
|
@ -491,7 +503,7 @@ impl Document {
|
|||
s,
|
||||
&CliJsrUrlProvider,
|
||||
Some(&resolver),
|
||||
Some(&npm_resolver),
|
||||
Some(npm_resolver.as_ref()),
|
||||
),
|
||||
)
|
||||
})
|
||||
|
@ -501,7 +513,7 @@ impl Document {
|
|||
Arc::new(d.with_new_resolver(
|
||||
&CliJsrUrlProvider,
|
||||
Some(&resolver),
|
||||
Some(&npm_resolver),
|
||||
Some(npm_resolver.as_ref()),
|
||||
))
|
||||
});
|
||||
is_script = self.is_script;
|
||||
|
@ -1069,7 +1081,7 @@ impl Documents {
|
|||
.or_else(|| self.file_system_docs.remove_document(specifier))
|
||||
.map(Ok)
|
||||
.unwrap_or_else(|| {
|
||||
Err(custom_error(
|
||||
Err(JsErrorBox::new(
|
||||
"NotFound",
|
||||
format!("The specifier \"{specifier}\" was not found."),
|
||||
))
|
||||
|
@ -1690,7 +1702,7 @@ fn analyze_module(
|
|||
) -> (ModuleResult, ResolutionMode) {
|
||||
match parsed_source_result {
|
||||
Ok(parsed_source) => {
|
||||
let npm_resolver = resolver.create_graph_npm_resolver(file_referrer);
|
||||
let npm_resolver = resolver.as_graph_npm_resolver(file_referrer);
|
||||
let cli_resolver = resolver.as_cli_resolver(file_referrer);
|
||||
let is_cjs_resolver = resolver.as_is_cjs_resolver(file_referrer);
|
||||
let config_data = resolver.as_config_data(file_referrer);
|
||||
|
@ -1719,7 +1731,7 @@ fn analyze_module(
|
|||
file_system: &deno_graph::source::NullFileSystem,
|
||||
jsr_url_provider: &CliJsrUrlProvider,
|
||||
maybe_resolver: Some(&resolver),
|
||||
maybe_npm_resolver: Some(&npm_resolver),
|
||||
maybe_npm_resolver: Some(npm_resolver.as_ref()),
|
||||
},
|
||||
)),
|
||||
module_resolution_mode,
|
||||
|
@ -1754,16 +1766,15 @@ fn bytes_to_content(
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::lsp::cache::LspCache;
|
||||
|
||||
use deno_config::deno_json::ConfigFile;
|
||||
use deno_config::deno_json::ConfigParseOptions;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use pretty_assertions::assert_eq;
|
||||
use test_util::TempDir;
|
||||
|
||||
use super::*;
|
||||
use crate::lsp::cache::LspCache;
|
||||
|
||||
async fn setup() -> (Documents, LspCache, TempDir) {
|
||||
let temp_dir = TempDir::new();
|
||||
temp_dir.create_dir_all(".deno_dir");
|
||||
|
@ -1912,7 +1923,6 @@ console.log(b, "hello deno");
|
|||
})
|
||||
.to_string(),
|
||||
config.root_uri().unwrap().join("deno.json").unwrap(),
|
||||
&ConfigParseOptions::default(),
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
|
@ -1956,7 +1966,6 @@ console.log(b, "hello deno");
|
|||
})
|
||||
.to_string(),
|
||||
config.root_uri().unwrap().join("deno.json").unwrap(),
|
||||
&ConfigParseOptions::default(),
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::args::jsr_api_url;
|
||||
use crate::args::jsr_url;
|
||||
use crate::file_fetcher::CliFileFetcher;
|
||||
use crate::file_fetcher::TextDecodedFile;
|
||||
use crate::jsr::partial_jsr_package_version_info_from_slice;
|
||||
use crate::jsr::JsrFetchResolver;
|
||||
use dashmap::DashMap;
|
||||
use deno_cache_dir::HttpCache;
|
||||
use deno_core::anyhow::anyhow;
|
||||
|
@ -21,11 +18,15 @@ use deno_semver::package::PackageReq;
|
|||
use deno_semver::StackString;
|
||||
use deno_semver::Version;
|
||||
use serde::Deserialize;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::config::ConfigData;
|
||||
use super::search::PackageSearchApi;
|
||||
use crate::args::jsr_api_url;
|
||||
use crate::args::jsr_url;
|
||||
use crate::file_fetcher::CliFileFetcher;
|
||||
use crate::file_fetcher::TextDecodedFile;
|
||||
use crate::jsr::partial_jsr_package_version_info_from_slice;
|
||||
use crate::jsr::JsrFetchResolver;
|
||||
|
||||
/// Keep in sync with `JsrFetchResolver`!
|
||||
#[derive(Debug)]
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue