mirror of
https://github.com/denoland/deno.git
synced 2025-08-04 10:59:13 +00:00
Merge branch 'main' into x/tunnel
# Conflicts: # cli/args/flags.rs # cli/factory.rs # cli/rt/run.rs # cli/tools/deploy.rs # ext/net/ops.rs # ext/telemetry/lib.rs
This commit is contained in:
commit
4492634bec
2036 changed files with 18954 additions and 112216 deletions
|
@ -33,6 +33,7 @@
|
|||
"cli/tsc/dts/typescript.d.ts",
|
||||
"cli/tools/doc/prism.css",
|
||||
"cli/tools/doc/prism.js",
|
||||
"ext/node/polyfills/deps",
|
||||
"ext/websocket/autobahn/reports",
|
||||
"gh-pages",
|
||||
"libs/config/testdata",
|
||||
|
@ -43,6 +44,7 @@
|
|||
"tests/node_compat/test",
|
||||
"tests/registry/",
|
||||
"tests/specs/bench/default_ts",
|
||||
"tests/specs/compile/bytes_and_text_imports",
|
||||
"tests/specs/fmt",
|
||||
"tests/specs/lint/bom",
|
||||
"tests/specs/lint/default_ts",
|
||||
|
@ -50,7 +52,6 @@
|
|||
"tests/specs/publish/no_check_surfaces_syntax_error",
|
||||
"tests/specs/run/default_ts",
|
||||
"tests/specs/test/default_ts",
|
||||
"tests/testdata/byte_order_mark.ts",
|
||||
"tests/testdata/encoding",
|
||||
"tests/testdata/file_extensions/ts_with_js_extension.js",
|
||||
"tests/testdata/fmt/",
|
||||
|
@ -61,6 +62,7 @@
|
|||
"tests/testdata/lint/glob/",
|
||||
"tests/testdata/malformed_config/",
|
||||
"tests/testdata/run/byte_order_mark.ts",
|
||||
"tests/testdata/run/invalid_utf8.ts",
|
||||
"tests/testdata/run/error_syntax_empty_trailing_line.mjs",
|
||||
"tests/testdata/run/inline_js_source_map*",
|
||||
"tests/testdata/test/markdown_windows.md",
|
||||
|
@ -69,6 +71,7 @@
|
|||
"tests/wpt/runner/manifest.json",
|
||||
"tests/wpt/suite",
|
||||
"third_party",
|
||||
"tests/specs/run/bytes_and_text_imports",
|
||||
"tests/specs/run/shebang_with_json_imports_tsc",
|
||||
"tests/specs/run/shebang_with_json_imports_swc",
|
||||
"tests/specs/run/ext_flag_takes_precedence_over_extension",
|
||||
|
|
2
.github/CONTRIBUTING.md
vendored
2
.github/CONTRIBUTING.md
vendored
|
@ -65,7 +65,7 @@ To use a development version of the LSP in VSCode:
|
|||
In addition to the above make sure that:
|
||||
|
||||
> To use the commands below, you need to first install the necessary tools on
|
||||
> your system as described [here](building_from_source).
|
||||
> your system as described [here](#building-from-source).
|
||||
|
||||
1. `cargo test` passes - this will run full test suite for `deno` including unit
|
||||
tests, integration tests and Web Platform Tests
|
||||
|
|
10
.github/workflows/ci.generate.ts
vendored
10
.github/workflows/ci.generate.ts
vendored
|
@ -5,7 +5,7 @@ import { stringify } from "jsr:@std/yaml@^0.221/stringify";
|
|||
// Bump this number when you want to purge the cache.
|
||||
// Note: the tools/release/01_bump_crate_versions.ts script will update this version
|
||||
// automatically via regex, so ensure that this line maintains this format.
|
||||
const cacheVersion = 63;
|
||||
const cacheVersion = 64;
|
||||
|
||||
const ubuntuX86Runner = "ubuntu-24.04";
|
||||
const ubuntuX86XlRunner = "ubuntu-24.04-xl";
|
||||
|
@ -479,7 +479,7 @@ const ci = {
|
|||
},
|
||||
{
|
||||
...submoduleStep("./tests/node_compat/runner/suite"),
|
||||
if: "matrix.job == 'lint' && matrix.os == 'linux'",
|
||||
if: "matrix.job == 'test'",
|
||||
},
|
||||
{
|
||||
...submoduleStep("./cli/bench/testdata/lsp_benchdata"),
|
||||
|
@ -711,12 +711,6 @@ const ci = {
|
|||
run:
|
||||
"deno run --allow-read --allow-env --allow-sys ./tools/jsdoc_checker.js",
|
||||
},
|
||||
{
|
||||
name: "node_compat/setup.ts --check",
|
||||
if: "matrix.job == 'lint' && matrix.os == 'linux'",
|
||||
run:
|
||||
"deno run --allow-write --allow-read --allow-run=git ./tests/node_compat/runner/setup.ts --check",
|
||||
},
|
||||
{
|
||||
name: "Check tracing build",
|
||||
if:
|
||||
|
|
13
.github/workflows/ci.yml
vendored
13
.github/workflows/ci.yml
vendored
|
@ -163,7 +163,7 @@ jobs:
|
|||
if: '!(matrix.skip) && (matrix.wpt)'
|
||||
- name: Clone submodule ./tests/node_compat/runner/suite
|
||||
run: git submodule update --init --recursive --depth=1 -- ./tests/node_compat/runner/suite
|
||||
if: '!(matrix.skip) && (matrix.job == ''lint'' && matrix.os == ''linux'')'
|
||||
if: '!(matrix.skip) && (matrix.job == ''test'')'
|
||||
- name: Clone submodule ./cli/bench/testdata/lsp_benchdata
|
||||
run: git submodule update --init --recursive --depth=1 -- ./cli/bench/testdata/lsp_benchdata
|
||||
if: '!(matrix.skip) && (matrix.job == ''bench'')'
|
||||
|
@ -188,8 +188,8 @@ jobs:
|
|||
~/.cargo/registry/index
|
||||
~/.cargo/registry/cache
|
||||
~/.cargo/git/db
|
||||
key: '63-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-${{ hashFiles(''Cargo.lock'') }}'
|
||||
restore-keys: '63-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-'
|
||||
key: '64-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-${{ hashFiles(''Cargo.lock'') }}'
|
||||
restore-keys: '64-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-'
|
||||
if: '!(matrix.skip)'
|
||||
- uses: dsherret/rust-toolchain-file@v1
|
||||
if: '!(matrix.skip)'
|
||||
|
@ -391,7 +391,7 @@ jobs:
|
|||
!./target/*/*.zip
|
||||
!./target/*/*.tar.gz
|
||||
key: never_saved
|
||||
restore-keys: '63-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-'
|
||||
restore-keys: '64-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
|
||||
|
@ -419,9 +419,6 @@ jobs:
|
|||
- name: jsdoc_checker.js
|
||||
if: '!(matrix.skip) && (matrix.job == ''lint'')'
|
||||
run: deno run --allow-read --allow-env --allow-sys ./tools/jsdoc_checker.js
|
||||
- name: node_compat/setup.ts --check
|
||||
if: '!(matrix.skip) && (matrix.job == ''lint'' && matrix.os == ''linux'')'
|
||||
run: deno run --allow-write --allow-read --allow-run=git ./tests/node_compat/runner/setup.ts --check
|
||||
- name: Check tracing build
|
||||
if: '!(matrix.skip) && (matrix.job == ''test'' && matrix.profile == ''debug'' && matrix.os == ''linux'' && matrix.arch == ''x86_64'')'
|
||||
run: cargo check -p deno --features=lsp-tracing
|
||||
|
@ -780,7 +777,7 @@ jobs:
|
|||
!./target/*/gn_root
|
||||
!./target/*/*.zip
|
||||
!./target/*/*.tar.gz
|
||||
key: '63-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-${{ github.sha }}'
|
||||
key: '64-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-${{ github.sha }}'
|
||||
libs:
|
||||
name: build libs
|
||||
needs:
|
||||
|
|
1
.gitmodules
vendored
1
.gitmodules
vendored
|
@ -10,6 +10,7 @@
|
|||
path = tests/node_compat/runner/suite
|
||||
url = https://github.com/denoland/node_test.git
|
||||
shallow = true
|
||||
ignore = untracked
|
||||
[submodule "cli/bench/testdata/lsp_benchdata"]
|
||||
path = cli/bench/testdata/lsp_benchdata
|
||||
url = https://github.com/denoland/deno_lsp_benchdata.git
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
max_width = 80
|
||||
tab_spaces = 2
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
|
|
154
Cargo.lock
generated
154
Cargo.lock
generated
|
@ -941,7 +941,7 @@ dependencies = [
|
|||
"chrono",
|
||||
"deno_bench_util",
|
||||
"deno_cache_dir",
|
||||
"deno_lockfile 0.30.1",
|
||||
"deno_lockfile 0.30.2",
|
||||
"deno_semver",
|
||||
"deno_terminal 0.2.2",
|
||||
"deno_tower_lsp",
|
||||
|
@ -1530,7 +1530,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno"
|
||||
version = "2.3.7"
|
||||
version = "2.4.0"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"async-trait",
|
||||
|
@ -1558,7 +1558,7 @@ dependencies = [
|
|||
"deno_graph",
|
||||
"deno_lib",
|
||||
"deno_lint",
|
||||
"deno_lockfile 0.30.1",
|
||||
"deno_lockfile 0.30.2",
|
||||
"deno_media_type",
|
||||
"deno_npm 0.35.0",
|
||||
"deno_npm_cache",
|
||||
|
@ -1676,9 +1676,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_ast"
|
||||
version = "0.48.0"
|
||||
version = "0.48.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f883bd8eae4dfc8019d925ec3dd04b634b6af9346a5168acc259d55f5f5021d"
|
||||
checksum = "0ced09fdb8884e29716cc0691e8510f9c655762bbb9da3111dacc0a2ef6e8960"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"capacity_builder",
|
||||
|
@ -1721,7 +1721,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_bench_util"
|
||||
version = "0.202.0"
|
||||
version = "0.203.0"
|
||||
dependencies = [
|
||||
"bencher",
|
||||
"deno_core",
|
||||
|
@ -1730,7 +1730,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_broadcast_channel"
|
||||
version = "0.202.0"
|
||||
version = "0.203.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"deno_core",
|
||||
|
@ -1743,7 +1743,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_cache"
|
||||
version = "0.140.0"
|
||||
version = "0.141.0"
|
||||
dependencies = [
|
||||
"async-stream",
|
||||
"async-trait",
|
||||
|
@ -1770,9 +1770,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_cache_dir"
|
||||
version = "0.22.2"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa3c29ca22ddd84eea69891b03f24be7fb9200beb4005ed105f0ad3afcdcd4f2"
|
||||
checksum = "7825da0551e670a270a3a20b92f8a0bffeb7d6120fa86b64e5daa969b8dd1a10"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base32",
|
||||
|
@ -1799,7 +1799,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_canvas"
|
||||
version = "0.77.0"
|
||||
version = "0.78.0"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"deno_core",
|
||||
|
@ -1812,7 +1812,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_config"
|
||||
version = "0.58.0"
|
||||
version = "0.59.0"
|
||||
dependencies = [
|
||||
"boxed_error",
|
||||
"capacity_builder",
|
||||
|
@ -1839,16 +1839,16 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_console"
|
||||
version = "0.208.0"
|
||||
version = "0.209.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deno_core"
|
||||
version = "0.351.0"
|
||||
version = "0.352.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4301eb6d378f3ae81fbac4cde14c3f467379efd7d46043268d76905effe3611d"
|
||||
checksum = "f79c49675a4356068f4dfae6513f7e0097e1ee8548c098a68f5bbf9a93330c51"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"az",
|
||||
|
@ -1890,7 +1890,7 @@ checksum = "fe4dccb6147bb3f3ba0c7a48e993bfeb999d2c2e47a81badee80e2b370c8d695"
|
|||
|
||||
[[package]]
|
||||
name = "deno_cron"
|
||||
version = "0.88.0"
|
||||
version = "0.89.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"chrono",
|
||||
|
@ -1904,7 +1904,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_crypto"
|
||||
version = "0.222.0"
|
||||
version = "0.223.0"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"aes-gcm",
|
||||
|
@ -1942,7 +1942,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_crypto_provider"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"aws-lc-sys",
|
||||
|
@ -1950,9 +1950,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_doc"
|
||||
version = "0.178.0"
|
||||
version = "0.179.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52fe9fb2d9e6efed6c19dbceecd14d169023ee61223336e386e0d7aa396249c4"
|
||||
checksum = "15013f500ab72ef8512a5d86eb62253707daad4206fcb958dfa4e4f952f199e0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
|
@ -2005,7 +2005,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_features"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"serde",
|
||||
|
@ -2014,7 +2014,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_fetch"
|
||||
version = "0.232.0"
|
||||
version = "0.233.0"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
|
@ -2054,7 +2054,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_ffi"
|
||||
version = "0.195.0"
|
||||
version = "0.196.0"
|
||||
dependencies = [
|
||||
"cranelift",
|
||||
"cranelift-native",
|
||||
|
@ -2078,7 +2078,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_fs"
|
||||
version = "0.118.0"
|
||||
version = "0.119.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base32",
|
||||
|
@ -2102,11 +2102,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_graph"
|
||||
version = "0.95.1"
|
||||
version = "0.96.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "365b662cfc14021c2994156d5a58b9c91d655879b817715e2d92d8adce5b3c31"
|
||||
checksum = "0733ed99295ebeddeb0fb33efa41ccd47ccd9481ab1ebe01f2ea8af80204479e"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"boxed_error",
|
||||
"capacity_builder",
|
||||
"data-url",
|
||||
"deno_ast",
|
||||
|
@ -2115,7 +2116,6 @@ dependencies = [
|
|||
"deno_path_util",
|
||||
"deno_semver",
|
||||
"deno_unsync",
|
||||
"encoding_rs",
|
||||
"futures",
|
||||
"import_map",
|
||||
"indexmap 2.9.0",
|
||||
|
@ -2136,7 +2136,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_http"
|
||||
version = "0.206.0"
|
||||
version = "0.207.0"
|
||||
dependencies = [
|
||||
"async-compression",
|
||||
"async-trait",
|
||||
|
@ -2179,7 +2179,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_io"
|
||||
version = "0.118.0"
|
||||
version = "0.119.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"deno_core",
|
||||
|
@ -2203,7 +2203,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_kv"
|
||||
version = "0.116.0"
|
||||
version = "0.117.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
|
@ -2235,7 +2235,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_lib"
|
||||
version = "0.26.0"
|
||||
version = "0.27.0"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"base64 0.22.1",
|
||||
|
@ -2299,9 +2299,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_lockfile"
|
||||
version = "0.30.1"
|
||||
version = "0.30.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5a7c1929be2f1558f798c1b75fbc828d8bc62b200435c10601a346f5a8fd67b"
|
||||
checksum = "0d4346e56cda020df5da35a3ec2624f09bd77c9f5ed18d903915007825fe9d3f"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"deno_semver",
|
||||
|
@ -2312,9 +2312,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_media_type"
|
||||
version = "0.2.8"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d9080fcfcea53bcd6eea1916217bd5611c896f3a0db4c001a859722a1258a47"
|
||||
checksum = "f0ec0dada9dc5ac4733b4175d36f6a150b7dd68fab46db35cb1ef00dd7366acb"
|
||||
dependencies = [
|
||||
"data-url",
|
||||
"encoding_rs",
|
||||
|
@ -2324,7 +2324,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_napi"
|
||||
version = "0.139.0"
|
||||
version = "0.140.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
|
@ -2354,7 +2354,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_net"
|
||||
version = "0.200.0"
|
||||
version = "0.201.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
|
@ -2379,7 +2379,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_node"
|
||||
version = "0.146.0"
|
||||
version = "0.147.0"
|
||||
dependencies = [
|
||||
"aead-gcm-stream",
|
||||
"aes",
|
||||
|
@ -2497,7 +2497,7 @@ dependencies = [
|
|||
"async-trait",
|
||||
"capacity_builder",
|
||||
"deno_error",
|
||||
"deno_lockfile 0.30.1",
|
||||
"deno_lockfile 0.30.2",
|
||||
"deno_semver",
|
||||
"futures",
|
||||
"indexmap 2.9.0",
|
||||
|
@ -2511,7 +2511,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_npm_cache"
|
||||
version = "0.27.0"
|
||||
version = "0.28.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.22.1",
|
||||
|
@ -2541,7 +2541,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_npm_installer"
|
||||
version = "0.3.0"
|
||||
version = "0.4.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-once-cell",
|
||||
|
@ -2552,7 +2552,7 @@ dependencies = [
|
|||
"deno_config",
|
||||
"deno_error",
|
||||
"deno_graph",
|
||||
"deno_lockfile 0.30.1",
|
||||
"deno_lockfile 0.30.2",
|
||||
"deno_npm 0.35.0",
|
||||
"deno_npm_cache",
|
||||
"deno_package_json",
|
||||
|
@ -2580,9 +2580,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_ops"
|
||||
version = "0.227.0"
|
||||
version = "0.228.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bab1eaf578a8cc0ae6fb933e91dc3388b41df22e5974d5891c17ba66b3a0bbb"
|
||||
checksum = "714adefbea6c347318737207f00eaf42c68c14ef51c040a96a6324b831ca59df"
|
||||
dependencies = [
|
||||
"indexmap 2.9.0",
|
||||
"proc-macro-rules",
|
||||
|
@ -2597,7 +2597,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_os"
|
||||
version = "0.25.0"
|
||||
version = "0.26.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
|
@ -2618,7 +2618,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_package_json"
|
||||
version = "0.10.0"
|
||||
version = "0.11.0"
|
||||
dependencies = [
|
||||
"boxed_error",
|
||||
"deno_error",
|
||||
|
@ -2657,7 +2657,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_permissions"
|
||||
version = "0.67.0"
|
||||
version = "0.68.0"
|
||||
dependencies = [
|
||||
"capacity_builder",
|
||||
"deno_error",
|
||||
|
@ -2665,6 +2665,7 @@ dependencies = [
|
|||
"deno_terminal 0.2.2",
|
||||
"deno_unsync",
|
||||
"fqdn",
|
||||
"ipnetwork",
|
||||
"libc",
|
||||
"log",
|
||||
"nix 0.27.1",
|
||||
|
@ -2683,7 +2684,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_process"
|
||||
version = "0.23.0"
|
||||
version = "0.24.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
|
@ -2711,7 +2712,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_resolver"
|
||||
version = "0.39.0"
|
||||
version = "0.40.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-once-cell",
|
||||
|
@ -2724,7 +2725,7 @@ dependencies = [
|
|||
"deno_config",
|
||||
"deno_error",
|
||||
"deno_graph",
|
||||
"deno_lockfile 0.30.1",
|
||||
"deno_lockfile 0.30.2",
|
||||
"deno_media_type",
|
||||
"deno_npm 0.35.0",
|
||||
"deno_package_json",
|
||||
|
@ -2738,6 +2739,7 @@ dependencies = [
|
|||
"http 1.1.0",
|
||||
"import_map",
|
||||
"indexmap 2.9.0",
|
||||
"jsonc-parser",
|
||||
"log",
|
||||
"node_resolver",
|
||||
"once_cell",
|
||||
|
@ -2753,7 +2755,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_runtime"
|
||||
version = "0.216.0"
|
||||
version = "0.217.0"
|
||||
dependencies = [
|
||||
"color-print",
|
||||
"deno_ast",
|
||||
|
@ -2835,14 +2837,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_snapshots"
|
||||
version = "0.23.0"
|
||||
version = "0.24.0"
|
||||
dependencies = [
|
||||
"deno_runtime",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deno_subprocess_windows"
|
||||
version = "0.3.0"
|
||||
version = "0.4.0"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"futures-channel",
|
||||
|
@ -2873,7 +2875,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_telemetry"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"deno_core",
|
||||
|
@ -2895,6 +2897,8 @@ dependencies = [
|
|||
"serde",
|
||||
"thiserror 2.0.12",
|
||||
"tokio",
|
||||
"tokio-vsock",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2919,7 +2923,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_tls"
|
||||
version = "0.195.0"
|
||||
version = "0.196.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
|
@ -2970,7 +2974,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_url"
|
||||
version = "0.208.0"
|
||||
version = "0.209.0"
|
||||
dependencies = [
|
||||
"deno_bench_util",
|
||||
"deno_console",
|
||||
|
@ -2982,7 +2986,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_web"
|
||||
version = "0.239.0"
|
||||
version = "0.240.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64-simd",
|
||||
|
@ -3005,7 +3009,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_webgpu"
|
||||
version = "0.175.0"
|
||||
version = "0.176.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
|
@ -3022,7 +3026,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_webidl"
|
||||
version = "0.208.0"
|
||||
version = "0.209.0"
|
||||
dependencies = [
|
||||
"deno_bench_util",
|
||||
"deno_core",
|
||||
|
@ -3030,7 +3034,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_websocket"
|
||||
version = "0.213.0"
|
||||
version = "0.214.0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"deno_core",
|
||||
|
@ -3053,7 +3057,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_webstorage"
|
||||
version = "0.203.0"
|
||||
version = "0.204.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
|
@ -3140,7 +3144,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "denort"
|
||||
version = "2.3.7"
|
||||
version = "2.4.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bincode",
|
||||
|
@ -3177,7 +3181,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "denort_helper"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"deno_error",
|
||||
"deno_path_util",
|
||||
|
@ -3473,9 +3477,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "dprint-plugin-typescript"
|
||||
version = "0.95.7"
|
||||
version = "0.95.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6761cbedde994ff3be4a5f7ad4ca822f10edf2c978725177f529789cb249c3c4"
|
||||
checksum = "a1107e3e0e59a4a5f8a07fef0427822a570295bf1f4971d70a22c23bb16a11f4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"capacity_builder",
|
||||
|
@ -3749,9 +3753,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "eszip"
|
||||
version = "0.92.0"
|
||||
version = "0.93.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dccf7977c7fcddecd68242e657b6a7b91047553da6bae3f7d1febb4e92e077b0"
|
||||
checksum = "404b07854be8333e4827b3cb3055c36ba385c7dafb4e27b8da1a0d078857723b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
|
@ -5598,9 +5602,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "malva"
|
||||
version = "0.11.2"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a952f521471c6c8302a17fc0c64a512221a9d4ff268af4d43a02bc2be48c712"
|
||||
checksum = "aa8f6005fe3f2348f1fc59d647ee6945d5832fd080178e6d034bab1bf7976348"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"itertools 0.14.0",
|
||||
|
@ -5611,9 +5615,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "markup_fmt"
|
||||
version = "0.21.0"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e59dd52b196245d3575b2af66ef15b0e20362de18b453dfbf264c258e8eefbf5"
|
||||
checksum = "2cc6a5130d40b34be77fbd52645323c199d2db25f90922d5cef1da2a9eca96b0"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"css_dataset",
|
||||
|
@ -5833,7 +5837,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "napi_sym"
|
||||
version = "0.138.0"
|
||||
version = "0.139.0"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"serde",
|
||||
|
@ -5901,7 +5905,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "node_resolver"
|
||||
version = "0.46.0"
|
||||
version = "0.47.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
|
@ -7749,9 +7753,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_v8"
|
||||
version = "0.260.0"
|
||||
version = "0.261.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4f284b4d521591b17ddee01aff830dd005a04476f7862aca9298c038d00fb7e"
|
||||
checksum = "5390adb1572a22916f7cff2e89e603053f2f1e1c7644e5c83fdaefb5ea1cb82b"
|
||||
dependencies = [
|
||||
"deno_error",
|
||||
"num-bigint",
|
||||
|
|
106
Cargo.toml
106
Cargo.toml
|
@ -53,21 +53,21 @@ exclude = ["tests/util/std/hash/_wasm"]
|
|||
|
||||
[workspace.package]
|
||||
authors = ["the Deno authors"]
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/denoland/deno"
|
||||
|
||||
[workspace.dependencies]
|
||||
deno_ast = { version = "=0.48.0", features = ["transpiling"] }
|
||||
deno_core = { version = "0.351.0" }
|
||||
deno_ast = { version = "=0.48.1", features = ["transpiling"] }
|
||||
deno_core = { version = "0.352.0" }
|
||||
|
||||
deno_cache_dir = "=0.22.2"
|
||||
deno_doc = "=0.178.0"
|
||||
deno_cache_dir = "=0.23.0"
|
||||
deno_doc = "=0.179.0"
|
||||
deno_error = "=0.6.1"
|
||||
deno_graph = { version = "=0.95.1", default-features = false }
|
||||
deno_graph = { version = "=0.96.2", default-features = false }
|
||||
deno_lint = "=0.76.0"
|
||||
deno_lockfile = "=0.30.1"
|
||||
deno_media_type = { version = "=0.2.8", features = ["module_specifier"] }
|
||||
deno_lockfile = "=0.30.2"
|
||||
deno_media_type = { version = "=0.2.9", features = ["module_specifier"] }
|
||||
deno_native_certs = "0.3.0"
|
||||
deno_npm = "=0.35.0"
|
||||
deno_path_util = "=0.4.0"
|
||||
|
@ -76,7 +76,7 @@ deno_task_shell = "=0.24.0"
|
|||
deno_terminal = "=0.2.2"
|
||||
deno_unsync = { version = "0.4.4", default-features = false }
|
||||
deno_whoami = "0.1.0"
|
||||
eszip = "=0.92.0"
|
||||
eszip = "=0.93.0"
|
||||
|
||||
denokv_proto = "0.11.0"
|
||||
denokv_remote = "0.11.0"
|
||||
|
@ -84,49 +84,49 @@ denokv_remote = "0.11.0"
|
|||
denokv_sqlite = { default-features = false, version = "0.11.0" }
|
||||
|
||||
# exts
|
||||
deno_broadcast_channel = { version = "0.202.0", path = "./ext/broadcast_channel" }
|
||||
deno_cache = { version = "0.140.0", path = "./ext/cache" }
|
||||
deno_canvas = { version = "0.77.0", path = "./ext/canvas" }
|
||||
deno_console = { version = "0.208.0", path = "./ext/console" }
|
||||
deno_cron = { version = "0.88.0", path = "./ext/cron" }
|
||||
deno_crypto = { version = "0.222.0", path = "./ext/crypto" }
|
||||
deno_fetch = { version = "0.232.0", path = "./ext/fetch" }
|
||||
deno_ffi = { version = "0.195.0", path = "./ext/ffi" }
|
||||
deno_fs = { version = "0.118.0", path = "./ext/fs" }
|
||||
deno_http = { version = "0.206.0", path = "./ext/http" }
|
||||
deno_io = { version = "0.118.0", path = "./ext/io" }
|
||||
deno_kv = { version = "0.116.0", path = "./ext/kv" }
|
||||
deno_napi = { version = "0.139.0", path = "./ext/napi" }
|
||||
deno_net = { version = "0.200.0", path = "./ext/net" }
|
||||
deno_node = { version = "0.146.0", path = "./ext/node" }
|
||||
deno_os = { version = "0.25.0", path = "./ext/os" }
|
||||
deno_process = { version = "0.23.0", path = "./ext/process" }
|
||||
deno_telemetry = { version = "0.30.0", path = "./ext/telemetry" }
|
||||
deno_tls = { version = "0.195.0", path = "./ext/tls" }
|
||||
deno_url = { version = "0.208.0", path = "./ext/url" }
|
||||
deno_web = { version = "0.239.0", path = "./ext/web" }
|
||||
deno_webgpu = { version = "0.175.0", path = "./ext/webgpu" }
|
||||
deno_webidl = { version = "0.208.0", path = "./ext/webidl" }
|
||||
deno_websocket = { version = "0.213.0", path = "./ext/websocket" }
|
||||
deno_webstorage = { version = "0.203.0", path = "./ext/webstorage" }
|
||||
denort_helper = { version = "0.6.0", path = "./ext/rt_helper" }
|
||||
deno_broadcast_channel = { version = "0.203.0", path = "./ext/broadcast_channel" }
|
||||
deno_cache = { version = "0.141.0", path = "./ext/cache" }
|
||||
deno_canvas = { version = "0.78.0", path = "./ext/canvas" }
|
||||
deno_console = { version = "0.209.0", path = "./ext/console" }
|
||||
deno_cron = { version = "0.89.0", path = "./ext/cron" }
|
||||
deno_crypto = { version = "0.223.0", path = "./ext/crypto" }
|
||||
deno_fetch = { version = "0.233.0", path = "./ext/fetch" }
|
||||
deno_ffi = { version = "0.196.0", path = "./ext/ffi" }
|
||||
deno_fs = { version = "0.119.0", path = "./ext/fs" }
|
||||
deno_http = { version = "0.207.0", path = "./ext/http" }
|
||||
deno_io = { version = "0.119.0", path = "./ext/io" }
|
||||
deno_kv = { version = "0.117.0", path = "./ext/kv" }
|
||||
deno_napi = { version = "0.140.0", path = "./ext/napi" }
|
||||
deno_net = { version = "0.201.0", path = "./ext/net" }
|
||||
deno_node = { version = "0.147.0", path = "./ext/node" }
|
||||
deno_os = { version = "0.26.0", path = "./ext/os" }
|
||||
deno_process = { version = "0.24.0", path = "./ext/process" }
|
||||
deno_telemetry = { version = "0.31.0", path = "./ext/telemetry" }
|
||||
deno_tls = { version = "0.196.0", path = "./ext/tls" }
|
||||
deno_url = { version = "0.209.0", path = "./ext/url" }
|
||||
deno_web = { version = "0.240.0", path = "./ext/web" }
|
||||
deno_webgpu = { version = "0.176.0", path = "./ext/webgpu" }
|
||||
deno_webidl = { version = "0.209.0", path = "./ext/webidl" }
|
||||
deno_websocket = { version = "0.214.0", path = "./ext/websocket" }
|
||||
deno_webstorage = { version = "0.204.0", path = "./ext/webstorage" }
|
||||
denort_helper = { version = "0.7.0", path = "./ext/rt_helper" }
|
||||
|
||||
# workspace libraries
|
||||
deno_bench_util = { version = "0.202.0", path = "./bench_util" }
|
||||
deno_config = { version = "0.58.0", features = ["workspace"], path = "./libs/config" }
|
||||
deno_crypto_provider = { version = "0.2.0", path = "./libs/crypto" }
|
||||
deno_features = { version = "0.5.0", path = "./runtime/features" }
|
||||
deno_lib = { version = "0.26.0", path = "./cli/lib" }
|
||||
deno_npm_cache = { version = "0.27.0", path = "./libs/npm_cache" }
|
||||
deno_npm_installer = { version = "0.3.0", path = "./libs/npm_installer" }
|
||||
deno_package_json = { version = "0.10.0", default-features = false, path = "./libs/package_json" }
|
||||
deno_permissions = { version = "0.67.0", path = "./runtime/permissions" }
|
||||
deno_resolver = { version = "0.39.0", path = "./libs/resolver" }
|
||||
deno_runtime = { version = "0.216.0", path = "./runtime" }
|
||||
deno_snapshots = { version = "0.23.0", path = "./cli/snapshot" }
|
||||
deno_subprocess_windows = { path = "./runtime/subprocess_windows", version = "0.3.0" }
|
||||
napi_sym = { version = "0.138.0", path = "./ext/napi/sym" }
|
||||
node_resolver = { version = "0.46.0", path = "./libs/node_resolver" }
|
||||
deno_bench_util = { version = "0.203.0", path = "./bench_util" }
|
||||
deno_config = { version = "0.59.0", features = ["workspace"], path = "./libs/config" }
|
||||
deno_crypto_provider = { version = "0.3.0", path = "./libs/crypto" }
|
||||
deno_features = { version = "0.6.0", path = "./runtime/features" }
|
||||
deno_lib = { version = "0.27.0", path = "./cli/lib" }
|
||||
deno_npm_cache = { version = "0.28.0", path = "./libs/npm_cache" }
|
||||
deno_npm_installer = { version = "0.4.0", path = "./libs/npm_installer" }
|
||||
deno_package_json = { version = "0.11.0", default-features = false, path = "./libs/package_json" }
|
||||
deno_permissions = { version = "0.68.0", path = "./runtime/permissions" }
|
||||
deno_resolver = { version = "0.40.0", path = "./libs/resolver" }
|
||||
deno_runtime = { version = "0.217.0", path = "./runtime" }
|
||||
deno_snapshots = { version = "0.24.0", path = "./cli/snapshot" }
|
||||
deno_subprocess_windows = { path = "./runtime/subprocess_windows", version = "0.4.0" }
|
||||
napi_sym = { version = "0.139.0", path = "./ext/napi/sym" }
|
||||
node_resolver = { version = "0.47.0", path = "./libs/node_resolver" }
|
||||
test_util = { package = "test_server", path = "./tests/util/server" }
|
||||
|
||||
# widely used libraries
|
||||
|
@ -303,12 +303,12 @@ dprint-core = "=0.67.4"
|
|||
dprint-plugin-json = "=0.20.0"
|
||||
dprint-plugin-jupyter = "=0.2.0"
|
||||
dprint-plugin-markdown = "=0.18.0"
|
||||
dprint-plugin-typescript = "=0.95.7"
|
||||
dprint-plugin-typescript = "=0.95.8"
|
||||
env_logger = "=0.11.6"
|
||||
fancy-regex = "=0.14.0"
|
||||
libsui = "0.10.0"
|
||||
malva = "=0.11.2"
|
||||
markup_fmt = "=0.21.0"
|
||||
malva = "=0.12.1"
|
||||
markup_fmt = "=0.22.0"
|
||||
open = "5.0.1"
|
||||
pathdiff = "0.2.1"
|
||||
pretty_yaml = "=0.5.0"
|
||||
|
|
58
Releases.md
58
Releases.md
|
@ -6,6 +6,64 @@ https://github.com/denoland/deno/releases
|
|||
We also have one-line install commands at:
|
||||
https://github.com/denoland/deno_install
|
||||
|
||||
### 2.4.0 / 2025.07.01
|
||||
|
||||
- feat(bundle): support text and bytes imports in bundle (#29908)
|
||||
- feat(check): tsconfig "references", "extends", "files", "include" and
|
||||
"exclude" (#29843)
|
||||
- feat(cli): add `--coverage` flag to `deno run` command (#29329)
|
||||
- feat(cli): alias --unstable-sloppy-imports to --sloppy-imports (#29780)
|
||||
- feat(ext/http): support `onListen()` callback in `deno serve` (#29449)
|
||||
- feat(fmt): add support for .xml, .svg and .mustache files (#29851)
|
||||
- feat(fmt): remove UTF-8 BOM instead of maintaining it (#29796)
|
||||
- feat(node API): add `fs.glob`, `fs.globSync`, `fs.promises.glob` (#28972)
|
||||
- feat(otel): stabilize OpenTelemetry support (#29822)
|
||||
- feat(process): add detached option to `Deno.Command` (#29933)
|
||||
- feat(run): resolve main module with workspace resolver (#29928)
|
||||
- feat(signals): support listening for ctrl+close on Windows (#27880)
|
||||
- feat(unstable): add DENO_NODE_CONDITIONS env var (#29848)
|
||||
- feat(unstable): bytes and text imports (#29855)
|
||||
- feat(unstable): support bytes and text imports in `deno compile` (#29924)
|
||||
- feat: --allow-net supports CIDR ranges (#29704)
|
||||
- feat: Add --deny-import flag (#29702)
|
||||
- feat: Deno.execPath() no longer requires --allow-read permission (#29620)
|
||||
- feat: add 'deno update' subcommand (#29187)
|
||||
- feat: add `DENO_AUTO_SERVE` env var (#29852)
|
||||
- feat: add `DENO_COMPAT` env var (#29889)
|
||||
- feat: add support for --preload/--import flag (#29626)
|
||||
- feat: deprecate --unstable-node-globals flag (#29887)
|
||||
- feat: make 'Buffer' and 'global' available as globals (#29416)
|
||||
- feat: make `setImmediate` and `clearImmediate` as globals (#29877)
|
||||
- feat: rename --unstable-node-conditions to --unstable-conditions (#29885)
|
||||
- feat: stabilize --allow-net subdomain wildcards (#29902)
|
||||
- feat: stabilize --node-conditions flag (#29628)
|
||||
- feat: unflag the deploy subcommand (#29863)
|
||||
- fix(bench): Make output table markdown compatible (#29532)
|
||||
- fix(bundle): only replace require shim in js files, spruce up output (#29892)
|
||||
- fix(check): don't detect tsconfigs with no deno.json/package.json or
|
||||
--no-config (#29925)
|
||||
- fix(coverage): Make output table markdown compatible (#29533)
|
||||
- fix(ext/node): add `lchmod`, `lchmod` promise, `lchmodSync` to `node:fs`
|
||||
(#29833)
|
||||
- fix(ext/node): add type check to LibuvStreamWrap.writeBuffer (#29879)
|
||||
- fix(ext/node): don't show deprecation warnings for dependencies (#29909)
|
||||
- fix(ext/node): export promise based `lchown` and `lutimes` from
|
||||
`node:fs/promises` (#29870)
|
||||
- fix(ext/node): fix reference error in node:stream (#29894)
|
||||
- fix(ext/node): improve assert.fail (#29850)
|
||||
- fix(ext/node): improve input validations of stream/consumers (#29880)
|
||||
- fix(ext/node): keep BOM in buffer.toString('utf8') (#29896)
|
||||
- fix(ext/node): remove duplicated stream classes (#29860)
|
||||
- fix(fmt/css): prefer collapsing font-family values (#29864)
|
||||
- fix(install): purge more packages from lockfile on config change (#29953)
|
||||
- fix(install/global): resolve bin name from npm packument (#29884)
|
||||
- fix(lsp): don't show no-export diagnostics for type-only npm imports (#29888)
|
||||
- fix(node): use primordials more consistently in `_events.mjs` (#29930)
|
||||
- fix(publish): disallow publishing with bytes or text imports (#29954)
|
||||
- fix: support `Deno.permissions.query({name:"import"})` (#29610)
|
||||
- perf: skip loading bytes and text imports into memory when already cached and
|
||||
building module graph (#29931)
|
||||
|
||||
### 2.3.7 / 2025.06.23
|
||||
|
||||
- feat(unstable): add `--platform` flag to deno bundle (#29697)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
[package]
|
||||
name = "deno_bench_util"
|
||||
version = "0.202.0"
|
||||
version = "0.203.0"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
|
|
@ -5,8 +5,8 @@ Example:
|
|||
```rust
|
||||
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_bench_util::bencher::benchmark_group;
|
||||
use deno_core::Extension;
|
||||
|
||||
#[op2]
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use deno_bench_util::BenchOptions;
|
||||
use deno_bench_util::bench_js_sync_with;
|
||||
use deno_bench_util::bench_or_profile;
|
||||
use deno_bench_util::bencher::benchmark_group;
|
||||
use deno_bench_util::bencher::Bencher;
|
||||
use deno_bench_util::BenchOptions;
|
||||
use deno_bench_util::bencher::benchmark_group;
|
||||
use deno_core::Extension;
|
||||
|
||||
fn setup() -> Vec<Extension> {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
use bencher::Bencher;
|
||||
use deno_core::v8;
|
||||
use deno_core::Extension;
|
||||
use deno_core::JsRuntime;
|
||||
use deno_core::PollEventLoopOptions;
|
||||
use deno_core::RuntimeOptions;
|
||||
use deno_core::v8;
|
||||
|
||||
use crate::profiling::is_profiling;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
[package]
|
||||
name = "deno"
|
||||
version = "2.3.7"
|
||||
version = "2.4.0"
|
||||
authors.workspace = true
|
||||
default-run = "deno"
|
||||
edition.workspace = true
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5,7 +5,6 @@ use std::str::FromStr;
|
|||
|
||||
use deno_core::url::Url;
|
||||
use deno_runtime::deno_permissions::NetDescriptor;
|
||||
use deno_runtime::deno_permissions::UnstableSubdomainWildcards;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct ParsePortError(String);
|
||||
|
@ -33,11 +32,7 @@ pub fn validator(host_and_port: &str) -> Result<String, String> {
|
|||
if Url::parse(&format!("internal://{host_and_port}")).is_ok()
|
||||
|| host_and_port.parse::<IpAddr>().is_ok()
|
||||
|| host_and_port.parse::<BarePort>().is_ok()
|
||||
|| NetDescriptor::parse_for_list(
|
||||
host_and_port,
|
||||
UnstableSubdomainWildcards::Enabled,
|
||||
)
|
||||
.is_ok()
|
||||
|| NetDescriptor::parse_for_list(host_and_port).is_ok()
|
||||
{
|
||||
Ok(host_and_port.to_string())
|
||||
} else {
|
||||
|
@ -57,11 +52,7 @@ pub fn parse(paths: Vec<String>) -> clap::error::Result<Vec<String>> {
|
|||
out.push(format!("{}:{}", host, port.0));
|
||||
}
|
||||
} else {
|
||||
NetDescriptor::parse_for_list(
|
||||
&host_and_port,
|
||||
UnstableSubdomainWildcards::Enabled,
|
||||
)
|
||||
.map_err(|e| {
|
||||
NetDescriptor::parse_for_list(&host_and_port).map_err(|e| {
|
||||
clap::Error::raw(clap::error::ErrorKind::InvalidValue, e.to_string())
|
||||
})?;
|
||||
out.push(host_and_port)
|
||||
|
@ -146,7 +137,10 @@ mod tests {
|
|||
"localhost:8000",
|
||||
"0.0.0.0:4545",
|
||||
"127.0.0.1:4545",
|
||||
"999.0.88.1:80"
|
||||
"999.0.88.1:80",
|
||||
"127.0.0.0/24",
|
||||
"192.168.1.0/24",
|
||||
"10.0.0.0/8"
|
||||
];
|
||||
let expected = svec![
|
||||
"deno.land",
|
||||
|
@ -168,7 +162,10 @@ mod tests {
|
|||
"localhost:8000",
|
||||
"0.0.0.0:4545",
|
||||
"127.0.0.1:4545",
|
||||
"999.0.88.1:80"
|
||||
"999.0.88.1:80",
|
||||
"127.0.0.0/24",
|
||||
"192.168.1.0/24",
|
||||
"10.0.0.0/8"
|
||||
];
|
||||
let actual = parse(entries).unwrap();
|
||||
assert_eq!(actual, expected);
|
||||
|
|
260
cli/args/mod.rs
260
cli/args/mod.rs
|
@ -24,8 +24,8 @@ 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::TsTypeLib;
|
||||
pub use deno_config::glob::FilePatterns;
|
||||
pub use deno_config::workspace::TsTypeLib;
|
||||
use deno_config::workspace::Workspace;
|
||||
use deno_config::workspace::WorkspaceDirLintConfig;
|
||||
use deno_config::workspace::WorkspaceDirectory;
|
||||
|
@ -35,20 +35,20 @@ use deno_core::error::AnyError;
|
|||
use deno_core::resolve_url_or_path;
|
||||
use deno_core::url::Url;
|
||||
use deno_graph::GraphKind;
|
||||
use deno_lib::args::CaData;
|
||||
use deno_lib::args::has_flag_env_var;
|
||||
use deno_lib::args::npm_pkg_req_ref_to_binary_command;
|
||||
use deno_lib::args::npm_process_state;
|
||||
use deno_lib::args::CaData;
|
||||
use deno_lib::version::DENO_VERSION_INFO;
|
||||
use deno_lib::worker::StorageKeyResolver;
|
||||
use deno_npm::NpmSystemInfo;
|
||||
use deno_npm_installer::graph::NpmCachingStrategy;
|
||||
use deno_npm_installer::LifecycleScriptsConfig;
|
||||
use deno_npm_installer::graph::NpmCachingStrategy;
|
||||
use deno_resolver::factory::resolve_jsr_url;
|
||||
use deno_runtime::deno_permissions::PermissionsOptions;
|
||||
use deno_runtime::inspector_server::InspectorServer;
|
||||
use deno_semver::npm::NpmPackageReqReference;
|
||||
use deno_semver::StackString;
|
||||
use deno_semver::npm::NpmPackageReqReference;
|
||||
use deno_telemetry::OtelConfig;
|
||||
use deno_terminal::colors;
|
||||
use dotenvy::from_filename;
|
||||
|
@ -59,8 +59,6 @@ use thiserror::Error;
|
|||
use crate::sys::CliSys;
|
||||
|
||||
pub type CliLockfile = deno_resolver::lockfile::LockfileLock<CliSys>;
|
||||
pub type CliTsConfigResolver =
|
||||
deno_resolver::deno_json::TsConfigResolver<CliSys>;
|
||||
|
||||
pub fn jsr_url() -> &'static Url {
|
||||
static JSR_URL: Lazy<Url> = Lazy::new(|| resolve_jsr_url(&CliSys::default()));
|
||||
|
@ -355,6 +353,110 @@ fn resolve_lint_rules_options(
|
|||
}
|
||||
}
|
||||
|
||||
pub struct WorkspaceMainModuleResolver {
|
||||
workspace_resolver: Arc<deno_resolver::workspace::WorkspaceResolver<CliSys>>,
|
||||
node_resolver: Arc<crate::node::CliNodeResolver>,
|
||||
}
|
||||
|
||||
impl WorkspaceMainModuleResolver {
|
||||
pub fn new(
|
||||
workspace_resolver: Arc<
|
||||
deno_resolver::workspace::WorkspaceResolver<CliSys>,
|
||||
>,
|
||||
node_resolver: Arc<crate::node::CliNodeResolver>,
|
||||
) -> Self {
|
||||
Self {
|
||||
workspace_resolver,
|
||||
node_resolver,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl WorkspaceMainModuleResolver {
|
||||
fn resolve_main_module(
|
||||
&self,
|
||||
specifier: &str,
|
||||
cwd: &Url,
|
||||
) -> Result<Url, AnyError> {
|
||||
let resolution = self.workspace_resolver.resolve(
|
||||
specifier,
|
||||
cwd,
|
||||
deno_resolver::workspace::ResolutionKind::Execution,
|
||||
)?;
|
||||
let url = match resolution {
|
||||
deno_resolver::workspace::MappedResolution::Normal {
|
||||
specifier, ..
|
||||
} => specifier,
|
||||
deno_resolver::workspace::MappedResolution::WorkspaceJsrPackage {
|
||||
specifier,
|
||||
..
|
||||
} => specifier,
|
||||
deno_resolver::workspace::MappedResolution::WorkspaceNpmPackage {
|
||||
target_pkg_json,
|
||||
sub_path,
|
||||
..
|
||||
} => self
|
||||
.node_resolver
|
||||
.resolve_package_subpath_from_deno_module(
|
||||
target_pkg_json.clone().dir_path(),
|
||||
sub_path.as_deref(),
|
||||
Some(cwd),
|
||||
node_resolver::ResolutionMode::Import,
|
||||
node_resolver::NodeResolutionKind::Execution,
|
||||
)?
|
||||
.into_url()?,
|
||||
deno_resolver::workspace::MappedResolution::PackageJson {
|
||||
sub_path,
|
||||
dep_result,
|
||||
alias,
|
||||
..
|
||||
} => {
|
||||
let result = dep_result
|
||||
.as_ref()
|
||||
.map_err(|e| deno_core::anyhow::anyhow!("{e}"))?;
|
||||
match result {
|
||||
deno_package_json::PackageJsonDepValue::File(file) => {
|
||||
let cwd_path = deno_path_util::url_to_file_path(cwd)?;
|
||||
deno_path_util::resolve_path(file, &cwd_path)?
|
||||
}
|
||||
deno_package_json::PackageJsonDepValue::Req(package_req) => {
|
||||
ModuleSpecifier::parse(&format!(
|
||||
"npm:{}{}",
|
||||
package_req,
|
||||
sub_path.map(|s| format!("/{}", s)).unwrap_or_default()
|
||||
))?
|
||||
}
|
||||
deno_package_json::PackageJsonDepValue::Workspace(version_req) => {
|
||||
let pkg_folder = self
|
||||
.workspace_resolver
|
||||
.resolve_workspace_pkg_json_folder_for_pkg_json_dep(
|
||||
alias,
|
||||
version_req,
|
||||
)?;
|
||||
self
|
||||
.node_resolver
|
||||
.resolve_package_subpath_from_deno_module(
|
||||
pkg_folder,
|
||||
sub_path.as_deref(),
|
||||
Some(cwd),
|
||||
node_resolver::ResolutionMode::Import,
|
||||
node_resolver::NodeResolutionKind::Execution,
|
||||
)?
|
||||
.into_url()?
|
||||
}
|
||||
deno_package_json::PackageJsonDepValue::JsrReq(_) => {
|
||||
return Err(
|
||||
deno_resolver::DenoResolveErrorKind::UnsupportedPackageJsonJsrReq
|
||||
.into_box()
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Ok(url)
|
||||
}
|
||||
}
|
||||
|
||||
/// Holds the resolved options of many sources used by subcommands
|
||||
/// and provides some helper function for creating common objects.
|
||||
#[derive(Debug)]
|
||||
|
@ -472,7 +574,11 @@ impl CliOptions {
|
|||
let maybe_node_channel_fd = std::env::var("NODE_CHANNEL_FD").ok();
|
||||
if let Some(node_channel_fd) = maybe_node_channel_fd {
|
||||
// Remove so that child processes don't inherit this environment variable.
|
||||
std::env::remove_var("NODE_CHANNEL_FD");
|
||||
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
unsafe {
|
||||
std::env::remove_var("NODE_CHANNEL_FD")
|
||||
};
|
||||
node_channel_fd.parse::<i64>().ok()
|
||||
} else {
|
||||
None
|
||||
|
@ -515,7 +621,43 @@ impl CliOptions {
|
|||
self.flags.env_file.as_ref()
|
||||
}
|
||||
|
||||
pub fn resolve_main_module(&self) -> Result<&ModuleSpecifier, AnyError> {
|
||||
pub fn preload_modules(&self) -> Result<Vec<ModuleSpecifier>, AnyError> {
|
||||
if self.flags.preload.is_empty() {
|
||||
return Ok(vec![]);
|
||||
}
|
||||
|
||||
let mut preload = Vec::with_capacity(self.flags.preload.len());
|
||||
for preload_specifier in self.flags.preload.iter() {
|
||||
preload.push(resolve_url_or_path(preload_specifier, self.initial_cwd())?);
|
||||
}
|
||||
|
||||
Ok(preload)
|
||||
}
|
||||
|
||||
fn resolve_main_module_with_resolver_if_bare(
|
||||
&self,
|
||||
raw_specifier: &str,
|
||||
resolver: Option<&WorkspaceMainModuleResolver>,
|
||||
default_resolve: impl Fn() -> Result<ModuleSpecifier, AnyError>,
|
||||
) -> Result<ModuleSpecifier, AnyError> {
|
||||
match resolver {
|
||||
Some(resolver)
|
||||
if !raw_specifier.starts_with('.')
|
||||
&& !Path::new(raw_specifier).is_absolute() =>
|
||||
{
|
||||
let cwd = deno_path_util::url_from_directory_path(self.initial_cwd())?;
|
||||
resolver
|
||||
.resolve_main_module(raw_specifier, &cwd)
|
||||
.or_else(|_| default_resolve())
|
||||
}
|
||||
_ => default_resolve(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_main_module_with_resolver(
|
||||
&self,
|
||||
resolver: Option<&WorkspaceMainModuleResolver>,
|
||||
) -> Result<&ModuleSpecifier, AnyError> {
|
||||
self
|
||||
.main_module_cell
|
||||
.get_or_init(|| {
|
||||
|
@ -533,25 +675,40 @@ impl CliOptions {
|
|||
if run_flags.is_stdin() {
|
||||
resolve_url_or_path("./$deno$stdin.mts", self.initial_cwd())?
|
||||
} else {
|
||||
let url =
|
||||
resolve_url_or_path(&run_flags.script, self.initial_cwd())?;
|
||||
if self.is_node_main()
|
||||
&& url.scheme() == "file"
|
||||
&& MediaType::from_specifier(&url) == MediaType::Unknown
|
||||
{
|
||||
try_resolve_node_binary_main_entrypoint(
|
||||
&run_flags.script,
|
||||
self.initial_cwd(),
|
||||
)?
|
||||
.unwrap_or(url)
|
||||
} else {
|
||||
url
|
||||
}
|
||||
let default_resolve = || {
|
||||
let url =
|
||||
resolve_url_or_path(&run_flags.script, self.initial_cwd())?;
|
||||
if self.is_node_main()
|
||||
&& url.scheme() == "file"
|
||||
&& MediaType::from_specifier(&url) == MediaType::Unknown
|
||||
{
|
||||
Ok::<_, AnyError>(
|
||||
try_resolve_node_binary_main_entrypoint(
|
||||
&run_flags.script,
|
||||
self.initial_cwd(),
|
||||
)?
|
||||
.unwrap_or(url),
|
||||
)
|
||||
} else {
|
||||
Ok(url)
|
||||
}
|
||||
};
|
||||
self.resolve_main_module_with_resolver_if_bare(
|
||||
&run_flags.script,
|
||||
resolver,
|
||||
default_resolve,
|
||||
)?
|
||||
}
|
||||
}
|
||||
DenoSubcommand::Serve(run_flags) => {
|
||||
resolve_url_or_path(&run_flags.script, self.initial_cwd())?
|
||||
}
|
||||
DenoSubcommand::Serve(run_flags) => self
|
||||
.resolve_main_module_with_resolver_if_bare(
|
||||
&run_flags.script,
|
||||
resolver,
|
||||
|| {
|
||||
resolve_url_or_path(&run_flags.script, self.initial_cwd())
|
||||
.map_err(|e| e.into())
|
||||
},
|
||||
)?,
|
||||
_ => {
|
||||
bail!("No main module.")
|
||||
}
|
||||
|
@ -561,6 +718,10 @@ impl CliOptions {
|
|||
.map_err(|err| deno_core::anyhow::anyhow!("{}", err))
|
||||
}
|
||||
|
||||
pub fn resolve_main_module(&self) -> Result<&ModuleSpecifier, AnyError> {
|
||||
self.resolve_main_module_with_resolver(None)
|
||||
}
|
||||
|
||||
pub fn resolve_file_header_overrides(
|
||||
&self,
|
||||
) -> HashMap<ModuleSpecifier, HashMap<String, String>> {
|
||||
|
@ -762,6 +923,11 @@ impl CliOptions {
|
|||
.as_ref()
|
||||
.map(ToOwned::to_owned)
|
||||
.or_else(|| env::var("DENO_COVERAGE_DIR").ok()),
|
||||
DenoSubcommand::Run(flags) => flags
|
||||
.coverage_dir
|
||||
.as_ref()
|
||||
.map(ToOwned::to_owned)
|
||||
.or_else(|| env::var("DENO_COVERAGE_DIR").ok()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -868,6 +1034,7 @@ impl CliOptions {
|
|||
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()),
|
||||
deny_import: flags.deny_import.clone(),
|
||||
prompt: !resolve_no_prompt(flags),
|
||||
}
|
||||
}
|
||||
|
@ -882,6 +1049,7 @@ impl CliOptions {
|
|||
if !options.allow_all && options.allow_import.is_none() {
|
||||
options.allow_import = Some(self.implicit_allow_import());
|
||||
}
|
||||
options.deny_import = options.deny_import.clone();
|
||||
}
|
||||
|
||||
fn implicit_allow_import(&self) -> Vec<String> {
|
||||
|
@ -978,7 +1146,11 @@ impl CliOptions {
|
|||
match std::env::var(NPM_CMD_NAME_ENV_VAR_NAME) {
|
||||
Ok(var) => {
|
||||
// remove the env var so that child sub processes won't pick this up
|
||||
std::env::remove_var(NPM_CMD_NAME_ENV_VAR_NAME);
|
||||
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
unsafe {
|
||||
std::env::remove_var(NPM_CMD_NAME_ENV_VAR_NAME)
|
||||
};
|
||||
Some(var)
|
||||
}
|
||||
Err(_) => NpmPackageReqReference::from_str(&flags.script).ok().map(
|
||||
|
@ -998,11 +1170,6 @@ impl CliOptions {
|
|||
&self.flags.unsafely_ignore_certificate_errors
|
||||
}
|
||||
|
||||
pub fn unstable_subdomain_wildcards(&self) -> bool {
|
||||
self.flags.unstable_config.subdomain_wildcards
|
||||
|| self.workspace().has_unstable("subdomain-wildcards")
|
||||
}
|
||||
|
||||
pub fn unstable_bare_node_builtins(&self) -> bool {
|
||||
self.flags.unstable_config.bare_node_builtins
|
||||
|| self.workspace().has_unstable("bare-node-builtins")
|
||||
|
@ -1020,6 +1187,11 @@ impl CliOptions {
|
|||
self.workspace().package_jsons().next().is_some() || self.is_node_main()
|
||||
}
|
||||
|
||||
pub fn unstable_raw_imports(&self) -> bool {
|
||||
self.flags.unstable_config.raw_imports
|
||||
|| self.workspace().has_unstable("raw-imports")
|
||||
}
|
||||
|
||||
pub fn unstable_lazy_dynamic_imports(&self) -> bool {
|
||||
self.flags.unstable_config.lazy_dynamic_imports
|
||||
|| self.workspace().has_unstable("lazy-dynamic-imports")
|
||||
|
@ -1252,10 +1424,28 @@ pub fn load_env_variables_from_env_file(
|
|||
.unwrap_or(true)
|
||||
{
|
||||
match error {
|
||||
dotenvy::Error::LineParse(line, index)=> eprintln!("{} Parsing failed within the specified environment file: {} at index: {} of the value: {}", colors::yellow("Warning"), env_file_name, index, line),
|
||||
dotenvy::Error::Io(_)=> eprintln!("{} The `--env-file` flag was used, but the environment file specified '{}' was not found.", colors::yellow("Warning"), env_file_name),
|
||||
dotenvy::Error::EnvVar(_)=> eprintln!("{} One or more of the environment variables isn't present or not unicode within the specified environment file: {}", colors::yellow("Warning"), env_file_name),
|
||||
_ => eprintln!("{} Unknown failure occurred with the specified environment file: {}", colors::yellow("Warning"), env_file_name),
|
||||
dotenvy::Error::LineParse(line, index) => eprintln!(
|
||||
"{} Parsing failed within the specified environment file: {} at index: {} of the value: {}",
|
||||
colors::yellow("Warning"),
|
||||
env_file_name,
|
||||
index,
|
||||
line
|
||||
),
|
||||
dotenvy::Error::Io(_) => eprintln!(
|
||||
"{} The `--env-file` flag was used, but the environment file specified '{}' was not found.",
|
||||
colors::yellow("Warning"),
|
||||
env_file_name
|
||||
),
|
||||
dotenvy::Error::EnvVar(_) => eprintln!(
|
||||
"{} One or more of the environment variables isn't present or not unicode within the specified environment file: {}",
|
||||
colors::yellow("Warning"),
|
||||
env_file_name
|
||||
),
|
||||
_ => eprintln!(
|
||||
"{} Unknown failure occurred with the specified environment file: {}",
|
||||
colors::yellow("Warning"),
|
||||
env_file_name
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,11 +7,11 @@ 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 deno_core::serde_json::json;
|
||||
use lsp_types::Uri;
|
||||
use test_util::lsp::LspClientBuilder;
|
||||
use test_util::PathRef;
|
||||
use test_util::lsp::LspClientBuilder;
|
||||
use tower_lsp::lsp_types as lsp;
|
||||
|
||||
static FIXTURE_CODE_LENS_TS: &str = include_str!("testdata/code_lens.ts");
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use deno_bench_util::bencher::Bencher;
|
||||
use deno_bench_util::bencher::benchmark_group;
|
||||
use deno_bench_util::bencher::benchmark_main;
|
||||
use deno_bench_util::bencher::Bencher;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_json::Value;
|
||||
use deno_core::serde_json::json;
|
||||
use test_util::lsp::LspClient;
|
||||
use test_util::lsp::LspClientBuilder;
|
||||
|
||||
|
|
12
cli/cache/cache_db.rs
vendored
12
cli/cache/cache_db.rs
vendored
|
@ -33,6 +33,10 @@ impl CacheDBHash {
|
|||
.finish(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn inner(&self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl rusqlite::types::ToSql for CacheDBHash {
|
||||
|
@ -423,7 +427,11 @@ fn open_connection(
|
|||
// Failed, try deleting it
|
||||
let is_tty = std::io::stderr().is_terminal();
|
||||
log::log!(
|
||||
if is_tty { log::Level::Warn } else { log::Level::Trace },
|
||||
if is_tty {
|
||||
log::Level::Warn
|
||||
} else {
|
||||
log::Level::Trace
|
||||
},
|
||||
"Could not initialize cache database '{}', deleting and retrying... ({err:?})",
|
||||
path.to_string_lossy()
|
||||
);
|
||||
|
@ -601,9 +609,9 @@ mod tests {
|
|||
}
|
||||
|
||||
fn assert_same_serialize_deserialize(original_hash: CacheDBHash) {
|
||||
use rusqlite::ToSql;
|
||||
use rusqlite::types::FromSql;
|
||||
use rusqlite::types::ValueRef;
|
||||
use rusqlite::ToSql;
|
||||
|
||||
let value = original_hash.to_sql().unwrap();
|
||||
match value {
|
||||
|
|
36
cli/cache/code_cache.rs
vendored
36
cli/cache/code_cache.rs
vendored
|
@ -178,14 +178,16 @@ mod test {
|
|||
let conn = CacheDB::in_memory(&CODE_CACHE_DB, "1.0.0");
|
||||
let cache = CodeCacheInner::new(conn);
|
||||
|
||||
assert!(cache
|
||||
.get_sync(
|
||||
"file:///foo/bar.js",
|
||||
code_cache::CodeCacheType::EsModule,
|
||||
CacheDBHash::new(1),
|
||||
)
|
||||
.unwrap()
|
||||
.is_none());
|
||||
assert!(
|
||||
cache
|
||||
.get_sync(
|
||||
"file:///foo/bar.js",
|
||||
code_cache::CodeCacheType::EsModule,
|
||||
CacheDBHash::new(1),
|
||||
)
|
||||
.unwrap()
|
||||
.is_none()
|
||||
);
|
||||
let data_esm = vec![1, 2, 3];
|
||||
cache
|
||||
.set_sync(
|
||||
|
@ -207,14 +209,16 @@ mod test {
|
|||
data_esm
|
||||
);
|
||||
|
||||
assert!(cache
|
||||
.get_sync(
|
||||
"file:///foo/bar.js",
|
||||
code_cache::CodeCacheType::Script,
|
||||
CacheDBHash::new(1),
|
||||
)
|
||||
.unwrap()
|
||||
.is_none());
|
||||
assert!(
|
||||
cache
|
||||
.get_sync(
|
||||
"file:///foo/bar.js",
|
||||
code_cache::CodeCacheType::Script,
|
||||
CacheDBHash::new(1),
|
||||
)
|
||||
.unwrap()
|
||||
.is_none()
|
||||
);
|
||||
let data_script = vec![4, 5, 6];
|
||||
cache
|
||||
.set_sync(
|
||||
|
|
2
cli/cache/incremental.rs
vendored
2
cli/cache/incremental.rs
vendored
|
@ -6,8 +6,8 @@ use std::path::PathBuf;
|
|||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::unsync::spawn;
|
||||
use deno_core::unsync::JoinHandle;
|
||||
use deno_core::unsync::spawn;
|
||||
use deno_runtime::deno_webstorage::rusqlite::params;
|
||||
|
||||
use super::cache_db::CacheDB;
|
||||
|
|
15
cli/cache/mod.rs
vendored
15
cli/cache/mod.rs
vendored
|
@ -4,14 +4,13 @@ mod cache_db;
|
|||
mod caches;
|
||||
mod check;
|
||||
mod code_cache;
|
||||
mod deno_dir;
|
||||
mod disk_cache;
|
||||
mod emit;
|
||||
mod fast_check;
|
||||
mod incremental;
|
||||
mod module_info;
|
||||
mod node;
|
||||
mod parsed_source;
|
||||
|
||||
pub type DenoDir = deno_resolver::cache::DenoDir<CliSys>;
|
||||
pub type DenoDirProvider = deno_resolver::cache::DenoDirProvider<CliSys>;
|
||||
|
||||
pub use cache_db::CacheDBHash;
|
||||
pub use caches::Caches;
|
||||
|
@ -19,16 +18,10 @@ pub use check::TypeCheckCache;
|
|||
pub use code_cache::CodeCache;
|
||||
/// Permissions used to save a file in the disk caches.
|
||||
pub use deno_cache_dir::CACHE_PERM;
|
||||
pub use deno_dir::DenoDir;
|
||||
pub use deno_dir::DenoDirProvider;
|
||||
pub use disk_cache::DiskCache;
|
||||
pub use emit::EmitCache;
|
||||
pub use fast_check::FastCheckCache;
|
||||
pub use incremental::IncrementalCache;
|
||||
pub use module_info::ModuleInfoCache;
|
||||
pub use node::NodeAnalysisCache;
|
||||
pub use parsed_source::LazyGraphSourceParser;
|
||||
pub use parsed_source::ParsedSourceCache;
|
||||
pub use node::SqliteNodeAnalysisCache;
|
||||
|
||||
use crate::sys::CliSys;
|
||||
|
||||
|
|
4
cli/cache/module_info.rs
vendored
4
cli/cache/module_info.rs
vendored
|
@ -9,13 +9,13 @@ use deno_core::serde_json;
|
|||
use deno_error::JsErrorBox;
|
||||
use deno_graph::analysis::ModuleInfo;
|
||||
use deno_graph::ast::ParserModuleAnalyzer;
|
||||
use deno_resolver::cache::ParsedSourceCache;
|
||||
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 super::ParsedSourceCache;
|
||||
|
||||
const SELECT_MODULE_INFO: &str = "
|
||||
SELECT
|
||||
|
@ -316,9 +316,9 @@ fn serialize_media_type(media_type: MediaType) -> i64 {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use deno_graph::PositionRange;
|
||||
use deno_graph::analysis::JsDocImportInfo;
|
||||
use deno_graph::analysis::SpecifierWithRange;
|
||||
use deno_graph::PositionRange;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
|
80
cli/cache/node.rs
vendored
80
cli/cache/node.rs
vendored
|
@ -2,13 +2,15 @@
|
|||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::serde_json;
|
||||
use deno_resolver::cjs::analyzer::DenoCjsAnalysis;
|
||||
use deno_resolver::cjs::analyzer::NodeAnalysisCache;
|
||||
use deno_resolver::cjs::analyzer::NodeAnalysisCacheSourceHash;
|
||||
use deno_runtime::deno_webstorage::rusqlite::params;
|
||||
|
||||
use super::CacheDBHash;
|
||||
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 {
|
||||
|
@ -25,11 +27,11 @@ pub static NODE_ANALYSIS_CACHE_DB: CacheDBConfiguration =
|
|||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct NodeAnalysisCache {
|
||||
pub struct SqliteNodeAnalysisCache {
|
||||
inner: NodeAnalysisCacheInner,
|
||||
}
|
||||
|
||||
impl NodeAnalysisCache {
|
||||
impl SqliteNodeAnalysisCache {
|
||||
pub fn new(db: CacheDB) -> Self {
|
||||
Self {
|
||||
inner: NodeAnalysisCacheInner::new(db),
|
||||
|
@ -52,27 +54,35 @@ impl NodeAnalysisCache {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_cjs_analysis(
|
||||
impl NodeAnalysisCache for SqliteNodeAnalysisCache {
|
||||
fn compute_source_hash(&self, source: &str) -> NodeAnalysisCacheSourceHash {
|
||||
NodeAnalysisCacheSourceHash(CacheDBHash::from_hashable(source).inner())
|
||||
}
|
||||
|
||||
fn get_cjs_analysis(
|
||||
&self,
|
||||
specifier: &str,
|
||||
expected_source_hash: CacheDBHash,
|
||||
) -> Option<CliCjsAnalysis> {
|
||||
specifier: &deno_ast::ModuleSpecifier,
|
||||
source_hash: NodeAnalysisCacheSourceHash,
|
||||
) -> Option<DenoCjsAnalysis> {
|
||||
Self::ensure_ok(
|
||||
self.inner.get_cjs_analysis(specifier, expected_source_hash),
|
||||
self
|
||||
.inner
|
||||
.get_cjs_analysis(specifier.as_str(), CacheDBHash::new(source_hash.0)),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn set_cjs_analysis(
|
||||
fn set_cjs_analysis(
|
||||
&self,
|
||||
specifier: &str,
|
||||
source_hash: CacheDBHash,
|
||||
cjs_analysis: &CliCjsAnalysis,
|
||||
specifier: &deno_ast::ModuleSpecifier,
|
||||
source_hash: NodeAnalysisCacheSourceHash,
|
||||
analysis: &DenoCjsAnalysis,
|
||||
) {
|
||||
Self::ensure_ok(self.inner.set_cjs_analysis(
|
||||
specifier,
|
||||
source_hash,
|
||||
cjs_analysis,
|
||||
specifier.as_str(),
|
||||
CacheDBHash::new(source_hash.0),
|
||||
analysis,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +101,7 @@ impl NodeAnalysisCacheInner {
|
|||
&self,
|
||||
specifier: &str,
|
||||
expected_source_hash: CacheDBHash,
|
||||
) -> Result<Option<CliCjsAnalysis>, AnyError> {
|
||||
) -> Result<Option<DenoCjsAnalysis>, AnyError> {
|
||||
let query = "
|
||||
SELECT
|
||||
data
|
||||
|
@ -116,7 +126,7 @@ impl NodeAnalysisCacheInner {
|
|||
&self,
|
||||
specifier: &str,
|
||||
source_hash: CacheDBHash,
|
||||
cjs_analysis: &CliCjsAnalysis,
|
||||
cjs_analysis: &DenoCjsAnalysis,
|
||||
) -> Result<(), AnyError> {
|
||||
let sql = "
|
||||
INSERT OR REPLACE INTO
|
||||
|
@ -137,7 +147,7 @@ impl NodeAnalysisCacheInner {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use deno_ast::ModuleExportsAndReExports;
|
||||
use deno_resolver::cjs::analyzer::ModuleExportsAndReExports;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -146,21 +156,25 @@ mod test {
|
|||
let conn = CacheDB::in_memory(&NODE_ANALYSIS_CACHE_DB, "1.0.0");
|
||||
let cache = NodeAnalysisCacheInner::new(conn);
|
||||
|
||||
assert!(cache
|
||||
.get_cjs_analysis("file.js", CacheDBHash::new(2))
|
||||
.unwrap()
|
||||
.is_none());
|
||||
let cjs_analysis = CliCjsAnalysis::Cjs(ModuleExportsAndReExports {
|
||||
assert!(
|
||||
cache
|
||||
.get_cjs_analysis("file.js", CacheDBHash::new(2))
|
||||
.unwrap()
|
||||
.is_none()
|
||||
);
|
||||
let cjs_analysis = DenoCjsAnalysis::Cjs(ModuleExportsAndReExports {
|
||||
exports: vec!["export1".to_string()],
|
||||
reexports: vec!["re-export1".to_string()],
|
||||
});
|
||||
cache
|
||||
.set_cjs_analysis("file.js", CacheDBHash::new(2), &cjs_analysis)
|
||||
.unwrap();
|
||||
assert!(cache
|
||||
.get_cjs_analysis("file.js", CacheDBHash::new(3))
|
||||
.unwrap()
|
||||
.is_none()); // different hash
|
||||
assert!(
|
||||
cache
|
||||
.get_cjs_analysis("file.js", CacheDBHash::new(3))
|
||||
.unwrap()
|
||||
.is_none()
|
||||
); // different hash
|
||||
let actual_cjs_analysis = cache
|
||||
.get_cjs_analysis("file.js", CacheDBHash::new(2))
|
||||
.unwrap()
|
||||
|
@ -184,9 +198,11 @@ mod test {
|
|||
// now changing the cli version should clear it
|
||||
let conn = cache.conn.recreate_with_version("2.0.0");
|
||||
let cache = NodeAnalysisCacheInner::new(conn);
|
||||
assert!(cache
|
||||
.get_cjs_analysis("file.js", CacheDBHash::new(2))
|
||||
.unwrap()
|
||||
.is_none());
|
||||
assert!(
|
||||
cache
|
||||
.get_cjs_analysis("file.js", CacheDBHash::new(2))
|
||||
.unwrap()
|
||||
.is_none()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
244
cli/factory.rs
244
cli/factory.rs
|
@ -6,8 +6,8 @@ use std::path::Path;
|
|||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_cache_dir::npm::NpmCacheDir;
|
||||
use deno_cache_dir::GlobalOrLocalHttpCache;
|
||||
use deno_cache_dir::npm::NpmCacheDir;
|
||||
use deno_config::workspace::WorkspaceDirectory;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
|
@ -15,46 +15,47 @@ use deno_core::futures::FutureExt;
|
|||
use deno_core::serde_json;
|
||||
use deno_core::url::Url;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_lib::args::CaData;
|
||||
use deno_lib::args::get_root_cert_store;
|
||||
use deno_lib::args::npm_process_state;
|
||||
use deno_lib::args::CaData;
|
||||
use deno_lib::loader::NpmModuleLoader;
|
||||
use deno_lib::npm::create_npm_process_state_provider;
|
||||
use deno_lib::npm::NpmRegistryReadPermissionChecker;
|
||||
use deno_lib::npm::NpmRegistryReadPermissionCheckerMode;
|
||||
use deno_lib::npm::create_npm_process_state_provider;
|
||||
use deno_lib::worker::LibMainWorkerFactory;
|
||||
use deno_lib::worker::LibMainWorkerOptions;
|
||||
use deno_lib::worker::LibWorkerFactoryRoots;
|
||||
use deno_npm::npm_rc::ResolvedNpmRc;
|
||||
use deno_npm_cache::NpmCacheSetting;
|
||||
use deno_npm_installer::NpmInstallerFactoryOptions;
|
||||
use deno_npm_installer::lifecycle_scripts::LifecycleScriptsExecutor;
|
||||
use deno_npm_installer::lifecycle_scripts::NullLifecycleScriptsExecutor;
|
||||
use deno_npm_installer::process_state::NpmProcessStateKind;
|
||||
use deno_npm_installer::NpmInstallerFactoryOptions;
|
||||
use deno_resolver::cache::ParsedSourceCache;
|
||||
use deno_resolver::cjs::IsCjsResolutionMode;
|
||||
use deno_resolver::deno_json::CompilerOptionsOverrides;
|
||||
use deno_resolver::deno_json::CompilerOptionsResolver;
|
||||
use deno_resolver::factory::ConfigDiscoveryOption;
|
||||
use deno_resolver::factory::DenoDirPathProviderOptions;
|
||||
use deno_resolver::factory::NpmProcessStateOptions;
|
||||
use deno_resolver::factory::ResolverFactoryOptions;
|
||||
use deno_resolver::factory::SpecifiedImportMapProvider;
|
||||
use deno_resolver::factory::WorkspaceDirectoryProvider;
|
||||
use deno_resolver::import_map::WorkspaceExternalImportMapLoader;
|
||||
use deno_resolver::npm::DenoInNpmPackageChecker;
|
||||
use deno_resolver::workspace::WorkspaceResolver;
|
||||
use deno_runtime::FeatureChecker;
|
||||
use deno_runtime::deno_fs;
|
||||
use deno_runtime::deno_fs::RealFs;
|
||||
use deno_runtime::deno_permissions::Permissions;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
use deno_runtime::deno_permissions::UnstableSubdomainWildcards;
|
||||
use deno_runtime::deno_tls::rustls::RootCertStore;
|
||||
use deno_runtime::deno_tls::RootCertStoreProvider;
|
||||
use deno_runtime::deno_tls::rustls::RootCertStore;
|
||||
use deno_runtime::deno_web::BlobStore;
|
||||
use deno_runtime::inspector_server::InspectorServer;
|
||||
use deno_runtime::permissions::RuntimePermissionDescriptorParser;
|
||||
use deno_runtime::FeatureChecker;
|
||||
use node_resolver::analyze::NodeCodeTranslator;
|
||||
use node_resolver::cache::NodeResolutionThreadLocalCache;
|
||||
use node_resolver::NodeConditionOptions;
|
||||
use node_resolver::NodeResolverOptions;
|
||||
use node_resolver::cache::NodeResolutionThreadLocalCache;
|
||||
use once_cell::sync::OnceCell;
|
||||
use sys_traits::EnvCurrentDir;
|
||||
|
||||
|
@ -62,7 +63,6 @@ use crate::args::BundleFlags;
|
|||
use crate::args::BundlePlatform;
|
||||
use crate::args::CliLockfile;
|
||||
use crate::args::CliOptions;
|
||||
use crate::args::CliTsConfigResolver;
|
||||
use crate::args::ConfigFlag;
|
||||
use crate::args::DenoSubcommand;
|
||||
use crate::args::Flags;
|
||||
|
@ -70,28 +70,22 @@ use crate::args::InstallFlags;
|
|||
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::ModuleInfoCache;
|
||||
use crate::cache::NodeAnalysisCache;
|
||||
use crate::cache::ParsedSourceCache;
|
||||
use crate::emit::Emitter;
|
||||
use crate::file_fetcher::create_cli_file_fetcher;
|
||||
use crate::cache::SqliteNodeAnalysisCache;
|
||||
use crate::file_fetcher::CliFileFetcher;
|
||||
use crate::file_fetcher::CreateCliFileFetcherOptions;
|
||||
use crate::file_fetcher::TextDecodedFile;
|
||||
use crate::file_fetcher::create_cli_file_fetcher;
|
||||
use crate::graph_container::MainModuleGraphContainer;
|
||||
use crate::graph_util::FileWatcherReporter;
|
||||
use crate::graph_util::ModuleGraphBuilder;
|
||||
use crate::graph_util::ModuleGraphCreator;
|
||||
use crate::http_util::HttpClientProvider;
|
||||
use crate::module_loader::CliEmitter;
|
||||
use crate::module_loader::CliModuleLoaderFactory;
|
||||
use crate::module_loader::EszipModuleLoader;
|
||||
use crate::module_loader::ModuleLoadPreparer;
|
||||
use crate::node::CliCjsCodeAnalyzer;
|
||||
use crate::node::CliCjsModuleExportAnalyzer;
|
||||
use crate::node::CliNodeCodeTranslator;
|
||||
use crate::node::CliNodeResolver;
|
||||
use crate::node::CliPackageJsonResolver;
|
||||
use crate::npm::CliNpmCache;
|
||||
|
@ -101,12 +95,13 @@ use crate::npm::CliNpmInstaller;
|
|||
use crate::npm::CliNpmInstallerFactory;
|
||||
use crate::npm::CliNpmResolver;
|
||||
use crate::npm::DenoTaskLifeCycleScriptsExecutor;
|
||||
use crate::resolver::on_resolve_diagnostic;
|
||||
use crate::resolver::CliCjsTracker;
|
||||
use crate::resolver::CliResolver;
|
||||
use crate::resolver::on_resolve_diagnostic;
|
||||
use crate::standalone::binary::DenoCompileBinaryWriter;
|
||||
use crate::sys::CliSys;
|
||||
use crate::tools::coverage::CoverageCollector;
|
||||
use crate::tools::installer::BinNameResolver;
|
||||
use crate::tools::lint::LintRuleProvider;
|
||||
use crate::tools::run::hmr::HmrRunner;
|
||||
use crate::tsc::TypeCheckingCjsTracker;
|
||||
|
@ -248,9 +243,6 @@ impl SpecifiedImportMapProvider for CliSpecifiedImportMapProvider {
|
|||
}
|
||||
|
||||
pub type CliWorkspaceFactory = deno_resolver::factory::WorkspaceFactory<CliSys>;
|
||||
pub type CliDenoDirPathProvider =
|
||||
deno_resolver::factory::DenoDirPathProvider<CliSys>;
|
||||
|
||||
pub type CliResolverFactory = deno_resolver::factory::ResolverFactory<CliSys>;
|
||||
|
||||
pub struct Deferred<T>(once_cell::unsync::OnceCell<T>);
|
||||
|
@ -303,13 +295,8 @@ impl<T> Deferred<T> {
|
|||
struct CliFactoryServices {
|
||||
blob_store: Deferred<Arc<BlobStore>>,
|
||||
caches: Deferred<Arc<Caches>>,
|
||||
cjs_module_export_analyzer: Deferred<Arc<CliCjsModuleExportAnalyzer>>,
|
||||
cli_options: Deferred<Arc<CliOptions>>,
|
||||
code_cache: Deferred<Arc<CodeCache>>,
|
||||
deno_dir_path_provider: Deferred<Arc<CliDenoDirPathProvider>>,
|
||||
deno_dir_provider: Deferred<Arc<DenoDirProvider>>,
|
||||
emit_cache: Deferred<Arc<EmitCache>>,
|
||||
emitter: Deferred<Arc<Emitter>>,
|
||||
eszip_module_loader_provider: Deferred<Arc<EszipModuleLoaderProvider>>,
|
||||
feature_checker: Deferred<Arc<FeatureChecker>>,
|
||||
file_fetcher: Deferred<Arc<CliFileFetcher>>,
|
||||
|
@ -322,9 +309,7 @@ struct CliFactoryServices {
|
|||
module_graph_creator: Deferred<Arc<ModuleGraphCreator>>,
|
||||
module_info_cache: Deferred<Arc<ModuleInfoCache>>,
|
||||
module_load_preparer: Deferred<Arc<ModuleLoadPreparer>>,
|
||||
node_code_translator: Deferred<Arc<CliNodeCodeTranslator>>,
|
||||
npm_installer_factory: Deferred<CliNpmInstallerFactory>,
|
||||
parsed_source_cache: Deferred<Arc<ParsedSourceCache>>,
|
||||
permission_desc_parser:
|
||||
Deferred<Arc<RuntimePermissionDescriptorParser<CliSys>>>,
|
||||
resolver_factory: Deferred<Arc<CliResolverFactory>>,
|
||||
|
@ -397,34 +382,21 @@ impl CliFactory {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn deno_dir_path_provider(&self) -> &Arc<CliDenoDirPathProvider> {
|
||||
self.services.deno_dir_path_provider.get_or_init(|| {
|
||||
Arc::new(CliDenoDirPathProvider::new(
|
||||
self.sys(),
|
||||
DenoDirPathProviderOptions {
|
||||
maybe_custom_root: self.flags.internal.cache_path.clone(),
|
||||
},
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn deno_dir_provider(&self) -> &Arc<DenoDirProvider> {
|
||||
self.services.deno_dir_provider.get_or_init(|| {
|
||||
Arc::new(DenoDirProvider::new(
|
||||
self.sys(),
|
||||
self.deno_dir_path_provider().clone(),
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn deno_dir(&self) -> Result<&DenoDir, AnyError> {
|
||||
Ok(self.deno_dir_provider().get_or_create()?)
|
||||
Ok(
|
||||
self
|
||||
.workspace_factory()?
|
||||
.deno_dir_provider()
|
||||
.get_or_create()?,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn caches(&self) -> Result<&Arc<Caches>, AnyError> {
|
||||
self.services.caches.get_or_try_init(|| {
|
||||
let cli_options = self.cli_options()?;
|
||||
let caches = Arc::new(Caches::new(self.deno_dir_provider().clone()));
|
||||
let caches = Arc::new(Caches::new(
|
||||
self.workspace_factory()?.deno_dir_provider().clone(),
|
||||
));
|
||||
// Warm up the caches we know we'll likely need based on the CLI mode
|
||||
match cli_options.sub_command() {
|
||||
DenoSubcommand::Run(_)
|
||||
|
@ -452,6 +424,12 @@ impl CliFactory {
|
|||
self.services.blob_store.get_or_init(Default::default)
|
||||
}
|
||||
|
||||
pub fn bin_name_resolver(&self) -> Result<BinNameResolver<'_>, AnyError> {
|
||||
let http_client = self.http_client_provider();
|
||||
let npm_api = self.npm_installer_factory()?.registry_info_provider()?;
|
||||
Ok(BinNameResolver::new(http_client, npm_api.as_ref()))
|
||||
}
|
||||
|
||||
pub fn root_cert_store_provider(&self) -> &Arc<dyn RootCertStoreProvider> {
|
||||
self.services.root_cert_store_provider.get_or_init(|| {
|
||||
Arc::new(CliRootCertStoreProvider::new(
|
||||
|
@ -616,11 +594,7 @@ impl CliFactory {
|
|||
.env_current_dir()
|
||||
.with_context(|| "Failed getting cwd.")?,
|
||||
};
|
||||
let options = new_workspace_factory_options(
|
||||
&initial_cwd,
|
||||
&self.flags,
|
||||
self.deno_dir_path_provider().clone(),
|
||||
);
|
||||
let options = new_workspace_factory_options(&initial_cwd, &self.flags);
|
||||
let mut factory =
|
||||
CliWorkspaceFactory::new(self.sys(), initial_cwd, options);
|
||||
if let Some(workspace_dir) = &self.overrides.workspace_directory {
|
||||
|
@ -653,17 +627,11 @@ impl CliFactory {
|
|||
.get_or_init(|| maybe_file_watcher_reporter)
|
||||
}
|
||||
|
||||
pub fn emit_cache(&self) -> Result<&Arc<EmitCache>, AnyError> {
|
||||
self.services.emit_cache.get_or_try_init(|| {
|
||||
Ok(Arc::new(EmitCache::new(self.deno_dir()?.gen_cache.clone())))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn module_info_cache(&self) -> Result<&Arc<ModuleInfoCache>, AnyError> {
|
||||
self.services.module_info_cache.get_or_try_init(|| {
|
||||
Ok(Arc::new(ModuleInfoCache::new(
|
||||
self.caches()?.dep_analysis_db(),
|
||||
self.parsed_source_cache().clone(),
|
||||
self.resolver_factory()?.parsed_source_cache().clone(),
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
@ -674,22 +642,14 @@ impl CliFactory {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn parsed_source_cache(&self) -> &Arc<ParsedSourceCache> {
|
||||
self
|
||||
.services
|
||||
.parsed_source_cache
|
||||
.get_or_init(Default::default)
|
||||
pub fn parsed_source_cache(
|
||||
&self,
|
||||
) -> Result<&Arc<ParsedSourceCache>, AnyError> {
|
||||
Ok(self.resolver_factory()?.parsed_source_cache())
|
||||
}
|
||||
|
||||
pub fn emitter(&self) -> Result<&Arc<Emitter>, AnyError> {
|
||||
self.services.emitter.get_or_try_init(|| {
|
||||
Ok(Arc::new(Emitter::new(
|
||||
self.cjs_tracker()?.clone(),
|
||||
self.emit_cache()?.clone(),
|
||||
self.parsed_source_cache().clone(),
|
||||
self.tsconfig_resolver()?.clone(),
|
||||
)))
|
||||
})
|
||||
pub fn emitter(&self) -> Result<&Arc<CliEmitter>, AnyError> {
|
||||
self.resolver_factory()?.emitter()
|
||||
}
|
||||
|
||||
pub async fn lint_rule_provider(&self) -> Result<LintRuleProvider, AnyError> {
|
||||
|
@ -710,74 +670,16 @@ impl CliFactory {
|
|||
.await
|
||||
}
|
||||
|
||||
pub async fn cjs_module_export_analyzer(
|
||||
&self,
|
||||
) -> Result<&Arc<CliCjsModuleExportAnalyzer>, AnyError> {
|
||||
self
|
||||
.services
|
||||
.cjs_module_export_analyzer
|
||||
.get_or_try_init_async(async {
|
||||
let node_resolver = self.node_resolver().await?.clone();
|
||||
let cjs_code_analyzer = self.create_cjs_code_analyzer()?;
|
||||
|
||||
Ok(Arc::new(CliCjsModuleExportAnalyzer::new(
|
||||
cjs_code_analyzer,
|
||||
self.in_npm_pkg_checker()?.clone(),
|
||||
node_resolver,
|
||||
self.npm_resolver().await?.clone(),
|
||||
self.pkg_json_resolver()?.clone(),
|
||||
self.sys(),
|
||||
)))
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn node_code_translator(
|
||||
&self,
|
||||
) -> Result<&Arc<CliNodeCodeTranslator>, AnyError> {
|
||||
self
|
||||
.services
|
||||
.node_code_translator
|
||||
.get_or_try_init_async(
|
||||
async {
|
||||
let module_export_analyzer =
|
||||
self.cjs_module_export_analyzer().await?;
|
||||
Ok(Arc::new(NodeCodeTranslator::new(
|
||||
module_export_analyzer.clone(),
|
||||
match self.cli_options()?.sub_command() {
|
||||
DenoSubcommand::Bundle(_) => {
|
||||
node_resolver::analyze::NodeCodeTranslatorMode::Bundling
|
||||
}
|
||||
_ => node_resolver::analyze::NodeCodeTranslatorMode::ModuleLoader,
|
||||
},
|
||||
)))
|
||||
}
|
||||
.boxed_local(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
fn create_cjs_code_analyzer(&self) -> Result<CliCjsCodeAnalyzer, AnyError> {
|
||||
let caches = self.caches()?;
|
||||
let node_analysis_cache = NodeAnalysisCache::new(caches.node_analysis_db());
|
||||
Ok(CliCjsCodeAnalyzer::new(
|
||||
node_analysis_cache,
|
||||
self.cjs_tracker()?.clone(),
|
||||
self.fs().clone(),
|
||||
Some(self.parsed_source_cache().clone()),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn pkg_json_resolver(
|
||||
&self,
|
||||
) -> Result<&Arc<CliPackageJsonResolver>, AnyError> {
|
||||
Ok(self.resolver_factory()?.pkg_json_resolver())
|
||||
}
|
||||
|
||||
pub fn tsconfig_resolver(
|
||||
pub fn compiler_options_resolver(
|
||||
&self,
|
||||
) -> Result<&Arc<CliTsConfigResolver>, AnyError> {
|
||||
Ok(self.workspace_factory()?.tsconfig_resolver()?)
|
||||
) -> Result<&Arc<CompilerOptionsResolver>, AnyError> {
|
||||
self.resolver_factory()?.compiler_options_resolver()
|
||||
}
|
||||
|
||||
pub async fn type_checker(&self) -> Result<&Arc<TypeChecker>, AnyError> {
|
||||
|
@ -798,7 +700,8 @@ impl CliFactory {
|
|||
self.node_resolver().await?.clone(),
|
||||
self.npm_resolver().await?.clone(),
|
||||
self.sys(),
|
||||
self.tsconfig_resolver()?.clone(),
|
||||
self.workspace_directory_provider()?.clone(),
|
||||
self.compiler_options_resolver()?.clone(),
|
||||
if cli_options.code_cache_enabled() {
|
||||
Some(self.code_cache()?.clone())
|
||||
} else {
|
||||
|
@ -833,11 +736,11 @@ impl CliFactory {
|
|||
self.npm_graph_resolver().await?.clone(),
|
||||
self.npm_installer_if_managed().await?.cloned(),
|
||||
self.npm_resolver().await?.clone(),
|
||||
self.parsed_source_cache().clone(),
|
||||
self.resolver_factory()?.parsed_source_cache().clone(),
|
||||
self.resolver().await?.clone(),
|
||||
self.root_permissions_container()?.clone(),
|
||||
self.sys(),
|
||||
self.tsconfig_resolver()?.clone(),
|
||||
self.compiler_options_resolver()?.clone(),
|
||||
)))
|
||||
}
|
||||
.boxed_local(),
|
||||
|
@ -926,14 +829,7 @@ impl CliFactory {
|
|||
&self,
|
||||
) -> Result<&Arc<RuntimePermissionDescriptorParser<CliSys>>, AnyError> {
|
||||
self.services.permission_desc_parser.get_or_try_init(|| {
|
||||
Ok(Arc::new(RuntimePermissionDescriptorParser::new(
|
||||
self.sys(),
|
||||
if self.cli_options()?.unstable_subdomain_wildcards() {
|
||||
UnstableSubdomainWildcards::Enabled
|
||||
} else {
|
||||
UnstableSubdomainWildcards::Disabled
|
||||
},
|
||||
)))
|
||||
Ok(Arc::new(RuntimePermissionDescriptorParser::new(self.sys())))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -958,11 +854,12 @@ impl CliFactory {
|
|||
) -> Result<DenoCompileBinaryWriter, AnyError> {
|
||||
let cli_options = self.cli_options()?;
|
||||
Ok(DenoCompileBinaryWriter::new(
|
||||
self.cjs_module_export_analyzer().await?,
|
||||
self.resolver_factory()?.cjs_module_export_analyzer()?,
|
||||
self.cjs_tracker()?,
|
||||
self.cli_options()?,
|
||||
self.deno_dir()?,
|
||||
self.emitter()?,
|
||||
self.file_fetcher()?,
|
||||
self.http_client_provider(),
|
||||
self.npm_resolver().await?,
|
||||
self.workspace_resolver().await?.as_ref(),
|
||||
|
@ -986,6 +883,12 @@ impl CliFactory {
|
|||
})
|
||||
}
|
||||
|
||||
fn workspace_directory_provider(
|
||||
&self,
|
||||
) -> Result<&Arc<WorkspaceDirectoryProvider>, AnyError> {
|
||||
Ok(self.workspace_factory()?.workspace_directory_provider()?)
|
||||
}
|
||||
|
||||
fn workspace_external_import_map_loader(
|
||||
&self,
|
||||
) -> Result<&Arc<WorkspaceExternalImportMapLoader<CliSys>>, AnyError> {
|
||||
|
@ -1010,11 +913,12 @@ impl CliFactory {
|
|||
let cli_options = self.cli_options()?;
|
||||
let cli_npm_resolver = self.npm_resolver().await?.clone();
|
||||
let in_npm_pkg_checker = self.in_npm_pkg_checker()?;
|
||||
let node_code_translator = self.node_code_translator().await?;
|
||||
let cjs_tracker = self.cjs_tracker()?.clone();
|
||||
let workspace_factory = self.workspace_factory()?;
|
||||
let resolver_factory = self.resolver_factory()?;
|
||||
let node_code_translator = resolver_factory.node_code_translator()?;
|
||||
let cjs_tracker = self.cjs_tracker()?.clone();
|
||||
let npm_registry_permission_checker = {
|
||||
let mode = if self.resolver_factory()?.use_byonm()? {
|
||||
let mode = if resolver_factory.use_byonm()? {
|
||||
NpmRegistryReadPermissionCheckerMode::Byonm
|
||||
} else if let Some(node_modules_dir) =
|
||||
workspace_factory.node_modules_dir_path()?
|
||||
|
@ -1041,10 +945,10 @@ impl CliFactory {
|
|||
None
|
||||
},
|
||||
self.emitter()?.clone(),
|
||||
self.file_fetcher()?.clone(),
|
||||
in_npm_pkg_checker.clone(),
|
||||
self.main_module_graph_container().await?.clone(),
|
||||
self.module_load_preparer().await?.clone(),
|
||||
node_code_translator.clone(),
|
||||
NpmModuleLoader::new(
|
||||
self.cjs_tracker()?.clone(),
|
||||
node_code_translator.clone(),
|
||||
|
@ -1052,7 +956,8 @@ impl CliFactory {
|
|||
),
|
||||
npm_registry_permission_checker,
|
||||
cli_npm_resolver.clone(),
|
||||
self.parsed_source_cache().clone(),
|
||||
resolver_factory.parsed_source_cache().clone(),
|
||||
resolver_factory.prepared_module_loader()?.clone(),
|
||||
self.resolver().await?.clone(),
|
||||
self.sys(),
|
||||
maybe_eszip_loader,
|
||||
|
@ -1152,6 +1057,7 @@ impl CliFactory {
|
|||
otel_config: cli_options.otel_config(),
|
||||
no_legacy_abort: cli_options.no_legacy_abort(),
|
||||
startup_snapshot: deno_snapshots::CLI_SNAPSHOT,
|
||||
enable_raw_imports: cli_options.unstable_raw_imports(),
|
||||
tunnel: self.flags.connected.is_some(),
|
||||
})
|
||||
}
|
||||
|
@ -1197,9 +1103,17 @@ impl CliFactory {
|
|||
pub fn resolver_factory(&self) -> Result<&Arc<CliResolverFactory>, AnyError> {
|
||||
self.services.resolver_factory.get_or_try_init(|| {
|
||||
let options = self.cli_options()?;
|
||||
let caches = self.caches()?;
|
||||
let node_analysis_cache =
|
||||
Arc::new(SqliteNodeAnalysisCache::new(caches.node_analysis_db()));
|
||||
Ok(Arc::new(CliResolverFactory::new(
|
||||
self.workspace_factory()?.clone(),
|
||||
ResolverFactoryOptions {
|
||||
compiler_options_overrides: CompilerOptionsOverrides {
|
||||
no_transpile: false,
|
||||
source_map_base: None,
|
||||
preserve_jsx: false,
|
||||
},
|
||||
is_cjs_resolution_mode: if options.is_node_main()
|
||||
|| options.unstable_detect_cjs()
|
||||
{
|
||||
|
@ -1209,6 +1123,7 @@ impl CliFactory {
|
|||
} else {
|
||||
IsCjsResolutionMode::Disabled
|
||||
},
|
||||
node_analysis_cache: Some(node_analysis_cache),
|
||||
node_resolver_options: NodeResolverOptions {
|
||||
conditions: NodeConditionOptions {
|
||||
conditions: options
|
||||
|
@ -1246,6 +1161,12 @@ impl CliFactory {
|
|||
})
|
||||
),
|
||||
},
|
||||
node_code_translator_mode: match options.sub_command() {
|
||||
DenoSubcommand::Bundle(_) => {
|
||||
node_resolver::analyze::NodeCodeTranslatorMode::Bundling
|
||||
}
|
||||
_ => node_resolver::analyze::NodeCodeTranslatorMode::ModuleLoader,
|
||||
},
|
||||
node_resolution_cache: Some(Arc::new(NodeResolutionThreadLocalCache)),
|
||||
npm_system_info: self.flags.subcommand.npm_system_info(),
|
||||
specified_import_map: Some(Box::new(CliSpecifiedImportMapProvider {
|
||||
|
@ -1258,8 +1179,8 @@ impl CliFactory {
|
|||
.workspace_external_import_map_loader()?
|
||||
.clone(),
|
||||
})),
|
||||
bare_node_builtins: self.flags.unstable_config.bare_node_builtins,
|
||||
unstable_sloppy_imports: self.flags.unstable_config.sloppy_imports,
|
||||
bare_node_builtins: options.unstable_bare_node_builtins(),
|
||||
unstable_sloppy_imports: options.unstable_sloppy_imports(),
|
||||
on_mapped_resolution_diagnostic: Some(Arc::new(
|
||||
on_resolve_diagnostic,
|
||||
)),
|
||||
|
@ -1283,8 +1204,7 @@ impl CliFactory {
|
|||
fn new_workspace_factory_options(
|
||||
initial_cwd: &Path,
|
||||
flags: &Flags,
|
||||
deno_dir_path_provider: Arc<CliDenoDirPathProvider>,
|
||||
) -> deno_resolver::factory::WorkspaceFactoryOptions<CliSys> {
|
||||
) -> deno_resolver::factory::WorkspaceFactoryOptions {
|
||||
deno_resolver::factory::WorkspaceFactoryOptions {
|
||||
additional_config_file_names: if matches!(
|
||||
flags.subcommand,
|
||||
|
@ -1307,7 +1227,7 @@ fn new_workspace_factory_options(
|
|||
}
|
||||
ConfigFlag::Disabled => ConfigDiscoveryOption::Disabled,
|
||||
},
|
||||
deno_dir_path_provider: Some(deno_dir_path_provider),
|
||||
maybe_custom_deno_dir_root: flags.internal.cache_path.clone(),
|
||||
// For `deno install/add/remove/init` we want to force the managed
|
||||
// resolver so it can set up the `node_modules/` directory.
|
||||
is_package_manager_subcommand: matches!(
|
||||
|
|
|
@ -3,24 +3,24 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use deno_ast::MediaType;
|
||||
use deno_cache_dir::GlobalOrLocalHttpCache;
|
||||
use deno_cache_dir::file_fetcher::BlobData;
|
||||
use deno_cache_dir::file_fetcher::CacheSetting;
|
||||
use deno_cache_dir::file_fetcher::File;
|
||||
use deno_cache_dir::file_fetcher::SendError;
|
||||
use deno_cache_dir::file_fetcher::SendResponse;
|
||||
use deno_cache_dir::GlobalOrLocalHttpCache;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_resolver::file_fetcher::PermissionedFileFetcherOptions;
|
||||
use deno_runtime::deno_web::BlobStore;
|
||||
use http::HeaderMap;
|
||||
use http::StatusCode;
|
||||
|
||||
use crate::colors;
|
||||
use crate::http_util::get_response_body_with_progress;
|
||||
use crate::http_util::HttpClientProvider;
|
||||
use crate::http_util::get_response_body_with_progress;
|
||||
use crate::sys::CliSys;
|
||||
use crate::util::progress_bar::ProgressBar;
|
||||
|
||||
|
@ -242,8 +242,8 @@ impl deno_cache_dir::file_fetcher::HttpClient for HttpClientAdapter {
|
|||
mod tests {
|
||||
use std::collections::HashMap;
|
||||
|
||||
use deno_cache_dir::file_fetcher::HttpClient;
|
||||
use deno_cache_dir::HttpCache;
|
||||
use deno_cache_dir::file_fetcher::HttpClient;
|
||||
use deno_core::resolve_url;
|
||||
use deno_resolver::file_fetcher::FetchErrorKind;
|
||||
use deno_resolver::file_fetcher::FetchPermissionsOptionRef;
|
||||
|
@ -869,7 +869,10 @@ mod tests {
|
|||
deno_cache_dir::file_fetcher::FetchNoFollowErrorKind::NoRemote {
|
||||
..
|
||||
} => {
|
||||
assert_eq!(err.to_string(), "A remote specifier was requested: \"http://localhost:4545/run/002_hello.ts\", but --no-remote is specified.");
|
||||
assert_eq!(
|
||||
err.to_string(),
|
||||
"A remote specifier was requested: \"http://localhost:4545/run/002_hello.ts\", but --no-remote is specified."
|
||||
);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
@ -924,7 +927,10 @@ mod tests {
|
|||
deno_cache_dir::file_fetcher::FetchNoFollowErrorKind::NotCached {
|
||||
..
|
||||
} => {
|
||||
assert_eq!(err.to_string(), "Specifier not found in cache: \"http://localhost:4545/run/002_hello.ts\", --cached-only is specified.");
|
||||
assert_eq!(
|
||||
err.to_string(),
|
||||
"Specifier not found in cache: \"http://localhost:4545/run/002_hello.ts\", --cached-only is specified."
|
||||
);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
|
|
@ -1,57 +1,58 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::error::Error;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_ast::MediaType;
|
||||
use deno_config::deno_json;
|
||||
use deno_config::deno_json::CompilerOptionTypesDeserializeError;
|
||||
use deno_config::deno_json::NodeModulesDirMode;
|
||||
use deno_config::workspace::JsrPackageConfig;
|
||||
use deno_config::workspace::ToMaybeJsxImportSourceConfigError;
|
||||
use deno_core::ModuleSpecifier;
|
||||
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::ResolveError;
|
||||
use deno_graph::CheckJsOption;
|
||||
use deno_graph::FillFromLockfileOptions;
|
||||
use deno_graph::GraphKind;
|
||||
use deno_graph::JsrLoadError;
|
||||
use deno_graph::ModuleError;
|
||||
use deno_graph::ModuleErrorKind;
|
||||
use deno_graph::ModuleGraph;
|
||||
use deno_graph::ModuleGraphError;
|
||||
use deno_graph::ModuleLoadError;
|
||||
use deno_graph::ResolutionError;
|
||||
use deno_graph::SpecifierError;
|
||||
use deno_graph::WorkspaceFastCheckOption;
|
||||
use deno_npm_installer::graph::NpmCachingStrategy;
|
||||
use deno_graph::source::Loader;
|
||||
use deno_graph::source::ResolveError;
|
||||
use deno_npm_installer::PackageCaching;
|
||||
use deno_npm_installer::graph::NpmCachingStrategy;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use deno_resolver::cache::ParsedSourceCache;
|
||||
use deno_resolver::deno_json::CompilerOptionsResolver;
|
||||
use deno_resolver::deno_json::JsxImportSourceConfigResolver;
|
||||
use deno_resolver::graph::EnhanceGraphErrorMode;
|
||||
use deno_resolver::graph::enhance_graph_error;
|
||||
use deno_resolver::graph::enhanced_integrity_error_message;
|
||||
use deno_resolver::graph::format_deno_graph_error;
|
||||
use deno_resolver::npm::DenoInNpmPackageChecker;
|
||||
use deno_resolver::workspace::sloppy_imports_resolve;
|
||||
use deno_resolver::workspace::ScopedJsxImportSourceConfig;
|
||||
use deno_runtime::deno_node;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
use deno_semver::jsr::JsrDepPackageReq;
|
||||
use deno_semver::SmallStackString;
|
||||
use deno_semver::jsr::JsrDepPackageReq;
|
||||
use indexmap::IndexMap;
|
||||
use sys_traits::FsMetadata;
|
||||
|
||||
use crate::args::config_to_deno_graph_workspace_member;
|
||||
use crate::args::jsr_url;
|
||||
use crate::args::CliLockfile;
|
||||
use crate::args::CliOptions;
|
||||
use crate::args::CliTsConfigResolver;
|
||||
use crate::args::DenoSubcommand;
|
||||
use crate::args::config_to_deno_graph_workspace_member;
|
||||
use crate::args::jsr_url;
|
||||
use crate::cache;
|
||||
use crate::cache::GlobalHttpCache;
|
||||
use crate::cache::ModuleInfoCache;
|
||||
use crate::cache::ParsedSourceCache;
|
||||
use crate::colors;
|
||||
use crate::file_fetcher::CliDenoGraphLoader;
|
||||
use crate::file_fetcher::CliFileFetcher;
|
||||
|
@ -109,17 +110,18 @@ pub fn graph_valid(
|
|||
allow_unknown_jsr_exports: options.allow_unknown_jsr_exports,
|
||||
},
|
||||
);
|
||||
if let Some(error) = errors.next() {
|
||||
Err(error)
|
||||
} else {
|
||||
// finally surface the npm resolution result
|
||||
if let Err(err) = &graph.npm_dep_graph_result {
|
||||
return Err(JsErrorBox::new(
|
||||
err.get_class(),
|
||||
format_deno_graph_error(err),
|
||||
));
|
||||
match errors.next() {
|
||||
Some(error) => Err(error),
|
||||
_ => {
|
||||
// finally surface the npm resolution result
|
||||
if let Err(err) = &graph.npm_dep_graph_result {
|
||||
return Err(JsErrorBox::new(
|
||||
err.get_class(),
|
||||
format_deno_graph_error(err),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,7 +186,7 @@ pub fn graph_walk_errors<'a>(
|
|||
should_ignore_resolution_error_for_types(err)
|
||||
}
|
||||
ModuleGraphError::ModuleError(module_error) => {
|
||||
matches!(module_error, ModuleError::Missing { .. })
|
||||
matches!(module_error.as_kind(), ModuleErrorKind::Missing { .. })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -198,8 +200,8 @@ pub fn graph_walk_errors<'a>(
|
|||
) -> bool {
|
||||
if (graph_kind == GraphKind::TypesOnly || allow_unknown_media_types)
|
||||
&& matches!(
|
||||
error,
|
||||
ModuleGraphError::ModuleError(ModuleError::UnsupportedMediaType { .. })
|
||||
error.as_module_error_kind(),
|
||||
Some(ModuleErrorKind::UnsupportedMediaType { .. })
|
||||
)
|
||||
{
|
||||
return true;
|
||||
|
@ -248,8 +250,8 @@ pub fn graph_walk_errors<'a>(
|
|||
if is_root
|
||||
&& options.allow_unknown_jsr_exports
|
||||
&& matches!(
|
||||
error,
|
||||
ModuleGraphError::ModuleError(ModuleError::Load {
|
||||
error.as_module_error_kind(),
|
||||
Some(ModuleErrorKind::Load {
|
||||
err: ModuleLoadError::Jsr(JsrLoadError::UnknownExport { .. }),
|
||||
..
|
||||
})
|
||||
|
@ -297,15 +299,15 @@ pub fn module_error_for_tsc_diagnostic<'a>(
|
|||
sys: &CliSys,
|
||||
error: &'a ModuleError,
|
||||
) -> Option<ModuleNotFoundGraphErrorRef<'a>> {
|
||||
match error {
|
||||
ModuleError::Missing {
|
||||
match error.as_kind() {
|
||||
ModuleErrorKind::Missing {
|
||||
specifier,
|
||||
maybe_referrer,
|
||||
} => Some(ModuleNotFoundGraphErrorRef {
|
||||
specifier,
|
||||
maybe_range: maybe_referrer.as_ref(),
|
||||
}),
|
||||
ModuleError::Load {
|
||||
ModuleErrorKind::Load {
|
||||
specifier,
|
||||
maybe_referrer,
|
||||
err: ModuleLoadError::Loader(_),
|
||||
|
@ -356,45 +358,6 @@ pub fn resolution_error_for_tsc_diagnostic(
|
|||
}
|
||||
}
|
||||
|
||||
#[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);
|
||||
|
@ -653,7 +616,9 @@ pub enum BuildGraphWithNpmResolutionError {
|
|||
#[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")]
|
||||
#[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,
|
||||
}
|
||||
|
||||
|
@ -687,7 +652,7 @@ pub struct ModuleGraphBuilder {
|
|||
resolver: Arc<CliResolver>,
|
||||
root_permissions_container: PermissionsContainer,
|
||||
sys: CliSys,
|
||||
tsconfig_resolver: Arc<CliTsConfigResolver>,
|
||||
compiler_options_resolver: Arc<CompilerOptionsResolver>,
|
||||
}
|
||||
|
||||
impl ModuleGraphBuilder {
|
||||
|
@ -709,7 +674,7 @@ impl ModuleGraphBuilder {
|
|||
resolver: Arc<CliResolver>,
|
||||
root_permissions_container: PermissionsContainer,
|
||||
sys: CliSys,
|
||||
tsconfig_resolver: Arc<CliTsConfigResolver>,
|
||||
compiler_options_resolver: Arc<CompilerOptionsResolver>,
|
||||
) -> Self {
|
||||
Self {
|
||||
caches,
|
||||
|
@ -728,7 +693,7 @@ impl ModuleGraphBuilder {
|
|||
resolver,
|
||||
root_permissions_container,
|
||||
sys,
|
||||
tsconfig_resolver,
|
||||
compiler_options_resolver,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -758,12 +723,14 @@ impl ModuleGraphBuilder {
|
|||
MutLoaderRef::Owned(self.create_graph_loader_with_root_permissions())
|
||||
}
|
||||
};
|
||||
let scoped_jsx_config = ScopedJsxImportSourceConfig::from_workspace_dir(
|
||||
&self.cli_options.start_dir,
|
||||
)?;
|
||||
let graph_resolver = self
|
||||
.resolver
|
||||
.as_graph_resolver(self.cjs_tracker.as_ref(), &scoped_jsx_config);
|
||||
let jsx_import_source_config_resolver =
|
||||
JsxImportSourceConfigResolver::from_compiler_options_resolver(
|
||||
&self.compiler_options_resolver,
|
||||
)?;
|
||||
let graph_resolver = self.resolver.as_graph_resolver(
|
||||
self.cjs_tracker.as_ref(),
|
||||
&jsx_import_source_config_resolver,
|
||||
);
|
||||
let maybe_file_watcher_reporter = self
|
||||
.maybe_file_watcher_reporter
|
||||
.as_ref()
|
||||
|
@ -788,6 +755,8 @@ impl ModuleGraphBuilder {
|
|||
reporter: maybe_file_watcher_reporter,
|
||||
resolver: Some(&graph_resolver),
|
||||
locker: locker.as_mut().map(|l| l as _),
|
||||
unstable_bytes_imports: self.cli_options.unstable_raw_imports(),
|
||||
unstable_text_imports: self.cli_options.unstable_raw_imports(),
|
||||
},
|
||||
options.npm_caching,
|
||||
)
|
||||
|
@ -850,19 +819,39 @@ impl ModuleGraphBuilder {
|
|||
return Err(BuildGraphWithNpmResolutionError::UnsupportedNpmSpecifierEntrypointResolutionWay);
|
||||
}
|
||||
let imports = if graph.graph_kind().include_types() {
|
||||
// Resolve all the imports from every deno.json. We'll separate
|
||||
// Resolve all the imports from every config file. We'll separate
|
||||
// them later based on the folder we're type checking.
|
||||
let mut imports = Vec::new();
|
||||
for deno_json in self.cli_options.workspace().deno_jsons() {
|
||||
let maybe_imports = deno_json.to_compiler_option_types()?;
|
||||
imports.extend(maybe_imports.into_iter().map(
|
||||
|(referrer, imports)| deno_graph::ReferrerImports {
|
||||
referrer,
|
||||
imports,
|
||||
},
|
||||
));
|
||||
let mut imports_by_referrer = IndexMap::<_, Vec<_>>::with_capacity(
|
||||
self.compiler_options_resolver.size(),
|
||||
);
|
||||
for (referrer, files) in self
|
||||
.compiler_options_resolver
|
||||
.ts_configs()
|
||||
.iter()
|
||||
.filter_map(|t| t.files())
|
||||
{
|
||||
imports_by_referrer
|
||||
.entry(referrer)
|
||||
.or_default()
|
||||
.extend(files.iter().map(|f| f.relative_specifier.clone()));
|
||||
}
|
||||
imports
|
||||
for (referrer, types) in self
|
||||
.compiler_options_resolver
|
||||
.all()
|
||||
.flat_map(|d| d.compiler_options_types().as_ref())
|
||||
{
|
||||
imports_by_referrer
|
||||
.entry(referrer)
|
||||
.or_default()
|
||||
.extend(types.clone());
|
||||
}
|
||||
imports_by_referrer
|
||||
.into_iter()
|
||||
.map(|(referrer, imports)| deno_graph::ReferrerImports {
|
||||
referrer: referrer.clone(),
|
||||
imports,
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
|
@ -934,12 +923,14 @@ impl ModuleGraphBuilder {
|
|||
None
|
||||
};
|
||||
let parser = self.parsed_source_cache.as_capturing_parser();
|
||||
let scoped_jsx_config = ScopedJsxImportSourceConfig::from_workspace_dir(
|
||||
&self.cli_options.start_dir,
|
||||
)?;
|
||||
let graph_resolver = self
|
||||
.resolver
|
||||
.as_graph_resolver(self.cjs_tracker.as_ref(), &scoped_jsx_config);
|
||||
let jsx_import_source_config_resolver =
|
||||
JsxImportSourceConfigResolver::from_compiler_options_resolver(
|
||||
&self.compiler_options_resolver,
|
||||
)?;
|
||||
let graph_resolver = self.resolver.as_graph_resolver(
|
||||
self.cjs_tracker.as_ref(),
|
||||
&jsx_import_source_config_resolver,
|
||||
);
|
||||
|
||||
graph.build_fast_check_type_graph(
|
||||
deno_graph::BuildFastCheckTypeGraphOptions {
|
||||
|
@ -1008,7 +999,9 @@ impl ModuleGraphBuilder {
|
|||
} else {
|
||||
GraphKind::CodeOnly
|
||||
},
|
||||
check_js: CheckJsOption::Custom(self.tsconfig_resolver.as_ref()),
|
||||
check_js: CheckJsOption::Custom(
|
||||
self.compiler_options_resolver.as_ref(),
|
||||
),
|
||||
exit_integrity_errors: true,
|
||||
allow_unknown_media_types,
|
||||
ignore_graph_errors: matches!(
|
||||
|
@ -1021,229 +1014,6 @@ impl ModuleGraphBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
/// Adds more explanatory information to a resolution error.
|
||||
pub fn enhanced_resolution_error_message(error: &ResolutionError) -> String {
|
||||
let mut message = format_deno_graph_error(error);
|
||||
|
||||
let maybe_hint = if let Some(specifier) =
|
||||
get_resolution_error_bare_node_specifier(error)
|
||||
{
|
||||
Some(format!("If you want to use a built-in Node module, add a \"node:\" prefix (ex. \"node:{specifier}\")."))
|
||||
} else {
|
||||
get_import_prefix_missing_error(error).map(|specifier| {
|
||||
format!(
|
||||
"If you want to use a JSR or npm package, try running `deno add jsr:{}` or `deno add npm:{}`",
|
||||
specifier, specifier
|
||||
)
|
||||
})
|
||||
};
|
||||
|
||||
if let Some(hint) = maybe_hint {
|
||||
message.push_str(&format!("\n {} {}", colors::cyan("hint:"), hint));
|
||||
}
|
||||
|
||||
message
|
||||
}
|
||||
|
||||
static RUN_WITH_SLOPPY_IMPORTS_MSG: &str =
|
||||
"or run with --unstable-sloppy-imports";
|
||||
|
||||
fn enhanced_sloppy_imports_error_message(
|
||||
sys: &CliSys,
|
||||
error: &ModuleError,
|
||||
) -> Option<String> {
|
||||
match error {
|
||||
ModuleError::Load { specifier, err: ModuleLoadError::Loader(_), .. } // ex. "Is a directory" error
|
||||
| ModuleError::Missing { specifier, .. } => {
|
||||
let additional_message = maybe_additional_sloppy_imports_message(sys, specifier)?;
|
||||
Some(format!(
|
||||
"{} {}",
|
||||
error,
|
||||
additional_message,
|
||||
))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn maybe_additional_sloppy_imports_message(
|
||||
sys: &CliSys,
|
||||
specifier: &ModuleSpecifier,
|
||||
) -> Option<String> {
|
||||
let (resolved, sloppy_reason) = sloppy_imports_resolve(
|
||||
specifier,
|
||||
deno_resolver::workspace::ResolutionKind::Execution,
|
||||
sys.clone(),
|
||||
)?;
|
||||
Some(format!(
|
||||
"{} {}",
|
||||
sloppy_reason.suggestion_message_for_specifier(&resolved),
|
||||
RUN_WITH_SLOPPY_IMPORTS_MSG
|
||||
))
|
||||
}
|
||||
|
||||
fn enhanced_integrity_error_message(err: &ModuleError) -> Option<String> {
|
||||
match err {
|
||||
ModuleError::Load {
|
||||
specifier,
|
||||
err: ModuleLoadError::Jsr(JsrLoadError::ContentChecksumIntegrity(
|
||||
checksum_err,
|
||||
)),
|
||||
..
|
||||
} => {
|
||||
Some(format!(
|
||||
concat!(
|
||||
"Integrity check failed in package. The package may have been tampered with.\n\n",
|
||||
" Specifier: {}\n",
|
||||
" Actual: {}\n",
|
||||
" Expected: {}\n\n",
|
||||
"If you modified your global cache, run again with the --reload flag to restore ",
|
||||
"its state. If you want to modify dependencies locally run again with the ",
|
||||
"--vendor flag or specify `\"vendor\": true` in a deno.json then modify the contents ",
|
||||
"of the vendor/ folder."
|
||||
),
|
||||
specifier,
|
||||
checksum_err.actual,
|
||||
checksum_err.expected,
|
||||
))
|
||||
}
|
||||
ModuleError::Load {
|
||||
err: ModuleLoadError::Jsr(
|
||||
JsrLoadError::PackageVersionManifestChecksumIntegrity(
|
||||
package_nv,
|
||||
checksum_err,
|
||||
),
|
||||
),
|
||||
..
|
||||
} => {
|
||||
Some(format!(
|
||||
concat!(
|
||||
"Integrity check failed for package. The source code is invalid, as it does not match the expected hash in the lock file.\n\n",
|
||||
" Package: {}\n",
|
||||
" Actual: {}\n",
|
||||
" Expected: {}\n\n",
|
||||
"This could be caused by:\n",
|
||||
" * the lock file may be corrupt\n",
|
||||
" * the source itself may be corrupt\n\n",
|
||||
"Investigate the lockfile; delete it to regenerate the lockfile or --reload to reload the source code from the server."
|
||||
),
|
||||
package_nv,
|
||||
checksum_err.actual,
|
||||
checksum_err.expected,
|
||||
))
|
||||
}
|
||||
ModuleError::Load {
|
||||
specifier,
|
||||
err: ModuleLoadError::HttpsChecksumIntegrity(checksum_err),
|
||||
..
|
||||
} => {
|
||||
Some(format!(
|
||||
concat!(
|
||||
"Integrity check failed for remote specifier. The source code is invalid, as it does not match the expected hash in the lock file.\n\n",
|
||||
" Specifier: {}\n",
|
||||
" Actual: {}\n",
|
||||
" Expected: {}\n\n",
|
||||
"This could be caused by:\n",
|
||||
" * the lock file may be corrupt\n",
|
||||
" * the source itself may be corrupt\n\n",
|
||||
"Investigate the lockfile; delete it to regenerate the lockfile or --reload to reload the source code from the server."
|
||||
),
|
||||
specifier,
|
||||
checksum_err.actual,
|
||||
checksum_err.expected,
|
||||
))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_resolution_error_bare_node_specifier(
|
||||
error: &ResolutionError,
|
||||
) -> Option<&str> {
|
||||
get_resolution_error_bare_specifier(error)
|
||||
.filter(|specifier| deno_node::is_builtin_node_module(specifier))
|
||||
}
|
||||
|
||||
fn get_resolution_error_bare_specifier(
|
||||
error: &ResolutionError,
|
||||
) -> Option<&str> {
|
||||
if let ResolutionError::InvalidSpecifier {
|
||||
error: SpecifierError::ImportPrefixMissing { specifier, .. },
|
||||
..
|
||||
} = error
|
||||
{
|
||||
Some(specifier.as_str())
|
||||
} else if let ResolutionError::ResolverError { error, .. } = error {
|
||||
if let ResolveError::ImportMap(error) = (*error).as_ref() {
|
||||
if let import_map::ImportMapErrorKind::UnmappedBareSpecifier(
|
||||
specifier,
|
||||
_,
|
||||
) = error.as_kind()
|
||||
{
|
||||
Some(specifier.as_str())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn get_import_prefix_missing_error(error: &ResolutionError) -> Option<&str> {
|
||||
// not exact, but ok because this is just a hint
|
||||
let media_type =
|
||||
MediaType::from_specifier_and_headers(&error.range().specifier, None);
|
||||
if media_type == MediaType::Wasm {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut maybe_specifier = None;
|
||||
if let ResolutionError::InvalidSpecifier {
|
||||
error: SpecifierError::ImportPrefixMissing { specifier, .. },
|
||||
range,
|
||||
} = error
|
||||
{
|
||||
if range.specifier.scheme() == "file" {
|
||||
maybe_specifier = Some(specifier);
|
||||
}
|
||||
} else if let ResolutionError::ResolverError { error, range, .. } = error {
|
||||
if range.specifier.scheme() == "file" {
|
||||
match error.as_ref() {
|
||||
ResolveError::Specifier(specifier_error) => {
|
||||
if let SpecifierError::ImportPrefixMissing { specifier, .. } =
|
||||
specifier_error
|
||||
{
|
||||
maybe_specifier = Some(specifier);
|
||||
}
|
||||
}
|
||||
ResolveError::Other(other_error) => {
|
||||
if let Some(SpecifierError::ImportPrefixMissing {
|
||||
specifier, ..
|
||||
}) = other_error.as_any().downcast_ref::<SpecifierError>()
|
||||
{
|
||||
maybe_specifier = Some(specifier);
|
||||
}
|
||||
}
|
||||
ResolveError::ImportMap(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(bartlomieju): For now, return None if a specifier contains a dot or a space. This is because
|
||||
// suggesting to `deno add bad-module.ts` makes no sense and is worse than not providing
|
||||
// a suggestion at all. This should be improved further in the future
|
||||
if let Some(specifier) = maybe_specifier {
|
||||
if specifier.contains('.') || specifier.contains(' ') {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
maybe_specifier.map(|s| s.as_str())
|
||||
}
|
||||
|
||||
/// Gets if any of the specified root's "file:" dependents are in the
|
||||
/// provided changed set.
|
||||
pub fn has_graph_root_local_dependent_changed(
|
||||
|
@ -1319,15 +1089,6 @@ impl deno_graph::source::Reporter for FileWatcherReporter {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn format_range_with_colors(referrer: &deno_graph::Range) -> String {
|
||||
format!(
|
||||
"{}:{}:{}",
|
||||
colors::cyan(referrer.specifier.as_str()),
|
||||
colors::yellow(&(referrer.range.start.line + 1).to_string()),
|
||||
colors::yellow(&(referrer.range.start.character + 1).to_string())
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy)]
|
||||
pub struct CliJsrUrlProvider;
|
||||
|
||||
|
@ -1336,100 +1097,3 @@ impl deno_graph::source::JsrUrlProvider for CliJsrUrlProvider {
|
|||
jsr_url()
|
||||
}
|
||||
}
|
||||
|
||||
fn format_deno_graph_error(err: &dyn Error) -> String {
|
||||
use std::fmt::Write;
|
||||
|
||||
let mut message = format!("{}", err);
|
||||
let mut maybe_source = err.source();
|
||||
|
||||
if maybe_source.is_some() {
|
||||
let mut past_message = message.clone();
|
||||
let mut count = 0;
|
||||
let mut display_count = 0;
|
||||
while let Some(source) = maybe_source {
|
||||
let current_message = format!("{}", source);
|
||||
maybe_source = source.source();
|
||||
|
||||
// sometimes an error might be repeated due to
|
||||
// being boxed multiple times in another AnyError
|
||||
if current_message != past_message {
|
||||
write!(message, "\n {}: ", display_count,).unwrap();
|
||||
for (i, line) in current_message.lines().enumerate() {
|
||||
if i > 0 {
|
||||
write!(message, "\n {}", line).unwrap();
|
||||
} else {
|
||||
write!(message, "{}", line).unwrap();
|
||||
}
|
||||
}
|
||||
display_count += 1;
|
||||
}
|
||||
|
||||
if count > 8 {
|
||||
write!(message, "\n {}: ...", count).unwrap();
|
||||
break;
|
||||
}
|
||||
|
||||
past_message = current_message;
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
message
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_graph::source::ResolveError;
|
||||
use deno_graph::PositionRange;
|
||||
use deno_graph::Range;
|
||||
use deno_graph::ResolutionError;
|
||||
use deno_graph::SpecifierError;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn import_map_node_resolution_error() {
|
||||
let cases = vec![("fs", Some("fs")), ("other", None)];
|
||||
for (input, output) in cases {
|
||||
let import_map = import_map::ImportMap::new(
|
||||
ModuleSpecifier::parse("file:///deno.json").unwrap(),
|
||||
);
|
||||
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::ImportMap(err)),
|
||||
specifier: input.to_string(),
|
||||
range: Range {
|
||||
specifier,
|
||||
resolution_mode: None,
|
||||
range: PositionRange::zeroed(),
|
||||
},
|
||||
};
|
||||
assert_eq!(get_resolution_error_bare_node_specifier(&err), output);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bare_specifier_node_resolution_error() {
|
||||
let cases = vec![("process", Some("process")), ("other", None)];
|
||||
for (input, output) in cases {
|
||||
let specifier = ModuleSpecifier::parse("file:///file.ts").unwrap();
|
||||
let err = ResolutionError::InvalidSpecifier {
|
||||
range: Range {
|
||||
specifier,
|
||||
resolution_mode: None,
|
||||
range: PositionRange::zeroed(),
|
||||
},
|
||||
error: SpecifierError::ImportPrefixMissing {
|
||||
specifier: input.to_string(),
|
||||
referrer: None,
|
||||
},
|
||||
};
|
||||
assert_eq!(get_resolution_error_bare_node_specifier(&err), output,);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,15 +16,15 @@ use deno_error::JsError;
|
|||
use deno_error::JsErrorBox;
|
||||
use deno_lib::version::DENO_VERSION_INFO;
|
||||
use deno_runtime::deno_fetch;
|
||||
use deno_runtime::deno_fetch::create_http_client;
|
||||
use deno_runtime::deno_fetch::CreateHttpClientOptions;
|
||||
use deno_runtime::deno_fetch::ResBody;
|
||||
use deno_runtime::deno_fetch::create_http_client;
|
||||
use deno_runtime::deno_tls::RootCertStoreProvider;
|
||||
use http::header::HeaderName;
|
||||
use http::header::HeaderValue;
|
||||
use http::header::CONTENT_LENGTH;
|
||||
use http::HeaderMap;
|
||||
use http::StatusCode;
|
||||
use http::header::CONTENT_LENGTH;
|
||||
use http::header::HeaderName;
|
||||
use http::header::HeaderValue;
|
||||
use http_body_util::BodyExt;
|
||||
use thiserror::Error;
|
||||
|
||||
|
@ -508,10 +508,10 @@ mod test {
|
|||
create_http_client(
|
||||
DENO_VERSION_INFO.user_agent,
|
||||
CreateHttpClientOptions {
|
||||
ca_certs: vec![std::fs::read(
|
||||
test_util::testdata_path().join("tls/RootCA.pem"),
|
||||
)
|
||||
.unwrap()],
|
||||
ca_certs: vec![
|
||||
std::fs::read(test_util::testdata_path().join("tls/RootCA.pem"))
|
||||
.unwrap(),
|
||||
],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
|
@ -574,7 +574,9 @@ mod test {
|
|||
return;
|
||||
}
|
||||
|
||||
panic!("None of the expected public URLs were available but internet appears to be available");
|
||||
panic!(
|
||||
"None of the expected public URLs were available but internet appears to be available"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -614,12 +616,14 @@ mod test {
|
|||
create_http_client(
|
||||
DENO_VERSION_INFO.user_agent,
|
||||
CreateHttpClientOptions {
|
||||
ca_certs: vec![std::fs::read(
|
||||
test_util::testdata_path()
|
||||
.join("tls/RootCA.pem")
|
||||
.to_string(),
|
||||
)
|
||||
.unwrap()],
|
||||
ca_certs: vec![
|
||||
std::fs::read(
|
||||
test_util::testdata_path()
|
||||
.join("tls/RootCA.pem")
|
||||
.to_string(),
|
||||
)
|
||||
.unwrap(),
|
||||
],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
|
@ -647,12 +651,14 @@ mod test {
|
|||
create_http_client(
|
||||
DENO_VERSION_INFO.user_agent,
|
||||
CreateHttpClientOptions {
|
||||
ca_certs: vec![std::fs::read(
|
||||
test_util::testdata_path()
|
||||
.join("tls/RootCA.pem")
|
||||
.to_string(),
|
||||
)
|
||||
.unwrap()],
|
||||
ca_certs: vec![
|
||||
std::fs::read(
|
||||
test_util::testdata_path()
|
||||
.join("tls/RootCA.pem")
|
||||
.to_string(),
|
||||
)
|
||||
.unwrap(),
|
||||
],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
|
@ -688,12 +694,14 @@ mod test {
|
|||
create_http_client(
|
||||
DENO_VERSION_INFO.user_agent,
|
||||
CreateHttpClientOptions {
|
||||
ca_certs: vec![std::fs::read(
|
||||
test_util::testdata_path()
|
||||
.join("tls/RootCA.pem")
|
||||
.to_string(),
|
||||
)
|
||||
.unwrap()],
|
||||
ca_certs: vec![
|
||||
std::fs::read(
|
||||
test_util::testdata_path()
|
||||
.join("tls/RootCA.pem")
|
||||
.to_string(),
|
||||
)
|
||||
.unwrap(),
|
||||
],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
[package]
|
||||
name = "deno_lib"
|
||||
version = "0.26.0"
|
||||
version = "0.27.0"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
|
|
@ -4,20 +4,20 @@ use std::io::BufReader;
|
|||
use std::io::Cursor;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use base64::prelude::Engine;
|
||||
use base64::prelude::BASE64_STANDARD;
|
||||
use base64::prelude::Engine;
|
||||
use deno_npm::resolution::PackageIdNotFoundError;
|
||||
use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot;
|
||||
use deno_npm_installer::process_state::NpmProcessState;
|
||||
use deno_npm_installer::process_state::NpmProcessStateFromEnvVarSys;
|
||||
use deno_npm_installer::process_state::NpmProcessStateKind;
|
||||
use deno_runtime::UNSTABLE_ENV_VAR_NAMES;
|
||||
use deno_runtime::colors;
|
||||
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::UNSTABLE_ENV_VAR_NAMES;
|
||||
use deno_semver::npm::NpmPackageReqReference;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
@ -170,7 +170,11 @@ pub fn npm_process_state(
|
|||
.get_or_init(|| {
|
||||
use deno_runtime::deno_process::NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME;
|
||||
let fd_or_path = std::env::var_os(NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME)?;
|
||||
std::env::remove_var(NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME);
|
||||
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
unsafe {
|
||||
std::env::remove_var(NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME)
|
||||
};
|
||||
if fd_or_path.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
@ -201,10 +205,10 @@ pub fn resolve_npm_resolution_snapshot(
|
|||
pub struct UnstableConfig {
|
||||
// TODO(bartlomieju): remove in Deno 2.5
|
||||
pub legacy_flag_enabled: bool, // --unstable
|
||||
pub subdomain_wildcards: bool,
|
||||
pub bare_node_builtins: bool,
|
||||
pub detect_cjs: bool,
|
||||
pub lazy_dynamic_imports: bool,
|
||||
pub raw_imports: bool,
|
||||
pub sloppy_imports: bool,
|
||||
pub npm_lazy_caching: bool,
|
||||
pub features: Vec<String>, // --unstabe-kv --unstable-cron
|
||||
|
@ -218,10 +222,6 @@ impl UnstableConfig {
|
|||
}
|
||||
}
|
||||
|
||||
maybe_set(
|
||||
&mut self.subdomain_wildcards,
|
||||
UNSTABLE_ENV_VAR_NAMES.subdomain_wildcards,
|
||||
);
|
||||
maybe_set(
|
||||
&mut self.bare_node_builtins,
|
||||
UNSTABLE_ENV_VAR_NAMES.bare_node_builtins,
|
||||
|
@ -234,9 +234,16 @@ impl UnstableConfig {
|
|||
&mut self.npm_lazy_caching,
|
||||
UNSTABLE_ENV_VAR_NAMES.npm_lazy_caching,
|
||||
);
|
||||
maybe_set(&mut self.raw_imports, UNSTABLE_ENV_VAR_NAMES.raw_imports);
|
||||
maybe_set(
|
||||
&mut self.sloppy_imports,
|
||||
UNSTABLE_ENV_VAR_NAMES.sloppy_imports,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn enable_node_compat(&mut self) {
|
||||
self.bare_node_builtins = true;
|
||||
self.sloppy_imports = true;
|
||||
self.detect_cjs = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,11 +8,12 @@ use deno_media_type::MediaType;
|
|||
use deno_resolver::cjs::CjsTracker;
|
||||
use deno_resolver::npm::DenoInNpmPackageChecker;
|
||||
use deno_runtime::deno_core::ModuleSourceCode;
|
||||
use node_resolver::analyze::CjsCodeAnalyzer;
|
||||
use node_resolver::analyze::NodeCodeTranslator;
|
||||
use deno_runtime::deno_core::ModuleType;
|
||||
use node_resolver::InNpmPackageChecker;
|
||||
use node_resolver::IsBuiltInNodeModuleChecker;
|
||||
use node_resolver::NpmPackageFolderResolver;
|
||||
use node_resolver::analyze::CjsCodeAnalyzer;
|
||||
use node_resolver::analyze::NodeCodeTranslator;
|
||||
use thiserror::Error;
|
||||
use url::Url;
|
||||
|
||||
|
@ -22,7 +23,7 @@ use crate::util::text_encoding::from_utf8_lossy_cow;
|
|||
pub struct ModuleCodeStringSource {
|
||||
pub code: ModuleSourceCode,
|
||||
pub found_url: Url,
|
||||
pub media_type: MediaType,
|
||||
pub module_type: ModuleType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error, deno_error::JsError)]
|
||||
|
@ -120,12 +121,12 @@ pub struct NpmModuleLoader<
|
|||
}
|
||||
|
||||
impl<
|
||||
TCjsCodeAnalyzer: CjsCodeAnalyzer,
|
||||
TInNpmPackageChecker: InNpmPackageChecker,
|
||||
TIsBuiltInNodeModuleChecker: IsBuiltInNodeModuleChecker,
|
||||
TNpmPackageFolderResolver: NpmPackageFolderResolver,
|
||||
TSys: DenoLibSys,
|
||||
>
|
||||
TCjsCodeAnalyzer: CjsCodeAnalyzer,
|
||||
TInNpmPackageChecker: InNpmPackageChecker,
|
||||
TIsBuiltInNodeModuleChecker: IsBuiltInNodeModuleChecker,
|
||||
TNpmPackageFolderResolver: NpmPackageFolderResolver,
|
||||
TSys: DenoLibSys,
|
||||
>
|
||||
NpmModuleLoader<
|
||||
TCjsCodeAnalyzer,
|
||||
TInNpmPackageChecker,
|
||||
|
@ -211,7 +212,17 @@ impl<
|
|||
Ok(ModuleCodeStringSource {
|
||||
code,
|
||||
found_url: specifier.clone(),
|
||||
media_type: MediaType::from_specifier(specifier),
|
||||
module_type: module_type_from_media_type(MediaType::from_specifier(
|
||||
specifier,
|
||||
)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn module_type_from_media_type(media_type: MediaType) -> ModuleType {
|
||||
match media_type {
|
||||
MediaType::Json => ModuleType::Json,
|
||||
MediaType::Wasm => ModuleType::Wasm,
|
||||
_ => ModuleType::JavaScript,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ impl ReleaseChannel {
|
|||
"rc" => Self::Rc,
|
||||
"lts" => Self::Lts,
|
||||
unknown => {
|
||||
return Err(UnrecognizedReleaseChannelError(unknown.to_string()))
|
||||
return Err(UnrecognizedReleaseChannelError(unknown.to_string()));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -136,9 +136,11 @@ pub enum CjsExportAnalysisEntry {
|
|||
const HAS_TRANSPILED_FLAG: u8 = 1 << 0;
|
||||
const HAS_SOURCE_MAP_FLAG: u8 = 1 << 1;
|
||||
const HAS_CJS_EXPORT_ANALYSIS_FLAG: u8 = 1 << 2;
|
||||
const HAS_VALID_UTF8_FLAG: u8 = 1 << 3;
|
||||
|
||||
pub struct RemoteModuleEntry<'a> {
|
||||
pub media_type: MediaType,
|
||||
pub is_valid_utf8: bool,
|
||||
pub data: Cow<'a, [u8]>,
|
||||
pub maybe_transpiled: Option<Cow<'a, [u8]>>,
|
||||
pub maybe_source_map: Option<Cow<'a, [u8]>>,
|
||||
|
@ -161,6 +163,9 @@ impl<'a> DenoRtSerializable<'a> for RemoteModuleEntry<'a> {
|
|||
}
|
||||
|
||||
let mut has_data_flags = 0;
|
||||
if self.is_valid_utf8 {
|
||||
has_data_flags |= HAS_VALID_UTF8_FLAG;
|
||||
}
|
||||
if self.maybe_transpiled.is_some() {
|
||||
has_data_flags |= HAS_TRANSPILED_FLAG;
|
||||
}
|
||||
|
@ -203,6 +208,7 @@ impl<'a> DenoRtDeserializable<'a> for RemoteModuleEntry<'a> {
|
|||
deserialize_data_if_has_flag(input, has_data_flags, HAS_TRANSPILED_FLAG)?;
|
||||
let (input, maybe_source_map) =
|
||||
deserialize_data_if_has_flag(input, has_data_flags, HAS_SOURCE_MAP_FLAG)?;
|
||||
let is_valid_utf8 = has_data_flags & HAS_VALID_UTF8_FLAG != 0;
|
||||
let (input, maybe_cjs_export_analysis) = deserialize_data_if_has_flag(
|
||||
input,
|
||||
has_data_flags,
|
||||
|
@ -213,6 +219,7 @@ impl<'a> DenoRtDeserializable<'a> for RemoteModuleEntry<'a> {
|
|||
Self {
|
||||
media_type,
|
||||
data: Cow::Borrowed(data),
|
||||
is_valid_utf8,
|
||||
maybe_transpiled,
|
||||
maybe_source_map,
|
||||
maybe_cjs_export_analysis,
|
||||
|
@ -270,7 +277,7 @@ impl<'a> DenoRtDeserializable<'a> for MediaType {
|
|||
return Err(std::io::Error::new(
|
||||
std::io::ErrorKind::InvalidData,
|
||||
format!("Unknown media type value: {value}"),
|
||||
))
|
||||
));
|
||||
}
|
||||
};
|
||||
Ok((input, value))
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::collections::VecDeque;
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::fmt;
|
||||
use std::io::Read;
|
||||
use std::path::Path;
|
||||
|
@ -14,17 +14,19 @@ use std::time::SystemTime;
|
|||
use deno_path_util::normalize_path;
|
||||
use deno_path_util::strip_unc_prefix;
|
||||
use deno_runtime::colors;
|
||||
use deno_runtime::deno_core::anyhow::bail;
|
||||
use deno_runtime::deno_core::anyhow::Context;
|
||||
use deno_runtime::deno_core::anyhow::bail;
|
||||
use deno_runtime::deno_core::error::AnyError;
|
||||
use indexmap::IndexSet;
|
||||
use serde::de;
|
||||
use serde::de::SeqAccess;
|
||||
use serde::de::Visitor;
|
||||
use serde::Deserialize;
|
||||
use serde::Deserializer;
|
||||
use serde::Serialize;
|
||||
use serde::Serializer;
|
||||
use serde::de;
|
||||
use serde::de::SeqAccess;
|
||||
use serde::de::Visitor;
|
||||
|
||||
use crate::util::text_encoding::is_valid_utf8;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum WindowsSystemRootablePath {
|
||||
|
@ -257,6 +259,8 @@ pub struct VirtualFile {
|
|||
pub name: String,
|
||||
#[serde(rename = "o")]
|
||||
pub offset: OffsetWithLength,
|
||||
#[serde(default, rename = "u", skip_serializing_if = "is_false")]
|
||||
pub is_valid_utf8: bool,
|
||||
#[serde(rename = "m", skip_serializing_if = "Option::is_none")]
|
||||
pub transpiled_offset: Option<OffsetWithLength>,
|
||||
#[serde(rename = "c", skip_serializing_if = "Option::is_none")]
|
||||
|
@ -267,6 +271,10 @@ pub struct VirtualFile {
|
|||
pub mtime: Option<u128>, // mtime in milliseconds
|
||||
}
|
||||
|
||||
fn is_false(value: &bool) -> bool {
|
||||
!value
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct VirtualSymlinkParts(Vec<String>);
|
||||
|
||||
|
@ -414,7 +422,7 @@ impl FilesData {
|
|||
if data.is_empty() {
|
||||
return OffsetWithLength { offset: 0, len: 0 };
|
||||
}
|
||||
let checksum = crate::util::checksum::gen(&[&data]);
|
||||
let checksum = crate::util::checksum::r#gen(&[&data]);
|
||||
match self.file_offsets.entry((checksum, data.len())) {
|
||||
Entry::Occupied(occupied_entry) => {
|
||||
let offset_and_len = *occupied_entry.get();
|
||||
|
@ -766,6 +774,7 @@ impl VfsBuilder {
|
|||
log::debug!("Adding file '{}'", path.display());
|
||||
let case_sensitivity = self.case_sensitivity;
|
||||
|
||||
let is_valid_utf8 = is_valid_utf8(&options.data);
|
||||
let offset_and_len = self.files.add_data(options.data);
|
||||
let transpiled_offset = options
|
||||
.maybe_transpiled
|
||||
|
@ -790,6 +799,7 @@ impl VfsBuilder {
|
|||
|| {
|
||||
VfsEntry::File(VirtualFile {
|
||||
name: name.to_string(),
|
||||
is_valid_utf8,
|
||||
offset: offset_and_len,
|
||||
transpiled_offset,
|
||||
cjs_export_analysis_offset,
|
||||
|
|
|
@ -4,7 +4,7 @@ use aws_lc_rs::digest::Context;
|
|||
use aws_lc_rs::digest::SHA256;
|
||||
|
||||
/// Generate a SHA256 checksum of a slice of byte-slice-like things.
|
||||
pub fn gen(v: &[impl AsRef<[u8]>]) -> String {
|
||||
pub fn r#gen(v: &[impl AsRef<[u8]>]) -> String {
|
||||
let mut ctx = Context::new(&SHA256);
|
||||
for src in v {
|
||||
ctx.update(src.as_ref());
|
||||
|
@ -18,7 +18,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_gen() {
|
||||
let actual = gen(&[b"hello world"]);
|
||||
let actual = r#gen(&[b"hello world"]);
|
||||
assert_eq!(
|
||||
actual,
|
||||
"b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
use std::borrow::Cow;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub fn is_valid_utf8(bytes: &[u8]) -> bool {
|
||||
matches!(String::from_utf8_lossy(bytes), Cow::Borrowed(_))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn from_utf8_lossy_owned(bytes: Vec<u8>) -> String {
|
||||
match String::from_utf8_lossy(&bytes) {
|
||||
|
|
|
@ -1 +1 @@
|
|||
2.3.7
|
||||
2.4.0
|
|
@ -11,17 +11,22 @@ use deno_path_util::url_from_file_path;
|
|||
use deno_path_util::url_to_file_path;
|
||||
use deno_resolver::npm::DenoInNpmPackageChecker;
|
||||
use deno_resolver::npm::NpmResolver;
|
||||
use deno_runtime::BootstrapOptions;
|
||||
use deno_runtime::FeatureChecker;
|
||||
use deno_runtime::UNSTABLE_FEATURES;
|
||||
use deno_runtime::WorkerExecutionMode;
|
||||
use deno_runtime::WorkerLogLevel;
|
||||
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::JsRuntime;
|
||||
use deno_runtime::deno_core::LocalInspectorSession;
|
||||
use deno_runtime::deno_core::ModuleLoader;
|
||||
use deno_runtime::deno_core::SharedArrayBufferStore;
|
||||
use deno_runtime::deno_core::error::CoreError;
|
||||
use deno_runtime::deno_core::v8;
|
||||
use deno_runtime::deno_fs;
|
||||
use deno_runtime::deno_napi::DenoRtNativeAddonLoaderRc;
|
||||
use deno_runtime::deno_node::NodeExtInitServices;
|
||||
|
@ -41,13 +46,8 @@ 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::FeatureChecker;
|
||||
use deno_runtime::WorkerExecutionMode;
|
||||
use deno_runtime::WorkerLogLevel;
|
||||
use deno_runtime::UNSTABLE_FEATURES;
|
||||
use node_resolver::errors::ResolvePkgJsonBinExportError;
|
||||
use node_resolver::UrlOrPath;
|
||||
use node_resolver::errors::ResolvePkgJsonBinExportError;
|
||||
use url::Url;
|
||||
|
||||
use crate::args::has_trace_permissions_enabled;
|
||||
|
@ -323,6 +323,7 @@ pub struct LibMainWorkerOptions {
|
|||
pub argv: Vec<String>,
|
||||
pub log_level: WorkerLogLevel,
|
||||
pub enable_op_summary_metrics: bool,
|
||||
pub enable_raw_imports: bool,
|
||||
pub enable_testing_features: bool,
|
||||
pub has_node_modules_dir: bool,
|
||||
pub inspect_brk: bool,
|
||||
|
@ -425,7 +426,7 @@ impl<TSys: DenoLibSys> LibWorkerFactorySharedState<TSys> {
|
|||
.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()]))
|
||||
get_cache_storage_dir().join(checksum::r#gen(&[key.as_bytes()]))
|
||||
});
|
||||
|
||||
// TODO(bartlomieju): this is cruft, update FeatureChecker to spit out
|
||||
|
@ -506,6 +507,7 @@ impl<TSys: DenoLibSys> LibWorkerFactorySharedState<TSys> {
|
|||
strace_ops: shared.options.strace_ops.clone(),
|
||||
close_on_idle: args.close_on_idle,
|
||||
maybe_worker_metadata: args.maybe_worker_metadata,
|
||||
enable_raw_imports: shared.options.enable_raw_imports,
|
||||
enable_stack_trace_arg_in_ops: has_trace_permissions_enabled(),
|
||||
};
|
||||
|
||||
|
@ -568,10 +570,12 @@ impl<TSys: DenoLibSys> LibMainWorkerFactory<TSys> {
|
|||
mode: WorkerExecutionMode,
|
||||
permissions: PermissionsContainer,
|
||||
main_module: Url,
|
||||
preload_modules: Vec<Url>,
|
||||
) -> Result<LibMainWorker, CoreError> {
|
||||
self.create_custom_worker(
|
||||
mode,
|
||||
main_module,
|
||||
preload_modules,
|
||||
permissions,
|
||||
vec![],
|
||||
Default::default(),
|
||||
|
@ -580,10 +584,12 @@ impl<TSys: DenoLibSys> LibMainWorkerFactory<TSys> {
|
|||
}
|
||||
|
||||
#[allow(clippy::result_large_err)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn create_custom_worker(
|
||||
&self,
|
||||
mode: WorkerExecutionMode,
|
||||
main_module: Url,
|
||||
preload_modules: Vec<Url>,
|
||||
permissions: PermissionsContainer,
|
||||
custom_extensions: Vec<Extension>,
|
||||
stdio: deno_runtime::deno_io::Stdio,
|
||||
|
@ -612,11 +618,11 @@ impl<TSys: DenoLibSys> LibMainWorkerFactory<TSys> {
|
|||
.origin_data_folder_path
|
||||
.as_ref()
|
||||
.unwrap() // must be set if storage key resolver returns a value
|
||||
.join(checksum::gen(&[key.as_bytes()]))
|
||||
.join(checksum::r#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()]))
|
||||
get_cache_storage_dir().join(checksum::r#gen(&[key.as_bytes()]))
|
||||
});
|
||||
|
||||
let services = WorkerServiceOptions {
|
||||
|
@ -690,6 +696,7 @@ impl<TSys: DenoLibSys> LibMainWorkerFactory<TSys> {
|
|||
origin_storage_dir,
|
||||
stdio,
|
||||
skip_op_registration: shared.options.skip_op_registration,
|
||||
enable_raw_imports: shared.options.enable_raw_imports,
|
||||
enable_stack_trace_arg_in_ops: has_trace_permissions_enabled(),
|
||||
unconfigured_runtime,
|
||||
};
|
||||
|
@ -700,6 +707,7 @@ impl<TSys: DenoLibSys> LibMainWorkerFactory<TSys> {
|
|||
|
||||
Ok(LibMainWorker {
|
||||
main_module,
|
||||
preload_modules,
|
||||
worker,
|
||||
})
|
||||
}
|
||||
|
@ -786,6 +794,7 @@ impl<TSys: DenoLibSys> LibMainWorkerFactory<TSys> {
|
|||
|
||||
pub struct LibMainWorker {
|
||||
main_module: Url,
|
||||
preload_modules: Vec<Url>,
|
||||
worker: MainWorker,
|
||||
}
|
||||
|
||||
|
@ -847,9 +856,21 @@ impl LibMainWorker {
|
|||
self.worker.evaluate_module(id).await
|
||||
}
|
||||
|
||||
pub async fn execute_preload_modules(&mut self) -> Result<(), CoreError> {
|
||||
for preload_module_url in self.preload_modules.iter() {
|
||||
let id = self.worker.preload_side_module(preload_module_url).await?;
|
||||
self.worker.evaluate_module(id).await?;
|
||||
self.worker.run_event_loop(false).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn run(&mut self) -> Result<i32, CoreError> {
|
||||
log::debug!("main_module {}", self.main_module);
|
||||
|
||||
// Run preload modules first if they were defined
|
||||
self.execute_preload_modules().await?;
|
||||
|
||||
self.execute_main_module().await?;
|
||||
self.worker.dispatch_load_event()?;
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ use std::sync::Arc;
|
|||
use deno_ast::SourceRange;
|
||||
use deno_ast::SourceRangedForSpanned;
|
||||
use deno_ast::SourceTextInfo;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::resolve_url;
|
||||
|
@ -18,13 +19,15 @@ use deno_core::serde::Serialize;
|
|||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_lint::diagnostic::LintDiagnosticRange;
|
||||
use deno_npm::NpmPackageId;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use deno_resolver::npm::managed::NpmResolutionCell;
|
||||
use deno_runtime::deno_node::PathClean;
|
||||
use deno_semver::SmallStackString;
|
||||
use deno_semver::StackString;
|
||||
use deno_semver::Version;
|
||||
use deno_semver::jsr::JsrPackageNvReference;
|
||||
use deno_semver::jsr::JsrPackageReqReference;
|
||||
use deno_semver::npm::NpmPackageReqReference;
|
||||
|
@ -32,9 +35,6 @@ use deno_semver::package::PackageNv;
|
|||
use deno_semver::package::PackageNvReference;
|
||||
use deno_semver::package::PackageReq;
|
||||
use deno_semver::package::PackageReqReference;
|
||||
use deno_semver::SmallStackString;
|
||||
use deno_semver::StackString;
|
||||
use deno_semver::Version;
|
||||
use import_map::ImportMap;
|
||||
use lsp_types::Uri;
|
||||
use node_resolver::InNpmPackageChecker;
|
||||
|
@ -632,11 +632,7 @@ fn maybe_reverse_definitely_typed(
|
|||
.filter_map(|(req, nv)| (*nv.name == package_name).then_some(req))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if reqs.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(reqs)
|
||||
}
|
||||
if reqs.is_empty() { None } else { Some(reqs) }
|
||||
}
|
||||
|
||||
fn try_reverse_map_package_json_exports(
|
||||
|
|
|
@ -6,8 +6,8 @@ use std::path::Path;
|
|||
use std::sync::Arc;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use deno_core::url::Url;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::url::Url;
|
||||
use deno_path_util::url_to_file_path;
|
||||
|
||||
use crate::cache::DenoDir;
|
||||
|
|
|
@ -37,8 +37,8 @@ fn code_action_capabilities(
|
|||
.unwrap_or(CodeActionProviderCapability::Simple(true))
|
||||
}
|
||||
|
||||
pub fn semantic_tokens_registration_options(
|
||||
) -> SemanticTokensRegistrationOptions {
|
||||
pub fn semantic_tokens_registration_options()
|
||||
-> SemanticTokensRegistrationOptions {
|
||||
const LANGUAGES: [&str; 4] = [
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
|
|
|
@ -12,8 +12,8 @@ use lsp_types::Uri;
|
|||
use tower_lsp::lsp_types as lsp;
|
||||
use tower_lsp::lsp_types::ConfigurationItem;
|
||||
|
||||
use super::config::WorkspaceSettings;
|
||||
use super::config::SETTINGS_SECTION;
|
||||
use super::config::WorkspaceSettings;
|
||||
use super::lsp_custom;
|
||||
use super::testing::lsp_custom as testing_lsp_custom;
|
||||
use crate::lsp::repl::get_repl_workspace_settings;
|
||||
|
|
|
@ -5,18 +5,18 @@ use std::collections::HashSet;
|
|||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_ast::swc::ast;
|
||||
use deno_ast::swc::ecma_visit::Visit;
|
||||
use deno_ast::swc::ecma_visit::VisitWith;
|
||||
use deno_ast::ParsedSource;
|
||||
use deno_ast::SourceRange;
|
||||
use deno_ast::SourceRangedForSpanned;
|
||||
use deno_ast::swc::ast;
|
||||
use deno_ast::swc::ecma_visit::Visit;
|
||||
use deno_ast::swc::ecma_visit::VisitWith;
|
||||
use deno_core::ModuleSpecifier;
|
||||
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 lazy_regex::lazy_regex;
|
||||
use lsp_types::Uri;
|
||||
use once_cell::sync::Lazy;
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
use deno_ast::LineAndColumnIndex;
|
||||
use deno_ast::SourceTextInfo;
|
||||
use deno_core::ModuleSpecifier;
|
||||
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;
|
||||
|
@ -180,7 +180,7 @@ pub async fn get_import_completions(
|
|||
NodeResolutionKind::Execution,
|
||||
)
|
||||
.ok();
|
||||
if let Some(completion_list) = get_jsr_completions(
|
||||
match get_jsr_completions(
|
||||
&module.specifier,
|
||||
text,
|
||||
&range,
|
||||
|
@ -190,85 +190,128 @@ pub async fn get_import_completions(
|
|||
)
|
||||
.await
|
||||
{
|
||||
Some(lsp::CompletionResponse::List(completion_list))
|
||||
} else if let Some(completion_list) =
|
||||
get_npm_completions(&module.specifier, text, &range, npm_search_api).await
|
||||
{
|
||||
Some(lsp::CompletionResponse::List(completion_list))
|
||||
} else if let Some(completion_list) = get_node_completions(text, &range) {
|
||||
Some(lsp::CompletionResponse::List(completion_list))
|
||||
} else if let Some(completion_list) = get_import_map_completions(
|
||||
&module.specifier,
|
||||
text,
|
||||
&range,
|
||||
maybe_import_map,
|
||||
) {
|
||||
// completions for import map specifiers
|
||||
Some(lsp::CompletionResponse::List(completion_list))
|
||||
} else if let Some(completion_list) = get_local_completions(
|
||||
&module.specifier,
|
||||
resolution_mode,
|
||||
text,
|
||||
&range,
|
||||
resolver,
|
||||
) {
|
||||
// completions for local relative modules
|
||||
Some(lsp::CompletionResponse::List(completion_list))
|
||||
} else if !text.is_empty() {
|
||||
// completion of modules from a module registry or cache
|
||||
check_auto_config_registry(
|
||||
text,
|
||||
config.workspace_settings_for_specifier(&module.specifier),
|
||||
client,
|
||||
module_registries,
|
||||
)
|
||||
.await;
|
||||
let maybe_list = module_registries
|
||||
.get_completions(text, &range, resolved.as_ref(), |s| {
|
||||
document_modules.specifier_exists(s, module.scope.as_deref())
|
||||
})
|
||||
.await;
|
||||
let maybe_list = maybe_list
|
||||
.or_else(|| module_registries.get_origin_completions(text, &range));
|
||||
let list = maybe_list.unwrap_or_else(|| CompletionList {
|
||||
items: get_remote_completions(module, text, &range, document_modules),
|
||||
is_incomplete: false,
|
||||
});
|
||||
Some(lsp::CompletionResponse::List(list))
|
||||
} else {
|
||||
// the import specifier is empty, so provide all possible specifiers we are
|
||||
// aware of
|
||||
let mut items: Vec<lsp::CompletionItem> = LOCAL_PATHS
|
||||
.iter()
|
||||
.map(|s| lsp::CompletionItem {
|
||||
label: s.to_string(),
|
||||
kind: Some(lsp::CompletionItemKind::FOLDER),
|
||||
detail: Some("(local)".to_string()),
|
||||
sort_text: Some("1".to_string()),
|
||||
insert_text: Some(s.to_string()),
|
||||
commit_characters: Some(
|
||||
IMPORT_COMMIT_CHARS.iter().map(|&c| c.into()).collect(),
|
||||
),
|
||||
..Default::default()
|
||||
})
|
||||
.collect();
|
||||
let mut is_incomplete = false;
|
||||
if let Some(import_map) = maybe_import_map {
|
||||
items.extend(get_base_import_map_completions(
|
||||
import_map,
|
||||
&module.specifier,
|
||||
));
|
||||
Some(completion_list) => {
|
||||
Some(lsp::CompletionResponse::List(completion_list))
|
||||
}
|
||||
if let Some(origin_items) =
|
||||
module_registries.get_origin_completions(text, &range)
|
||||
{
|
||||
is_incomplete = origin_items.is_incomplete;
|
||||
items.extend(origin_items.items);
|
||||
_ => {
|
||||
match get_npm_completions(&module.specifier, text, &range, npm_search_api)
|
||||
.await
|
||||
{
|
||||
Some(completion_list) => {
|
||||
Some(lsp::CompletionResponse::List(completion_list))
|
||||
}
|
||||
_ => {
|
||||
match get_node_completions(text, &range) {
|
||||
Some(completion_list) => {
|
||||
Some(lsp::CompletionResponse::List(completion_list))
|
||||
}
|
||||
_ => {
|
||||
match get_import_map_completions(
|
||||
&module.specifier,
|
||||
text,
|
||||
&range,
|
||||
maybe_import_map,
|
||||
) {
|
||||
Some(completion_list) => {
|
||||
// completions for import map specifiers
|
||||
Some(lsp::CompletionResponse::List(completion_list))
|
||||
}
|
||||
_ => {
|
||||
match get_local_completions(
|
||||
&module.specifier,
|
||||
resolution_mode,
|
||||
text,
|
||||
&range,
|
||||
resolver,
|
||||
) {
|
||||
Some(completion_list) => {
|
||||
// completions for local relative modules
|
||||
Some(lsp::CompletionResponse::List(completion_list))
|
||||
}
|
||||
_ => {
|
||||
if !text.is_empty() {
|
||||
// completion of modules from a module registry or cache
|
||||
check_auto_config_registry(
|
||||
text,
|
||||
config.workspace_settings_for_specifier(
|
||||
&module.specifier,
|
||||
),
|
||||
client,
|
||||
module_registries,
|
||||
)
|
||||
.await;
|
||||
let maybe_list = module_registries
|
||||
.get_completions(
|
||||
text,
|
||||
&range,
|
||||
resolved.as_ref(),
|
||||
|s| {
|
||||
document_modules
|
||||
.specifier_exists(s, module.scope.as_deref())
|
||||
},
|
||||
)
|
||||
.await;
|
||||
let maybe_list = maybe_list.or_else(|| {
|
||||
module_registries.get_origin_completions(text, &range)
|
||||
});
|
||||
let list =
|
||||
maybe_list.unwrap_or_else(|| CompletionList {
|
||||
items: get_remote_completions(
|
||||
module,
|
||||
text,
|
||||
&range,
|
||||
document_modules,
|
||||
),
|
||||
is_incomplete: false,
|
||||
});
|
||||
Some(lsp::CompletionResponse::List(list))
|
||||
} else {
|
||||
// the import specifier is empty, so provide all possible specifiers we are
|
||||
// aware of
|
||||
let mut items: Vec<lsp::CompletionItem> = LOCAL_PATHS
|
||||
.iter()
|
||||
.map(|s| lsp::CompletionItem {
|
||||
label: s.to_string(),
|
||||
kind: Some(lsp::CompletionItemKind::FOLDER),
|
||||
detail: Some("(local)".to_string()),
|
||||
sort_text: Some("1".to_string()),
|
||||
insert_text: Some(s.to_string()),
|
||||
commit_characters: Some(
|
||||
IMPORT_COMMIT_CHARS
|
||||
.iter()
|
||||
.map(|&c| c.into())
|
||||
.collect(),
|
||||
),
|
||||
..Default::default()
|
||||
})
|
||||
.collect();
|
||||
let mut is_incomplete = false;
|
||||
if let Some(import_map) = maybe_import_map {
|
||||
items.extend(get_base_import_map_completions(
|
||||
import_map,
|
||||
&module.specifier,
|
||||
));
|
||||
}
|
||||
if let Some(origin_items) =
|
||||
module_registries.get_origin_completions(text, &range)
|
||||
{
|
||||
is_incomplete = origin_items.is_incomplete;
|
||||
items.extend(origin_items.items);
|
||||
}
|
||||
Some(lsp::CompletionResponse::List(CompletionList {
|
||||
is_incomplete,
|
||||
items,
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(lsp::CompletionResponse::List(CompletionList {
|
||||
is_incomplete,
|
||||
items,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -909,8 +952,10 @@ mod tests {
|
|||
for item in actual.items {
|
||||
match item.text_edit {
|
||||
Some(lsp::CompletionTextEdit::Edit(text_edit)) => {
|
||||
assert!(["./b", "./f.mjs", "./g.json"]
|
||||
.contains(&text_edit.new_text.as_str()));
|
||||
assert!(
|
||||
["./b", "./f.mjs", "./g.json"]
|
||||
.contains(&text_edit.new_text.as_str())
|
||||
);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
|
|
@ -27,27 +27,27 @@ use deno_config::workspace::WorkspaceDirLintConfig;
|
|||
use deno_config::workspace::WorkspaceDirectory;
|
||||
use deno_config::workspace::WorkspaceDirectoryEmptyOptions;
|
||||
use deno_config::workspace::WorkspaceDiscoverOptions;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::serde::de::DeserializeOwned;
|
||||
use deno_core::serde::Deserialize;
|
||||
use deno_core::serde::Serialize;
|
||||
use deno_core::serde::de::DeserializeOwned;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_json::Value;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_lib::args::has_flag_env_var;
|
||||
use deno_lib::util::hash::FastInsecureHasher;
|
||||
use deno_lint::linter::LintConfig as DenoLintConfig;
|
||||
use deno_npm::npm_rc::ResolvedNpmRc;
|
||||
use deno_npm_cache::NpmCacheSetting;
|
||||
use deno_npm_installer::graph::NpmCachingStrategy;
|
||||
use deno_npm_installer::lifecycle_scripts::NullLifecycleScriptsExecutor;
|
||||
use deno_npm_installer::LifecycleScriptsConfig;
|
||||
use deno_npm_installer::NpmInstallerFactory;
|
||||
use deno_npm_installer::NpmInstallerFactoryOptions;
|
||||
use deno_npm_installer::graph::NpmCachingStrategy;
|
||||
use deno_npm_installer::lifecycle_scripts::NullLifecycleScriptsExecutor;
|
||||
use deno_package_json::PackageJsonCache;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use deno_resolver::factory::ConfigDiscoveryOption;
|
||||
|
@ -703,7 +703,9 @@ impl WorkspaceSettings {
|
|||
let inlay_hints: InlayHintsSettings =
|
||||
parse_or_default(inlay_hints, "settings under \"deno.inlayHints\"");
|
||||
if inlay_hints.parameter_names.enabled != Default::default() {
|
||||
lsp_warn!("\"deno.inlayHints.parameterNames.enabled\" is deprecated. Instead use \"javascript.inlayHints.parameterNames.enabled\" and \"typescript.inlayHints.parameterNames.enabled\".");
|
||||
lsp_warn!(
|
||||
"\"deno.inlayHints.parameterNames.enabled\" is deprecated. Instead use \"javascript.inlayHints.parameterNames.enabled\" and \"typescript.inlayHints.parameterNames.enabled\"."
|
||||
);
|
||||
settings.javascript.inlay_hints.parameter_names.enabled =
|
||||
inlay_hints.parameter_names.enabled.clone();
|
||||
settings.typescript.inlay_hints.parameter_names.enabled =
|
||||
|
@ -713,7 +715,9 @@ impl WorkspaceSettings {
|
|||
.parameter_names
|
||||
.suppress_when_argument_matches_name
|
||||
{
|
||||
lsp_warn!("\"deno.inlayHints.parameterNames.suppressWhenArgumentMatchesName\" is deprecated. Instead use \"javascript.inlayHints.parameterNames.suppressWhenArgumentMatchesName\" and \"typescript.inlayHints.parameterNames.suppressWhenArgumentMatchesName\".");
|
||||
lsp_warn!(
|
||||
"\"deno.inlayHints.parameterNames.suppressWhenArgumentMatchesName\" is deprecated. Instead use \"javascript.inlayHints.parameterNames.suppressWhenArgumentMatchesName\" and \"typescript.inlayHints.parameterNames.suppressWhenArgumentMatchesName\"."
|
||||
);
|
||||
settings
|
||||
.javascript
|
||||
.inlay_hints
|
||||
|
@ -730,21 +734,27 @@ impl WorkspaceSettings {
|
|||
.suppress_when_argument_matches_name;
|
||||
}
|
||||
if inlay_hints.parameter_types.enabled {
|
||||
lsp_warn!("\"deno.inlayHints.parameterTypes.enabled\" is deprecated. Instead use \"javascript.inlayHints.parameterTypes.enabled\" and \"typescript.inlayHints.parameterTypes.enabled\".");
|
||||
lsp_warn!(
|
||||
"\"deno.inlayHints.parameterTypes.enabled\" is deprecated. Instead use \"javascript.inlayHints.parameterTypes.enabled\" and \"typescript.inlayHints.parameterTypes.enabled\"."
|
||||
);
|
||||
settings.javascript.inlay_hints.parameter_types.enabled =
|
||||
inlay_hints.parameter_types.enabled;
|
||||
settings.typescript.inlay_hints.parameter_types.enabled =
|
||||
inlay_hints.parameter_types.enabled;
|
||||
}
|
||||
if inlay_hints.variable_types.enabled {
|
||||
lsp_warn!("\"deno.inlayHints.variableTypes.enabled\" is deprecated. Instead use \"javascript.inlayHints.variableTypes.enabled\" and \"typescript.inlayHints.variableTypes.enabled\".");
|
||||
lsp_warn!(
|
||||
"\"deno.inlayHints.variableTypes.enabled\" is deprecated. Instead use \"javascript.inlayHints.variableTypes.enabled\" and \"typescript.inlayHints.variableTypes.enabled\"."
|
||||
);
|
||||
settings.javascript.inlay_hints.variable_types.enabled =
|
||||
inlay_hints.variable_types.enabled;
|
||||
settings.typescript.inlay_hints.variable_types.enabled =
|
||||
inlay_hints.variable_types.enabled;
|
||||
}
|
||||
if !inlay_hints.variable_types.suppress_when_type_matches_name {
|
||||
lsp_warn!("\"deno.inlayHints.variableTypes.suppressWhenTypeMatchesName\" is deprecated. Instead use \"javascript.inlayHints.variableTypes.suppressWhenTypeMatchesName\" and \"typescript.inlayHints.variableTypes.suppressWhenTypeMatchesName\".");
|
||||
lsp_warn!(
|
||||
"\"deno.inlayHints.variableTypes.suppressWhenTypeMatchesName\" is deprecated. Instead use \"javascript.inlayHints.variableTypes.suppressWhenTypeMatchesName\" and \"typescript.inlayHints.variableTypes.suppressWhenTypeMatchesName\"."
|
||||
);
|
||||
settings
|
||||
.javascript
|
||||
.inlay_hints
|
||||
|
@ -759,7 +769,9 @@ impl WorkspaceSettings {
|
|||
inlay_hints.variable_types.suppress_when_type_matches_name;
|
||||
}
|
||||
if inlay_hints.property_declaration_types.enabled {
|
||||
lsp_warn!("\"deno.inlayHints.propertyDeclarationTypes.enabled\" is deprecated. Instead use \"javascript.inlayHints.propertyDeclarationTypes.enabled\" and \"typescript.inlayHints.propertyDeclarationTypes.enabled\".");
|
||||
lsp_warn!(
|
||||
"\"deno.inlayHints.propertyDeclarationTypes.enabled\" is deprecated. Instead use \"javascript.inlayHints.propertyDeclarationTypes.enabled\" and \"typescript.inlayHints.propertyDeclarationTypes.enabled\"."
|
||||
);
|
||||
settings
|
||||
.javascript
|
||||
.inlay_hints
|
||||
|
@ -772,7 +784,9 @@ impl WorkspaceSettings {
|
|||
.enabled = inlay_hints.property_declaration_types.enabled;
|
||||
}
|
||||
if inlay_hints.function_like_return_types.enabled {
|
||||
lsp_warn!("\"deno.inlayHints.functionLikeReturnTypes.enabled\" is deprecated. Instead use \"javascript.inlayHints.functionLikeReturnTypes.enabled\" and \"typescript.inlayHints.functionLikeReturnTypes.enabled\".");
|
||||
lsp_warn!(
|
||||
"\"deno.inlayHints.functionLikeReturnTypes.enabled\" is deprecated. Instead use \"javascript.inlayHints.functionLikeReturnTypes.enabled\" and \"typescript.inlayHints.functionLikeReturnTypes.enabled\"."
|
||||
);
|
||||
settings
|
||||
.javascript
|
||||
.inlay_hints
|
||||
|
@ -785,7 +799,9 @@ impl WorkspaceSettings {
|
|||
.enabled = inlay_hints.function_like_return_types.enabled;
|
||||
}
|
||||
if inlay_hints.enum_member_values.enabled {
|
||||
lsp_warn!("\"deno.inlayHints.enumMemberValues.enabled\" is deprecated. Instead use \"javascript.inlayHints.enumMemberValues.enabled\" and \"typescript.inlayHints.enumMemberValues.enabled\".");
|
||||
lsp_warn!(
|
||||
"\"deno.inlayHints.enumMemberValues.enabled\" is deprecated. Instead use \"javascript.inlayHints.enumMemberValues.enabled\" and \"typescript.inlayHints.enumMemberValues.enabled\"."
|
||||
);
|
||||
settings.javascript.inlay_hints.enum_member_values.enabled =
|
||||
inlay_hints.enum_member_values.enabled;
|
||||
settings.typescript.inlay_hints.enum_member_values.enabled =
|
||||
|
@ -796,24 +812,32 @@ impl WorkspaceSettings {
|
|||
let suggest: CompletionSettings =
|
||||
parse_or_default(suggest, "settings under \"deno.suggest\"");
|
||||
if suggest.complete_function_calls {
|
||||
lsp_warn!("\"deno.suggest.completeFunctionCalls\" is deprecated. Instead use \"javascript.suggest.completeFunctionCalls\" and \"typescript.suggest.completeFunctionCalls\".");
|
||||
lsp_warn!(
|
||||
"\"deno.suggest.completeFunctionCalls\" is deprecated. Instead use \"javascript.suggest.completeFunctionCalls\" and \"typescript.suggest.completeFunctionCalls\"."
|
||||
);
|
||||
settings.javascript.suggest.complete_function_calls =
|
||||
suggest.complete_function_calls;
|
||||
settings.typescript.suggest.complete_function_calls =
|
||||
suggest.complete_function_calls;
|
||||
}
|
||||
if !suggest.names {
|
||||
lsp_warn!("\"deno.suggest.names\" is deprecated. Instead use \"javascript.suggest.names\" and \"typescript.suggest.names\".");
|
||||
lsp_warn!(
|
||||
"\"deno.suggest.names\" is deprecated. Instead use \"javascript.suggest.names\" and \"typescript.suggest.names\"."
|
||||
);
|
||||
settings.javascript.suggest.names = suggest.names;
|
||||
settings.typescript.suggest.names = suggest.names;
|
||||
}
|
||||
if !suggest.paths {
|
||||
lsp_warn!("\"deno.suggest.paths\" is deprecated. Instead use \"javascript.suggest.paths\" and \"typescript.suggest.paths\".");
|
||||
lsp_warn!(
|
||||
"\"deno.suggest.paths\" is deprecated. Instead use \"javascript.suggest.paths\" and \"typescript.suggest.paths\"."
|
||||
);
|
||||
settings.javascript.suggest.paths = suggest.paths;
|
||||
settings.typescript.suggest.paths = suggest.paths;
|
||||
}
|
||||
if !suggest.auto_imports {
|
||||
lsp_warn!("\"deno.suggest.autoImports\" is deprecated. Instead use \"javascript.suggest.autoImports\" and \"typescript.suggest.autoImports\".");
|
||||
lsp_warn!(
|
||||
"\"deno.suggest.autoImports\" is deprecated. Instead use \"javascript.suggest.autoImports\" and \"typescript.suggest.autoImports\"."
|
||||
);
|
||||
settings.javascript.suggest.auto_imports = suggest.auto_imports;
|
||||
settings.typescript.suggest.auto_imports = suggest.auto_imports;
|
||||
}
|
||||
|
@ -1451,7 +1475,7 @@ impl ConfigData {
|
|||
WorkspaceFactoryOptions {
|
||||
additional_config_file_names: &[],
|
||||
config_discovery: ConfigDiscoveryOption::DiscoverCwd,
|
||||
deno_dir_path_provider: None,
|
||||
maybe_custom_deno_dir_root: None,
|
||||
is_package_manager_subcommand: false,
|
||||
frozen_lockfile: None,
|
||||
lock_arg: None,
|
||||
|
@ -1472,9 +1496,12 @@ impl ConfigData {
|
|||
ResolverFactoryOptions {
|
||||
// these default options are fine because we don't use this for
|
||||
// anything other than resolving the lockfile at the moment
|
||||
compiler_options_overrides: Default::default(),
|
||||
is_cjs_resolution_mode: Default::default(),
|
||||
npm_system_info: Default::default(),
|
||||
node_code_translator_mode: Default::default(),
|
||||
node_resolver_options: NodeResolverOptions::default(),
|
||||
node_analysis_cache: None,
|
||||
node_resolution_cache: None,
|
||||
package_json_cache: None,
|
||||
package_json_dep_resolution: None,
|
||||
|
|
|
@ -5,13 +5,14 @@ use std::collections::HashMap;
|
|||
use std::collections::HashSet;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::thread;
|
||||
|
||||
use deno_ast::MediaType;
|
||||
use deno_config::glob::FilePatterns;
|
||||
use deno_config::workspace::WorkspaceDirLintConfig;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
|
@ -20,17 +21,16 @@ use deno_core::resolve_url;
|
|||
use deno_core::serde::Deserialize;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::unsync::JoinHandle;
|
||||
use deno_core::unsync::spawn;
|
||||
use deno_core::unsync::spawn_blocking;
|
||||
use deno_core::unsync::JoinHandle;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_graph::source::ResolutionKind;
|
||||
use deno_graph::source::ResolveError;
|
||||
use deno_graph::Resolution;
|
||||
use deno_graph::ResolutionError;
|
||||
use deno_graph::SpecifierError;
|
||||
use deno_graph::source::ResolveError;
|
||||
use deno_lint::linter::LintConfig as DenoLintConfig;
|
||||
use deno_resolver::graph::enhanced_resolution_error_message;
|
||||
use deno_resolver::workspace::sloppy_imports_resolve;
|
||||
use deno_runtime::deno_node;
|
||||
use deno_runtime::tokio_util::create_basic_runtime;
|
||||
|
@ -42,8 +42,8 @@ use import_map::ImportMapErrorKind;
|
|||
use log::error;
|
||||
use lsp_types::Uri;
|
||||
use node_resolver::NodeResolutionKind;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::sync::Mutex as AsyncMutex;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::time::Duration;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tower_lsp::lsp_types as lsp;
|
||||
|
@ -61,8 +61,6 @@ use super::performance::Performance;
|
|||
use super::tsc;
|
||||
use super::tsc::MaybeAmbientModules;
|
||||
use super::tsc::TsServer;
|
||||
use crate::graph_util;
|
||||
use crate::graph_util::enhanced_resolution_error_message;
|
||||
use crate::lsp::logging::lsp_warn;
|
||||
use crate::lsp::lsp_custom::DiagnosticBatchNotificationParams;
|
||||
use crate::sys::CliSys;
|
||||
|
@ -460,13 +458,13 @@ impl DeferredDiagnostics {
|
|||
}
|
||||
let mut regex_string = ambient_modules_to_regex_string(&value);
|
||||
regex_string.push('$');
|
||||
if let Ok(regex) = regex::Regex::new(®ex_string).inspect_err(|e| {
|
||||
match regex::Regex::new(®ex_string).inspect_err(|e| {
|
||||
lsp_warn!("failed to compile ambient modules pattern: {e} (pattern is {regex_string:?})");
|
||||
}) {
|
||||
}) { Ok(regex) => {
|
||||
ambient.regex = Some(regex);
|
||||
} else {
|
||||
} _ => {
|
||||
ambient.regex = None;
|
||||
}
|
||||
}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1030,15 +1028,12 @@ fn generate_document_lint_diagnostics(
|
|||
.and_then(|d| d.parsed_source.as_ref())
|
||||
{
|
||||
Some(Ok(parsed_source)) => {
|
||||
if let Ok(references) =
|
||||
analysis::get_lint_references(parsed_source, linter, token)
|
||||
{
|
||||
references
|
||||
match analysis::get_lint_references(parsed_source, linter, token) {
|
||||
Ok(references) => references
|
||||
.into_iter()
|
||||
.map(|r| r.to_diagnostic())
|
||||
.collect::<Vec<_>>()
|
||||
} else {
|
||||
Vec::new()
|
||||
.collect::<Vec<_>>(),
|
||||
_ => Vec::new(),
|
||||
}
|
||||
}
|
||||
Some(Err(_)) => Vec::new(),
|
||||
|
@ -1201,7 +1196,9 @@ impl DenoDiagnostic {
|
|||
Self::NoExportNpm(_) => "no-export-npm",
|
||||
Self::NoLocal(_) => "no-local",
|
||||
Self::ResolutionError(err) => {
|
||||
if graph_util::get_resolution_error_bare_node_specifier(err).is_some() {
|
||||
if deno_resolver::graph::get_resolution_error_bare_node_specifier(err)
|
||||
.is_some()
|
||||
{
|
||||
"import-node-prefix-missing"
|
||||
} else {
|
||||
match err {
|
||||
|
@ -1384,7 +1381,7 @@ impl DenoDiagnostic {
|
|||
return Err(anyhow!(
|
||||
"Unsupported diagnostic code (\"{}\") provided.",
|
||||
code
|
||||
))
|
||||
));
|
||||
}
|
||||
};
|
||||
Ok(code_action)
|
||||
|
@ -1469,7 +1466,7 @@ impl DenoDiagnostic {
|
|||
(
|
||||
lsp::DiagnosticSeverity::ERROR,
|
||||
message,
|
||||
graph_util::get_resolution_error_bare_node_specifier(err)
|
||||
deno_resolver::graph::get_resolution_error_bare_node_specifier(err)
|
||||
.map(|specifier| json!({ "specifier": specifier }))
|
||||
)},
|
||||
Self::UnknownNodeSpecifier(specifier) => (lsp::DiagnosticSeverity::ERROR, format!("No such built-in module: node:{}", specifier.path()), None),
|
||||
|
@ -1568,7 +1565,6 @@ fn diagnose_resolution(
|
|||
snapshot: &language_server::StateSnapshot,
|
||||
dependency_key: &str,
|
||||
resolution: &Resolution,
|
||||
resolution_kind: ResolutionKind,
|
||||
is_dynamic: bool,
|
||||
maybe_assert_type: Option<&str>,
|
||||
referrer_module: &DocumentModule,
|
||||
|
@ -1589,100 +1585,127 @@ fn diagnose_resolution(
|
|||
diagnostics.push(DenoDiagnostic::DenoWarn(message.clone()));
|
||||
}
|
||||
}
|
||||
if let Some(module) = snapshot
|
||||
match snapshot
|
||||
.document_modules
|
||||
.module_for_specifier(specifier, referrer_module.scope.as_deref())
|
||||
{
|
||||
if let Some(headers) = &module.headers {
|
||||
if let Some(message) = headers.get("x-deno-warning") {
|
||||
diagnostics.push(DenoDiagnostic::DenoWarn(message.clone()));
|
||||
Some(module) => {
|
||||
if let Some(headers) = &module.headers {
|
||||
if let Some(message) = headers.get("x-deno-warning") {
|
||||
diagnostics.push(DenoDiagnostic::DenoWarn(message.clone()));
|
||||
}
|
||||
}
|
||||
if module.media_type == MediaType::Json {
|
||||
match maybe_assert_type {
|
||||
// The module has the correct assertion type, no diagnostic
|
||||
Some("json") => (),
|
||||
// The dynamic import statement is missing an attribute type, which
|
||||
// we might not be able to statically detect, therefore we will
|
||||
// not provide a potentially incorrect diagnostic.
|
||||
None if is_dynamic => (),
|
||||
// The module has an incorrect assertion type, diagnostic
|
||||
Some(assert_type) => diagnostics.push(
|
||||
DenoDiagnostic::InvalidAttributeType(assert_type.to_string()),
|
||||
),
|
||||
// The module is missing an attribute type, diagnostic
|
||||
None => diagnostics.push(DenoDiagnostic::NoAttributeType),
|
||||
}
|
||||
}
|
||||
}
|
||||
if module.media_type == MediaType::Json {
|
||||
match maybe_assert_type {
|
||||
// The module has the correct assertion type, no diagnostic
|
||||
Some("json") => (),
|
||||
// The dynamic import statement is missing an attribute type, which
|
||||
// we might not be able to statically detect, therefore we will
|
||||
// not provide a potentially incorrect diagnostic.
|
||||
None if is_dynamic => (),
|
||||
// The module has an incorrect assertion type, diagnostic
|
||||
Some(assert_type) => diagnostics.push(
|
||||
DenoDiagnostic::InvalidAttributeType(assert_type.to_string()),
|
||||
),
|
||||
// The module is missing an attribute type, diagnostic
|
||||
None => diagnostics.push(DenoDiagnostic::NoAttributeType),
|
||||
}
|
||||
}
|
||||
} else if let Ok(pkg_ref) =
|
||||
JsrPackageReqReference::from_specifier(specifier)
|
||||
{
|
||||
let req = pkg_ref.into_inner().req;
|
||||
diagnostics
|
||||
.push(DenoDiagnostic::NotInstalledJsr(req, specifier.clone()));
|
||||
} else if let Ok(pkg_ref) =
|
||||
NpmPackageReqReference::from_specifier(specifier)
|
||||
{
|
||||
if let Some(npm_resolver) = managed_npm_resolver {
|
||||
// show diagnostics for npm package references that aren't cached
|
||||
let req = pkg_ref.req();
|
||||
if !npm_resolver.is_pkg_req_folder_cached(req) {
|
||||
diagnostics.push(DenoDiagnostic::NotInstalledNpm(
|
||||
req.clone(),
|
||||
specifier.clone(),
|
||||
));
|
||||
} else if scoped_resolver
|
||||
.npm_to_file_url(
|
||||
&pkg_ref,
|
||||
&referrer_module.specifier,
|
||||
NodeResolutionKind::from_deno_graph(resolution_kind),
|
||||
referrer_module.resolution_mode,
|
||||
)
|
||||
.is_none()
|
||||
{
|
||||
diagnostics.push(DenoDiagnostic::NoExportNpm(pkg_ref.clone()));
|
||||
}
|
||||
}
|
||||
} else if let Some(module_name) = specifier.as_str().strip_prefix("node:")
|
||||
{
|
||||
if !deno_node::is_builtin_node_module(module_name) {
|
||||
diagnostics
|
||||
.push(DenoDiagnostic::UnknownNodeSpecifier(specifier.clone()));
|
||||
} else if module_name == dependency_key {
|
||||
let mut is_mapped = false;
|
||||
if let Some(import_map) = import_map {
|
||||
if let Resolution::Ok(resolved) = &resolution {
|
||||
if import_map.resolve(module_name, &resolved.specifier).is_ok() {
|
||||
is_mapped = true;
|
||||
_ => {
|
||||
match JsrPackageReqReference::from_specifier(specifier) {
|
||||
Ok(pkg_ref) => {
|
||||
let req = pkg_ref.into_inner().req;
|
||||
diagnostics
|
||||
.push(DenoDiagnostic::NotInstalledJsr(req, specifier.clone()));
|
||||
}
|
||||
_ => {
|
||||
match NpmPackageReqReference::from_specifier(specifier) {
|
||||
Ok(pkg_ref) => {
|
||||
if let Some(npm_resolver) = managed_npm_resolver {
|
||||
// show diagnostics for npm package references that aren't cached
|
||||
let req = pkg_ref.req();
|
||||
if !npm_resolver.is_pkg_req_folder_cached(req) {
|
||||
diagnostics.push(DenoDiagnostic::NotInstalledNpm(
|
||||
req.clone(),
|
||||
specifier.clone(),
|
||||
));
|
||||
} else {
|
||||
let resolution_kinds = [
|
||||
NodeResolutionKind::Types,
|
||||
NodeResolutionKind::Execution,
|
||||
];
|
||||
if resolution_kinds.into_iter().all(|k| {
|
||||
scoped_resolver
|
||||
.npm_to_file_url(
|
||||
&pkg_ref,
|
||||
&referrer_module.specifier,
|
||||
k,
|
||||
referrer_module.resolution_mode,
|
||||
)
|
||||
.is_none()
|
||||
}) {
|
||||
diagnostics
|
||||
.push(DenoDiagnostic::NoExportNpm(pkg_ref.clone()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if let Some(module_name) =
|
||||
specifier.as_str().strip_prefix("node:")
|
||||
{
|
||||
if !deno_node::is_builtin_node_module(module_name) {
|
||||
diagnostics.push(DenoDiagnostic::UnknownNodeSpecifier(
|
||||
specifier.clone(),
|
||||
));
|
||||
} else if module_name == dependency_key {
|
||||
let mut is_mapped = false;
|
||||
if let Some(import_map) = import_map {
|
||||
if let Resolution::Ok(resolved) = &resolution {
|
||||
if import_map
|
||||
.resolve(module_name, &resolved.specifier)
|
||||
.is_ok()
|
||||
{
|
||||
is_mapped = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// show diagnostics for bare node specifiers that aren't mapped by import map
|
||||
if !is_mapped {
|
||||
diagnostics.push(DenoDiagnostic::BareNodeSpecifier(
|
||||
module_name.to_string(),
|
||||
));
|
||||
}
|
||||
} else if let Some(npm_resolver) = managed_npm_resolver {
|
||||
// check that a @types/node package exists in the resolver
|
||||
let types_node_req =
|
||||
PackageReq::from_str("@types/node").unwrap();
|
||||
if !npm_resolver.is_pkg_req_folder_cached(&types_node_req)
|
||||
{
|
||||
diagnostics.push(DenoDiagnostic::NotInstalledNpm(
|
||||
types_node_req,
|
||||
ModuleSpecifier::parse("npm:@types/node").unwrap(),
|
||||
));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// When the document is not available, it means that it cannot be found
|
||||
// in the cache or locally on the disk, so we want to issue a diagnostic
|
||||
// about that.
|
||||
// these may be invalid, however, if this is an ambient module with
|
||||
// no real source (as in the case of a virtual module).
|
||||
let deno_diagnostic = match specifier.scheme() {
|
||||
"file" => DenoDiagnostic::NoLocal(specifier.clone()),
|
||||
_ => DenoDiagnostic::NoCache(specifier.clone()),
|
||||
};
|
||||
deferred_diagnostics.push(deno_diagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// show diagnostics for bare node specifiers that aren't mapped by import map
|
||||
if !is_mapped {
|
||||
diagnostics
|
||||
.push(DenoDiagnostic::BareNodeSpecifier(module_name.to_string()));
|
||||
}
|
||||
} else if let Some(npm_resolver) = managed_npm_resolver {
|
||||
// check that a @types/node package exists in the resolver
|
||||
let types_node_req = PackageReq::from_str("@types/node").unwrap();
|
||||
if !npm_resolver.is_pkg_req_folder_cached(&types_node_req) {
|
||||
diagnostics.push(DenoDiagnostic::NotInstalledNpm(
|
||||
types_node_req,
|
||||
ModuleSpecifier::parse("npm:@types/node").unwrap(),
|
||||
));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// When the document is not available, it means that it cannot be found
|
||||
// in the cache or locally on the disk, so we want to issue a diagnostic
|
||||
// about that.
|
||||
// these may be invalid, however, if this is an ambient module with
|
||||
// no real source (as in the case of a virtual module).
|
||||
let deno_diagnostic = match specifier.scheme() {
|
||||
"file" => DenoDiagnostic::NoLocal(specifier.clone()),
|
||||
_ => DenoDiagnostic::NoCache(specifier.clone()),
|
||||
};
|
||||
deferred_diagnostics.push(deno_diagnostic);
|
||||
}
|
||||
}
|
||||
// The specifier resolution resulted in an error, so we want to issue a
|
||||
|
@ -1763,9 +1786,7 @@ fn diagnose_dependency(
|
|||
.includes(i.specifier_range.range.start)
|
||||
.is_some()
|
||||
});
|
||||
let resolution;
|
||||
let resolution_kind;
|
||||
if dependency.maybe_code.is_none()
|
||||
let resolution = if dependency.maybe_code.is_none()
|
||||
// If not @ts-types, diagnose the types if the code errored because
|
||||
// it's likely resolving into the node_modules folder, which might be
|
||||
// erroring correctly due to resolution only being for bundlers. Let this
|
||||
|
@ -1773,17 +1794,14 @@ fn diagnose_dependency(
|
|||
|| !is_types_deno_types && matches!(dependency.maybe_type, Resolution::Ok(_))
|
||||
&& matches!(dependency.maybe_code, Resolution::Err(_))
|
||||
{
|
||||
resolution = &dependency.maybe_type;
|
||||
resolution_kind = ResolutionKind::Types;
|
||||
&dependency.maybe_type
|
||||
} else {
|
||||
resolution = &dependency.maybe_code;
|
||||
resolution_kind = ResolutionKind::Execution;
|
||||
&dependency.maybe_code
|
||||
};
|
||||
let (resolution_diagnostics, deferred) = diagnose_resolution(
|
||||
snapshot,
|
||||
dependency_key,
|
||||
resolution,
|
||||
resolution_kind,
|
||||
dependency.is_dynamic,
|
||||
dependency.maybe_attribute_type.as_deref(),
|
||||
referrer_module,
|
||||
|
@ -1819,7 +1837,6 @@ fn diagnose_dependency(
|
|||
snapshot,
|
||||
dependency_key,
|
||||
&dependency.maybe_type,
|
||||
ResolutionKind::Types,
|
||||
dependency.is_dynamic,
|
||||
dependency.maybe_attribute_type.as_deref(),
|
||||
referrer_module,
|
||||
|
|
|
@ -16,19 +16,19 @@ use std::sync::Weak;
|
|||
use std::time::SystemTime;
|
||||
|
||||
use dashmap::DashMap;
|
||||
use deno_ast::swc::ecma_visit::VisitWith;
|
||||
use deno_ast::MediaType;
|
||||
use deno_ast::ParsedSource;
|
||||
use deno_ast::SourceTextInfo;
|
||||
use deno_ast::swc::ecma_visit::VisitWith;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::futures::future;
|
||||
use deno_core::futures::future::Shared;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::parking_lot::RwLock;
|
||||
use deno_core::resolve_url;
|
||||
use deno_core::url::Position;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_graph::TypesDependency;
|
||||
use deno_path_util::url_to_file_path;
|
||||
|
@ -38,17 +38,17 @@ use deno_semver::npm::NpmPackageReqReference;
|
|||
use indexmap::IndexMap;
|
||||
use indexmap::IndexSet;
|
||||
use lsp_types::Uri;
|
||||
use node_resolver::cache::NodeResolutionThreadLocalCache;
|
||||
use node_resolver::NodeResolutionKind;
|
||||
use node_resolver::ResolutionMode;
|
||||
use node_resolver::cache::NodeResolutionThreadLocalCache;
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::Serialize;
|
||||
use tower_lsp::lsp_types as lsp;
|
||||
use weak_table::PtrWeakKeyHashMap;
|
||||
use weak_table::WeakValueHashMap;
|
||||
|
||||
use super::cache::calculate_fs_version_at_path;
|
||||
use super::cache::LspCache;
|
||||
use super::cache::calculate_fs_version_at_path;
|
||||
use super::config::Config;
|
||||
use super::logging::lsp_warn;
|
||||
use super::resolver::LspResolver;
|
||||
|
@ -59,12 +59,12 @@ use super::testing::TestModule;
|
|||
use super::text::LineIndex;
|
||||
use super::tsc::ChangeKind;
|
||||
use super::tsc::NavigationTree;
|
||||
use super::urls::COMPONENT;
|
||||
use super::urls::normalize_uri;
|
||||
use super::urls::uri_is_file_like;
|
||||
use super::urls::uri_to_file_path;
|
||||
use super::urls::uri_to_url;
|
||||
use super::urls::url_to_uri;
|
||||
use super::urls::COMPONENT;
|
||||
use crate::graph_util::CliJsrUrlProvider;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -197,7 +197,7 @@ fn data_url_to_uri(url: &Url) -> Option<Uri> {
|
|||
file_name_str.push('?');
|
||||
file_name_str.push_str(query);
|
||||
}
|
||||
let hash = deno_lib::util::checksum::gen(&[file_name_str.as_bytes()]);
|
||||
let hash = deno_lib::util::checksum::r#gen(&[file_name_str.as_bytes()]);
|
||||
Uri::from_str(&format!("deno:/data_url/{hash}{extension}",))
|
||||
.inspect_err(|err| {
|
||||
lsp_warn!("Couldn't convert data url \"{url}\" to URI: {err}")
|
||||
|
@ -410,7 +410,7 @@ pub static ASSET_DOCUMENTS: Lazy<AssetDocuments> =
|
|||
inner: crate::tsc::LAZILY_LOADED_STATIC_ASSETS
|
||||
.iter()
|
||||
.map(|(k, v)| {
|
||||
let doc = Arc::new(ServerDocument::asset(k, v.as_str()));
|
||||
let doc = Arc::new(ServerDocument::asset(k, v.source.as_str()));
|
||||
let uri = doc.uri.clone();
|
||||
(uri, doc)
|
||||
})
|
||||
|
@ -702,12 +702,16 @@ impl Documents {
|
|||
if let Some(doc) = self.server.get(&uri) {
|
||||
return Some(Document::Server(doc.clone()));
|
||||
}
|
||||
let doc = if let Some(doc) = ServerDocument::load(&uri) {
|
||||
doc
|
||||
} else if let Some(data_url) = self.data_urls_by_uri.get(&uri) {
|
||||
ServerDocument::data_url(&uri, data_url.value().clone())?
|
||||
} else {
|
||||
return None;
|
||||
let doc = match ServerDocument::load(&uri) {
|
||||
Some(doc) => doc,
|
||||
_ => match self.data_urls_by_uri.get(&uri) {
|
||||
Some(data_url) => {
|
||||
ServerDocument::data_url(&uri, data_url.value().clone())?
|
||||
}
|
||||
_ => {
|
||||
return None;
|
||||
}
|
||||
},
|
||||
};
|
||||
let doc = Arc::new(doc);
|
||||
self.server.insert(uri.into_owned(), doc.clone());
|
||||
|
@ -1221,12 +1225,11 @@ impl DocumentModules {
|
|||
scope: Option<&Url>,
|
||||
) -> Option<Arc<DocumentModule>> {
|
||||
let scoped_resolver = self.resolver.get_scoped_resolver(scope);
|
||||
let specifier = if let Ok(jsr_req_ref) =
|
||||
JsrPackageReqReference::from_specifier(specifier)
|
||||
{
|
||||
Cow::Owned(scoped_resolver.jsr_to_resource_url(&jsr_req_ref)?)
|
||||
} else {
|
||||
Cow::Borrowed(specifier)
|
||||
let specifier = match JsrPackageReqReference::from_specifier(specifier) {
|
||||
Ok(jsr_req_ref) => {
|
||||
Cow::Owned(scoped_resolver.jsr_to_resource_url(&jsr_req_ref)?)
|
||||
}
|
||||
_ => Cow::Borrowed(specifier),
|
||||
};
|
||||
let specifier = scoped_resolver.resolve_redirects(&specifier)?;
|
||||
let document =
|
||||
|
@ -1322,12 +1325,11 @@ impl DocumentModules {
|
|||
scope: Option<&Url>,
|
||||
) -> Option<Arc<DocumentModule>> {
|
||||
let scoped_resolver = self.resolver.get_scoped_resolver(scope);
|
||||
let specifier = if let Ok(jsr_req_ref) =
|
||||
JsrPackageReqReference::from_specifier(specifier)
|
||||
{
|
||||
Cow::Owned(scoped_resolver.jsr_to_resource_url(&jsr_req_ref)?)
|
||||
} else {
|
||||
Cow::Borrowed(specifier)
|
||||
let specifier = match JsrPackageReqReference::from_specifier(specifier) {
|
||||
Ok(jsr_req_ref) => {
|
||||
Cow::Owned(scoped_resolver.jsr_to_resource_url(&jsr_req_ref)?)
|
||||
}
|
||||
_ => Cow::Borrowed(specifier),
|
||||
};
|
||||
let specifier = scoped_resolver.resolve_redirects(&specifier)?;
|
||||
let modules = self.modules_for_scope(scope)?;
|
||||
|
@ -1601,21 +1603,26 @@ impl DocumentModules {
|
|||
} else {
|
||||
results.push(None);
|
||||
}
|
||||
} else if let Ok(specifier) = scoped_resolver.as_cli_resolver().resolve(
|
||||
raw_specifier,
|
||||
referrer,
|
||||
deno_graph::Position::zeroed(),
|
||||
resolution_mode,
|
||||
NodeResolutionKind::Types,
|
||||
) {
|
||||
results.push(self.resolve_dependency(
|
||||
&specifier,
|
||||
referrer,
|
||||
resolution_mode,
|
||||
scope,
|
||||
));
|
||||
} else {
|
||||
results.push(None);
|
||||
match scoped_resolver.as_cli_resolver().resolve(
|
||||
raw_specifier,
|
||||
referrer,
|
||||
deno_graph::Position::zeroed(),
|
||||
resolution_mode,
|
||||
NodeResolutionKind::Types,
|
||||
) {
|
||||
Ok(specifier) => {
|
||||
results.push(self.resolve_dependency(
|
||||
&specifier,
|
||||
referrer,
|
||||
resolution_mode,
|
||||
scope,
|
||||
));
|
||||
}
|
||||
_ => {
|
||||
results.push(None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
results
|
||||
|
@ -1998,11 +2005,12 @@ fn analyze_module(
|
|||
}
|
||||
Err(diagnostic) => (
|
||||
Err(deno_graph::ModuleGraphError::ModuleError(
|
||||
deno_graph::ModuleError::Parse {
|
||||
deno_graph::ModuleErrorKind::Parse {
|
||||
specifier,
|
||||
mtime: None,
|
||||
diagnostic: Arc::new(JsErrorBox::from_err(diagnostic.clone())),
|
||||
},
|
||||
}
|
||||
.into_box(),
|
||||
)),
|
||||
ResolutionMode::Import,
|
||||
),
|
||||
|
|
|
@ -9,15 +9,15 @@ use deno_core::anyhow::anyhow;
|
|||
use deno_core::error::AnyError;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::url::Url;
|
||||
use deno_graph::ModuleSpecifier;
|
||||
use deno_graph::packages::JsrPackageInfo;
|
||||
use deno_graph::packages::JsrPackageInfoVersion;
|
||||
use deno_graph::packages::JsrPackageVersionInfo;
|
||||
use deno_graph::ModuleSpecifier;
|
||||
use deno_semver::StackString;
|
||||
use deno_semver::Version;
|
||||
use deno_semver::jsr::JsrPackageReqReference;
|
||||
use deno_semver::package::PackageNv;
|
||||
use deno_semver::package::PackageReq;
|
||||
use deno_semver::StackString;
|
||||
use deno_semver::Version;
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::config::ConfigData;
|
||||
|
@ -26,8 +26,8 @@ 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 crate::jsr::partial_jsr_package_version_info_from_slice;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct WorkspacePackage {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::HashMap;
|
||||
|
@ -13,27 +14,27 @@ use std::str::FromStr;
|
|||
use std::sync::Arc;
|
||||
|
||||
use deno_ast::MediaType;
|
||||
use deno_cache_dir::file_fetcher::CacheSetting;
|
||||
use deno_cache_dir::GlobalOrLocalHttpCache;
|
||||
use deno_cache_dir::file_fetcher::CacheSetting;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_json::Value;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::unsync::spawn;
|
||||
use deno_core::url;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_graph::CheckJsOption;
|
||||
use deno_graph::GraphKind;
|
||||
use deno_graph::Resolution;
|
||||
use deno_lib::args::get_root_cert_store;
|
||||
use deno_lib::args::CaData;
|
||||
use deno_lib::args::get_root_cert_store;
|
||||
use deno_lib::version::DENO_VERSION_INFO;
|
||||
use deno_npm_installer::graph::NpmCachingStrategy;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use deno_runtime::deno_tls::rustls::RootCertStore;
|
||||
use deno_runtime::deno_tls::RootCertStoreProvider;
|
||||
use deno_runtime::deno_tls::rustls::RootCertStore;
|
||||
use deno_semver::jsr::JsrPackageReqReference;
|
||||
use indexmap::Equivalent;
|
||||
use indexmap::IndexMap;
|
||||
|
@ -43,20 +44,20 @@ use node_resolver::NodeResolutionKind;
|
|||
use node_resolver::ResolutionMode;
|
||||
use serde::Deserialize;
|
||||
use serde_json::from_value;
|
||||
use tokio::sync::mpsc::unbounded_channel;
|
||||
use tokio::sync::mpsc::UnboundedReceiver;
|
||||
use tokio::sync::mpsc::UnboundedSender;
|
||||
use tokio::sync::mpsc::unbounded_channel;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tower_lsp::jsonrpc::Error as LspError;
|
||||
use tower_lsp::jsonrpc::Result as LspResult;
|
||||
use tower_lsp::lsp_types::request::*;
|
||||
use tower_lsp::lsp_types::*;
|
||||
|
||||
use super::analysis::fix_ts_import_changes;
|
||||
use super::analysis::ts_changes_to_edit;
|
||||
use super::analysis::CodeActionCollection;
|
||||
use super::analysis::CodeActionData;
|
||||
use super::analysis::TsResponseImportMapper;
|
||||
use super::analysis::fix_ts_import_changes;
|
||||
use super::analysis::ts_changes_to_edit;
|
||||
use super::cache::LspCache;
|
||||
use super::capabilities;
|
||||
use super::capabilities::semantic_tokens_registration_options;
|
||||
|
@ -64,9 +65,9 @@ use super::client::Client;
|
|||
use super::code_lens;
|
||||
use super::completions;
|
||||
use super::config::Config;
|
||||
use super::config::SETTINGS_SECTION;
|
||||
use super::config::UpdateImportsOnFileMoveEnabled;
|
||||
use super::config::WorkspaceSettings;
|
||||
use super::config::SETTINGS_SECTION;
|
||||
use super::diagnostics;
|
||||
use super::diagnostics::DiagnosticDataSpecifier;
|
||||
use super::diagnostics::DiagnosticServerUpdateMessage;
|
||||
|
@ -99,8 +100,8 @@ use crate::args::Flags;
|
|||
use crate::args::InternalFlags;
|
||||
use crate::args::UnstableFmtOptions;
|
||||
use crate::factory::CliFactory;
|
||||
use crate::file_fetcher::create_cli_file_fetcher;
|
||||
use crate::file_fetcher::CreateCliFileFetcherOptions;
|
||||
use crate::file_fetcher::create_cli_file_fetcher;
|
||||
use crate::graph_util;
|
||||
use crate::http_util::HttpClientProvider;
|
||||
use crate::lsp::config::ConfigWatchedFileType;
|
||||
|
@ -1797,7 +1798,10 @@ impl Inner {
|
|||
});
|
||||
format_file(
|
||||
&file_path,
|
||||
&document.text(),
|
||||
&crate::tools::fmt::FileContents {
|
||||
text: Cow::Borrowed(document.text().as_ref()),
|
||||
had_bom: false,
|
||||
},
|
||||
&fmt_options,
|
||||
&unstable_options,
|
||||
ext,
|
||||
|
@ -1866,35 +1870,48 @@ impl Inner {
|
|||
.map(|d| &d.dependency)
|
||||
.unwrap_or(&Resolution::None)
|
||||
});
|
||||
let value = match (dep.maybe_code.is_none(), dep.maybe_type.is_none(), &dep_types_dependency) {
|
||||
let value = match (
|
||||
dep.maybe_code.is_none(),
|
||||
dep.maybe_type.is_none(),
|
||||
&dep_types_dependency,
|
||||
) {
|
||||
(false, false, None) => format!(
|
||||
"**Resolved Dependency**\n\n**Code**: {}\n\n**Types**: {}\n",
|
||||
self.resolution_to_hover_text(&dep.maybe_code, module.scope.as_deref()),
|
||||
self.resolution_to_hover_text(&dep.maybe_type, module.scope.as_deref()),
|
||||
self
|
||||
.resolution_to_hover_text(&dep.maybe_code, module.scope.as_deref()),
|
||||
self
|
||||
.resolution_to_hover_text(&dep.maybe_type, module.scope.as_deref()),
|
||||
),
|
||||
(false, false, Some(types_dep)) if !types_dep.is_none() => format!(
|
||||
"**Resolved Dependency**\n\n**Code**: {}\n**Types**: {}\n**Import Types**: {}\n",
|
||||
self.resolution_to_hover_text(&dep.maybe_code, module.scope.as_deref()),
|
||||
self.resolution_to_hover_text(&dep.maybe_type, module.scope.as_deref()),
|
||||
self
|
||||
.resolution_to_hover_text(&dep.maybe_code, module.scope.as_deref()),
|
||||
self
|
||||
.resolution_to_hover_text(&dep.maybe_type, module.scope.as_deref()),
|
||||
self.resolution_to_hover_text(types_dep, module.scope.as_deref()),
|
||||
),
|
||||
(false, false, Some(_)) => format!(
|
||||
"**Resolved Dependency**\n\n**Code**: {}\n\n**Types**: {}\n",
|
||||
self.resolution_to_hover_text(&dep.maybe_code, module.scope.as_deref()),
|
||||
self.resolution_to_hover_text(&dep.maybe_type, module.scope.as_deref()),
|
||||
self
|
||||
.resolution_to_hover_text(&dep.maybe_code, module.scope.as_deref()),
|
||||
self
|
||||
.resolution_to_hover_text(&dep.maybe_type, module.scope.as_deref()),
|
||||
),
|
||||
(false, true, Some(types_dep)) if !types_dep.is_none() => format!(
|
||||
"**Resolved Dependency**\n\n**Code**: {}\n\n**Types**: {}\n",
|
||||
self.resolution_to_hover_text(&dep.maybe_code, module.scope.as_deref()),
|
||||
self
|
||||
.resolution_to_hover_text(&dep.maybe_code, module.scope.as_deref()),
|
||||
self.resolution_to_hover_text(types_dep, module.scope.as_deref()),
|
||||
),
|
||||
(false, true, _) => format!(
|
||||
"**Resolved Dependency**\n\n**Code**: {}\n",
|
||||
self.resolution_to_hover_text(&dep.maybe_code, module.scope.as_deref()),
|
||||
self
|
||||
.resolution_to_hover_text(&dep.maybe_code, module.scope.as_deref()),
|
||||
),
|
||||
(true, false, _) => format!(
|
||||
"**Resolved Dependency**\n\n**Types**: {}\n",
|
||||
self.resolution_to_hover_text(&dep.maybe_type, module.scope.as_deref()),
|
||||
self
|
||||
.resolution_to_hover_text(&dep.maybe_type, module.scope.as_deref()),
|
||||
),
|
||||
(true, true, _) => unreachable!("{}", json!(params)),
|
||||
};
|
||||
|
@ -2359,7 +2376,11 @@ impl Inner {
|
|||
if token.is_cancelled() {
|
||||
return Err(LspError::request_cancelled());
|
||||
} else {
|
||||
lsp_warn!("Unable to get refactor edit info from TypeScript: {:#}\nCode action data: {:#}", err, json!(&action_data));
|
||||
lsp_warn!(
|
||||
"Unable to get refactor edit info from TypeScript: {:#}\nCode action data: {:#}",
|
||||
err,
|
||||
json!(&action_data)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4780,19 +4801,22 @@ impl Inner {
|
|||
}
|
||||
|
||||
Some(contents)
|
||||
} else if let Some(document) = self.get_document(
|
||||
¶ms.text_document.uri,
|
||||
Enabled::Ignore,
|
||||
Exists::Filter,
|
||||
Diagnosable::Ignore,
|
||||
)? {
|
||||
Some(document.text().to_string())
|
||||
} else {
|
||||
lsp_warn!(
|
||||
"The document was not found: {}",
|
||||
params.text_document.uri.as_str()
|
||||
);
|
||||
None
|
||||
match self.get_document(
|
||||
¶ms.text_document.uri,
|
||||
Enabled::Ignore,
|
||||
Exists::Filter,
|
||||
Diagnosable::Ignore,
|
||||
)? {
|
||||
Some(document) => Some(document.text().to_string()),
|
||||
_ => {
|
||||
lsp_warn!(
|
||||
"The document was not found: {}",
|
||||
params.text_document.uri.as_str()
|
||||
);
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
self.performance.measure(mark);
|
||||
Ok(contents)
|
||||
|
|
|
@ -72,9 +72,11 @@ pub fn init_log_file(enabled: bool) {
|
|||
LOG_FILE.buffer.lock().clear();
|
||||
return;
|
||||
};
|
||||
thread::spawn(move || loop {
|
||||
LOG_FILE.commit(&path);
|
||||
thread::sleep(std::time::Duration::from_secs(1));
|
||||
thread::spawn(move || {
|
||||
loop {
|
||||
LOG_FILE.commit(&path);
|
||||
thread::sleep(std::time::Duration::from_secs(1));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ use deno_core::error::AnyError;
|
|||
use deno_core::serde_json;
|
||||
use deno_core::url::Url;
|
||||
use deno_npm::npm_rc::NpmRc;
|
||||
use deno_semver::package::PackageNv;
|
||||
use deno_semver::Version;
|
||||
use deno_semver::package::PackageNv;
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::Deserialize;
|
||||
|
||||
|
|
|
@ -7,11 +7,13 @@ use std::time::Duration;
|
|||
/// it will terminate the current process.
|
||||
pub fn start(parent_process_id: u32) {
|
||||
// use a separate thread in case the runtime gets hung up
|
||||
std::thread::spawn(move || loop {
|
||||
std::thread::sleep(Duration::from_secs(10));
|
||||
std::thread::spawn(move || {
|
||||
loop {
|
||||
std::thread::sleep(Duration::from_secs(10));
|
||||
|
||||
if !is_process_active(parent_process_id) {
|
||||
deno_runtime::exit(1);
|
||||
if !is_process_active(parent_process_id) {
|
||||
deno_runtime::exit(1);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -875,13 +875,27 @@ mod tests {
|
|||
);
|
||||
let actual = result.unwrap();
|
||||
if let Some((text, start, end)) = *expected {
|
||||
assert!(actual.is_some(), "Match failure for path \"{path}\" and fixture \"{fixture}\". Expected Some got None");
|
||||
assert!(
|
||||
actual.is_some(),
|
||||
"Match failure for path \"{path}\" and fixture \"{fixture}\". Expected Some got None"
|
||||
);
|
||||
let actual = actual.unwrap();
|
||||
assert_eq!(actual.as_str(), text, "Match failure for path \"{}\" and fixture \"{}\". Expected \"{}\" got \"{}\".", path, fixture, text, actual.as_str());
|
||||
assert_eq!(
|
||||
actual.as_str(),
|
||||
text,
|
||||
"Match failure for path \"{}\" and fixture \"{}\". Expected \"{}\" got \"{}\".",
|
||||
path,
|
||||
fixture,
|
||||
text,
|
||||
actual.as_str()
|
||||
);
|
||||
assert_eq!(actual.start(), start);
|
||||
assert_eq!(actual.end(), end);
|
||||
} else {
|
||||
assert!(actual.is_none(), "Match failure for path \"{path}\" and fixture \"{fixture}\". Expected None got {actual:?}");
|
||||
assert!(
|
||||
actual.is_none(),
|
||||
"Match failure for path \"{path}\" and fixture \"{fixture}\". Expected None got {actual:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,16 +6,16 @@ use std::path::PathBuf;
|
|||
use std::sync::Arc;
|
||||
|
||||
use deno_cache_dir::file_fetcher::CacheSetting;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::serde::Deserialize;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_json::Value;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::url::ParseError;
|
||||
use deno_core::url::Position;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_graph::Dependency;
|
||||
use deno_resolver::file_fetcher::FetchOptions;
|
||||
use deno_resolver::file_fetcher::FetchPermissionsOptionRef;
|
||||
|
@ -25,8 +25,6 @@ use tower_lsp::lsp_types as lsp;
|
|||
|
||||
use super::completions::IMPORT_COMMIT_CHARS;
|
||||
use super::logging::lsp_log;
|
||||
use super::path_to_regex::parse;
|
||||
use super::path_to_regex::string_to_regex;
|
||||
use super::path_to_regex::Compiler;
|
||||
use super::path_to_regex::Key;
|
||||
use super::path_to_regex::MatchResult;
|
||||
|
@ -34,12 +32,14 @@ use super::path_to_regex::Matcher;
|
|||
use super::path_to_regex::StringOrNumber;
|
||||
use super::path_to_regex::StringOrVec;
|
||||
use super::path_to_regex::Token;
|
||||
use super::path_to_regex::parse;
|
||||
use super::path_to_regex::string_to_regex;
|
||||
use crate::cache::GlobalHttpCache;
|
||||
use crate::cache::HttpCache;
|
||||
use crate::file_fetcher::create_cli_file_fetcher;
|
||||
use crate::file_fetcher::CliFileFetcher;
|
||||
use crate::file_fetcher::CreateCliFileFetcherOptions;
|
||||
use crate::file_fetcher::TextDecodedFile;
|
||||
use crate::file_fetcher::create_cli_file_fetcher;
|
||||
use crate::http_util::HttpClientProvider;
|
||||
use crate::sys::CliSys;
|
||||
|
||||
|
@ -322,7 +322,11 @@ fn validate_config(config: &RegistryConfigurationJson) -> Result<(), AnyError> {
|
|||
.map(|var| var.key.to_owned())
|
||||
.any(|x| x == *key_name)
|
||||
{
|
||||
return Err(anyhow!("Invalid registry configuration. Registry with schema \"{}\" is missing variable declaration for key \"{}\".", registry.schema, key_name));
|
||||
return Err(anyhow!(
|
||||
"Invalid registry configuration. Registry with schema \"{}\" is missing variable declaration for key \"{}\".",
|
||||
registry.schema,
|
||||
key_name
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,13 +338,27 @@ fn validate_config(config: &RegistryConfigurationJson) -> Result<(), AnyError> {
|
|||
let limited_keys = key_names.get(0..key_index).unwrap();
|
||||
for v in replacement_variables {
|
||||
if variable.key == v && config.version == 1 {
|
||||
return Err(anyhow!("Invalid registry configuration. Url \"{}\" (for variable \"{}\" in registry with schema \"{}\") uses variable \"{}\", which is not allowed because that would be a self reference.", variable.url, variable.key, registry.schema, v));
|
||||
return Err(anyhow!(
|
||||
"Invalid registry configuration. Url \"{}\" (for variable \"{}\" in registry with schema \"{}\") uses variable \"{}\", which is not allowed because that would be a self reference.",
|
||||
variable.url,
|
||||
variable.key,
|
||||
registry.schema,
|
||||
v
|
||||
));
|
||||
}
|
||||
|
||||
let key_index = limited_keys.iter().position(|key| key == &v);
|
||||
|
||||
if key_index.is_none() && variable.key != v {
|
||||
return Err(anyhow!("Invalid registry configuration. Url \"{}\" (for variable \"{}\" in registry with schema \"{}\") uses variable \"{}\", which is not allowed because the schema defines \"{}\" to the right of \"{}\".", variable.url, variable.key, registry.schema, v, v, variable.key));
|
||||
return Err(anyhow!(
|
||||
"Invalid registry configuration. Url \"{}\" (for variable \"{}\" in registry with schema \"{}\") uses variable \"{}\", which is not allowed because the schema defines \"{}\" to the right of \"{}\".",
|
||||
variable.url,
|
||||
variable.key,
|
||||
registry.schema,
|
||||
v,
|
||||
v,
|
||||
variable.key
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1113,11 +1131,13 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_validate_registry_configuration() {
|
||||
assert!(validate_config(&RegistryConfigurationJson {
|
||||
version: 3,
|
||||
registries: vec![],
|
||||
})
|
||||
.is_err());
|
||||
assert!(
|
||||
validate_config(&RegistryConfigurationJson {
|
||||
version: 3,
|
||||
registries: vec![],
|
||||
})
|
||||
.is_err()
|
||||
);
|
||||
|
||||
let cfg = RegistryConfigurationJson {
|
||||
version: 1,
|
||||
|
|
|
@ -10,6 +10,7 @@ use deno_core::error::AnyError;
|
|||
use deno_core::serde_json;
|
||||
use lsp_types::Uri;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tower_lsp::LanguageServer;
|
||||
use tower_lsp::lsp_types::ClientCapabilities;
|
||||
use tower_lsp::lsp_types::ClientInfo;
|
||||
use tower_lsp::lsp_types::CompletionContext;
|
||||
|
@ -31,7 +32,6 @@ use tower_lsp::lsp_types::TextDocumentItem;
|
|||
use tower_lsp::lsp_types::TextDocumentPositionParams;
|
||||
use tower_lsp::lsp_types::VersionedTextDocumentIdentifier;
|
||||
use tower_lsp::lsp_types::WorkDoneProgressParams;
|
||||
use tower_lsp::LanguageServer;
|
||||
|
||||
use super::client::Client;
|
||||
use super::config::ClassMemberSnippets;
|
||||
|
|
|
@ -9,8 +9,8 @@ use std::sync::Arc;
|
|||
|
||||
use dashmap::DashMap;
|
||||
use deno_ast::MediaType;
|
||||
use deno_cache_dir::npm::NpmCacheDir;
|
||||
use deno_cache_dir::HttpCache;
|
||||
use deno_cache_dir::npm::NpmCacheDir;
|
||||
use deno_config::workspace::JsxImportSourceConfig;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::url::Url;
|
||||
|
@ -20,27 +20,27 @@ use deno_graph::ModuleSpecifier;
|
|||
use deno_graph::Range;
|
||||
use deno_npm::NpmSystemInfo;
|
||||
use deno_npm_cache::TarballCache;
|
||||
use deno_npm_installer::LifecycleScriptsConfig;
|
||||
use deno_npm_installer::initializer::NpmResolutionInitializer;
|
||||
use deno_npm_installer::initializer::NpmResolverManagedSnapshotOption;
|
||||
use deno_npm_installer::lifecycle_scripts::NullLifecycleScriptsExecutor;
|
||||
use deno_npm_installer::package_json::NpmInstallDepsProvider;
|
||||
use deno_npm_installer::resolution::NpmResolutionInstaller;
|
||||
use deno_npm_installer::LifecycleScriptsConfig;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use deno_resolver::DenoResolverOptions;
|
||||
use deno_resolver::NodeAndNpmResolvers;
|
||||
use deno_resolver::cjs::IsCjsResolutionMode;
|
||||
use deno_resolver::graph::FoundPackageJsonDepFlag;
|
||||
use deno_resolver::npm::managed::ManagedInNpmPkgCheckerCreateOptions;
|
||||
use deno_resolver::npm::managed::ManagedNpmResolverCreateOptions;
|
||||
use deno_resolver::npm::managed::NpmResolutionCell;
|
||||
use deno_resolver::npm::CreateInNpmPkgCheckerOptions;
|
||||
use deno_resolver::npm::DenoInNpmPackageChecker;
|
||||
use deno_resolver::npm::NpmReqResolverOptions;
|
||||
use deno_resolver::npm::managed::ManagedInNpmPkgCheckerCreateOptions;
|
||||
use deno_resolver::npm::managed::ManagedNpmResolverCreateOptions;
|
||||
use deno_resolver::npm::managed::NpmResolutionCell;
|
||||
use deno_resolver::npmrc::create_default_npmrc;
|
||||
use deno_resolver::workspace::PackageJsonDepResolution;
|
||||
use deno_resolver::workspace::WorkspaceNpmLinkPackages;
|
||||
use deno_resolver::workspace::WorkspaceResolver;
|
||||
use deno_resolver::DenoResolverOptions;
|
||||
use deno_resolver::NodeAndNpmResolvers;
|
||||
use deno_runtime::tokio_util::create_basic_runtime;
|
||||
use deno_semver::jsr::JsrPackageReqReference;
|
||||
use deno_semver::npm::NpmPackageReqReference;
|
||||
|
@ -48,14 +48,14 @@ use deno_semver::package::PackageNv;
|
|||
use deno_semver::package::PackageReq;
|
||||
use import_map::ImportMap;
|
||||
use indexmap::IndexMap;
|
||||
use node_resolver::cache::NodeResolutionSys;
|
||||
use node_resolver::cache::NodeResolutionThreadLocalCache;
|
||||
use node_resolver::DenoIsBuiltInNodeModuleChecker;
|
||||
use node_resolver::NodeResolutionKind;
|
||||
use node_resolver::NodeResolverOptions;
|
||||
use node_resolver::PackageJson;
|
||||
use node_resolver::PackageJsonThreadLocalCache;
|
||||
use node_resolver::ResolutionMode;
|
||||
use node_resolver::cache::NodeResolutionSys;
|
||||
use node_resolver::cache::NodeResolutionThreadLocalCache;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use super::cache::LspCache;
|
||||
|
@ -78,10 +78,10 @@ use crate::npm::CliNpmInstaller;
|
|||
use crate::npm::CliNpmRegistryInfoProvider;
|
||||
use crate::npm::CliNpmResolver;
|
||||
use crate::npm::CliNpmResolverCreateOptions;
|
||||
use crate::resolver::on_resolve_diagnostic;
|
||||
use crate::resolver::CliIsCjsResolver;
|
||||
use crate::resolver::CliNpmReqResolver;
|
||||
use crate::resolver::CliResolver;
|
||||
use crate::resolver::on_resolve_diagnostic;
|
||||
use crate::sys::CliSys;
|
||||
use crate::tsc::into_specifier_and_media_type;
|
||||
use crate::util::progress_bar::ProgressBar;
|
||||
|
@ -950,7 +950,7 @@ impl<'a> ResolverFactory<'a> {
|
|||
Arc::new(NullLifecycleScriptsExecutor),
|
||||
npm_cache.clone(),
|
||||
Arc::new(NpmInstallDepsProvider::empty()),
|
||||
Arc::new(registry_info_provider.as_npm_registry_api()),
|
||||
registry_info_provider.clone(),
|
||||
self.services.npm_resolution.clone(),
|
||||
npm_resolution_initializer.clone(),
|
||||
npm_resolution_installer,
|
||||
|
|
|
@ -3,15 +3,15 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_semver::package::PackageNv;
|
||||
use deno_semver::Version;
|
||||
use deno_semver::package::PackageNv;
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
pub trait PackageSearchApi {
|
||||
async fn search(&self, query: &str) -> Result<Arc<Vec<String>>, AnyError>;
|
||||
async fn versions(&self, name: &str) -> Result<Arc<Vec<Version>>, AnyError>;
|
||||
async fn exports(&self, nv: &PackageNv)
|
||||
-> Result<Arc<Vec<String>>, AnyError>;
|
||||
-> Result<Arc<Vec<String>>, AnyError>;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
|
||||
use deno_ast::SourceRangedForSpanned;
|
||||
use deno_ast::SourceTextInfo;
|
||||
use deno_ast::swc::ast;
|
||||
use deno_ast::swc::ecma_visit::Visit;
|
||||
use deno_ast::swc::ecma_visit::VisitWith;
|
||||
use deno_ast::SourceRangedForSpanned;
|
||||
use deno_ast::SourceTextInfo;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use lsp::Range;
|
||||
use tower_lsp::lsp_types as lsp;
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_lib::util::checksum;
|
||||
use lsp::Range;
|
||||
use tower_lsp::lsp_types as lsp;
|
||||
|
@ -56,7 +56,11 @@ impl TestModule {
|
|||
let parent = match self.defs.get(parent_id) {
|
||||
Some(d) => d,
|
||||
None => {
|
||||
lsp_warn!("Internal Error: parent_id \"{}\" of test \"{}\" was not registered.", parent_id, &name);
|
||||
lsp_warn!(
|
||||
"Internal Error: parent_id \"{}\" of test \"{}\" was not registered.",
|
||||
parent_id,
|
||||
&name
|
||||
);
|
||||
id_components.push("<unknown>".as_bytes());
|
||||
break;
|
||||
}
|
||||
|
@ -66,7 +70,7 @@ impl TestModule {
|
|||
}
|
||||
id_components.push(self.specifier.as_str().as_bytes());
|
||||
id_components.reverse();
|
||||
let id = checksum::gen(&id_components);
|
||||
let id = checksum::r#gen(&id_components);
|
||||
if self.defs.contains_key(&id) {
|
||||
return (id, false);
|
||||
}
|
||||
|
|
|
@ -7,16 +7,16 @@ use std::sync::Arc;
|
|||
use std::time::Duration;
|
||||
use std::time::Instant;
|
||||
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::JsError;
|
||||
use deno_core::futures::StreamExt;
|
||||
use deno_core::futures::future;
|
||||
use deno_core::futures::stream;
|
||||
use deno_core::futures::StreamExt;
|
||||
use deno_core::parking_lot::RwLock;
|
||||
use deno_core::unsync::spawn;
|
||||
use deno_core::unsync::spawn_blocking;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_runtime::deno_permissions::Permissions;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
use deno_runtime::tokio_util::create_and_run_current_thread;
|
||||
|
@ -28,9 +28,9 @@ use super::definitions::TestDefinition;
|
|||
use super::definitions::TestModule;
|
||||
use super::lsp_custom;
|
||||
use super::server::TestServerTests;
|
||||
use crate::args::DenoSubcommand;
|
||||
use crate::args::flags_from_vec;
|
||||
use crate::args::parallelism_count;
|
||||
use crate::args::DenoSubcommand;
|
||||
use crate::factory::CliFactory;
|
||||
use crate::lsp::client::Client;
|
||||
use crate::lsp::client::TestingNotification;
|
||||
|
@ -40,10 +40,10 @@ use crate::lsp::urls::uri_parse_unencoded;
|
|||
use crate::lsp::urls::uri_to_url;
|
||||
use crate::lsp::urls::url_to_uri;
|
||||
use crate::tools::test;
|
||||
use crate::tools::test::create_test_event_channel;
|
||||
use crate::tools::test::FailFastTracker;
|
||||
use crate::tools::test::TestFailure;
|
||||
use crate::tools::test::TestFailureFormatOptions;
|
||||
use crate::tools::test::create_test_event_channel;
|
||||
|
||||
/// Logic to convert a test request into a set of test modules to be tested and
|
||||
/// any filters to be applied to those tests
|
||||
|
@ -316,6 +316,8 @@ impl TestRun {
|
|||
worker_factory,
|
||||
permissions_container,
|
||||
specifier,
|
||||
// Executing tests in the LSP currently doesn't support preload option
|
||||
vec![],
|
||||
worker_sender,
|
||||
fail_fast_tracker,
|
||||
test::TestSpecifierOptions {
|
||||
|
@ -698,7 +700,10 @@ impl LspTestReporter {
|
|||
let err_string = format!(
|
||||
"Uncaught error from {}: {}\nThis error was not caught from a test and caused the test runner to fail on the referenced module.\nIt most likely originated from a dangling promise, event/timeout handler or top-level code.",
|
||||
origin,
|
||||
test::fmt::format_test_error(js_error, &TestFailureFormatOptions::default())
|
||||
test::fmt::format_test_error(
|
||||
js_error,
|
||||
&TestFailureFormatOptions::default()
|
||||
)
|
||||
);
|
||||
let messages = vec![lsp_custom::TestMessage {
|
||||
message: lsp::MarkupContent {
|
||||
|
|
|
@ -5,12 +5,12 @@ use std::collections::HashSet;
|
|||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_json::Value;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_runtime::tokio_util::create_basic_runtime;
|
||||
use tokio::sync::mpsc;
|
||||
use tower_lsp::jsonrpc::Error as LspError;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use dissimilar::diff;
|
||||
use dissimilar::Chunk;
|
||||
use dissimilar::diff;
|
||||
use text_size::TextRange;
|
||||
use text_size::TextSize;
|
||||
use tower_lsp::jsonrpc;
|
||||
|
|
|
@ -29,15 +29,15 @@ impl fmt::Debug for TracingGuard {
|
|||
#[cfg(feature = "lsp-tracing")]
|
||||
mod real_tracing {
|
||||
use deno_core::anyhow;
|
||||
use opentelemetry::trace::TracerProvider;
|
||||
pub use opentelemetry::Context;
|
||||
use opentelemetry::KeyValue;
|
||||
use opentelemetry::trace::TracerProvider;
|
||||
use opentelemetry_otlp::WithExportConfig;
|
||||
use opentelemetry_sdk::Resource;
|
||||
use opentelemetry_semantic_conventions::resource::SERVICE_NAME;
|
||||
pub use tracing::Span;
|
||||
use tracing::level_filters::LevelFilter;
|
||||
pub use tracing::span::EnteredSpan;
|
||||
pub use tracing::Span;
|
||||
use tracing_opentelemetry::OpenTelemetryLayer;
|
||||
pub use tracing_opentelemetry::OpenTelemetrySpanExt as SpanExt;
|
||||
use tracing_subscriber::fmt::format::FmtSpan;
|
||||
|
|
|
@ -12,12 +12,17 @@ use std::net::SocketAddr;
|
|||
use std::ops::Range;
|
||||
use std::path::Path;
|
||||
use std::rc::Rc;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::thread;
|
||||
|
||||
use dashmap::DashMap;
|
||||
use deno_ast::MediaType;
|
||||
use deno_core::JsRuntime;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::OpState;
|
||||
use deno_core::PollEventLoopOptions;
|
||||
use deno_core::RuntimeOptions;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::convert::Smi;
|
||||
use deno_core::convert::ToV8;
|
||||
|
@ -26,20 +31,15 @@ use deno_core::futures::FutureExt;
|
|||
use deno_core::op2;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::resolve_url;
|
||||
use deno_core::serde::de;
|
||||
use deno_core::serde::Deserialize;
|
||||
use deno_core::serde::Serialize;
|
||||
use deno_core::serde::de;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_json::Value;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_v8;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::v8;
|
||||
use deno_core::JsRuntime;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::OpState;
|
||||
use deno_core::PollEventLoopOptions;
|
||||
use deno_core::RuntimeOptions;
|
||||
use deno_lib::util::result::InfallibleResultExt;
|
||||
use deno_lib::worker::create_isolate_create_params;
|
||||
use deno_path_util::url_to_file_path;
|
||||
|
@ -51,9 +51,9 @@ use indexmap::IndexSet;
|
|||
use lazy_regex::lazy_regex;
|
||||
use log::error;
|
||||
use lsp_types::Uri;
|
||||
use node_resolver::cache::NodeResolutionThreadLocalCache;
|
||||
use node_resolver::NodeResolutionKind;
|
||||
use node_resolver::ResolutionMode;
|
||||
use node_resolver::cache::NodeResolutionThreadLocalCache;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Captures;
|
||||
use regex::Regex;
|
||||
|
@ -80,22 +80,22 @@ use super::language_server::StateSnapshot;
|
|||
use super::logging::lsp_log;
|
||||
use super::performance::Performance;
|
||||
use super::performance::PerformanceMark;
|
||||
use super::refactor::RefactorCodeActionData;
|
||||
use super::refactor::ALL_KNOWN_REFACTOR_ACTION_KINDS;
|
||||
use super::refactor::EXTRACT_CONSTANT;
|
||||
use super::refactor::EXTRACT_INTERFACE;
|
||||
use super::refactor::EXTRACT_TYPE;
|
||||
use super::refactor::RefactorCodeActionData;
|
||||
use super::semantic_tokens;
|
||||
use super::semantic_tokens::SemanticTokensBuilder;
|
||||
use super::text::LineIndex;
|
||||
use super::urls::uri_to_url;
|
||||
use super::urls::url_to_uri;
|
||||
use crate::args::jsr_url;
|
||||
use crate::args::FmtOptionsConfig;
|
||||
use crate::args::jsr_url;
|
||||
use crate::lsp::documents::Document;
|
||||
use crate::lsp::logging::lsp_warn;
|
||||
use crate::tsc::ResolveArgs;
|
||||
use crate::tsc::MISSING_DEPENDENCY_SPECIFIER;
|
||||
use crate::tsc::ResolveArgs;
|
||||
use crate::util::path::relative_specifier;
|
||||
use crate::util::path::to_percent_decoded_str;
|
||||
use crate::util::v8::convert;
|
||||
|
|
217
cli/main.rs
217
cli/main.rs
|
@ -3,7 +3,6 @@
|
|||
mod args;
|
||||
mod cache;
|
||||
mod cdp;
|
||||
mod emit;
|
||||
mod factory;
|
||||
mod file_fetcher;
|
||||
mod graph_container;
|
||||
|
@ -47,10 +46,10 @@ use deno_lib::util::result::any_and_jserrorbox_downcast_ref;
|
|||
use deno_lib::worker::LibWorkerFactoryRoots;
|
||||
use deno_resolver::npm::ByonmResolvePkgFolderFromDenoReqError;
|
||||
use deno_resolver::npm::ResolvePkgFolderFromDenoReqError;
|
||||
use deno_runtime::fmt_errors::format_js_error;
|
||||
use deno_runtime::tokio_util::create_and_run_current_thread_with_maybe_metrics;
|
||||
use deno_runtime::UnconfiguredRuntime;
|
||||
use deno_runtime::WorkerExecutionMode;
|
||||
use deno_runtime::fmt_errors::format_js_error;
|
||||
use deno_runtime::tokio_util::create_and_run_current_thread_with_maybe_metrics;
|
||||
use deno_telemetry::OtelConfig;
|
||||
use deno_terminal::colors;
|
||||
use factory::CliFactory;
|
||||
|
@ -60,10 +59,10 @@ const UNSUPPORTED_SCHEME: &str = "Unsupported scheme";
|
|||
|
||||
use self::args::load_env_variables_from_env_file;
|
||||
use self::util::draw_thread::DrawThread;
|
||||
use crate::args::flags_from_vec;
|
||||
use crate::args::get_default_v8_flags;
|
||||
use crate::args::DenoSubcommand;
|
||||
use crate::args::Flags;
|
||||
use crate::args::flags_from_vec;
|
||||
use crate::args::get_default_v8_flags;
|
||||
use crate::util::display;
|
||||
use crate::util::v8::get_v8_flags_from_env;
|
||||
use crate::util::v8::init_v8_flags;
|
||||
|
@ -117,25 +116,25 @@ async fn run_subcommand(
|
|||
DenoSubcommand::Add(add_flags) => spawn_subcommand(async {
|
||||
tools::pm::add(flags, add_flags, tools::pm::AddCommandName::Add).await
|
||||
}),
|
||||
DenoSubcommand::Remove(remove_flags) => spawn_subcommand(async {
|
||||
tools::pm::remove(flags, remove_flags).await
|
||||
}),
|
||||
DenoSubcommand::Remove(remove_flags) => {
|
||||
spawn_subcommand(async { tools::pm::remove(flags, remove_flags).await })
|
||||
}
|
||||
DenoSubcommand::Bench(bench_flags) => spawn_subcommand(async {
|
||||
if bench_flags.watch.is_some() {
|
||||
tools::bench::run_benchmarks_with_watch(flags, bench_flags).boxed_local().await
|
||||
tools::bench::run_benchmarks_with_watch(flags, bench_flags)
|
||||
.boxed_local()
|
||||
.await
|
||||
} else {
|
||||
tools::bench::run_benchmarks(flags, bench_flags).await
|
||||
}
|
||||
}),
|
||||
DenoSubcommand::Bundle(bundle_flags) => {
|
||||
spawn_subcommand(async {
|
||||
log::warn!(
|
||||
"⚠️ {} is experimental and subject to changes",
|
||||
colors::cyan("deno bundle")
|
||||
);
|
||||
tools::bundle::bundle(flags, bundle_flags).await
|
||||
})
|
||||
},
|
||||
DenoSubcommand::Bundle(bundle_flags) => spawn_subcommand(async {
|
||||
log::warn!(
|
||||
"⚠️ {} is experimental and subject to changes",
|
||||
colors::cyan("deno bundle")
|
||||
);
|
||||
tools::bundle::bundle(flags, bundle_flags).await
|
||||
}),
|
||||
DenoSubcommand::Deploy => {
|
||||
spawn_subcommand(async { tools::deploy::deploy(Arc::unwrap_or_clone(flags)).await })
|
||||
}
|
||||
|
@ -146,23 +145,31 @@ async fn run_subcommand(
|
|||
tools::run::eval_command(flags, eval_flags).await
|
||||
}),
|
||||
DenoSubcommand::Cache(cache_flags) => spawn_subcommand(async move {
|
||||
tools::installer::install_from_entrypoints(flags, &cache_flags.files).await
|
||||
}),
|
||||
DenoSubcommand::Check(check_flags) => spawn_subcommand(async move {
|
||||
tools::check::check(flags, check_flags).await
|
||||
}),
|
||||
DenoSubcommand::Clean(clean_flags) => spawn_subcommand(async move {
|
||||
tools::clean::clean(flags, clean_flags).await
|
||||
tools::installer::install_from_entrypoints(flags, &cache_flags.files)
|
||||
.await
|
||||
}),
|
||||
DenoSubcommand::Check(check_flags) => {
|
||||
spawn_subcommand(
|
||||
async move { tools::check::check(flags, check_flags).await },
|
||||
)
|
||||
}
|
||||
DenoSubcommand::Clean(clean_flags) => {
|
||||
spawn_subcommand(
|
||||
async move { tools::clean::clean(flags, clean_flags).await },
|
||||
)
|
||||
}
|
||||
DenoSubcommand::Compile(compile_flags) => spawn_subcommand(async {
|
||||
if compile_flags.eszip {
|
||||
tools::compile::compile_eszip(flags, compile_flags).boxed_local().await
|
||||
tools::compile::compile_eszip(flags, compile_flags)
|
||||
.boxed_local()
|
||||
.await
|
||||
} else {
|
||||
tools::compile::compile(flags, compile_flags).await
|
||||
}
|
||||
}),
|
||||
DenoSubcommand::Coverage(coverage_flags) => spawn_subcommand(async move {
|
||||
let reporter = crate::tools::coverage::reporter::create(coverage_flags.r#type.clone());
|
||||
let reporter =
|
||||
crate::tools::coverage::reporter::create(coverage_flags.r#type.clone());
|
||||
tools::coverage::cover_files(
|
||||
flags,
|
||||
coverage_flags.files.include,
|
||||
|
@ -170,7 +177,7 @@ async fn run_subcommand(
|
|||
coverage_flags.include,
|
||||
coverage_flags.exclude,
|
||||
coverage_flags.output,
|
||||
&[&*reporter]
|
||||
&[&*reporter],
|
||||
)
|
||||
}),
|
||||
DenoSubcommand::Fmt(fmt_flags) => {
|
||||
|
@ -179,9 +186,7 @@ async fn run_subcommand(
|
|||
)
|
||||
}
|
||||
DenoSubcommand::Init(init_flags) => {
|
||||
spawn_subcommand(async {
|
||||
tools::init::init_project(init_flags).await
|
||||
})
|
||||
spawn_subcommand(async { tools::init::init_project(init_flags).await })
|
||||
}
|
||||
DenoSubcommand::Info(info_flags) => {
|
||||
spawn_subcommand(async { tools::info::info(flags, info_flags).await })
|
||||
|
@ -189,9 +194,13 @@ async fn run_subcommand(
|
|||
DenoSubcommand::Install(install_flags) => spawn_subcommand(async {
|
||||
tools::installer::install_command(flags, install_flags).await
|
||||
}),
|
||||
DenoSubcommand::JSONReference(json_reference) => spawn_subcommand(async move {
|
||||
display::write_to_stdout_ignore_sigpipe(&deno_core::serde_json::to_vec_pretty(&json_reference.json).unwrap())
|
||||
}),
|
||||
DenoSubcommand::JSONReference(json_reference) => {
|
||||
spawn_subcommand(async move {
|
||||
display::write_to_stdout_ignore_sigpipe(
|
||||
&deno_core::serde_json::to_vec_pretty(&json_reference.json).unwrap(),
|
||||
)
|
||||
})
|
||||
}
|
||||
DenoSubcommand::Jupyter(jupyter_flags) => spawn_subcommand(async {
|
||||
tools::jupyter::kernel(flags, jupyter_flags).await
|
||||
}),
|
||||
|
@ -223,9 +232,9 @@ async fn run_subcommand(
|
|||
}
|
||||
}),
|
||||
DenoSubcommand::Outdated(update_flags) => {
|
||||
spawn_subcommand(async move {
|
||||
tools::pm::outdated(flags, update_flags).await
|
||||
})
|
||||
spawn_subcommand(
|
||||
async move { tools::pm::outdated(flags, update_flags).await },
|
||||
)
|
||||
}
|
||||
DenoSubcommand::Repl(repl_flags) => {
|
||||
spawn_subcommand(async move { tools::repl::run(flags, repl_flags).await })
|
||||
|
@ -233,38 +242,77 @@ async fn run_subcommand(
|
|||
DenoSubcommand::Run(run_flags) => spawn_subcommand(async move {
|
||||
if run_flags.is_stdin() {
|
||||
// these futures are boxed to prevent stack overflows on Windows
|
||||
tools::run::run_from_stdin(flags.clone(), unconfigured_runtime, roots).boxed_local().await
|
||||
tools::run::run_from_stdin(flags.clone(), unconfigured_runtime, roots)
|
||||
.boxed_local()
|
||||
.await
|
||||
} else if flags.eszip {
|
||||
tools::run::run_eszip(flags, run_flags, unconfigured_runtime, roots).boxed_local().await
|
||||
tools::run::run_eszip(flags, run_flags, unconfigured_runtime, roots)
|
||||
.boxed_local()
|
||||
.await
|
||||
} else {
|
||||
let result = tools::run::run_script(WorkerExecutionMode::Run, flags.clone(), run_flags.watch, unconfigured_runtime, roots.clone()).await;
|
||||
let result = tools::run::run_script(
|
||||
WorkerExecutionMode::Run,
|
||||
flags.clone(),
|
||||
run_flags.watch,
|
||||
unconfigured_runtime,
|
||||
roots.clone(),
|
||||
)
|
||||
.await;
|
||||
match result {
|
||||
Ok(v) => Ok(v),
|
||||
Err(script_err) => {
|
||||
if let Some(worker::CreateCustomWorkerError::ResolvePkgFolderFromDenoReq(ResolvePkgFolderFromDenoReqError::Byonm(ByonmResolvePkgFolderFromDenoReqError::UnmatchedReq(_)))) = any_and_jserrorbox_downcast_ref::<worker::CreateCustomWorkerError>(&script_err) {
|
||||
if let Some(
|
||||
worker::CreateCustomWorkerError::ResolvePkgFolderFromDenoReq(
|
||||
ResolvePkgFolderFromDenoReqError::Byonm(
|
||||
ByonmResolvePkgFolderFromDenoReqError::UnmatchedReq(_),
|
||||
),
|
||||
),
|
||||
) = any_and_jserrorbox_downcast_ref::<
|
||||
worker::CreateCustomWorkerError,
|
||||
>(&script_err)
|
||||
{
|
||||
if flags.node_modules_dir.is_none() {
|
||||
let mut flags = flags.deref().clone();
|
||||
let watch = match &flags.subcommand {
|
||||
DenoSubcommand::Run(run_flags) => run_flags.watch.clone(),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
flags.node_modules_dir = Some(deno_config::deno_json::NodeModulesDirMode::None);
|
||||
flags.node_modules_dir =
|
||||
Some(deno_config::deno_json::NodeModulesDirMode::None);
|
||||
// use the current lockfile, but don't write it out
|
||||
if flags.frozen_lockfile.is_none() {
|
||||
flags.internal.lockfile_skip_write = true;
|
||||
}
|
||||
return tools::run::run_script(WorkerExecutionMode::Run, Arc::new(flags), watch, None, roots).boxed_local().await;
|
||||
return tools::run::run_script(
|
||||
WorkerExecutionMode::Run,
|
||||
Arc::new(flags),
|
||||
watch,
|
||||
None,
|
||||
roots,
|
||||
)
|
||||
.boxed_local()
|
||||
.await;
|
||||
}
|
||||
}
|
||||
let script_err_msg = script_err.to_string();
|
||||
if script_err_msg.starts_with(MODULE_NOT_FOUND) || script_err_msg.starts_with(UNSUPPORTED_SCHEME) {
|
||||
if script_err_msg.starts_with(MODULE_NOT_FOUND)
|
||||
|| script_err_msg.starts_with(UNSUPPORTED_SCHEME)
|
||||
{
|
||||
if run_flags.bare {
|
||||
let mut cmd = args::clap_root();
|
||||
cmd.build();
|
||||
let command_names = cmd.get_subcommands().map(|command| command.get_name()).collect::<Vec<_>>();
|
||||
let suggestions = args::did_you_mean(&run_flags.script, command_names);
|
||||
let command_names = cmd
|
||||
.get_subcommands()
|
||||
.map(|command| command.get_name())
|
||||
.collect::<Vec<_>>();
|
||||
let suggestions =
|
||||
args::did_you_mean(&run_flags.script, command_names);
|
||||
if !suggestions.is_empty() && !run_flags.script.contains('.') {
|
||||
let mut error = clap::error::Error::<clap::error::DefaultFormatter>::new(clap::error::ErrorKind::InvalidSubcommand).with_cmd(&cmd);
|
||||
let mut error =
|
||||
clap::error::Error::<clap::error::DefaultFormatter>::new(
|
||||
clap::error::ErrorKind::InvalidSubcommand,
|
||||
)
|
||||
.with_cmd(&cmd);
|
||||
error.insert(
|
||||
clap::error::ContextKind::SuggestedSubcommand,
|
||||
clap::error::ContextValue::Strings(suggestions),
|
||||
|
@ -285,7 +333,11 @@ async fn run_subcommand(
|
|||
eval: false,
|
||||
};
|
||||
new_flags.subcommand = DenoSubcommand::Task(task_flags.clone());
|
||||
let result = tools::task::execute_script(Arc::new(new_flags), task_flags.clone()).await;
|
||||
let result = tools::task::execute_script(
|
||||
Arc::new(new_flags),
|
||||
task_flags.clone(),
|
||||
)
|
||||
.await;
|
||||
match result {
|
||||
Ok(v) => Ok(v),
|
||||
Err(_) => {
|
||||
|
@ -318,10 +370,14 @@ async fn run_subcommand(
|
|||
.with_context(|| format!("Failed creating: {coverage_dir}"))?;
|
||||
// this is set in order to ensure spawned processes use the same
|
||||
// coverage directory
|
||||
env::set_var(
|
||||
"DENO_COVERAGE_DIR",
|
||||
PathBuf::from(coverage_dir).canonicalize()?,
|
||||
);
|
||||
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
unsafe {
|
||||
env::set_var(
|
||||
"DENO_COVERAGE_DIR",
|
||||
PathBuf::from(coverage_dir).canonicalize()?,
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
if test_flags.watch.is_some() {
|
||||
|
@ -349,18 +405,24 @@ async fn run_subcommand(
|
|||
"This deno was built without the \"upgrade\" feature. Please upgrade using the installation method originally used to install Deno.",
|
||||
1,
|
||||
),
|
||||
DenoSubcommand::Vendor => exit_with_message("⚠️ `deno vendor` was removed in Deno 2.\n\nSee the Deno 1.x to 2.x Migration Guide for migration instructions: https://docs.deno.com/runtime/manual/advanced/migrate_deprecations", 1),
|
||||
DenoSubcommand::Vendor => exit_with_message(
|
||||
"⚠️ `deno vendor` was removed in Deno 2.\n\nSee the Deno 1.x to 2.x Migration Guide for migration instructions: https://docs.deno.com/runtime/manual/advanced/migrate_deprecations",
|
||||
1,
|
||||
),
|
||||
DenoSubcommand::Publish(publish_flags) => spawn_subcommand(async {
|
||||
tools::publish::publish(flags, publish_flags).await
|
||||
}),
|
||||
DenoSubcommand::Help(help_flags) => spawn_subcommand(async move {
|
||||
use std::io::Write;
|
||||
|
||||
let mut stream = anstream::AutoStream::new(std::io::stdout(), if colors::use_color() {
|
||||
anstream::ColorChoice::Auto
|
||||
} else {
|
||||
anstream::ColorChoice::Never
|
||||
});
|
||||
let mut stream = anstream::AutoStream::new(
|
||||
std::io::stdout(),
|
||||
if colors::use_color() {
|
||||
anstream::ColorChoice::Auto
|
||||
} else {
|
||||
anstream::ColorChoice::Never
|
||||
},
|
||||
);
|
||||
|
||||
match stream.write_all(help_flags.help.ansi().to_string().as_bytes()) {
|
||||
Ok(()) => Ok(()),
|
||||
|
@ -548,6 +610,17 @@ async fn resolve_flags_and_init(
|
|||
|
||||
load_env_variables_from_env_file(flags.env_file.as_ref(), flags.log_level);
|
||||
flags.unstable_config.fill_with_env();
|
||||
if std::env::var("DENO_COMPAT").is_ok() {
|
||||
flags.unstable_config.enable_node_compat();
|
||||
}
|
||||
if flags.node_conditions.is_empty() {
|
||||
if let Ok(conditions) = std::env::var("DENO_CONDITIONS") {
|
||||
flags.node_conditions = conditions
|
||||
.split(",")
|
||||
.map(|c| c.trim().to_string())
|
||||
.collect();
|
||||
}
|
||||
}
|
||||
|
||||
// Tunnel is initialized before OTEL since
|
||||
// OTEL data is submitted via the tunnel.
|
||||
|
@ -636,11 +709,15 @@ fn wait_for_start(
|
|||
Option<(UnconfiguredRuntime, Vec<std::ffi::OsString>)>,
|
||||
AnyError,
|
||||
>,
|
||||
>,
|
||||
> + use<>,
|
||||
> {
|
||||
let startup_snapshot = deno_snapshots::CLI_SNAPSHOT?;
|
||||
let addr = std::env::var("DENO_UNSTABLE_CONTROL_SOCK").ok()?;
|
||||
std::env::remove_var("DENO_UNSTABLE_CONTROL_SOCK");
|
||||
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
unsafe {
|
||||
std::env::remove_var("DENO_UNSTABLE_CONTROL_SOCK")
|
||||
};
|
||||
|
||||
let argv0 = args[0].clone();
|
||||
|
||||
|
@ -663,15 +740,18 @@ fn wait_for_start(
|
|||
deno_resolver::npm::DenoInNpmPackageChecker,
|
||||
crate::npm::CliNpmResolver,
|
||||
crate::sys::CliSys,
|
||||
>(
|
||||
>(deno_runtime::UnconfiguredRuntimeOptions {
|
||||
startup_snapshot,
|
||||
deno_lib::worker::create_isolate_create_params(
|
||||
create_params: deno_lib::worker::create_isolate_create_params(
|
||||
&crate::sys::CliSys::default(),
|
||||
),
|
||||
Some(roots.shared_array_buffer_store.clone()),
|
||||
Some(roots.compiled_wasm_module_store.clone()),
|
||||
vec![],
|
||||
);
|
||||
shared_array_buffer_store: Some(roots.shared_array_buffer_store.clone()),
|
||||
compiled_wasm_module_store: Some(
|
||||
roots.compiled_wasm_module_store.clone(),
|
||||
),
|
||||
additional_extensions: vec![],
|
||||
enable_raw_imports: false,
|
||||
});
|
||||
|
||||
let (rx, mut tx): (
|
||||
Box<dyn AsyncRead + Unpin>,
|
||||
|
@ -737,7 +817,10 @@ fn wait_for_start(
|
|||
std::env::set_current_dir(cmd.cwd)?;
|
||||
|
||||
for (k, v) in cmd.env {
|
||||
std::env::set_var(k, v);
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
unsafe {
|
||||
std::env::set_var(k, v)
|
||||
};
|
||||
}
|
||||
|
||||
let args = [argv0]
|
||||
|
|
|
@ -10,26 +10,16 @@ use std::path::PathBuf;
|
|||
use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
use std::str;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::AtomicU16;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::sync::Arc;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use boxed_error::Boxed;
|
||||
use deno_ast::MediaType;
|
||||
use deno_ast::ModuleKind;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context as _;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::ModuleLoaderError;
|
||||
use deno_core::futures::future::FutureExt;
|
||||
use deno_core::futures::io::BufReader;
|
||||
use deno_core::futures::stream::FuturesOrdered;
|
||||
use deno_core::futures::StreamExt;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::resolve_url;
|
||||
use deno_core::resolve_url_or_path;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::ModuleCodeString;
|
||||
use deno_cache_dir::file_fetcher::FetchLocalOptions;
|
||||
use deno_core::FastString;
|
||||
use deno_core::ModuleLoader;
|
||||
use deno_core::ModuleSource;
|
||||
use deno_core::ModuleSourceCode;
|
||||
|
@ -37,60 +27,72 @@ use deno_core::ModuleSpecifier;
|
|||
use deno_core::ModuleType;
|
||||
use deno_core::RequestedModuleType;
|
||||
use deno_core::SourceCodeCacheInfo;
|
||||
use deno_core::anyhow::Context as _;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::ModuleLoaderError;
|
||||
use deno_core::futures::StreamExt;
|
||||
use deno_core::futures::future::FutureExt;
|
||||
use deno_core::futures::io::BufReader;
|
||||
use deno_core::futures::stream::FuturesOrdered;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::resolve_url;
|
||||
use deno_core::resolve_url_or_path;
|
||||
use deno_core::serde_json;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_graph::GraphKind;
|
||||
use deno_graph::JsModule;
|
||||
use deno_graph::JsonModule;
|
||||
use deno_graph::ModuleGraph;
|
||||
use deno_graph::ModuleGraphError;
|
||||
use deno_graph::WalkOptions;
|
||||
use deno_graph::WasmModule;
|
||||
use deno_lib::loader::ModuleCodeStringSource;
|
||||
use deno_lib::loader::NpmModuleLoadError;
|
||||
use deno_lib::loader::StrippingTypesNodeModulesError;
|
||||
use deno_lib::loader::module_type_from_media_type;
|
||||
use deno_lib::npm::NpmRegistryReadPermissionChecker;
|
||||
use deno_lib::util::hash::FastInsecureHasher;
|
||||
use deno_lib::worker::CreateModuleLoaderResult;
|
||||
use deno_lib::worker::ModuleLoaderFactory;
|
||||
use deno_resolver::cache::ParsedSourceCache;
|
||||
use deno_resolver::file_fetcher::FetchOptions;
|
||||
use deno_resolver::file_fetcher::FetchPermissionsOptionRef;
|
||||
use deno_resolver::graph::ResolveWithGraphErrorKind;
|
||||
use deno_resolver::graph::ResolveWithGraphOptions;
|
||||
use deno_resolver::loader::LoadPreparedModuleError;
|
||||
use deno_resolver::loader::PreparedModuleOrAsset;
|
||||
use deno_resolver::loader::PreparedModuleSource;
|
||||
use deno_resolver::npm::DenoInNpmPackageChecker;
|
||||
use deno_resolver::npm::ResolveNpmReqRefError;
|
||||
use deno_runtime::code_cache;
|
||||
use deno_runtime::deno_node::NodeRequireLoader;
|
||||
use deno_runtime::deno_node::create_host_defined_options;
|
||||
use deno_runtime::deno_node::ops::require::UnableToGetCwdError;
|
||||
use deno_runtime::deno_node::NodeRequireLoader;
|
||||
use deno_runtime::deno_permissions::CheckSpecifierKind;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
use deno_semver::npm::NpmPackageReqReference;
|
||||
use eszip::EszipV2;
|
||||
use node_resolver::errors::ClosestPkgJsonError;
|
||||
use node_resolver::DenoIsBuiltInNodeModuleChecker;
|
||||
use node_resolver::InNpmPackageChecker;
|
||||
use node_resolver::NodeResolutionKind;
|
||||
use node_resolver::ResolutionMode;
|
||||
use node_resolver::errors::ClosestPkgJsonError;
|
||||
use sys_traits::FsMetadata;
|
||||
use sys_traits::FsMetadataValue;
|
||||
use sys_traits::FsRead;
|
||||
use tokio_util::compat::TokioAsyncReadCompatExt;
|
||||
|
||||
use crate::args::jsr_url;
|
||||
use crate::args::CliLockfile;
|
||||
use crate::args::CliOptions;
|
||||
use crate::args::DenoSubcommand;
|
||||
use crate::args::TsTypeLib;
|
||||
use crate::args::jsr_url;
|
||||
use crate::cache::CodeCache;
|
||||
use crate::cache::ParsedSourceCache;
|
||||
use crate::emit::Emitter;
|
||||
use crate::file_fetcher::CliFileFetcher;
|
||||
use crate::graph_container::MainModuleGraphContainer;
|
||||
use crate::graph_container::ModuleGraphContainer;
|
||||
use crate::graph_container::ModuleGraphUpdatePermit;
|
||||
use crate::graph_util::enhance_graph_error;
|
||||
use crate::graph_util::BuildGraphRequest;
|
||||
use crate::graph_util::BuildGraphWithNpmOptions;
|
||||
use crate::graph_util::EnhanceGraphErrorMode;
|
||||
use crate::graph_util::ModuleGraphBuilder;
|
||||
use crate::node::CliCjsCodeAnalyzer;
|
||||
use crate::node::CliNodeCodeTranslator;
|
||||
use crate::npm::CliNpmResolver;
|
||||
use crate::resolver::CliCjsTracker;
|
||||
use crate::resolver::CliResolver;
|
||||
|
@ -109,6 +111,10 @@ pub type CliNpmModuleLoader = deno_lib::loader::NpmModuleLoader<
|
|||
CliNpmResolver,
|
||||
CliSys,
|
||||
>;
|
||||
pub type CliEmitter =
|
||||
deno_resolver::emit::Emitter<DenoInNpmPackageChecker, CliSys>;
|
||||
pub type CliPreparedModuleLoader =
|
||||
deno_resolver::loader::PreparedModuleLoader<DenoInNpmPackageChecker, CliSys>;
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum PrepareModuleLoadError {
|
||||
|
@ -325,16 +331,17 @@ struct SharedCliModuleLoaderState {
|
|||
is_repl: bool,
|
||||
cjs_tracker: Arc<CliCjsTracker>,
|
||||
code_cache: Option<Arc<CodeCache>>,
|
||||
emitter: Arc<Emitter>,
|
||||
emitter: Arc<CliEmitter>,
|
||||
file_fetcher: Arc<CliFileFetcher>,
|
||||
in_npm_pkg_checker: DenoInNpmPackageChecker,
|
||||
main_module_graph_container: Arc<MainModuleGraphContainer>,
|
||||
module_load_preparer: Arc<ModuleLoadPreparer>,
|
||||
node_code_translator: Arc<CliNodeCodeTranslator>,
|
||||
npm_module_loader: CliNpmModuleLoader,
|
||||
npm_registry_permission_checker:
|
||||
Arc<NpmRegistryReadPermissionChecker<CliSys>>,
|
||||
npm_resolver: CliNpmResolver,
|
||||
parsed_source_cache: Arc<ParsedSourceCache>,
|
||||
prepared_module_loader: Arc<CliPreparedModuleLoader>,
|
||||
resolver: Arc<CliResolver>,
|
||||
sys: CliSys,
|
||||
in_flight_loads_tracker: InFlightModuleLoadsTracker,
|
||||
|
@ -386,17 +393,18 @@ impl CliModuleLoaderFactory {
|
|||
options: &CliOptions,
|
||||
cjs_tracker: Arc<CliCjsTracker>,
|
||||
code_cache: Option<Arc<CodeCache>>,
|
||||
emitter: Arc<Emitter>,
|
||||
emitter: Arc<CliEmitter>,
|
||||
file_fetcher: Arc<CliFileFetcher>,
|
||||
in_npm_pkg_checker: DenoInNpmPackageChecker,
|
||||
main_module_graph_container: Arc<MainModuleGraphContainer>,
|
||||
module_load_preparer: Arc<ModuleLoadPreparer>,
|
||||
node_code_translator: Arc<CliNodeCodeTranslator>,
|
||||
npm_module_loader: CliNpmModuleLoader,
|
||||
npm_registry_permission_checker: Arc<
|
||||
NpmRegistryReadPermissionChecker<CliSys>,
|
||||
>,
|
||||
npm_resolver: CliNpmResolver,
|
||||
parsed_source_cache: Arc<ParsedSourceCache>,
|
||||
prepared_module_loader: Arc<CliPreparedModuleLoader>,
|
||||
resolver: Arc<CliResolver>,
|
||||
sys: CliSys,
|
||||
maybe_eszip_loader: Option<Arc<EszipModuleLoader>>,
|
||||
|
@ -415,14 +423,15 @@ impl CliModuleLoaderFactory {
|
|||
cjs_tracker,
|
||||
code_cache,
|
||||
emitter,
|
||||
file_fetcher,
|
||||
in_npm_pkg_checker,
|
||||
main_module_graph_container,
|
||||
module_load_preparer,
|
||||
node_code_translator,
|
||||
npm_module_loader,
|
||||
npm_registry_permission_checker,
|
||||
npm_resolver,
|
||||
parsed_source_cache,
|
||||
prepared_module_loader,
|
||||
resolver,
|
||||
sys,
|
||||
in_flight_loads_tracker: InFlightModuleLoadsTracker {
|
||||
|
@ -450,9 +459,6 @@ impl CliModuleLoaderFactory {
|
|||
parent_permissions,
|
||||
permissions,
|
||||
graph_container: graph_container.clone(),
|
||||
node_code_translator: self.shared.node_code_translator.clone(),
|
||||
emitter: self.shared.emitter.clone(),
|
||||
parsed_source_cache: self.shared.parsed_source_cache.clone(),
|
||||
shared: self.shared.clone(),
|
||||
loaded_files: Default::default(),
|
||||
})));
|
||||
|
@ -518,9 +524,6 @@ impl CliModuleLoaderFactory {
|
|||
parent_permissions: root_permissions.clone(),
|
||||
permissions: root_permissions,
|
||||
graph_container: (*self.shared.main_module_graph_container).clone(),
|
||||
node_code_translator: self.shared.node_code_translator.clone(),
|
||||
emitter: self.shared.emitter.clone(),
|
||||
parsed_source_cache: self.shared.parsed_source_cache.clone(),
|
||||
shared: self.shared.clone(),
|
||||
loaded_files: Default::default(),
|
||||
}))
|
||||
|
@ -535,41 +538,6 @@ pub struct LoadUnpreparedModuleError {
|
|||
maybe_referrer: Option<ModuleSpecifier>,
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
#[error("{message}")]
|
||||
#[class(inherit)]
|
||||
pub struct EnhancedGraphError {
|
||||
#[inherit]
|
||||
pub error: deno_graph::ModuleError,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum LoadPreparedModuleError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
NpmModuleLoad(#[from] crate::emit::EmitParsedSourceHelperError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
LoadMaybeCjs(#[from] LoadMaybeCjsError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Graph(#[from] Box<EnhancedGraphError>),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Other(#[from] JsErrorBox),
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum LoadMaybeCjsError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
NpmModuleLoad(#[from] crate::emit::EmitParsedSourceHelperError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
TranslateCjsToEsm(#[from] node_resolver::analyze::TranslateCjsToEsmError),
|
||||
}
|
||||
|
||||
struct CliModuleLoaderInner<TGraphContainer: ModuleGraphContainer> {
|
||||
lib: TsTypeLib,
|
||||
is_worker: bool,
|
||||
|
@ -579,23 +547,13 @@ struct CliModuleLoaderInner<TGraphContainer: ModuleGraphContainer> {
|
|||
parent_permissions: PermissionsContainer,
|
||||
permissions: PermissionsContainer,
|
||||
shared: Arc<SharedCliModuleLoaderState>,
|
||||
emitter: Arc<Emitter>,
|
||||
node_code_translator: Arc<CliNodeCodeTranslator>,
|
||||
parsed_source_cache: Arc<ParsedSourceCache>,
|
||||
graph_container: TGraphContainer,
|
||||
loaded_files: RefCell<HashSet<ModuleSpecifier>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
#[derive(Debug, deno_error::JsError, Boxed)]
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
pub struct LoadCodeSourceError(#[from] pub Box<LoadCodeSourceErrorKind>);
|
||||
|
||||
impl LoadCodeSourceError {
|
||||
pub fn from_err<E: Into<LoadCodeSourceErrorKind>>(err: E) -> Self {
|
||||
Self(Box::new(err.into()))
|
||||
}
|
||||
}
|
||||
pub struct LoadCodeSourceError(pub Box<LoadCodeSourceErrorKind>);
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum LoadCodeSourceErrorKind {
|
||||
|
@ -617,6 +575,9 @@ pub enum LoadCodeSourceErrorKind {
|
|||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
NpmReqRef(#[from] ResolveNpmReqRefError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Fetch(#[from] deno_resolver::file_fetcher::FetchError),
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
|
@ -628,7 +589,9 @@ pub enum CliModuleLoaderError {
|
|||
#[error(transparent)]
|
||||
LoadPreparedModule(#[from] Box<LoadPreparedModuleError>),
|
||||
#[class(generic)]
|
||||
#[error("Attempted to load JSON module without specifying \"type\": \"json\" attribute in the import statement.")]
|
||||
#[error(
|
||||
"Attempted to load JSON module without specifying \"type\": \"json\" attribute in the import statement."
|
||||
)]
|
||||
MissingJsonAttribute,
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
|
@ -643,7 +606,7 @@ impl<TGraphContainer: ModuleGraphContainer> CliModuleLoader<TGraphContainer> {
|
|||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
maybe_referrer: Option<&ModuleSpecifier>,
|
||||
requested_module_type: RequestedModuleType,
|
||||
requested_module_type: &RequestedModuleType,
|
||||
) -> Result<ModuleSource, CliModuleLoaderError> {
|
||||
self
|
||||
.0
|
||||
|
@ -659,26 +622,22 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
maybe_referrer: Option<&ModuleSpecifier>,
|
||||
requested_module_type: RequestedModuleType,
|
||||
requested_module_type: &RequestedModuleType,
|
||||
) -> Result<ModuleSource, CliModuleLoaderError> {
|
||||
let code_source = self.load_code_source(specifier, maybe_referrer).await?;
|
||||
|
||||
let module_type = match code_source.media_type {
|
||||
MediaType::Json => ModuleType::Json,
|
||||
MediaType::Wasm => ModuleType::Wasm,
|
||||
_ => ModuleType::JavaScript,
|
||||
};
|
||||
let code_source = self
|
||||
.load_code_source(specifier, maybe_referrer, requested_module_type)
|
||||
.await?;
|
||||
|
||||
// If we loaded a JSON file, but the "requested_module_type" (that is computed from
|
||||
// import attributes) is not JSON we need to fail.
|
||||
if module_type == ModuleType::Json
|
||||
&& requested_module_type != RequestedModuleType::Json
|
||||
if code_source.module_type == ModuleType::Json
|
||||
&& *requested_module_type != RequestedModuleType::Json
|
||||
{
|
||||
return Err(CliModuleLoaderError::MissingJsonAttribute);
|
||||
}
|
||||
|
||||
Ok(ModuleSource::new_with_redirect(
|
||||
module_type,
|
||||
code_source.module_type,
|
||||
code_source.code,
|
||||
specifier,
|
||||
&code_source.found_url,
|
||||
|
@ -690,27 +649,22 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
maybe_referrer: Option<&ModuleSpecifier>,
|
||||
requested_module_type: RequestedModuleType,
|
||||
requested_module_type: &RequestedModuleType,
|
||||
) -> Result<ModuleSource, ModuleLoaderError> {
|
||||
let code_source = self
|
||||
.load_code_source(specifier, maybe_referrer)
|
||||
.load_code_source(specifier, maybe_referrer, requested_module_type)
|
||||
.await
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
let module_type = match code_source.media_type {
|
||||
MediaType::Json => ModuleType::Json,
|
||||
MediaType::Wasm => ModuleType::Wasm,
|
||||
_ => ModuleType::JavaScript,
|
||||
};
|
||||
|
||||
// If we loaded a JSON file, but the "requested_module_type" (that is computed from
|
||||
// import attributes) is not JSON we need to fail.
|
||||
if module_type == ModuleType::Json
|
||||
&& requested_module_type != RequestedModuleType::Json
|
||||
if code_source.module_type == ModuleType::Json
|
||||
&& *requested_module_type != RequestedModuleType::Json
|
||||
{
|
||||
return Err(JsErrorBox::generic("Attempted to load JSON module without specifying \"type\": \"json\" attribute in the import statement.").into());
|
||||
}
|
||||
let code = if self.shared.is_inspecting
|
||||
|| code_source.media_type == MediaType::Wasm
|
||||
|| code_source.module_type == ModuleType::Wasm
|
||||
{
|
||||
// we need the code with the source map in order for
|
||||
// it to work with --inspect or --inspect-brk
|
||||
|
@ -720,7 +674,7 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
code_without_source_map(code_source.code)
|
||||
};
|
||||
|
||||
let code_cache = if module_type == ModuleType::JavaScript {
|
||||
let code_cache = if code_source.module_type == ModuleType::JavaScript {
|
||||
self.shared.code_cache.as_ref().map(|cache| {
|
||||
let code_hash = FastInsecureHasher::new_deno_versioned()
|
||||
.write_hashable(&code)
|
||||
|
@ -744,7 +698,7 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
};
|
||||
|
||||
Ok(ModuleSource::new_with_redirect(
|
||||
module_type,
|
||||
code_source.module_type,
|
||||
code,
|
||||
specifier,
|
||||
&code_source.found_url,
|
||||
|
@ -756,13 +710,74 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
maybe_referrer: Option<&ModuleSpecifier>,
|
||||
requested_module_type: &RequestedModuleType,
|
||||
) -> Result<ModuleCodeStringSource, LoadCodeSourceError> {
|
||||
fn as_deno_resolver_requested_module_type(
|
||||
value: &RequestedModuleType,
|
||||
) -> deno_resolver::loader::RequestedModuleType<'_> {
|
||||
match value {
|
||||
RequestedModuleType::None => {
|
||||
deno_resolver::loader::RequestedModuleType::None
|
||||
}
|
||||
RequestedModuleType::Json => {
|
||||
deno_resolver::loader::RequestedModuleType::Json
|
||||
}
|
||||
RequestedModuleType::Text => {
|
||||
deno_resolver::loader::RequestedModuleType::Text
|
||||
}
|
||||
RequestedModuleType::Bytes => {
|
||||
deno_resolver::loader::RequestedModuleType::Bytes
|
||||
}
|
||||
RequestedModuleType::Other(text) => {
|
||||
deno_resolver::loader::RequestedModuleType::Other(text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let graph = self.graph_container.graph();
|
||||
match self
|
||||
.load_prepared_module(specifier)
|
||||
.shared
|
||||
.prepared_module_loader
|
||||
.load_prepared_module(
|
||||
&graph,
|
||||
specifier,
|
||||
&as_deno_resolver_requested_module_type(requested_module_type),
|
||||
)
|
||||
.await
|
||||
.map_err(LoadCodeSourceError::from_err)?
|
||||
.map_err(LoadCodeSourceError::from)?
|
||||
{
|
||||
Some(code) => Ok(code),
|
||||
Some(module_or_asset) => match module_or_asset {
|
||||
PreparedModuleOrAsset::Module(prepared_module) => {
|
||||
Ok(ModuleCodeStringSource {
|
||||
code: match prepared_module.source {
|
||||
PreparedModuleSource::ArcStr(text) => {
|
||||
ModuleSourceCode::String(text.into())
|
||||
}
|
||||
PreparedModuleSource::ArcBytes(bytes) => {
|
||||
ModuleSourceCode::Bytes(bytes.into())
|
||||
}
|
||||
},
|
||||
found_url: prepared_module.specifier.clone(),
|
||||
module_type: match requested_module_type {
|
||||
RequestedModuleType::Json => ModuleType::Json,
|
||||
RequestedModuleType::Text => ModuleType::Text,
|
||||
RequestedModuleType::Bytes => ModuleType::Bytes,
|
||||
RequestedModuleType::None | RequestedModuleType::Other(_) => {
|
||||
module_type_from_media_type(prepared_module.media_type)
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
PreparedModuleOrAsset::ExternalAsset { specifier } => {
|
||||
self.load_asset(
|
||||
specifier,
|
||||
/* do not use dynamic import permissions because this was statically analyzable */ CheckSpecifierKind::Static,
|
||||
requested_module_type
|
||||
)
|
||||
.await
|
||||
.map_err(|err| LoadCodeSourceErrorKind::Fetch(err).into_box())
|
||||
}
|
||||
},
|
||||
None => {
|
||||
let specifier = if let Ok(reference) =
|
||||
NpmPackageReqReference::from_specifier(specifier)
|
||||
|
@ -776,7 +791,7 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
None => Cow::Owned(
|
||||
self
|
||||
.resolve_referrer("")
|
||||
.map_err(LoadCodeSourceError::from_err)?,
|
||||
.map_err(LoadCodeSourceError::from)?,
|
||||
),
|
||||
};
|
||||
Cow::Owned(
|
||||
|
@ -789,10 +804,10 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
ResolutionMode::Import,
|
||||
NodeResolutionKind::Execution,
|
||||
)
|
||||
.map_err(LoadCodeSourceError::from_err)?
|
||||
.map_err(LoadCodeSourceError::from)?
|
||||
.unwrap()
|
||||
.into_url()
|
||||
.map_err(LoadCodeSourceError::from_err)?,
|
||||
.map_err(LoadCodeSourceError::from)?,
|
||||
)
|
||||
} else {
|
||||
Cow::Borrowed(specifier)
|
||||
|
@ -803,16 +818,70 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
.npm_module_loader
|
||||
.load(&specifier, maybe_referrer)
|
||||
.await
|
||||
.map_err(LoadCodeSourceError::from_err);
|
||||
.map_err(LoadCodeSourceError::from);
|
||||
}
|
||||
|
||||
match requested_module_type {
|
||||
RequestedModuleType::Text | RequestedModuleType::Bytes => self
|
||||
.load_asset(
|
||||
&specifier,
|
||||
/* force using permissions because this was not statically analyzable */ CheckSpecifierKind::Dynamic,
|
||||
requested_module_type
|
||||
)
|
||||
.await
|
||||
.map_err(LoadCodeSourceError::from),
|
||||
_ => Err(LoadCodeSourceError::from(LoadUnpreparedModuleError {
|
||||
specifier: specifier.into_owned(),
|
||||
maybe_referrer: maybe_referrer.cloned(),
|
||||
})),
|
||||
}
|
||||
Err(LoadCodeSourceError::from_err(LoadUnpreparedModuleError {
|
||||
specifier: specifier.into_owned(),
|
||||
maybe_referrer: maybe_referrer.cloned(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn load_asset(
|
||||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
check_specifier_kind: CheckSpecifierKind,
|
||||
requested_module_type: &RequestedModuleType,
|
||||
) -> Result<ModuleCodeStringSource, deno_resolver::file_fetcher::FetchError>
|
||||
{
|
||||
let file = self
|
||||
.shared
|
||||
.file_fetcher
|
||||
.fetch_with_options(
|
||||
specifier,
|
||||
FetchPermissionsOptionRef::Restricted(
|
||||
match check_specifier_kind {
|
||||
CheckSpecifierKind::Static => &self.permissions,
|
||||
CheckSpecifierKind::Dynamic => &self.parent_permissions,
|
||||
},
|
||||
check_specifier_kind,
|
||||
),
|
||||
FetchOptions {
|
||||
local: FetchLocalOptions {
|
||||
include_mtime: false,
|
||||
},
|
||||
maybe_auth: None,
|
||||
maybe_accept: None,
|
||||
maybe_cache_setting: Some(
|
||||
&deno_cache_dir::file_fetcher::CacheSetting::Use,
|
||||
),
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(ModuleCodeStringSource {
|
||||
code: ModuleSourceCode::Bytes(file.source.into()),
|
||||
found_url: file.url,
|
||||
module_type: match requested_module_type {
|
||||
RequestedModuleType::Text => ModuleType::Text,
|
||||
RequestedModuleType::Bytes => ModuleType::Bytes,
|
||||
_ => unreachable!(),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async fn maybe_reload_dynamic(
|
||||
&self,
|
||||
graph: &ModuleGraph,
|
||||
|
@ -869,7 +938,10 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
self.has_module_changed_on_file_system(specifier, module.mtime())
|
||||
}
|
||||
deno_graph::ModuleEntryRef::Err(err) => {
|
||||
if matches!(err, deno_graph::ModuleError::Missing { .. }) {
|
||||
if matches!(
|
||||
err.as_kind(),
|
||||
deno_graph::ModuleErrorKind::Missing { .. }
|
||||
) {
|
||||
self.mtime_of_specifier(specifier).is_some() // it exists now
|
||||
} else {
|
||||
self.has_module_changed_on_file_system(specifier, err.mtime())
|
||||
|
@ -955,7 +1027,10 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
&& !specifier.as_str().starts_with(jsr_url().as_str())
|
||||
&& matches!(specifier.scheme(), "http" | "https")
|
||||
{
|
||||
return Err(JsErrorBox::generic(format!("Importing {} blocked. JSR packages cannot import non-JSR remote modules for security reasons.", specifier)));
|
||||
return Err(JsErrorBox::generic(format!(
|
||||
"Importing {} blocked. JSR packages cannot import non-JSR remote modules for security reasons.",
|
||||
specifier
|
||||
)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1012,255 +1087,6 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
|
||||
Ok(specifier)
|
||||
}
|
||||
|
||||
async fn load_prepared_module(
|
||||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
) -> Result<Option<ModuleCodeStringSource>, LoadPreparedModuleError> {
|
||||
// Note: keep this in sync with the sync version below
|
||||
let graph = self.graph_container.graph();
|
||||
match self.load_prepared_module_or_defer_emit(&graph, specifier)? {
|
||||
Some(CodeOrDeferredEmit::Code(code_source)) => Ok(Some(code_source)),
|
||||
Some(CodeOrDeferredEmit::DeferredEmit {
|
||||
specifier,
|
||||
media_type,
|
||||
source,
|
||||
}) => {
|
||||
let transpile_result = self
|
||||
.emitter
|
||||
.emit_parsed_source(specifier, media_type, ModuleKind::Esm, source)
|
||||
.await?;
|
||||
|
||||
// at this point, we no longer need the parsed source in memory, so free it
|
||||
self.parsed_source_cache.free(specifier);
|
||||
|
||||
Ok(Some(ModuleCodeStringSource {
|
||||
// note: it's faster to provide a string if we know it's a string
|
||||
code: ModuleSourceCode::String(transpile_result.into()),
|
||||
found_url: specifier.clone(),
|
||||
media_type,
|
||||
}))
|
||||
}
|
||||
Some(CodeOrDeferredEmit::Cjs {
|
||||
specifier,
|
||||
media_type,
|
||||
source,
|
||||
}) => self
|
||||
.load_maybe_cjs(specifier, media_type, source)
|
||||
.await
|
||||
.map(Some)
|
||||
.map_err(LoadPreparedModuleError::LoadMaybeCjs),
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
fn load_prepared_module_for_source_map_sync(
|
||||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
) -> Result<Option<ModuleCodeStringSource>, AnyError> {
|
||||
// Note: keep this in sync with the async version above
|
||||
let graph = self.graph_container.graph();
|
||||
match self.load_prepared_module_or_defer_emit(&graph, specifier)? {
|
||||
Some(CodeOrDeferredEmit::Code(code_source)) => Ok(Some(code_source)),
|
||||
Some(CodeOrDeferredEmit::DeferredEmit {
|
||||
specifier,
|
||||
media_type,
|
||||
source,
|
||||
}) => {
|
||||
let transpile_result = self.emitter.emit_parsed_source_sync(
|
||||
specifier,
|
||||
media_type,
|
||||
ModuleKind::Esm,
|
||||
source,
|
||||
)?;
|
||||
|
||||
// at this point, we no longer need the parsed source in memory, so free it
|
||||
self.parsed_source_cache.free(specifier);
|
||||
|
||||
Ok(Some(ModuleCodeStringSource {
|
||||
// note: it's faster to provide a string if we know it's a string
|
||||
code: ModuleSourceCode::String(transpile_result.into()),
|
||||
found_url: specifier.clone(),
|
||||
media_type,
|
||||
}))
|
||||
}
|
||||
Some(CodeOrDeferredEmit::Cjs { .. }) => {
|
||||
self.parsed_source_cache.free(specifier);
|
||||
|
||||
// todo(dsherret): to make this work, we should probably just
|
||||
// rely on the CJS export cache. At the moment this is hard because
|
||||
// cjs export analysis is only async
|
||||
Ok(None)
|
||||
}
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
fn load_prepared_module_or_defer_emit<'graph>(
|
||||
&self,
|
||||
graph: &'graph ModuleGraph,
|
||||
specifier: &ModuleSpecifier,
|
||||
) -> Result<Option<CodeOrDeferredEmit<'graph>>, LoadPreparedModuleError> {
|
||||
if specifier.scheme() == "node" {
|
||||
// Node built-in modules should be handled internally.
|
||||
unreachable!("Deno bug. {} was misconfigured internally.", specifier);
|
||||
}
|
||||
|
||||
let maybe_module = graph.try_get(specifier).map_err(|err| {
|
||||
Box::new(EnhancedGraphError {
|
||||
message: enhance_graph_error(
|
||||
&self.shared.sys,
|
||||
&ModuleGraphError::ModuleError(err.clone()),
|
||||
EnhanceGraphErrorMode::ShowRange,
|
||||
),
|
||||
error: err.clone(),
|
||||
})
|
||||
})?;
|
||||
|
||||
match maybe_module {
|
||||
Some(deno_graph::Module::Json(JsonModule {
|
||||
source,
|
||||
media_type,
|
||||
specifier,
|
||||
..
|
||||
})) => Ok(Some(CodeOrDeferredEmit::Code(ModuleCodeStringSource {
|
||||
code: ModuleSourceCode::String(source.clone().into()),
|
||||
found_url: specifier.clone(),
|
||||
media_type: *media_type,
|
||||
}))),
|
||||
Some(deno_graph::Module::Js(JsModule {
|
||||
source,
|
||||
media_type,
|
||||
specifier,
|
||||
is_script,
|
||||
..
|
||||
})) => {
|
||||
if self
|
||||
.shared
|
||||
.cjs_tracker
|
||||
.is_cjs_with_known_is_script(specifier, *media_type, *is_script)
|
||||
.map_err(JsErrorBox::from_err)?
|
||||
{
|
||||
return Ok(Some(CodeOrDeferredEmit::Cjs {
|
||||
specifier,
|
||||
media_type: *media_type,
|
||||
source,
|
||||
}));
|
||||
}
|
||||
let code: ModuleCodeString = match media_type {
|
||||
MediaType::JavaScript
|
||||
| MediaType::Unknown
|
||||
| MediaType::Mjs
|
||||
| MediaType::Json => source.clone().into(),
|
||||
MediaType::Dts | MediaType::Dcts | MediaType::Dmts => {
|
||||
Default::default()
|
||||
}
|
||||
MediaType::Cjs | MediaType::Cts => {
|
||||
return Ok(Some(CodeOrDeferredEmit::Cjs {
|
||||
specifier,
|
||||
media_type: *media_type,
|
||||
source,
|
||||
}));
|
||||
}
|
||||
MediaType::TypeScript
|
||||
| MediaType::Mts
|
||||
| MediaType::Jsx
|
||||
| MediaType::Tsx => {
|
||||
return Ok(Some(CodeOrDeferredEmit::DeferredEmit {
|
||||
specifier,
|
||||
media_type: *media_type,
|
||||
source,
|
||||
}));
|
||||
}
|
||||
MediaType::Css
|
||||
| MediaType::Html
|
||||
| MediaType::Sql
|
||||
| MediaType::Wasm
|
||||
| MediaType::SourceMap => {
|
||||
panic!("Unexpected media type {media_type} for {specifier}")
|
||||
}
|
||||
};
|
||||
|
||||
// at this point, we no longer need the parsed source in memory, so free it
|
||||
self.parsed_source_cache.free(specifier);
|
||||
|
||||
Ok(Some(CodeOrDeferredEmit::Code(ModuleCodeStringSource {
|
||||
code: ModuleSourceCode::String(code),
|
||||
found_url: specifier.clone(),
|
||||
media_type: *media_type,
|
||||
})))
|
||||
}
|
||||
Some(deno_graph::Module::Wasm(WasmModule {
|
||||
source, specifier, ..
|
||||
})) => Ok(Some(CodeOrDeferredEmit::Code(ModuleCodeStringSource {
|
||||
code: ModuleSourceCode::Bytes(source.clone().into()),
|
||||
found_url: specifier.clone(),
|
||||
media_type: MediaType::Wasm,
|
||||
}))),
|
||||
Some(
|
||||
deno_graph::Module::External(_)
|
||||
| deno_graph::Module::Node(_)
|
||||
| deno_graph::Module::Npm(_),
|
||||
)
|
||||
| None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
async fn load_maybe_cjs(
|
||||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
media_type: MediaType,
|
||||
original_source: &Arc<str>,
|
||||
) -> Result<ModuleCodeStringSource, LoadMaybeCjsError> {
|
||||
let js_source = if media_type.is_emittable() {
|
||||
Cow::Owned(
|
||||
self
|
||||
.emitter
|
||||
.emit_parsed_source(
|
||||
specifier,
|
||||
media_type,
|
||||
ModuleKind::Cjs,
|
||||
original_source,
|
||||
)
|
||||
.await?,
|
||||
)
|
||||
} else {
|
||||
Cow::Borrowed(original_source.as_ref())
|
||||
};
|
||||
let text = self
|
||||
.node_code_translator
|
||||
.translate_cjs_to_esm(specifier, Some(js_source))
|
||||
.await?;
|
||||
// at this point, we no longer need the parsed source in memory, so free it
|
||||
self.parsed_source_cache.free(specifier);
|
||||
Ok(ModuleCodeStringSource {
|
||||
code: match text {
|
||||
// perf: if the text is borrowed, that means it didn't make any changes
|
||||
// to the original source, so we can just provide that instead of cloning
|
||||
// the borrowed text
|
||||
Cow::Borrowed(_) => {
|
||||
ModuleSourceCode::String(original_source.clone().into())
|
||||
}
|
||||
Cow::Owned(text) => ModuleSourceCode::String(text.into()),
|
||||
},
|
||||
found_url: specifier.clone(),
|
||||
media_type,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
enum CodeOrDeferredEmit<'a> {
|
||||
Code(ModuleCodeStringSource),
|
||||
DeferredEmit {
|
||||
specifier: &'a ModuleSpecifier,
|
||||
media_type: MediaType,
|
||||
source: &'a Arc<str>,
|
||||
},
|
||||
Cjs {
|
||||
specifier: &'a ModuleSpecifier,
|
||||
media_type: MediaType,
|
||||
source: &'a Arc<str>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -1330,7 +1156,7 @@ impl<TGraphContainer: ModuleGraphContainer> ModuleLoader
|
|||
.load_inner(
|
||||
&specifier,
|
||||
maybe_referrer.as_ref(),
|
||||
requested_module_type,
|
||||
&requested_module_type,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
@ -1343,8 +1169,19 @@ impl<TGraphContainer: ModuleGraphContainer> ModuleLoader
|
|||
specifier: &ModuleSpecifier,
|
||||
_maybe_referrer: Option<String>,
|
||||
is_dynamic: bool,
|
||||
requested_module_type: RequestedModuleType,
|
||||
) -> Pin<Box<dyn Future<Output = Result<(), ModuleLoaderError>>>> {
|
||||
// always call this first unconditionally because it will be
|
||||
// decremented unconditionally in "finish_load"
|
||||
self.0.shared.in_flight_loads_tracker.increase();
|
||||
|
||||
if matches!(
|
||||
requested_module_type,
|
||||
RequestedModuleType::Text | RequestedModuleType::Bytes
|
||||
) {
|
||||
return Box::pin(deno_core::futures::future::ready(Ok(())));
|
||||
}
|
||||
|
||||
if self.0.shared.in_npm_pkg_checker.in_npm_package(specifier) {
|
||||
return Box::pin(deno_core::futures::future::ready(Ok(())));
|
||||
}
|
||||
|
@ -1480,11 +1317,14 @@ impl<TGraphContainer: ModuleGraphContainer> ModuleLoader
|
|||
"wasm" | "file" | "http" | "https" | "data" | "blob" => (),
|
||||
_ => return None,
|
||||
}
|
||||
let graph = self.0.graph_container.graph();
|
||||
let source = self
|
||||
.0
|
||||
.load_prepared_module_for_source_map_sync(&specifier)
|
||||
.shared
|
||||
.prepared_module_loader
|
||||
.load_prepared_module_for_source_map_sync(&graph, &specifier)
|
||||
.ok()??;
|
||||
source_map_from_code(source.code.as_bytes()).map(Cow::Owned)
|
||||
source_map_from_code(source.source.as_bytes()).map(Cow::Owned)
|
||||
}
|
||||
|
||||
fn get_source_mapped_source_line(
|
||||
|
@ -1494,8 +1334,8 @@ impl<TGraphContainer: ModuleGraphContainer> ModuleLoader
|
|||
) -> Option<String> {
|
||||
let graph = self.0.graph_container.graph();
|
||||
let code = match graph.get(&resolve_url(file_name).ok()?) {
|
||||
Some(deno_graph::Module::Js(module)) => &module.source,
|
||||
Some(deno_graph::Module::Json(module)) => &module.source,
|
||||
Some(deno_graph::Module::Js(module)) => &module.source.text,
|
||||
Some(deno_graph::Module::Json(module)) => &module.source.text,
|
||||
_ => return None,
|
||||
};
|
||||
// Do NOT use .lines(): it skips the terminating empty line.
|
||||
|
@ -1504,7 +1344,8 @@ impl<TGraphContainer: ModuleGraphContainer> ModuleLoader
|
|||
if line_number >= lines.len() {
|
||||
Some(format!(
|
||||
"{} Couldn't format source line: Line {} is out of bounds (source may have changed at runtime)",
|
||||
crate::colors::yellow("Warning"), line_number + 1,
|
||||
crate::colors::yellow("Warning"),
|
||||
line_number + 1,
|
||||
))
|
||||
} else {
|
||||
Some(lines[line_number].to_string())
|
||||
|
@ -1566,7 +1407,7 @@ impl ModuleGraphUpdatePermit for WorkerModuleGraphUpdatePermit {
|
|||
#[derive(Debug)]
|
||||
struct CliNodeRequireLoader<TGraphContainer: ModuleGraphContainer> {
|
||||
cjs_tracker: Arc<CliCjsTracker>,
|
||||
emitter: Arc<Emitter>,
|
||||
emitter: Arc<CliEmitter>,
|
||||
npm_resolver: CliNpmResolver,
|
||||
sys: CliSys,
|
||||
graph_container: TGraphContainer,
|
||||
|
@ -1598,7 +1439,7 @@ impl<TGraphContainer: ModuleGraphContainer> NodeRequireLoader
|
|||
fn load_text_file_lossy(
|
||||
&self,
|
||||
path: &Path,
|
||||
) -> Result<Cow<'static, str>, JsErrorBox> {
|
||||
) -> Result<FastString, JsErrorBox> {
|
||||
// todo(dsherret): use the preloaded module from the graph if available?
|
||||
let media_type = MediaType::from_path(path);
|
||||
let text = self
|
||||
|
@ -1613,9 +1454,9 @@ impl<TGraphContainer: ModuleGraphContainer> NodeRequireLoader
|
|||
specifier,
|
||||
}));
|
||||
}
|
||||
self
|
||||
let text = self
|
||||
.emitter
|
||||
.emit_parsed_source_sync(
|
||||
.maybe_emit_source_sync(
|
||||
&specifier,
|
||||
media_type,
|
||||
// this is probably not super accurate due to require esm, but probably ok.
|
||||
|
@ -1624,10 +1465,13 @@ impl<TGraphContainer: ModuleGraphContainer> NodeRequireLoader
|
|||
ModuleKind::Cjs,
|
||||
&text.into(),
|
||||
)
|
||||
.map(Cow::Owned)
|
||||
.map_err(JsErrorBox::from_err)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
Ok(text.into())
|
||||
} else {
|
||||
Ok(text)
|
||||
Ok(match text {
|
||||
Cow::Borrowed(s) => FastString::from_static(s),
|
||||
Cow::Owned(s) => s.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1756,7 +1600,7 @@ mod tests {
|
|||
let source = "const a = 'hello';";
|
||||
let parsed_source_cache = Arc::new(ParsedSourceCache::default());
|
||||
let parsed_source = parsed_source_cache
|
||||
.remove_or_parse_module(&specifier, source.into(), MediaType::JavaScript)
|
||||
.remove_or_parse_module(&specifier, MediaType::JavaScript, source.into())
|
||||
.unwrap();
|
||||
parsed_source_cache.set_parsed_source(specifier, parsed_source);
|
||||
|
||||
|
|
203
cli/node.rs
203
cli/node.rs
|
@ -1,32 +1,15 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_ast::MediaType;
|
||||
use deno_ast::ModuleExportsAndReExports;
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_graph::ast::ParsedSourceStore;
|
||||
use deno_resolver::cjs::analyzer::DenoCjsCodeAnalyzer;
|
||||
use deno_resolver::npm::DenoInNpmPackageChecker;
|
||||
use deno_runtime::deno_fs;
|
||||
use node_resolver::analyze::CjsAnalysis as ExtNodeCjsAnalysis;
|
||||
use node_resolver::analyze::CjsAnalysisExports;
|
||||
use node_resolver::analyze::CjsCodeAnalyzer;
|
||||
use node_resolver::analyze::CjsModuleExportAnalyzer;
|
||||
use node_resolver::analyze::EsmAnalysisMode;
|
||||
use node_resolver::analyze::NodeCodeTranslator;
|
||||
use node_resolver::DenoIsBuiltInNodeModuleChecker;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use node_resolver::analyze::CjsModuleExportAnalyzer;
|
||||
|
||||
use crate::cache::CacheDBHash;
|
||||
use crate::cache::NodeAnalysisCache;
|
||||
use crate::cache::ParsedSourceCache;
|
||||
use crate::npm::CliNpmResolver;
|
||||
use crate::resolver::CliCjsTracker;
|
||||
use crate::sys::CliSys;
|
||||
|
||||
pub type CliCjsCodeAnalyzer = DenoCjsCodeAnalyzer<CliSys>;
|
||||
|
||||
pub type CliCjsModuleExportAnalyzer = CjsModuleExportAnalyzer<
|
||||
CliCjsCodeAnalyzer,
|
||||
DenoInNpmPackageChecker,
|
||||
|
@ -34,187 +17,9 @@ pub type CliCjsModuleExportAnalyzer = CjsModuleExportAnalyzer<
|
|||
CliNpmResolver,
|
||||
CliSys,
|
||||
>;
|
||||
pub type CliNodeCodeTranslator = NodeCodeTranslator<
|
||||
CliCjsCodeAnalyzer,
|
||||
DenoInNpmPackageChecker,
|
||||
DenoIsBuiltInNodeModuleChecker,
|
||||
CliNpmResolver,
|
||||
CliSys,
|
||||
>;
|
||||
pub type CliNodeResolver = deno_runtime::deno_node::NodeResolver<
|
||||
DenoInNpmPackageChecker,
|
||||
CliNpmResolver,
|
||||
CliSys,
|
||||
>;
|
||||
pub type CliPackageJsonResolver = node_resolver::PackageJsonResolver<CliSys>;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum CliCjsAnalysis {
|
||||
/// The module was found to be an ES module.
|
||||
Esm,
|
||||
/// The module was found to be an ES module and
|
||||
/// it was analyzed for imports and exports.
|
||||
EsmAnalysis(ModuleExportsAndReExports),
|
||||
/// The module was CJS.
|
||||
Cjs(ModuleExportsAndReExports),
|
||||
}
|
||||
|
||||
pub struct CliCjsCodeAnalyzer {
|
||||
cache: NodeAnalysisCache,
|
||||
cjs_tracker: Arc<CliCjsTracker>,
|
||||
fs: deno_fs::FileSystemRc,
|
||||
parsed_source_cache: Option<Arc<ParsedSourceCache>>,
|
||||
}
|
||||
|
||||
impl CliCjsCodeAnalyzer {
|
||||
pub fn new(
|
||||
cache: NodeAnalysisCache,
|
||||
cjs_tracker: Arc<CliCjsTracker>,
|
||||
fs: deno_fs::FileSystemRc,
|
||||
parsed_source_cache: Option<Arc<ParsedSourceCache>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
cache,
|
||||
cjs_tracker,
|
||||
fs,
|
||||
parsed_source_cache,
|
||||
}
|
||||
}
|
||||
|
||||
async fn inner_cjs_analysis(
|
||||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
source: &str,
|
||||
esm_analysis_mode: EsmAnalysisMode,
|
||||
) -> Result<CliCjsAnalysis, JsErrorBox> {
|
||||
let source = source.strip_prefix('\u{FEFF}').unwrap_or(source); // strip BOM
|
||||
let source_hash = CacheDBHash::from_hashable(source);
|
||||
if let Some(analysis) =
|
||||
self.cache.get_cjs_analysis(specifier.as_str(), source_hash)
|
||||
{
|
||||
return Ok(analysis);
|
||||
}
|
||||
|
||||
let media_type = MediaType::from_specifier(specifier);
|
||||
if media_type == MediaType::Json {
|
||||
return Ok(CliCjsAnalysis::Cjs(Default::default()));
|
||||
}
|
||||
|
||||
let cjs_tracker = self.cjs_tracker.clone();
|
||||
let is_maybe_cjs = cjs_tracker
|
||||
.is_maybe_cjs(specifier, media_type)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
let analysis = if is_maybe_cjs
|
||||
|| esm_analysis_mode == EsmAnalysisMode::SourceImportsAndExports
|
||||
{
|
||||
let maybe_parsed_source = self
|
||||
.parsed_source_cache
|
||||
.as_ref()
|
||||
.and_then(|c| c.remove_parsed_source(specifier));
|
||||
|
||||
deno_core::unsync::spawn_blocking({
|
||||
let specifier = specifier.clone();
|
||||
let source: Arc<str> = source.into();
|
||||
move || -> Result<_, JsErrorBox> {
|
||||
let parsed_source = maybe_parsed_source
|
||||
.map(Ok)
|
||||
.unwrap_or_else(|| {
|
||||
deno_ast::parse_program(deno_ast::ParseParams {
|
||||
specifier,
|
||||
text: source,
|
||||
media_type,
|
||||
capture_tokens: true,
|
||||
scope_analysis: false,
|
||||
maybe_syntax: None,
|
||||
})
|
||||
})
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
let is_script = is_maybe_cjs && parsed_source.compute_is_script();
|
||||
let is_cjs = is_maybe_cjs
|
||||
&& cjs_tracker
|
||||
.is_cjs_with_known_is_script(
|
||||
parsed_source.specifier(),
|
||||
media_type,
|
||||
is_script,
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
if is_cjs {
|
||||
let analysis = parsed_source.analyze_cjs();
|
||||
Ok(CliCjsAnalysis::Cjs(analysis))
|
||||
} else {
|
||||
match esm_analysis_mode {
|
||||
EsmAnalysisMode::SourceOnly => Ok(CliCjsAnalysis::Esm),
|
||||
EsmAnalysisMode::SourceImportsAndExports => {
|
||||
Ok(CliCjsAnalysis::EsmAnalysis(
|
||||
parsed_source.analyze_es_runtime_exports(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.await
|
||||
.unwrap()?
|
||||
} else {
|
||||
CliCjsAnalysis::Esm
|
||||
};
|
||||
|
||||
self
|
||||
.cache
|
||||
.set_cjs_analysis(specifier.as_str(), source_hash, &analysis);
|
||||
|
||||
Ok(analysis)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl CjsCodeAnalyzer for CliCjsCodeAnalyzer {
|
||||
async fn analyze_cjs<'a>(
|
||||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
source: Option<Cow<'a, str>>,
|
||||
esm_analysis_mode: EsmAnalysisMode,
|
||||
) -> Result<ExtNodeCjsAnalysis<'a>, JsErrorBox> {
|
||||
let source = match source {
|
||||
Some(source) => source,
|
||||
None => {
|
||||
if let Ok(path) = specifier.to_file_path() {
|
||||
if let Ok(source_from_file) =
|
||||
self.fs.read_text_file_lossy_async(path, None).await
|
||||
{
|
||||
source_from_file
|
||||
} else {
|
||||
return Ok(ExtNodeCjsAnalysis::Cjs(CjsAnalysisExports {
|
||||
exports: vec![],
|
||||
reexports: vec![],
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
return Ok(ExtNodeCjsAnalysis::Cjs(CjsAnalysisExports {
|
||||
exports: vec![],
|
||||
reexports: vec![],
|
||||
}));
|
||||
}
|
||||
}
|
||||
};
|
||||
let analysis = self
|
||||
.inner_cjs_analysis(specifier, &source, esm_analysis_mode)
|
||||
.await?;
|
||||
match analysis {
|
||||
CliCjsAnalysis::Esm => Ok(ExtNodeCjsAnalysis::Esm(source, None)),
|
||||
CliCjsAnalysis::EsmAnalysis(analysis) => Ok(ExtNodeCjsAnalysis::Esm(
|
||||
source,
|
||||
Some(CjsAnalysisExports {
|
||||
exports: analysis.exports,
|
||||
reexports: analysis.reexports,
|
||||
}),
|
||||
)),
|
||||
CliCjsAnalysis::Cjs(analysis) => {
|
||||
Ok(ExtNodeCjsAnalysis::Cjs(CjsAnalysisExports {
|
||||
exports: analysis.exports,
|
||||
reexports: analysis.reexports,
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
44
cli/npm.rs
44
cli/npm.rs
|
@ -12,23 +12,25 @@ use deno_core::serde_json;
|
|||
use deno_core::url::Url;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_lib::version::DENO_VERSION_INFO;
|
||||
use deno_npm::NpmResolutionPackage;
|
||||
use deno_npm::npm_rc::ResolvedNpmRc;
|
||||
use deno_npm::registry::NpmPackageInfo;
|
||||
use deno_npm::resolution::NpmResolutionSnapshot;
|
||||
use deno_npm::NpmResolutionPackage;
|
||||
use deno_npm_cache::NpmCacheHttpClientBytesResponse;
|
||||
use deno_npm_cache::NpmCacheHttpClientResponse;
|
||||
use deno_npm_installer::lifecycle_scripts::is_broken_default_install_script;
|
||||
use deno_npm_installer::lifecycle_scripts::LifecycleScriptsExecutor;
|
||||
use deno_npm_installer::lifecycle_scripts::LifecycleScriptsExecutorOptions;
|
||||
use deno_npm_installer::lifecycle_scripts::PackageWithScript;
|
||||
use deno_npm_installer::lifecycle_scripts::LIFECYCLE_SCRIPTS_RUNNING_ENV_VAR;
|
||||
use deno_npm_installer::BinEntries;
|
||||
use deno_npm_installer::CachedNpmPackageExtraInfoProvider;
|
||||
use deno_npm_installer::ExpectedExtraInfo;
|
||||
use deno_npm_installer::lifecycle_scripts::LIFECYCLE_SCRIPTS_RUNNING_ENV_VAR;
|
||||
use deno_npm_installer::lifecycle_scripts::LifecycleScriptsExecutor;
|
||||
use deno_npm_installer::lifecycle_scripts::LifecycleScriptsExecutorOptions;
|
||||
use deno_npm_installer::lifecycle_scripts::PackageWithScript;
|
||||
use deno_npm_installer::lifecycle_scripts::is_broken_default_install_script;
|
||||
use deno_resolver::npm::ByonmNpmResolverCreateOptions;
|
||||
use deno_resolver::npm::ManagedNpmResolverRc;
|
||||
use deno_runtime::deno_io::FromRawIoHandle;
|
||||
use deno_semver::Version;
|
||||
use deno_semver::VersionReq;
|
||||
use deno_semver::package::PackageNv;
|
||||
use deno_semver::package::PackageReq;
|
||||
use deno_task_shell::KillSignal;
|
||||
|
@ -179,18 +181,8 @@ impl NpmFetchResolver {
|
|||
let maybe_get_nv = || async {
|
||||
let name = req.name.clone();
|
||||
let package_info = self.package_info(&name).await?;
|
||||
if let Some(dist_tag) = req.version_req.tag() {
|
||||
let version = package_info.dist_tags.get(dist_tag)?.clone();
|
||||
return Some(PackageNv { name, version });
|
||||
}
|
||||
// Find the first matching version of the package.
|
||||
let mut versions = package_info.versions.keys().collect::<Vec<_>>();
|
||||
versions.sort();
|
||||
let version = versions
|
||||
.into_iter()
|
||||
.rev()
|
||||
.find(|v| req.version_req.tag().is_none() && req.version_req.matches(v))
|
||||
.cloned()?;
|
||||
let version =
|
||||
version_from_package_info(&package_info, &req.version_req)?.clone();
|
||||
Some(PackageNv { name, version })
|
||||
};
|
||||
let nv = maybe_get_nv().await;
|
||||
|
@ -233,6 +225,22 @@ impl NpmFetchResolver {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn version_from_package_info<'a>(
|
||||
package_info: &'a NpmPackageInfo,
|
||||
version_req: &VersionReq,
|
||||
) -> Option<&'a Version> {
|
||||
if let Some(dist_tag) = version_req.tag() {
|
||||
return package_info.dist_tags.get(dist_tag);
|
||||
}
|
||||
// Find the first matching version of the package.
|
||||
let mut versions = package_info.versions.keys().collect::<Vec<_>>();
|
||||
versions.sort();
|
||||
versions
|
||||
.into_iter()
|
||||
.rev()
|
||||
.find(|v| version_req.tag().is_none() && version_req.matches(v))
|
||||
}
|
||||
|
||||
pub static NPM_CONFIG_USER_AGENT_ENV_VAR: &str = "npm_config_user_agent";
|
||||
|
||||
pub fn get_npm_config_user_agent() -> String {
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
use deno_core::op2;
|
||||
use deno_core::v8;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::OpState;
|
||||
use deno_core::op2;
|
||||
use deno_core::v8;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_runtime::deno_permissions::ChildPermissionsArg;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
|
@ -77,16 +77,19 @@ pub fn op_restore_test_permissions(
|
|||
state: &mut OpState,
|
||||
#[serde] token: Uuid,
|
||||
) -> Result<(), JsErrorBox> {
|
||||
if let Some(permissions_holder) = state.try_take::<PermissionsHolder>() {
|
||||
if token != permissions_holder.0 {
|
||||
panic!("restore test permissions token does not match the stored token");
|
||||
}
|
||||
match state.try_take::<PermissionsHolder>() {
|
||||
Some(permissions_holder) => {
|
||||
if token != permissions_holder.0 {
|
||||
panic!(
|
||||
"restore test permissions token does not match the stored token"
|
||||
);
|
||||
}
|
||||
|
||||
let permissions = permissions_holder.1;
|
||||
state.put::<PermissionsContainer>(permissions);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(JsErrorBox::generic("no permissions to restore"))
|
||||
let permissions = permissions_holder.1;
|
||||
state.put::<PermissionsContainer>(permissions);
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(JsErrorBox::generic("no permissions to restore")),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,11 +8,11 @@ use std::cell::RefCell;
|
|||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_core::OpState;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op2;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::OpState;
|
||||
use deno_error::JsErrorBox;
|
||||
use jupyter_runtime::InputRequest;
|
||||
use jupyter_runtime::JupyterMessage;
|
||||
|
@ -329,7 +329,7 @@ pub fn op_jupyter_create_png_from_texture(
|
|||
return Err(JsErrorBox::type_error(format!(
|
||||
"Unsupported texture format '{}'",
|
||||
texture.format.as_str()
|
||||
)))
|
||||
)));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ use deno_ast::ParseDiagnostic;
|
|||
use deno_ast::SourceRange;
|
||||
use deno_ast::SourceTextInfo;
|
||||
use deno_ast::SourceTextProvider;
|
||||
use deno_core::op2;
|
||||
use deno_core::OpState;
|
||||
use deno_core::op2;
|
||||
use deno_lint::diagnostic::LintDiagnostic;
|
||||
use deno_lint::diagnostic::LintDiagnosticDetails;
|
||||
use deno_lint::diagnostic::LintDiagnosticRange;
|
||||
|
@ -236,7 +236,9 @@ struct LintReportFix {
|
|||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum LintReportError {
|
||||
#[class(type)]
|
||||
#[error("Invalid range [{start}, {end}], the source has a range of [0, {source_end}]")]
|
||||
#[error(
|
||||
"Invalid range [{start}, {end}], the source has a range of [0, {source_end}]"
|
||||
)]
|
||||
IncorrectRange {
|
||||
start: usize,
|
||||
end: usize,
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
use deno_core::op2;
|
||||
use deno_core::v8;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::OpState;
|
||||
use deno_core::op2;
|
||||
use deno_core::v8;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_runtime::deno_permissions::ChildPermissionsArg;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
|
@ -72,16 +72,19 @@ pub fn op_restore_test_permissions(
|
|||
state: &mut OpState,
|
||||
#[serde] token: Uuid,
|
||||
) -> Result<(), JsErrorBox> {
|
||||
if let Some(permissions_holder) = state.try_take::<PermissionsHolder>() {
|
||||
if token != permissions_holder.0 {
|
||||
panic!("restore test permissions token does not match the stored token");
|
||||
}
|
||||
match state.try_take::<PermissionsHolder>() {
|
||||
Some(permissions_holder) => {
|
||||
if token != permissions_holder.0 {
|
||||
panic!(
|
||||
"restore test permissions token does not match the stored token"
|
||||
);
|
||||
}
|
||||
|
||||
let permissions = permissions_holder.1;
|
||||
state.put::<PermissionsContainer>(permissions);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(JsErrorBox::generic("no permissions to restore"))
|
||||
let permissions = permissions_holder.1;
|
||||
state.put::<PermissionsContainer>(permissions);
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(JsErrorBox::generic("no permissions to restore")),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
[package]
|
||||
name = "denort"
|
||||
version = "2.3.7"
|
||||
version = "2.4.0"
|
||||
authors.workspace = true
|
||||
default-run = "denort"
|
||||
edition.workspace = true
|
||||
|
|
|
@ -8,34 +8,35 @@ use std::path::Path;
|
|||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::FastString;
|
||||
use deno_core::ModuleCodeBytes;
|
||||
use deno_core::ModuleSourceCode;
|
||||
use deno_core::ModuleType;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::FastString;
|
||||
use deno_core::ModuleSourceCode;
|
||||
use deno_core::ModuleType;
|
||||
use deno_error::JsError;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_lib::standalone::binary::DenoRtDeserializable;
|
||||
use deno_lib::standalone::binary::MAGIC_BYTES;
|
||||
use deno_lib::standalone::binary::Metadata;
|
||||
use deno_lib::standalone::binary::RemoteModuleEntry;
|
||||
use deno_lib::standalone::binary::SpecifierDataStore;
|
||||
use deno_lib::standalone::binary::SpecifierId;
|
||||
use deno_lib::standalone::binary::MAGIC_BYTES;
|
||||
use deno_lib::standalone::virtual_fs::VirtualDirectory;
|
||||
use deno_lib::standalone::virtual_fs::VirtualDirectoryEntries;
|
||||
use deno_media_type::MediaType;
|
||||
use deno_npm::NpmPackageId;
|
||||
use deno_npm::resolution::SerializedNpmResolutionSnapshot;
|
||||
use deno_npm::resolution::SerializedNpmResolutionSnapshotPackage;
|
||||
use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot;
|
||||
use deno_npm::NpmPackageId;
|
||||
use deno_runtime::deno_fs::FileSystem;
|
||||
use deno_runtime::deno_fs::RealFs;
|
||||
use deno_runtime::deno_io::fs::FsError;
|
||||
use deno_semver::package::PackageReq;
|
||||
use deno_semver::StackString;
|
||||
use deno_semver::package::PackageReq;
|
||||
use indexmap::IndexMap;
|
||||
use thiserror::Error;
|
||||
|
||||
|
@ -348,12 +349,14 @@ impl StandaloneModules {
|
|||
let mut transpiled = None;
|
||||
let mut source_map = None;
|
||||
let mut cjs_export_analysis = None;
|
||||
let mut is_valid_utf8 = false;
|
||||
let bytes = match self.vfs.file_entry(&path) {
|
||||
Ok(entry) => {
|
||||
let bytes = self
|
||||
.vfs
|
||||
.read_file_all(entry)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
is_valid_utf8 = entry.is_valid_utf8;
|
||||
transpiled = entry
|
||||
.transpiled_offset
|
||||
.and_then(|t| self.vfs.read_file_offset_with_len(t).ok());
|
||||
|
@ -369,7 +372,7 @@ impl StandaloneModules {
|
|||
match RealFs.read_file_sync(&path, None) {
|
||||
Ok(bytes) => bytes,
|
||||
Err(FsError::Io(err)) if err.kind() == ErrorKind::NotFound => {
|
||||
return Ok(None)
|
||||
return Ok(None);
|
||||
}
|
||||
Err(err) => return Err(JsErrorBox::from_err(err)),
|
||||
}
|
||||
|
@ -379,6 +382,7 @@ impl StandaloneModules {
|
|||
Ok(Some(DenoCompileModuleData {
|
||||
media_type: MediaType::from_specifier(specifier),
|
||||
specifier,
|
||||
is_valid_utf8,
|
||||
data: bytes,
|
||||
transpiled,
|
||||
source_map,
|
||||
|
@ -393,6 +397,7 @@ impl StandaloneModules {
|
|||
pub struct DenoCompileModuleData<'a> {
|
||||
pub specifier: &'a Url,
|
||||
pub media_type: MediaType,
|
||||
pub is_valid_utf8: bool,
|
||||
pub data: Cow<'static, [u8]>,
|
||||
pub transpiled: Option<Cow<'static, [u8]>>,
|
||||
pub source_map: Option<Cow<'static, [u8]>>,
|
||||
|
@ -401,12 +406,18 @@ pub struct DenoCompileModuleData<'a> {
|
|||
|
||||
impl<'a> DenoCompileModuleData<'a> {
|
||||
pub fn into_parts(self) -> (&'a Url, ModuleType, DenoCompileModuleSource) {
|
||||
fn into_string_unsafe(data: Cow<'static, [u8]>) -> DenoCompileModuleSource {
|
||||
fn into_string_unsafe(
|
||||
is_valid_utf8: bool,
|
||||
data: Cow<'static, [u8]>,
|
||||
) -> DenoCompileModuleSource {
|
||||
match data {
|
||||
Cow::Borrowed(d) => DenoCompileModuleSource::String(
|
||||
// SAFETY: we know this is a valid utf8 string
|
||||
unsafe { std::str::from_utf8_unchecked(d) },
|
||||
),
|
||||
Cow::Borrowed(d) if is_valid_utf8 => {
|
||||
DenoCompileModuleSource::String(
|
||||
// SAFETY: we know this is a valid utf8 string
|
||||
unsafe { std::str::from_utf8_unchecked(d) },
|
||||
)
|
||||
}
|
||||
Cow::Borrowed(_) => DenoCompileModuleSource::Bytes(data),
|
||||
Cow::Owned(d) => DenoCompileModuleSource::Bytes(Cow::Owned(d)),
|
||||
}
|
||||
}
|
||||
|
@ -423,8 +434,14 @@ impl<'a> DenoCompileModuleData<'a> {
|
|||
| MediaType::Dts
|
||||
| MediaType::Dmts
|
||||
| MediaType::Dcts
|
||||
| MediaType::Tsx => (ModuleType::JavaScript, into_string_unsafe(data)),
|
||||
MediaType::Json => (ModuleType::Json, into_string_unsafe(data)),
|
||||
| MediaType::Tsx => (
|
||||
ModuleType::JavaScript,
|
||||
into_string_unsafe(self.is_valid_utf8, data),
|
||||
),
|
||||
MediaType::Json => (
|
||||
ModuleType::Json,
|
||||
into_string_unsafe(self.is_valid_utf8, data),
|
||||
),
|
||||
MediaType::Wasm => {
|
||||
(ModuleType::Wasm, DenoCompileModuleSource::Bytes(data))
|
||||
}
|
||||
|
@ -441,6 +458,7 @@ impl<'a> DenoCompileModuleData<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DenoCompileModuleSource {
|
||||
String(&'static str),
|
||||
Bytes(Cow<'static, [u8]>),
|
||||
|
@ -448,21 +466,28 @@ pub enum DenoCompileModuleSource {
|
|||
|
||||
impl DenoCompileModuleSource {
|
||||
pub fn into_for_v8(self) -> ModuleSourceCode {
|
||||
fn into_bytes(data: Cow<'static, [u8]>) -> ModuleSourceCode {
|
||||
ModuleSourceCode::Bytes(match data {
|
||||
Cow::Borrowed(d) => d.into(),
|
||||
Cow::Owned(d) => d.into_boxed_slice().into(),
|
||||
})
|
||||
}
|
||||
|
||||
match self {
|
||||
// todo(https://github.com/denoland/deno_core/pull/943): store whether
|
||||
// the string is ascii or not ahead of time so we can avoid the is_ascii()
|
||||
// check in FastString::from_static
|
||||
Self::String(s) => ModuleSourceCode::String(FastString::from_static(s)),
|
||||
Self::Bytes(b) => into_bytes(b),
|
||||
Self::Bytes(b) => ModuleSourceCode::Bytes(module_source_into_bytes(b)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_bytes_for_v8(self) -> ModuleCodeBytes {
|
||||
match self {
|
||||
DenoCompileModuleSource::String(text) => text.as_bytes().into(),
|
||||
DenoCompileModuleSource::Bytes(b) => module_source_into_bytes(b),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn module_source_into_bytes(data: Cow<'static, [u8]>) -> ModuleCodeBytes {
|
||||
match data {
|
||||
Cow::Borrowed(d) => d.into(),
|
||||
Cow::Owned(d) => d.into_boxed_slice().into(),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error, JsError)]
|
||||
|
@ -558,6 +583,7 @@ impl RemoteModulesStore {
|
|||
self.specifiers.get_specifier(specifier).unwrap()
|
||||
},
|
||||
media_type: entry.media_type,
|
||||
is_valid_utf8: entry.is_valid_utf8,
|
||||
data: handle_cow_ref(&entry.data),
|
||||
transpiled: entry.maybe_transpiled.as_ref().map(handle_cow_ref),
|
||||
source_map: entry.maybe_source_map.as_ref().map(handle_cow_ref),
|
||||
|
|
|
@ -461,12 +461,16 @@ mod test {
|
|||
// first run
|
||||
{
|
||||
let code_cache = DenoCompileCodeCache::new(file_path.clone(), 1234);
|
||||
assert!(code_cache
|
||||
.get_sync(&url1, CodeCacheType::EsModule, 0)
|
||||
.is_none());
|
||||
assert!(code_cache
|
||||
.get_sync(&url2, CodeCacheType::EsModule, 1)
|
||||
.is_none());
|
||||
assert!(
|
||||
code_cache
|
||||
.get_sync(&url1, CodeCacheType::EsModule, 0)
|
||||
.is_none()
|
||||
);
|
||||
assert!(
|
||||
code_cache
|
||||
.get_sync(&url2, CodeCacheType::EsModule, 1)
|
||||
.is_none()
|
||||
);
|
||||
assert!(code_cache.enabled());
|
||||
code_cache.set_sync(url1.clone(), CodeCacheType::EsModule, 0, &[1, 2, 3]);
|
||||
assert!(code_cache.enabled());
|
||||
|
@ -494,12 +498,16 @@ mod test {
|
|||
// new cache key first run
|
||||
{
|
||||
let code_cache = DenoCompileCodeCache::new(file_path.clone(), 54321);
|
||||
assert!(code_cache
|
||||
.get_sync(&url1, CodeCacheType::EsModule, 0)
|
||||
.is_none());
|
||||
assert!(code_cache
|
||||
.get_sync(&url2, CodeCacheType::EsModule, 1)
|
||||
.is_none());
|
||||
assert!(
|
||||
code_cache
|
||||
.get_sync(&url1, CodeCacheType::EsModule, 0)
|
||||
.is_none()
|
||||
);
|
||||
assert!(
|
||||
code_cache
|
||||
.get_sync(&url2, CodeCacheType::EsModule, 1)
|
||||
.is_none()
|
||||
);
|
||||
code_cache.set_sync(url1.clone(), CodeCacheType::EsModule, 0, &[2, 2, 3]);
|
||||
code_cache.set_sync(url2.clone(), CodeCacheType::EsModule, 1, &[3, 2, 3]);
|
||||
}
|
||||
|
@ -510,9 +518,11 @@ mod test {
|
|||
.get_sync(&url1, CodeCacheType::EsModule, 0)
|
||||
.unwrap();
|
||||
assert_eq!(result1, vec![2, 2, 3]);
|
||||
assert!(code_cache
|
||||
.get_sync(&url2, CodeCacheType::EsModule, 5) // different hash will cause none
|
||||
.is_none());
|
||||
assert!(
|
||||
code_cache
|
||||
.get_sync(&url2, CodeCacheType::EsModule, 5) // different hash will cause none
|
||||
.is_none()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,11 +39,11 @@ use deno_runtime::deno_napi::DenoRtNativeAddonLoader;
|
|||
use deno_runtime::deno_napi::DenoRtNativeAddonLoaderRc;
|
||||
#[cfg(windows)]
|
||||
use deno_subprocess_windows::Stdio as StdStdio;
|
||||
use sys_traits::FsCopy;
|
||||
use sys_traits::boxed::BoxedFsDirEntry;
|
||||
use sys_traits::boxed::BoxedFsMetadataValue;
|
||||
use sys_traits::boxed::FsMetadataBoxed;
|
||||
use sys_traits::boxed::FsReadDirBoxed;
|
||||
use sys_traits::FsCopy;
|
||||
use url::Url;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -195,6 +195,16 @@ impl FileSystem for DenoRtSys {
|
|||
RealFs.chown_async(path, uid, gid).await
|
||||
}
|
||||
|
||||
fn lchmod_sync(&self, path: &Path, mode: u32) -> FsResult<()> {
|
||||
self.error_if_in_vfs(path)?;
|
||||
RealFs.lchmod_sync(path, mode)
|
||||
}
|
||||
|
||||
async fn lchmod_async(&self, path: PathBuf, mode: u32) -> FsResult<()> {
|
||||
self.error_if_in_vfs(&path)?;
|
||||
RealFs.lchmod_async(path, mode).await
|
||||
}
|
||||
|
||||
fn lchown_sync(
|
||||
&self,
|
||||
path: &Path,
|
||||
|
@ -1080,7 +1090,10 @@ impl FileBackedVfsFile {
|
|||
if offset >= 0 {
|
||||
*current_pos += offset as u64;
|
||||
} else if -offset as u64 > *current_pos {
|
||||
return Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied, "An attempt was made to move the file pointer before the beginning of the file."));
|
||||
return Err(std::io::Error::new(
|
||||
std::io::ErrorKind::PermissionDenied,
|
||||
"An attempt was made to move the file pointer before the beginning of the file.",
|
||||
));
|
||||
} else {
|
||||
*current_pos -= -offset as u64;
|
||||
}
|
||||
|
@ -1397,7 +1410,7 @@ impl FileBackedVfs {
|
|||
pub fn read_dir_with_metadata(
|
||||
&self,
|
||||
path: &Path,
|
||||
) -> std::io::Result<impl Iterator<Item = FileBackedVfsDirEntry>> {
|
||||
) -> std::io::Result<impl Iterator<Item = FileBackedVfsDirEntry> + use<>> {
|
||||
let dir = self.dir_entry(path)?;
|
||||
let path = path.to_path_buf();
|
||||
Ok(
|
||||
|
@ -1528,8 +1541,8 @@ mod test {
|
|||
use std::io::Write;
|
||||
|
||||
use deno_lib::standalone::virtual_fs::VfsBuilder;
|
||||
use test_util::assert_contains;
|
||||
use test_util::TempDir;
|
||||
use test_util::assert_contains;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -1763,10 +1776,7 @@ mod test {
|
|||
file.read_to_buf(&mut buf).unwrap();
|
||||
assert_eq!(buf, b"23");
|
||||
assert_eq!(
|
||||
file
|
||||
.seek(SeekFrom::Current(-5))
|
||||
.unwrap_err()
|
||||
.to_string(),
|
||||
file.seek(SeekFrom::Current(-5)).unwrap_err().to_string(),
|
||||
"An attempt was made to move the file pointer before the beginning of the file."
|
||||
);
|
||||
// go beyond the file length, then back
|
||||
|
|
|
@ -60,7 +60,10 @@ fn unwrap_or_exit<T>(result: Result<T, AnyError>) -> T {
|
|||
fn load_env_vars(env_vars: &IndexMap<String, String>) {
|
||||
env_vars.iter().for_each(|env_var| {
|
||||
if env::var(env_var.0).is_err() {
|
||||
std::env::set_var(env_var.0, env_var.1);
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
unsafe {
|
||||
std::env::set_var(env_var.0, env_var.1)
|
||||
};
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -11,11 +11,11 @@ use deno_media_type::MediaType;
|
|||
use deno_resolver::npm::DenoInNpmPackageChecker;
|
||||
use deno_resolver::npm::NpmReqResolver;
|
||||
use deno_runtime::deno_fs::FileSystem;
|
||||
use node_resolver::DenoIsBuiltInNodeModuleChecker;
|
||||
use node_resolver::analyze::CjsAnalysis;
|
||||
use node_resolver::analyze::CjsAnalysisExports;
|
||||
use node_resolver::analyze::EsmAnalysisMode;
|
||||
use node_resolver::analyze::NodeCodeTranslator;
|
||||
use node_resolver::DenoIsBuiltInNodeModuleChecker;
|
||||
|
||||
use crate::binary::StandaloneModules;
|
||||
use crate::file_system::DenoRtSys;
|
||||
|
|
115
cli/rt/run.rs
115
cli/rt/run.rs
|
@ -8,12 +8,6 @@ use std::sync::OnceLock;
|
|||
|
||||
use deno_cache_dir::npm::NpmCacheDir;
|
||||
use deno_config::workspace::ResolverWorkspaceJsrPackage;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::ModuleLoaderError;
|
||||
use deno_core::futures::future::LocalBoxFuture;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::v8_set_flags;
|
||||
use deno_core::FastString;
|
||||
use deno_core::ModuleLoader;
|
||||
use deno_core::ModuleSourceCode;
|
||||
|
@ -21,15 +15,21 @@ use deno_core::ModuleType;
|
|||
use deno_core::RequestedModuleType;
|
||||
use deno_core::ResolutionKind;
|
||||
use deno_core::SourceCodeCacheInfo;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::ModuleLoaderError;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::futures::future::LocalBoxFuture;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::v8_set_flags;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_lib::args::get_root_cert_store;
|
||||
use deno_lib::args::npm_pkg_req_ref_to_binary_command;
|
||||
use deno_lib::args::CaData;
|
||||
use deno_lib::args::RootCertStoreLoadError;
|
||||
use deno_lib::args::get_root_cert_store;
|
||||
use deno_lib::args::npm_pkg_req_ref_to_binary_command;
|
||||
use deno_lib::loader::NpmModuleLoader;
|
||||
use deno_lib::npm::create_npm_process_state_provider;
|
||||
use deno_lib::npm::NpmRegistryReadPermissionChecker;
|
||||
use deno_lib::npm::NpmRegistryReadPermissionCheckerMode;
|
||||
use deno_lib::npm::create_npm_process_state_provider;
|
||||
use deno_lib::standalone::binary::NodeModules;
|
||||
use deno_lib::util::hash::FastInsecureHasher;
|
||||
use deno_lib::util::text_encoding::from_utf8_lossy_cow;
|
||||
|
@ -44,11 +44,9 @@ use deno_media_type::MediaType;
|
|||
use deno_npm::npm_rc::ResolvedNpmRc;
|
||||
use deno_npm::resolution::NpmResolutionSnapshot;
|
||||
use deno_package_json::PackageJsonDepValue;
|
||||
use deno_resolver::DenoResolveErrorKind;
|
||||
use deno_resolver::cjs::CjsTracker;
|
||||
use deno_resolver::cjs::IsCjsResolutionMode;
|
||||
use deno_resolver::npm::managed::ManagedInNpmPkgCheckerCreateOptions;
|
||||
use deno_resolver::npm::managed::ManagedNpmResolverCreateOptions;
|
||||
use deno_resolver::npm::managed::NpmResolutionCell;
|
||||
use deno_resolver::npm::ByonmNpmResolverCreateOptions;
|
||||
use deno_resolver::npm::CreateInNpmPkgCheckerOptions;
|
||||
use deno_resolver::npm::DenoInNpmPackageChecker;
|
||||
|
@ -56,35 +54,36 @@ use deno_resolver::npm::NpmReqResolver;
|
|||
use deno_resolver::npm::NpmReqResolverOptions;
|
||||
use deno_resolver::npm::NpmResolver;
|
||||
use deno_resolver::npm::NpmResolverCreateOptions;
|
||||
use deno_resolver::npm::managed::ManagedInNpmPkgCheckerCreateOptions;
|
||||
use deno_resolver::npm::managed::ManagedNpmResolverCreateOptions;
|
||||
use deno_resolver::npm::managed::NpmResolutionCell;
|
||||
use deno_resolver::workspace::MappedResolution;
|
||||
use deno_resolver::workspace::SloppyImportsOptions;
|
||||
use deno_resolver::workspace::WorkspaceResolver;
|
||||
use deno_resolver::DenoResolveErrorKind;
|
||||
use deno_runtime::code_cache::CodeCache;
|
||||
use deno_runtime::deno_fs::FileSystem;
|
||||
use deno_runtime::deno_node::create_host_defined_options;
|
||||
use deno_runtime::deno_node::NodeRequireLoader;
|
||||
use deno_runtime::deno_permissions::Permissions;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
use deno_runtime::deno_permissions::UnstableSubdomainWildcards;
|
||||
use deno_runtime::deno_tls::rustls::RootCertStore;
|
||||
use deno_runtime::deno_tls::RootCertStoreProvider;
|
||||
use deno_runtime::deno_web::BlobStore;
|
||||
use deno_runtime::permissions::RuntimePermissionDescriptorParser;
|
||||
use deno_runtime::FeatureChecker;
|
||||
use deno_runtime::WorkerExecutionMode;
|
||||
use deno_runtime::WorkerLogLevel;
|
||||
use deno_runtime::code_cache::CodeCache;
|
||||
use deno_runtime::deno_fs::FileSystem;
|
||||
use deno_runtime::deno_node::NodeRequireLoader;
|
||||
use deno_runtime::deno_node::create_host_defined_options;
|
||||
use deno_runtime::deno_permissions::Permissions;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
use deno_runtime::deno_tls::RootCertStoreProvider;
|
||||
use deno_runtime::deno_tls::rustls::RootCertStore;
|
||||
use deno_runtime::deno_web::BlobStore;
|
||||
use deno_runtime::permissions::RuntimePermissionDescriptorParser;
|
||||
use deno_semver::npm::NpmPackageReqReference;
|
||||
use node_resolver::analyze::CjsModuleExportAnalyzer;
|
||||
use node_resolver::analyze::NodeCodeTranslator;
|
||||
use node_resolver::cache::NodeResolutionSys;
|
||||
use node_resolver::errors::ClosestPkgJsonError;
|
||||
use node_resolver::DenoIsBuiltInNodeModuleChecker;
|
||||
use node_resolver::NodeResolutionKind;
|
||||
use node_resolver::NodeResolver;
|
||||
use node_resolver::PackageJsonResolver;
|
||||
use node_resolver::PackageJsonThreadLocalCache;
|
||||
use node_resolver::ResolutionMode;
|
||||
use node_resolver::analyze::CjsModuleExportAnalyzer;
|
||||
use node_resolver::analyze::NodeCodeTranslator;
|
||||
use node_resolver::cache::NodeResolutionSys;
|
||||
use node_resolver::errors::ClosestPkgJsonError;
|
||||
|
||||
use crate::binary::DenoCompileModuleSource;
|
||||
use crate::binary::StandaloneData;
|
||||
|
@ -372,7 +371,7 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
original_specifier: &Url,
|
||||
maybe_referrer: Option<&Url>,
|
||||
_is_dynamic: bool,
|
||||
_requested_module_type: RequestedModuleType,
|
||||
requested_module_type: RequestedModuleType,
|
||||
) -> deno_core::ModuleLoadResponse {
|
||||
if original_specifier.scheme() == "data" {
|
||||
let data_url_text =
|
||||
|
@ -412,10 +411,7 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
code_source.code.as_bytes(),
|
||||
);
|
||||
Ok(deno_core::ModuleSource::new_with_redirect(
|
||||
match code_source.media_type {
|
||||
MediaType::Json => ModuleType::Json,
|
||||
_ => ModuleType::JavaScript,
|
||||
},
|
||||
code_source.module_type,
|
||||
code_source.code,
|
||||
&original_specifier,
|
||||
&code_source.found_url,
|
||||
|
@ -428,6 +424,36 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
|
||||
match self.shared.modules.read(original_specifier) {
|
||||
Ok(Some(module)) => {
|
||||
match requested_module_type {
|
||||
RequestedModuleType::Text | RequestedModuleType::Bytes => {
|
||||
let module_source = DenoCompileModuleSource::Bytes(module.data);
|
||||
return deno_core::ModuleLoadResponse::Sync(Ok(
|
||||
deno_core::ModuleSource::new_with_redirect(
|
||||
match requested_module_type {
|
||||
RequestedModuleType::Text => ModuleType::Text,
|
||||
RequestedModuleType::Bytes => ModuleType::Bytes,
|
||||
_ => unreachable!(),
|
||||
},
|
||||
match requested_module_type {
|
||||
RequestedModuleType::Text => module_source.into_for_v8(),
|
||||
RequestedModuleType::Bytes => {
|
||||
ModuleSourceCode::Bytes(module_source.into_bytes_for_v8())
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
original_specifier,
|
||||
module.specifier,
|
||||
None,
|
||||
),
|
||||
));
|
||||
}
|
||||
RequestedModuleType::Other(_)
|
||||
| RequestedModuleType::None
|
||||
| RequestedModuleType::Json => {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
let media_type = module.media_type;
|
||||
let (module_specifier, module_type, module_source) =
|
||||
module.into_parts();
|
||||
|
@ -552,7 +578,8 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
if line_number >= lines.len() {
|
||||
Some(format!(
|
||||
"{} Couldn't format source line: Line {} is out of bounds (source may have changed at runtime)",
|
||||
crate::colors::yellow("Warning"), line_number + 1,
|
||||
crate::colors::yellow("Warning"),
|
||||
line_number + 1,
|
||||
))
|
||||
} else {
|
||||
Some(lines[line_number].to_string())
|
||||
|
@ -581,7 +608,7 @@ impl NodeRequireLoader for EmbeddedModuleLoader {
|
|||
fn load_text_file_lossy(
|
||||
&self,
|
||||
path: &std::path::Path,
|
||||
) -> Result<Cow<'static, str>, JsErrorBox> {
|
||||
) -> Result<FastString, JsErrorBox> {
|
||||
let file_entry = self
|
||||
.shared
|
||||
.vfs
|
||||
|
@ -594,7 +621,10 @@ impl NodeRequireLoader for EmbeddedModuleLoader {
|
|||
file_entry.transpiled_offset.unwrap_or(file_entry.offset),
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
Ok(from_utf8_lossy_cow(file_bytes))
|
||||
Ok(match from_utf8_lossy_cow(file_bytes) {
|
||||
Cow::Borrowed(s) => FastString::from_static(s),
|
||||
Cow::Owned(s) => s.into(),
|
||||
})
|
||||
}
|
||||
|
||||
fn is_maybe_cjs(&self, specifier: &Url) -> Result<bool, ClosestPkgJsonError> {
|
||||
|
@ -933,14 +963,8 @@ pub async fn run(
|
|||
}
|
||||
}
|
||||
|
||||
let desc_parser = Arc::new(RuntimePermissionDescriptorParser::new(
|
||||
sys.clone(),
|
||||
if metadata.unstable_config.subdomain_wildcards {
|
||||
UnstableSubdomainWildcards::Enabled
|
||||
} else {
|
||||
UnstableSubdomainWildcards::Disabled
|
||||
},
|
||||
));
|
||||
let desc_parser =
|
||||
Arc::new(RuntimePermissionDescriptorParser::new(sys.clone()));
|
||||
let permissions =
|
||||
Permissions::from_options(desc_parser.as_ref(), &permissions)?;
|
||||
PermissionsContainer::new(desc_parser, permissions)
|
||||
|
@ -984,6 +1008,7 @@ pub async fn run(
|
|||
otel_config: metadata.otel_config,
|
||||
no_legacy_abort: false,
|
||||
startup_snapshot: deno_snapshots::CLI_SNAPSHOT,
|
||||
enable_raw_imports: metadata.unstable_config.raw_imports,
|
||||
tunnel: false,
|
||||
};
|
||||
let worker_factory = LibMainWorkerFactory::new(
|
||||
|
@ -1033,6 +1058,8 @@ pub async fn run(
|
|||
WorkerExecutionMode::Run,
|
||||
permissions,
|
||||
main_module,
|
||||
// TODO(bartlomieju): support preload modules in `deno compile`
|
||||
vec![],
|
||||
)?;
|
||||
|
||||
let exit_code = worker.run().await?;
|
||||
|
|
|
@ -699,6 +699,7 @@
|
|||
"kv",
|
||||
"net",
|
||||
"node-globals",
|
||||
"raw-imports",
|
||||
"sloppy-imports",
|
||||
"temporal",
|
||||
"unsafe-proto",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
[package]
|
||||
name = "deno_snapshots"
|
||||
version = "0.23.0"
|
||||
version = "0.24.0"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
|
|
@ -17,8 +17,8 @@ use deno_ast::MediaType;
|
|||
use deno_ast::ModuleKind;
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_cache_dir::CACHE_PERM;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::url::Url;
|
||||
|
@ -27,6 +27,7 @@ use deno_lib::args::CaData;
|
|||
use deno_lib::args::UnstableConfig;
|
||||
use deno_lib::shared::ReleaseChannel;
|
||||
use deno_lib::standalone::binary::CjsExportAnalysisEntry;
|
||||
use deno_lib::standalone::binary::MAGIC_BYTES;
|
||||
use deno_lib::standalone::binary::Metadata;
|
||||
use deno_lib::standalone::binary::NodeModules;
|
||||
use deno_lib::standalone::binary::RemoteModuleEntry;
|
||||
|
@ -35,33 +36,37 @@ use deno_lib::standalone::binary::SerializedWorkspaceResolver;
|
|||
use deno_lib::standalone::binary::SerializedWorkspaceResolverImportMap;
|
||||
use deno_lib::standalone::binary::SpecifierDataStore;
|
||||
use deno_lib::standalone::binary::SpecifierId;
|
||||
use deno_lib::standalone::binary::MAGIC_BYTES;
|
||||
use deno_lib::standalone::virtual_fs::BuiltVfs;
|
||||
use deno_lib::standalone::virtual_fs::DENO_COMPILE_GLOBAL_NODE_MODULES_DIR_NAME;
|
||||
use deno_lib::standalone::virtual_fs::VfsBuilder;
|
||||
use deno_lib::standalone::virtual_fs::VfsEntry;
|
||||
use deno_lib::standalone::virtual_fs::VirtualDirectory;
|
||||
use deno_lib::standalone::virtual_fs::VirtualDirectoryEntries;
|
||||
use deno_lib::standalone::virtual_fs::WindowsSystemRootablePath;
|
||||
use deno_lib::standalone::virtual_fs::DENO_COMPILE_GLOBAL_NODE_MODULES_DIR_NAME;
|
||||
use deno_lib::util::hash::FastInsecureHasher;
|
||||
use deno_lib::util::text_encoding::is_valid_utf8;
|
||||
use deno_lib::util::v8::construct_v8_flags;
|
||||
use deno_lib::version::DENO_VERSION_INFO;
|
||||
use deno_npm::resolution::SerializedNpmResolutionSnapshot;
|
||||
use deno_npm::NpmSystemInfo;
|
||||
use deno_npm::resolution::SerializedNpmResolutionSnapshot;
|
||||
use deno_path_util::fs::atomic_write_file_with_retries;
|
||||
use deno_path_util::url_from_directory_path;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use deno_resolver::file_fetcher::FetchLocalOptions;
|
||||
use deno_resolver::file_fetcher::FetchOptions;
|
||||
use deno_resolver::file_fetcher::FetchPermissionsOptionRef;
|
||||
use deno_resolver::workspace::WorkspaceResolver;
|
||||
use indexmap::IndexMap;
|
||||
use node_resolver::analyze::ResolvedCjsAnalysis;
|
||||
|
||||
use super::virtual_fs::output_vfs;
|
||||
use crate::args::get_default_v8_flags;
|
||||
use crate::args::CliOptions;
|
||||
use crate::args::CompileFlags;
|
||||
use crate::args::get_default_v8_flags;
|
||||
use crate::cache::DenoDir;
|
||||
use crate::emit::Emitter;
|
||||
use crate::file_fetcher::CliFileFetcher;
|
||||
use crate::http_util::HttpClientProvider;
|
||||
use crate::module_loader::CliEmitter;
|
||||
use crate::node::CliCjsModuleExportAnalyzer;
|
||||
use crate::npm::CliNpmResolver;
|
||||
use crate::resolver::CliCjsTracker;
|
||||
|
@ -196,7 +201,8 @@ pub struct DenoCompileBinaryWriter<'a> {
|
|||
cjs_tracker: &'a CliCjsTracker,
|
||||
cli_options: &'a CliOptions,
|
||||
deno_dir: &'a DenoDir,
|
||||
emitter: &'a Emitter,
|
||||
emitter: &'a CliEmitter,
|
||||
file_fetcher: &'a CliFileFetcher,
|
||||
http_client_provider: &'a HttpClientProvider,
|
||||
npm_resolver: &'a CliNpmResolver,
|
||||
workspace_resolver: &'a WorkspaceResolver<CliSys>,
|
||||
|
@ -210,7 +216,8 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
|||
cjs_tracker: &'a CliCjsTracker,
|
||||
cli_options: &'a CliOptions,
|
||||
deno_dir: &'a DenoDir,
|
||||
emitter: &'a Emitter,
|
||||
emitter: &'a CliEmitter,
|
||||
file_fetcher: &'a CliFileFetcher,
|
||||
http_client_provider: &'a HttpClientProvider,
|
||||
npm_resolver: &'a CliNpmResolver,
|
||||
workspace_resolver: &'a WorkspaceResolver<CliSys>,
|
||||
|
@ -222,6 +229,7 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
|||
cli_options,
|
||||
deno_dir,
|
||||
emitter,
|
||||
file_fetcher,
|
||||
http_client_provider,
|
||||
npm_resolver,
|
||||
workspace_resolver,
|
||||
|
@ -409,6 +417,7 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
|||
let mut specifier_store = SpecifierStore::with_capacity(specifiers_count);
|
||||
let mut remote_modules_store =
|
||||
SpecifierDataStore::with_capacity(specifiers_count);
|
||||
let mut asset_module_urls = graph.asset_module_urls();
|
||||
// todo(dsherret): transpile and analyze CJS in parallel
|
||||
for module in graph.modules() {
|
||||
if module.specifier().scheme() == "data" {
|
||||
|
@ -420,7 +429,10 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
|||
let (maybe_original_source, media_type) = match module {
|
||||
deno_graph::Module::Js(m) => {
|
||||
let specifier = &m.specifier;
|
||||
let original_bytes = m.source.as_bytes();
|
||||
let original_bytes = match m.source.try_get_original_bytes() {
|
||||
Some(bytes) => bytes,
|
||||
None => self.load_asset_bypass_permissions(specifier).await?.source,
|
||||
};
|
||||
if self.cjs_tracker.is_maybe_cjs(specifier, m.media_type)? {
|
||||
if self.cjs_tracker.is_cjs_with_known_is_script(
|
||||
specifier,
|
||||
|
@ -431,7 +443,7 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
|||
.cjs_module_export_analyzer
|
||||
.analyze_all_exports(
|
||||
module.specifier(),
|
||||
Some(Cow::Borrowed(m.source.as_ref())),
|
||||
Some(Cow::Borrowed(m.source.text.as_ref())),
|
||||
)
|
||||
.await?;
|
||||
maybe_cjs_analysis = Some(match cjs_analysis {
|
||||
|
@ -452,13 +464,13 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
|||
_ => ModuleKind::Esm,
|
||||
};
|
||||
let (source, source_map) =
|
||||
self.emitter.emit_parsed_source_for_deno_compile(
|
||||
self.emitter.emit_source_for_deno_compile(
|
||||
&m.specifier,
|
||||
m.media_type,
|
||||
module_kind,
|
||||
&m.source,
|
||||
&m.source.text,
|
||||
)?;
|
||||
if source != m.source.as_ref() {
|
||||
if source != m.source.text.as_ref() {
|
||||
maybe_source_map = Some(source_map.into_bytes());
|
||||
maybe_transpiled = Some(source.into_bytes());
|
||||
}
|
||||
|
@ -466,16 +478,26 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
|||
(Some(original_bytes), m.media_type)
|
||||
}
|
||||
deno_graph::Module::Json(m) => {
|
||||
(Some(m.source.as_bytes()), m.media_type)
|
||||
let original_bytes = match m.source.try_get_original_bytes() {
|
||||
Some(bytes) => bytes,
|
||||
None => {
|
||||
self
|
||||
.load_asset_bypass_permissions(&m.specifier)
|
||||
.await?
|
||||
.source
|
||||
}
|
||||
};
|
||||
(Some(original_bytes), m.media_type)
|
||||
}
|
||||
deno_graph::Module::Wasm(m) => {
|
||||
(Some(m.source.as_ref()), MediaType::Wasm)
|
||||
(Some(m.source.clone()), MediaType::Wasm)
|
||||
}
|
||||
deno_graph::Module::Npm(_)
|
||||
| deno_graph::Module::Node(_)
|
||||
| deno_graph::Module::External(_) => (None, MediaType::Unknown),
|
||||
};
|
||||
if let Some(original_source) = maybe_original_source {
|
||||
asset_module_urls.swap_remove(module.specifier());
|
||||
let maybe_cjs_export_analysis = maybe_cjs_analysis
|
||||
.as_ref()
|
||||
.map(bincode::serialize)
|
||||
|
@ -505,7 +527,8 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
|||
specifier_id,
|
||||
RemoteModuleEntry {
|
||||
media_type,
|
||||
data: Cow::Borrowed(original_source),
|
||||
is_valid_utf8: is_valid_utf8(&original_source),
|
||||
data: Cow::Owned(original_source.to_vec()),
|
||||
maybe_transpiled: maybe_transpiled.map(Cow::Owned),
|
||||
maybe_source_map: maybe_source_map.map(Cow::Owned),
|
||||
maybe_cjs_export_analysis: maybe_cjs_export_analysis
|
||||
|
@ -516,6 +539,42 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
for url in asset_module_urls {
|
||||
if graph.try_get(url).is_err() {
|
||||
// skip because there was an error loading this module
|
||||
continue;
|
||||
}
|
||||
match url.scheme() {
|
||||
"file" => {
|
||||
let file_path = deno_path_util::url_to_file_path(url)?;
|
||||
vfs.add_file_at_path(&file_path)?;
|
||||
}
|
||||
"http" | "https" => {
|
||||
let specifier_id = specifier_store.get_or_add(url);
|
||||
if !remote_modules_store.contains(specifier_id) {
|
||||
// it's ok to bypass permissions here because we verified the module
|
||||
// loaded successfully in the graph
|
||||
let file = self.load_asset_bypass_permissions(url).await?;
|
||||
remote_modules_store.add(
|
||||
specifier_id,
|
||||
RemoteModuleEntry {
|
||||
media_type: MediaType::from_specifier_and_headers(
|
||||
&file.url,
|
||||
file.maybe_headers.as_ref(),
|
||||
),
|
||||
is_valid_utf8: is_valid_utf8(&file.source),
|
||||
data: Cow::Owned(file.source.to_vec()),
|
||||
maybe_cjs_export_analysis: None,
|
||||
maybe_source_map: None,
|
||||
maybe_transpiled: None,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let mut redirects_store =
|
||||
SpecifierDataStore::with_capacity(graph.redirects.len());
|
||||
for (from, to) in &graph.redirects {
|
||||
|
@ -638,7 +697,11 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
|||
Some(env_filenames) => {
|
||||
let mut aggregated_env_vars = IndexMap::new();
|
||||
for env_filename in env_filenames.iter().rev() {
|
||||
log::info!("{} Environment variables from the file \"{}\" were embedded in the generated executable file", crate::colors::yellow("Warning"), env_filename);
|
||||
log::info!(
|
||||
"{} Environment variables from the file \"{}\" were embedded in the generated executable file",
|
||||
crate::colors::yellow("Warning"),
|
||||
env_filename
|
||||
);
|
||||
|
||||
let env_vars = get_file_env_vars(env_filename.to_string())?;
|
||||
aggregated_env_vars.extend(env_vars);
|
||||
|
@ -709,7 +772,6 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
|||
node_modules,
|
||||
unstable_config: UnstableConfig {
|
||||
legacy_flag_enabled: false,
|
||||
subdomain_wildcards: self.cli_options.unstable_subdomain_wildcards(),
|
||||
bare_node_builtins: self.cli_options.unstable_bare_node_builtins(),
|
||||
detect_cjs: self.cli_options.unstable_detect_cjs(),
|
||||
features: self
|
||||
|
@ -720,6 +782,7 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
|||
.collect(),
|
||||
lazy_dynamic_imports: self.cli_options.unstable_lazy_dynamic_imports(),
|
||||
npm_lazy_caching: self.cli_options.unstable_npm_lazy_caching(),
|
||||
raw_imports: self.cli_options.unstable_raw_imports(),
|
||||
sloppy_imports: self.cli_options.unstable_sloppy_imports(),
|
||||
},
|
||||
otel_config: self.cli_options.otel_config(),
|
||||
|
@ -756,10 +819,39 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
|||
.context("Writing binary bytes")
|
||||
}
|
||||
|
||||
async fn load_asset_bypass_permissions(
|
||||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
) -> Result<
|
||||
deno_cache_dir::file_fetcher::File,
|
||||
deno_resolver::file_fetcher::FetchError,
|
||||
> {
|
||||
self
|
||||
.file_fetcher
|
||||
.fetch_with_options(
|
||||
specifier,
|
||||
FetchPermissionsOptionRef::AllowAll,
|
||||
FetchOptions {
|
||||
local: FetchLocalOptions {
|
||||
include_mtime: false,
|
||||
},
|
||||
maybe_auth: None,
|
||||
maybe_accept: None,
|
||||
maybe_cache_setting: Some(
|
||||
&deno_cache_dir::file_fetcher::CacheSetting::Use,
|
||||
),
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
fn fill_npm_vfs(&self, builder: &mut VfsBuilder) -> Result<(), AnyError> {
|
||||
fn maybe_warn_different_system(system_info: &NpmSystemInfo) {
|
||||
if system_info != &NpmSystemInfo::default() {
|
||||
log::warn!("{} The node_modules directory may be incompatible with the target system.", crate::colors::yellow("Warning"));
|
||||
log::warn!(
|
||||
"{} The node_modules directory may be incompatible with the target system.",
|
||||
crate::colors::yellow("Warning")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ use std::collections::HashSet;
|
|||
use std::path::PathBuf;
|
||||
|
||||
use deno_lib::standalone::virtual_fs::BuiltVfs;
|
||||
use deno_lib::standalone::virtual_fs::DENO_COMPILE_GLOBAL_NODE_MODULES_DIR_NAME;
|
||||
use deno_lib::standalone::virtual_fs::OffsetWithLength;
|
||||
use deno_lib::standalone::virtual_fs::VfsEntry;
|
||||
use deno_lib::standalone::virtual_fs::VirtualDirectory;
|
||||
|
@ -12,7 +13,6 @@ use deno_lib::standalone::virtual_fs::VirtualDirectoryEntries;
|
|||
use deno_lib::standalone::virtual_fs::VirtualFile;
|
||||
use deno_lib::standalone::virtual_fs::VirtualSymlinkParts;
|
||||
use deno_lib::standalone::virtual_fs::WindowsSystemRootablePath;
|
||||
use deno_lib::standalone::virtual_fs::DENO_COMPILE_GLOBAL_NODE_MODULES_DIR_NAME;
|
||||
use deno_resolver::display::DisplayTreeNode;
|
||||
|
||||
use crate::util::display::human_size;
|
||||
|
|
|
@ -290,7 +290,6 @@ impl ShellCommand for NodeCommand {
|
|||
"-A".into(),
|
||||
"--unstable-bare-node-builtins".into(),
|
||||
"--unstable-detect-cjs".into(),
|
||||
"--unstable-node-globals".into(),
|
||||
"--unstable-sloppy-imports".into(),
|
||||
"--unstable-unsafe-proto".into(),
|
||||
]);
|
||||
|
@ -324,7 +323,10 @@ impl ShellCommand for NodeGypCommand {
|
|||
.resolve_command_path(OsStr::new("node-gyp"))
|
||||
.is_err()
|
||||
{
|
||||
log::warn!("{} node-gyp was used in a script, but was not listed as a dependency. Either add it as a dependency or install it globally (e.g. `npm install -g node-gyp`)", crate::colors::yellow("Warning"));
|
||||
log::warn!(
|
||||
"{} node-gyp was used in a script, but was not listed as a dependency. Either add it as a dependency or install it globally (e.g. `npm install -g node-gyp`)",
|
||||
crate::colors::yellow("Warning")
|
||||
);
|
||||
}
|
||||
ExecutableCommand::new(
|
||||
"node-gyp".to_string(),
|
||||
|
@ -342,25 +344,28 @@ impl ShellCommand for NpxCommand {
|
|||
mut context: ShellCommandContext,
|
||||
) -> LocalBoxFuture<'static, ExecuteResult> {
|
||||
if let Some(first_arg) = context.args.first().cloned() {
|
||||
if let Some(command) = context.state.resolve_custom_command(&first_arg) {
|
||||
let context = ShellCommandContext {
|
||||
args: context.args.into_iter().skip(1).collect::<Vec<_>>(),
|
||||
..context
|
||||
};
|
||||
command.execute(context)
|
||||
} else {
|
||||
// can't find the command, so fallback to running the real npx command
|
||||
let npx_path =
|
||||
match context.state.resolve_command_path(OsStr::new("npx")) {
|
||||
Ok(npx) => npx,
|
||||
Err(err) => {
|
||||
let _ = context.stderr.write_line(&format!("{}", err));
|
||||
return Box::pin(std::future::ready(
|
||||
ExecuteResult::from_exit_code(err.exit_code()),
|
||||
));
|
||||
}
|
||||
match context.state.resolve_custom_command(&first_arg) {
|
||||
Some(command) => {
|
||||
let context = ShellCommandContext {
|
||||
args: context.args.into_iter().skip(1).collect::<Vec<_>>(),
|
||||
..context
|
||||
};
|
||||
ExecutableCommand::new("npx".to_string(), npx_path).execute(context)
|
||||
command.execute(context)
|
||||
}
|
||||
_ => {
|
||||
// can't find the command, so fallback to running the real npx command
|
||||
let npx_path =
|
||||
match context.state.resolve_command_path(OsStr::new("npx")) {
|
||||
Ok(npx) => npx,
|
||||
Err(err) => {
|
||||
let _ = context.stderr.write_line(&format!("{}", err));
|
||||
return Box::pin(std::future::ready(
|
||||
ExecuteResult::from_exit_code(err.exit_code()),
|
||||
));
|
||||
}
|
||||
};
|
||||
ExecutableCommand::new("npx".to_string(), npx_path).execute(context)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let _ = context.stderr.write_line("npx: missing command");
|
||||
|
|
|
@ -6,33 +6,33 @@ use std::sync::Arc;
|
|||
use std::time::Duration;
|
||||
|
||||
use deno_config::glob::WalkEntry;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::PollEventLoopOptions;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::CoreError;
|
||||
use deno_core::error::JsError;
|
||||
use deno_core::futures::StreamExt;
|
||||
use deno_core::futures::future;
|
||||
use deno_core::futures::stream;
|
||||
use deno_core::futures::StreamExt;
|
||||
use deno_core::serde_v8;
|
||||
use deno_core::unsync::spawn;
|
||||
use deno_core::unsync::spawn_blocking;
|
||||
use deno_core::v8;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::PollEventLoopOptions;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_npm_installer::graph::NpmCachingStrategy;
|
||||
use deno_runtime::WorkerExecutionMode;
|
||||
use deno_runtime::deno_permissions::Permissions;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
use deno_runtime::permissions::RuntimePermissionDescriptorParser;
|
||||
use deno_runtime::tokio_util::create_and_run_current_thread;
|
||||
use deno_runtime::WorkerExecutionMode;
|
||||
use indexmap::IndexMap;
|
||||
use indexmap::IndexSet;
|
||||
use log::Level;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use tokio::sync::mpsc::unbounded_channel;
|
||||
use tokio::sync::mpsc::UnboundedSender;
|
||||
use tokio::sync::mpsc::unbounded_channel;
|
||||
|
||||
use crate::args::BenchFlags;
|
||||
use crate::args::Flags;
|
||||
|
@ -43,8 +43,8 @@ use crate::graph_container::CheckSpecifiersOptions;
|
|||
use crate::graph_util::has_graph_root_local_dependent_changed;
|
||||
use crate::ops;
|
||||
use crate::sys::CliSys;
|
||||
use crate::tools::test::format_test_error;
|
||||
use crate::tools::test::TestFilter;
|
||||
use crate::tools::test::format_test_error;
|
||||
use crate::util::file_watcher;
|
||||
use crate::util::fs::collect_specifiers;
|
||||
use crate::util::path::is_script_ext;
|
||||
|
@ -154,6 +154,7 @@ async fn bench_specifier(
|
|||
worker_factory: Arc<CliMainWorkerFactory>,
|
||||
permissions_container: PermissionsContainer,
|
||||
specifier: ModuleSpecifier,
|
||||
preload_modules: Vec<ModuleSpecifier>,
|
||||
sender: UnboundedSender<BenchEvent>,
|
||||
filter: TestFilter,
|
||||
) -> Result<(), AnyError> {
|
||||
|
@ -161,6 +162,7 @@ async fn bench_specifier(
|
|||
worker_factory,
|
||||
permissions_container,
|
||||
specifier.clone(),
|
||||
preload_modules,
|
||||
&sender,
|
||||
filter,
|
||||
)
|
||||
|
@ -183,6 +185,7 @@ async fn bench_specifier_inner(
|
|||
worker_factory: Arc<CliMainWorkerFactory>,
|
||||
permissions_container: PermissionsContainer,
|
||||
specifier: ModuleSpecifier,
|
||||
preload_modules: Vec<ModuleSpecifier>,
|
||||
sender: &UnboundedSender<BenchEvent>,
|
||||
filter: TestFilter,
|
||||
) -> Result<(), CreateCustomWorkerError> {
|
||||
|
@ -190,6 +193,7 @@ async fn bench_specifier_inner(
|
|||
.create_custom_worker(
|
||||
WorkerExecutionMode::Bench,
|
||||
specifier.clone(),
|
||||
preload_modules,
|
||||
permissions_container,
|
||||
vec![ops::bench::deno_bench::init(sender.clone())],
|
||||
Default::default(),
|
||||
|
@ -197,6 +201,7 @@ async fn bench_specifier_inner(
|
|||
)
|
||||
.await?;
|
||||
|
||||
worker.execute_preload_modules().await?;
|
||||
// We execute the main module as a side module so that import.meta.main is not set.
|
||||
worker.execute_side_module().await?;
|
||||
|
||||
|
@ -289,6 +294,7 @@ async fn bench_specifiers(
|
|||
permissions: &Permissions,
|
||||
permissions_desc_parser: &Arc<RuntimePermissionDescriptorParser<CliSys>>,
|
||||
specifiers: Vec<ModuleSpecifier>,
|
||||
preload_modules: Vec<ModuleSpecifier>,
|
||||
options: BenchSpecifierOptions,
|
||||
) -> Result<(), AnyError> {
|
||||
let (sender, mut receiver) = unbounded_channel::<BenchEvent>();
|
||||
|
@ -303,11 +309,13 @@ async fn bench_specifiers(
|
|||
);
|
||||
let sender = sender.clone();
|
||||
let options = option_for_handles.clone();
|
||||
let preload_modules = preload_modules.clone();
|
||||
spawn_blocking(move || {
|
||||
let future = bench_specifier(
|
||||
worker_factory,
|
||||
permissions_container,
|
||||
specifier,
|
||||
preload_modules,
|
||||
sender,
|
||||
options.filter,
|
||||
);
|
||||
|
@ -478,6 +486,7 @@ pub async fn run_benchmarks(
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let preload_modules = cli_options.preload_modules()?;
|
||||
let log_level = cli_options.log_level();
|
||||
let worker_factory =
|
||||
Arc::new(factory.create_cli_main_worker_factory().await?);
|
||||
|
@ -486,6 +495,7 @@ pub async fn run_benchmarks(
|
|||
&permissions,
|
||||
&permission_desc_parser,
|
||||
specifiers,
|
||||
preload_modules,
|
||||
BenchSpecifierOptions {
|
||||
filter: TestFilter::from_flag(&workspace_bench_options.filter),
|
||||
json: workspace_bench_options.json,
|
||||
|
@ -618,11 +628,13 @@ pub async fn run_benchmarks_with_watch(
|
|||
}
|
||||
|
||||
let log_level = cli_options.log_level();
|
||||
let preload_modules = cli_options.preload_modules()?;
|
||||
bench_specifiers(
|
||||
worker_factory,
|
||||
&permissions,
|
||||
&permission_desc_parser,
|
||||
specifiers,
|
||||
preload_modules,
|
||||
BenchSpecifierOptions {
|
||||
filter: TestFilter::from_flag(&workspace_bench_options.filter),
|
||||
json: workspace_bench_options.json,
|
||||
|
|
|
@ -233,7 +233,13 @@ impl BenchReporter for ConsoleReporter {
|
|||
);
|
||||
|
||||
if !stats.high_precision && stats.used_explicit_timers {
|
||||
println!("{}", colors::yellow(format!("Warning: start() and end() calls in \"{}\" are ignored because it averages less\nthan 10µs per iteration. Remove them for better results.", &desc.name)));
|
||||
println!(
|
||||
"{}",
|
||||
colors::yellow(format!(
|
||||
"Warning: start() and end() calls in \"{}\" are ignored because it averages less\nthan 10µs per iteration. Remove them for better results.",
|
||||
&desc.name
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
self.group_measurements.push((desc, stats.clone()));
|
||||
|
@ -306,8 +312,12 @@ impl BenchReporter for ConsoleReporter {
|
|||
colors::red_bold("error"),
|
||||
format_test_error(&error, &TestFailureFormatOptions::default())
|
||||
);
|
||||
println!("This error was not caught from a benchmark and caused the bench runner to fail on the referenced module.");
|
||||
println!("It most likely originated from a dangling promise, event/timeout handler or top-level code.");
|
||||
println!(
|
||||
"This error was not caught from a benchmark and caused the bench runner to fail on the referenced module."
|
||||
);
|
||||
println!(
|
||||
"It most likely originated from a dangling promise, event/timeout handler or top-level code."
|
||||
);
|
||||
println!();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ fn esbuild_platform() -> &'static str {
|
|||
pub async fn ensure_esbuild(
|
||||
deno_dir: &DenoDir,
|
||||
npmrc: &ResolvedNpmRc,
|
||||
npm_registry_info: &Arc<CliNpmRegistryInfoProvider>,
|
||||
api: &Arc<CliNpmRegistryInfoProvider>,
|
||||
workspace_link_packages: &Arc<WorkspaceNpmLinkPackages>,
|
||||
tarball_cache: &Arc<TarballCache<CliNpmCacheHttpClient, CliSys>>,
|
||||
npm_cache: &CliNpmCache,
|
||||
|
@ -60,7 +60,6 @@ pub async fn ensure_esbuild(
|
|||
let pkg_name = format!("@esbuild/{}", target);
|
||||
let nv =
|
||||
PackageNv::from_str(&format!("{}@{}", pkg_name, ESBUILD_VERSION)).unwrap();
|
||||
let api = npm_registry_info.as_npm_registry_api();
|
||||
let mut info = api.package_info(&pkg_name).await?;
|
||||
let version_info = match info.version_info(&nv, &workspace_link_packages.0) {
|
||||
Ok(version_info) => version_info,
|
||||
|
|
|
@ -4,40 +4,43 @@ mod esbuild;
|
|||
mod externals;
|
||||
mod transform;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::cell::RefCell;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use std::sync::LazyLock;
|
||||
use std::time::Duration;
|
||||
|
||||
use deno_ast::EmitOptions;
|
||||
use deno_ast::MediaType;
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_config::deno_json::TsTypeLib;
|
||||
use deno_config::workspace::TsTypeLib;
|
||||
use deno_core::RequestedModuleType;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::FutureExt as _;
|
||||
use deno_core::resolve_url_or_path;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::RequestedModuleType;
|
||||
use deno_error::JsError;
|
||||
use deno_graph::ModuleError;
|
||||
use deno_graph::ModuleErrorKind;
|
||||
use deno_graph::Position;
|
||||
use deno_resolver::graph::ResolveWithGraphError;
|
||||
use deno_resolver::graph::ResolveWithGraphOptions;
|
||||
use deno_resolver::loader::LoadPreparedModuleError;
|
||||
use deno_resolver::npm::managed::ResolvePkgFolderFromDenoModuleError;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
use deno_semver::npm::NpmPackageReqReference;
|
||||
use esbuild_client::protocol;
|
||||
use esbuild_client::protocol::BuildResponse;
|
||||
use esbuild_client::EsbuildFlags;
|
||||
use esbuild_client::EsbuildFlagsBuilder;
|
||||
use esbuild_client::EsbuildService;
|
||||
use esbuild_client::protocol;
|
||||
use esbuild_client::protocol::BuildResponse;
|
||||
use indexmap::IndexMap;
|
||||
use node_resolver::errors::PackageSubpathResolveError;
|
||||
use node_resolver::NodeResolutionKind;
|
||||
use node_resolver::ResolutionMode;
|
||||
use node_resolver::errors::PackageSubpathResolveError;
|
||||
use sys_traits::EnvCurrentDir;
|
||||
|
||||
use crate::args::BundleFlags;
|
||||
|
@ -51,10 +54,8 @@ use crate::graph_container::ModuleGraphContainer;
|
|||
use crate::graph_container::ModuleGraphUpdatePermit;
|
||||
use crate::module_loader::CliModuleLoader;
|
||||
use crate::module_loader::CliModuleLoaderError;
|
||||
use crate::module_loader::EnhancedGraphError;
|
||||
use crate::module_loader::LoadCodeSourceError;
|
||||
use crate::module_loader::LoadCodeSourceErrorKind;
|
||||
use crate::module_loader::LoadPreparedModuleError;
|
||||
use crate::module_loader::ModuleLoadPreparer;
|
||||
use crate::module_loader::PrepareModuleLoadOptions;
|
||||
use crate::node::CliNodeResolver;
|
||||
|
@ -153,22 +154,18 @@ pub async fn bundle(
|
|||
let response = bundler.build().await?;
|
||||
|
||||
if bundle_flags.watch {
|
||||
return bundle_watch(flags, bundler).await;
|
||||
return bundle_watch(flags, bundler, bundle_flags.minify).await;
|
||||
}
|
||||
|
||||
handle_esbuild_errors_and_warnings(&response, &init_cwd);
|
||||
|
||||
if response.errors.is_empty() {
|
||||
process_result(&response, *DISABLE_HACK)?;
|
||||
let metafile = metafile_from_response(&response)?;
|
||||
let output_infos =
|
||||
process_result(&response, &init_cwd, *DISABLE_HACK, bundle_flags.minify)?;
|
||||
|
||||
if bundle_flags.output_dir.is_some() || bundle_flags.output_path.is_some() {
|
||||
log::info!(
|
||||
"{}",
|
||||
deno_terminal::colors::green(format!(
|
||||
"bundled in {}",
|
||||
crate::display::human_elapsed(start.elapsed().as_millis()),
|
||||
))
|
||||
);
|
||||
print_finished_message(&metafile, &output_infos, start.elapsed())?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,9 +176,20 @@ pub async fn bundle(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn metafile_from_response(
|
||||
response: &BuildResponse,
|
||||
) -> Result<esbuild_client::Metafile, AnyError> {
|
||||
Ok(serde_json::from_str::<esbuild_client::Metafile>(
|
||||
response.metafile.as_deref().ok_or_else(|| {
|
||||
deno_core::anyhow::anyhow!("expected a metafile to be present")
|
||||
})?,
|
||||
)?)
|
||||
}
|
||||
|
||||
async fn bundle_watch(
|
||||
flags: Arc<Flags>,
|
||||
bundler: EsbuildBundler,
|
||||
minified: bool,
|
||||
) -> Result<(), AnyError> {
|
||||
let initial_roots = bundler
|
||||
.roots
|
||||
|
@ -218,14 +226,10 @@ async fn bundle_watch(
|
|||
let response = bundler.rebuild().await?;
|
||||
handle_esbuild_errors_and_warnings(&response, &bundler.cwd);
|
||||
if response.errors.is_empty() {
|
||||
process_result(&response, *DISABLE_HACK)?;
|
||||
log::info!(
|
||||
"{}",
|
||||
deno_terminal::colors::green(format!(
|
||||
"bundled in {}",
|
||||
crate::display::human_elapsed(start.elapsed().as_millis()),
|
||||
))
|
||||
);
|
||||
let metafile = metafile_from_response(&response)?;
|
||||
let output_infos =
|
||||
process_result(&response, &bundler.cwd, *DISABLE_HACK, minified)?;
|
||||
print_finished_message(&metafile, &output_infos, start.elapsed())?;
|
||||
|
||||
let new_watched = get_input_paths_for_watch(&response);
|
||||
*current_roots.borrow_mut() = new_watched.clone();
|
||||
|
@ -360,8 +364,17 @@ impl EsbuildBundler {
|
|||
// TODO(nathanwhit): MASSIVE HACK
|
||||
// See tests::specs::bundle::requires_node_builtin for why this is needed.
|
||||
// Without this hack, that test would fail with "Dynamic require of "util" is not supported"
|
||||
fn replace_require_shim(contents: &str) -> String {
|
||||
contents.replace(
|
||||
fn replace_require_shim(contents: &str, minified: bool) -> String {
|
||||
if minified {
|
||||
let re = lazy_regex::regex!(
|
||||
r#"var (\w+)\s*=\((\w+)\s*=>typeof require<"u"\?require:typeof Proxy<"u"\?new Proxy\((\w+)\,\{get:\(\w+,\w+\)=>\(typeof require<"u"\?require:\w+\)\[l\]\}\):(\w+)\)\(function\(\w+\)\{if\(typeof require<"u"\)return require\.apply\(this\,arguments\);throw Error\('Dynamic require of "'\+\w+\+'" is not supported'\)\}\);"#
|
||||
);
|
||||
re.replace(contents, |c: ®ex::Captures<'_>| {
|
||||
let var_name = c.get(1).unwrap().as_str();
|
||||
format!("import{{createRequire}} from \"node:module\";var {var_name}=createRequire(import.meta.url);")
|
||||
}).into_owned()
|
||||
} else {
|
||||
contents.replace(
|
||||
r#"var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
||||
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
||||
}) : x)(function(x) {
|
||||
|
@ -372,6 +385,7 @@ fn replace_require_shim(contents: &str) -> String {
|
|||
var __require = createRequire(import.meta.url);
|
||||
"#,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn format_message(
|
||||
|
@ -445,6 +459,8 @@ fn requested_type_from_map(
|
|||
let type_ = map.get("type").map(|s| s.as_str());
|
||||
match type_ {
|
||||
Some("json") => RequestedModuleType::Json,
|
||||
Some("bytes") => RequestedModuleType::Bytes,
|
||||
Some("text") => RequestedModuleType::Text,
|
||||
Some(other) => RequestedModuleType::Other(other.to_string().into()),
|
||||
None => RequestedModuleType::None,
|
||||
}
|
||||
|
@ -536,7 +552,7 @@ impl esbuild_client::PluginHandler for DenoPluginHandler {
|
|||
args: esbuild_client::OnLoadArgs,
|
||||
) -> Result<Option<esbuild_client::OnLoadResult>, AnyError> {
|
||||
let result = self
|
||||
.bundle_load(&args.path, requested_type_from_map(&args.with))
|
||||
.bundle_load(&args.path, &requested_type_from_map(&args.with))
|
||||
.await;
|
||||
let result = match result {
|
||||
Ok(r) => r,
|
||||
|
@ -636,16 +652,13 @@ impl BundleLoadError {
|
|||
pub fn is_unsupported_media_type(&self) -> bool {
|
||||
match self {
|
||||
BundleLoadError::CliModuleLoader(
|
||||
CliModuleLoaderError::LoadCodeSource(LoadCodeSourceError(ref e)),
|
||||
CliModuleLoaderError::LoadCodeSource(LoadCodeSourceError(e)),
|
||||
) => match &**e {
|
||||
LoadCodeSourceErrorKind::LoadPreparedModule(
|
||||
LoadPreparedModuleError::Graph(ref e),
|
||||
LoadPreparedModuleError::Graph(e),
|
||||
) => matches!(
|
||||
&**e,
|
||||
EnhancedGraphError {
|
||||
error: ModuleError::UnsupportedMediaType { .. },
|
||||
..
|
||||
}
|
||||
e.error.as_kind(),
|
||||
ModuleErrorKind::UnsupportedMediaType { .. },
|
||||
),
|
||||
_ => false,
|
||||
},
|
||||
|
@ -729,7 +742,7 @@ impl DenoPluginHandler {
|
|||
Position::new(0, 0),
|
||||
ResolveWithGraphOptions {
|
||||
mode: import_kind_to_resolution_mode(kind),
|
||||
kind: NodeResolutionKind::Execution,
|
||||
kind: NodeResolutionKind::Bundling,
|
||||
maintain_npm_specifiers: false,
|
||||
},
|
||||
);
|
||||
|
@ -778,7 +791,7 @@ impl DenoPluginHandler {
|
|||
async fn bundle_load(
|
||||
&self,
|
||||
specifier: &str,
|
||||
requested_type: RequestedModuleType,
|
||||
requested_type: &RequestedModuleType,
|
||||
) -> Result<Option<(Vec<u8>, esbuild_client::BuiltinLoader)>, BundleLoadError>
|
||||
{
|
||||
log::debug!(
|
||||
|
@ -793,7 +806,19 @@ impl DenoPluginHandler {
|
|||
Path::new(""), // should be absolute already, feels kind of hacky though
|
||||
)?;
|
||||
let (specifier, media_type, loader) =
|
||||
if let Some((specifier, media_type, loader)) =
|
||||
if let RequestedModuleType::Bytes = requested_type {
|
||||
(
|
||||
specifier,
|
||||
MediaType::Unknown,
|
||||
esbuild_client::BuiltinLoader::Binary,
|
||||
)
|
||||
} else if let RequestedModuleType::Text = requested_type {
|
||||
(
|
||||
specifier,
|
||||
MediaType::Unknown,
|
||||
esbuild_client::BuiltinLoader::Text,
|
||||
)
|
||||
} else if let Some((specifier, media_type, loader)) =
|
||||
self.specifier_and_type_from_graph(&specifier)?
|
||||
{
|
||||
(specifier, media_type, loader)
|
||||
|
@ -1028,19 +1053,20 @@ fn resolve_roots(
|
|||
let mut roots = Vec::with_capacity(entrypoints.len());
|
||||
|
||||
for url in entrypoints {
|
||||
let root = if let Ok(v) = NpmPackageReqReference::from_specifier(&url) {
|
||||
let referrer =
|
||||
ModuleSpecifier::from_directory_path(sys.env_current_dir().unwrap())
|
||||
let root = match NpmPackageReqReference::from_specifier(&url) {
|
||||
Ok(v) => {
|
||||
let referrer =
|
||||
ModuleSpecifier::from_directory_path(sys.env_current_dir().unwrap())
|
||||
.unwrap();
|
||||
let package_folder = npm_resolver
|
||||
.resolve_pkg_folder_from_deno_module_req(v.req(), &referrer)
|
||||
.unwrap();
|
||||
let package_folder = npm_resolver
|
||||
.resolve_pkg_folder_from_deno_module_req(v.req(), &referrer)
|
||||
.unwrap();
|
||||
let main_module = node_resolver
|
||||
.resolve_binary_export(&package_folder, v.sub_path())
|
||||
.unwrap();
|
||||
Url::from_file_path(&main_module).unwrap()
|
||||
} else {
|
||||
url
|
||||
let main_module = node_resolver
|
||||
.resolve_binary_export(&package_folder, v.sub_path())
|
||||
.unwrap();
|
||||
Url::from_file_path(&main_module).unwrap()
|
||||
}
|
||||
_ => url,
|
||||
};
|
||||
roots.push(root)
|
||||
}
|
||||
|
@ -1076,7 +1102,7 @@ fn configure_esbuild_flags(bundle_flags: &BundleFlags) -> EsbuildFlags {
|
|||
let mut builder = EsbuildFlagsBuilder::default();
|
||||
|
||||
builder
|
||||
.bundle(bundle_flags.one_file)
|
||||
.bundle(bundle_flags.inline_imports)
|
||||
.minify(bundle_flags.minify)
|
||||
.splitting(bundle_flags.code_splitting)
|
||||
.external(bundle_flags.external.clone())
|
||||
|
@ -1104,9 +1130,7 @@ fn configure_esbuild_flags(bundle_flags: &BundleFlags) -> EsbuildFlags {
|
|||
} else if let Some(output_path) = bundle_flags.output_path.clone() {
|
||||
builder.outfile(output_path);
|
||||
}
|
||||
if bundle_flags.watch {
|
||||
builder.metafile(true);
|
||||
}
|
||||
builder.metafile(true);
|
||||
|
||||
match bundle_flags.platform {
|
||||
crate::args::BundlePlatform::Browser => {
|
||||
|
@ -1139,38 +1163,117 @@ fn handle_esbuild_errors_and_warnings(
|
|||
}
|
||||
}
|
||||
|
||||
fn is_js(path: &Path) -> bool {
|
||||
if let Some(ext) = path.extension() {
|
||||
matches!(
|
||||
ext.to_string_lossy().as_ref(),
|
||||
"js" | "mjs" | "cjs" | "jsx" | "ts" | "tsx" | "mts" | "cts" | "dts"
|
||||
)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
struct OutputFileInfo {
|
||||
relative_path: PathBuf,
|
||||
size: usize,
|
||||
is_js: bool,
|
||||
}
|
||||
fn process_result(
|
||||
response: &BuildResponse,
|
||||
// init_cwd: &Path,
|
||||
cwd: &Path,
|
||||
should_replace_require_shim: bool,
|
||||
) -> Result<(), AnyError> {
|
||||
if let Some(output_files) = response.output_files.as_ref() {
|
||||
let mut exists_cache = std::collections::HashSet::new();
|
||||
for file in output_files.iter() {
|
||||
minified: bool,
|
||||
) -> Result<Vec<OutputFileInfo>, AnyError> {
|
||||
let mut exists_cache = std::collections::HashSet::new();
|
||||
let output_files = response
|
||||
.output_files
|
||||
.as_ref()
|
||||
.map(Cow::Borrowed)
|
||||
.unwrap_or_default();
|
||||
let mut output_infos = Vec::new();
|
||||
for file in output_files.iter() {
|
||||
let path = Path::new(&file.path);
|
||||
let relative_path =
|
||||
pathdiff::diff_paths(path, cwd).unwrap_or_else(|| path.to_path_buf());
|
||||
let is_js = is_js(path);
|
||||
let bytes = if is_js || file.path.ends_with("<stdout>") {
|
||||
let string = String::from_utf8(file.contents.clone())?;
|
||||
let string = if should_replace_require_shim {
|
||||
replace_require_shim(&string)
|
||||
replace_require_shim(&string, minified)
|
||||
} else {
|
||||
string
|
||||
};
|
||||
Cow::Owned(string.into_bytes())
|
||||
} else {
|
||||
Cow::Borrowed(&file.contents)
|
||||
};
|
||||
|
||||
if file.path == "<stdout>" {
|
||||
crate::display::write_to_stdout_ignore_sigpipe(string.as_bytes())?;
|
||||
continue;
|
||||
}
|
||||
let path = PathBuf::from(&file.path);
|
||||
|
||||
if let Some(parent) = path.parent() {
|
||||
if !exists_cache.contains(parent) {
|
||||
if !parent.exists() {
|
||||
std::fs::create_dir_all(parent)?;
|
||||
}
|
||||
exists_cache.insert(parent.to_path_buf());
|
||||
}
|
||||
}
|
||||
|
||||
std::fs::write(&file.path, string)?;
|
||||
if file.path.ends_with("<stdout>") {
|
||||
crate::display::write_to_stdout_ignore_sigpipe(bytes.as_slice())?;
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(parent) = path.parent() {
|
||||
if !exists_cache.contains(parent) {
|
||||
if !parent.exists() {
|
||||
std::fs::create_dir_all(parent)?;
|
||||
}
|
||||
exists_cache.insert(parent.to_path_buf());
|
||||
}
|
||||
}
|
||||
|
||||
output_infos.push(OutputFileInfo {
|
||||
relative_path,
|
||||
size: bytes.len(),
|
||||
is_js,
|
||||
});
|
||||
|
||||
std::fs::write(path, bytes.as_ref())?;
|
||||
}
|
||||
Ok(output_infos)
|
||||
}
|
||||
|
||||
fn print_finished_message(
|
||||
metafile: &esbuild_client::Metafile,
|
||||
output_infos: &[OutputFileInfo],
|
||||
duration: Duration,
|
||||
) -> Result<(), AnyError> {
|
||||
let mut output = String::new();
|
||||
output.push_str(&format!(
|
||||
"{} {} module{} in {}",
|
||||
deno_terminal::colors::green("Bundled"),
|
||||
metafile.inputs.len(),
|
||||
if metafile.inputs.len() == 1 { "" } else { "s" },
|
||||
crate::display::human_elapsed(duration.as_millis()),
|
||||
));
|
||||
|
||||
let longest = output_infos
|
||||
.iter()
|
||||
.map(|info| info.relative_path.to_string_lossy().len())
|
||||
.max()
|
||||
.unwrap_or(0);
|
||||
for info in output_infos {
|
||||
output.push_str(&format!(
|
||||
"\n {} {}",
|
||||
if info.is_js {
|
||||
deno_terminal::colors::cyan(format!(
|
||||
"{:<longest$}",
|
||||
info.relative_path.display()
|
||||
))
|
||||
} else {
|
||||
deno_terminal::colors::magenta(format!(
|
||||
"{:<longest$}",
|
||||
info.relative_path.display()
|
||||
))
|
||||
},
|
||||
deno_terminal::colors::gray(
|
||||
crate::display::human_size(info.size as f64,)
|
||||
)
|
||||
));
|
||||
}
|
||||
output.push('\n');
|
||||
log::info!("{}", output);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -9,12 +9,12 @@ use std::path::PathBuf;
|
|||
use std::sync::Arc;
|
||||
|
||||
use deno_cache_dir::GlobalOrLocalHttpCache;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::url::Url;
|
||||
use deno_graph::packages::PackageSpecifiers;
|
||||
use deno_graph::ModuleGraph;
|
||||
use deno_graph::packages::PackageSpecifiers;
|
||||
use deno_npm_installer::graph::NpmCachingStrategy;
|
||||
use sys_traits::FsCanonicalize;
|
||||
use sys_traits::FsCreateDirAll;
|
||||
|
@ -527,7 +527,7 @@ fn clean_node_modules(
|
|||
"failed to clean node_modules directory at {}",
|
||||
dir.display()
|
||||
)
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -646,22 +646,23 @@ fn remove_file(
|
|||
}
|
||||
state.files_removed += 1;
|
||||
state.update_progress();
|
||||
if let Err(e) = std::fs::remove_file(path)
|
||||
match std::fs::remove_file(path)
|
||||
.with_context(|| format!("Failed to remove file: {}", path.display()))
|
||||
{
|
||||
if cfg!(windows) {
|
||||
if let Ok(meta) = path.symlink_metadata() {
|
||||
if meta.is_symlink() {
|
||||
std::fs::remove_dir(path).with_context(|| {
|
||||
format!("Failed to remove symlink: {}", path.display())
|
||||
})?;
|
||||
return Ok(());
|
||||
Err(e) => {
|
||||
if cfg!(windows) {
|
||||
if let Ok(meta) = path.symlink_metadata() {
|
||||
if meta.is_symlink() {
|
||||
std::fs::remove_dir(path).with_context(|| {
|
||||
format!("Failed to remove symlink: {}", path.display())
|
||||
})?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e)
|
||||
}
|
||||
Err(e)
|
||||
} else {
|
||||
Ok(())
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ use std::sync::Arc;
|
|||
|
||||
use deno_ast::MediaType;
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::resolve_url_or_path;
|
||||
use deno_graph::GraphKind;
|
||||
|
@ -21,13 +21,12 @@ use deno_path_util::url_to_file_path;
|
|||
use deno_terminal::colors;
|
||||
use rand::Rng;
|
||||
|
||||
use super::installer::infer_name_from_url;
|
||||
use super::installer::BinNameResolver;
|
||||
use crate::args::CompileFlags;
|
||||
use crate::args::Flags;
|
||||
use crate::factory::CliFactory;
|
||||
use crate::http_util::HttpClientProvider;
|
||||
use crate::standalone::binary::is_standalone_binary;
|
||||
use crate::standalone::binary::WriteBinOptions;
|
||||
use crate::standalone::binary::is_standalone_binary;
|
||||
|
||||
pub async fn compile(
|
||||
flags: Arc<Flags>,
|
||||
|
@ -37,10 +36,10 @@ pub async fn compile(
|
|||
let cli_options = factory.cli_options()?;
|
||||
let module_graph_creator = factory.module_graph_creator().await?;
|
||||
let binary_writer = factory.create_compile_binary_writer().await?;
|
||||
let http_client = factory.http_client_provider();
|
||||
let entrypoint = cli_options.resolve_main_module()?;
|
||||
let bin_name_resolver = factory.bin_name_resolver()?;
|
||||
let output_path = resolve_compile_executable_output_path(
|
||||
http_client,
|
||||
&bin_name_resolver,
|
||||
&compile_flags,
|
||||
cli_options.initial_cwd(),
|
||||
)
|
||||
|
@ -84,7 +83,7 @@ pub async fn compile(
|
|||
temp_filename.push(format!(
|
||||
".tmp-{}",
|
||||
faster_hex::hex_encode(
|
||||
&rand::thread_rng().gen::<[u8; 8]>(),
|
||||
&rand::thread_rng().r#gen::<[u8; 8]>(),
|
||||
&mut [0u8; 16]
|
||||
)
|
||||
.unwrap()
|
||||
|
@ -163,12 +162,12 @@ pub async fn compile_eszip(
|
|||
let factory = CliFactory::from_flags(flags);
|
||||
let cli_options = factory.cli_options()?;
|
||||
let module_graph_creator = factory.module_graph_creator().await?;
|
||||
let parsed_source_cache = factory.parsed_source_cache();
|
||||
let tsconfig_resolver = factory.tsconfig_resolver()?;
|
||||
let http_client = factory.http_client_provider();
|
||||
let parsed_source_cache = factory.parsed_source_cache()?;
|
||||
let compiler_options_resolver = factory.compiler_options_resolver()?;
|
||||
let bin_name_resolver = factory.bin_name_resolver()?;
|
||||
let entrypoint = cli_options.resolve_main_module()?;
|
||||
let mut output_path = resolve_compile_executable_output_path(
|
||||
http_client,
|
||||
&bin_name_resolver,
|
||||
&compile_flags,
|
||||
cli_options.initial_cwd(),
|
||||
)
|
||||
|
@ -204,8 +203,9 @@ pub async fn compile_eszip(
|
|||
graph
|
||||
};
|
||||
|
||||
let transpile_and_emit_options = tsconfig_resolver
|
||||
.transpile_and_emit_options(cli_options.workspace().root_dir())?;
|
||||
let transpile_and_emit_options = compiler_options_resolver
|
||||
.for_specifier(cli_options.workspace().root_dir())
|
||||
.transpile_options()?;
|
||||
let transpile_options = transpile_and_emit_options.transpile.clone();
|
||||
let emit_options = transpile_and_emit_options.emit.clone();
|
||||
|
||||
|
@ -307,13 +307,13 @@ fn validate_output_path(output_path: &Path) -> Result<(), AnyError> {
|
|||
let output_base = &output_path.parent().unwrap();
|
||||
if output_base.exists() && output_base.is_file() {
|
||||
bail!(
|
||||
concat!(
|
||||
"Could not compile to file '{}' because its parent directory ",
|
||||
"is an existing file. You can use the `--output <file-path>` flag to ",
|
||||
"provide an alternative name.",
|
||||
),
|
||||
output_base.display(),
|
||||
);
|
||||
concat!(
|
||||
"Could not compile to file '{}' because its parent directory ",
|
||||
"is an existing file. You can use the `--output <file-path>` flag to ",
|
||||
"provide an alternative name.",
|
||||
),
|
||||
output_base.display(),
|
||||
);
|
||||
}
|
||||
std::fs::create_dir_all(output_base)?;
|
||||
}
|
||||
|
@ -420,7 +420,7 @@ fn get_module_roots_and_include_paths(
|
|||
}
|
||||
|
||||
async fn resolve_compile_executable_output_path(
|
||||
http_client_provider: &HttpClientProvider,
|
||||
bin_name_resolver: &BinNameResolver<'_>,
|
||||
compile_flags: &CompileFlags,
|
||||
current_dir: &Path,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
|
@ -431,10 +431,10 @@ async fn resolve_compile_executable_output_path(
|
|||
let mut output_path = if let Some(out) = output_flag.as_ref() {
|
||||
let mut out_path = PathBuf::from(out);
|
||||
if out.ends_with('/') || out.ends_with('\\') {
|
||||
if let Some(infer_file_name) =
|
||||
infer_name_from_url(http_client_provider, &module_specifier)
|
||||
.await
|
||||
.map(PathBuf::from)
|
||||
if let Some(infer_file_name) = bin_name_resolver
|
||||
.infer_name_from_url(&module_specifier)
|
||||
.await
|
||||
.map(PathBuf::from)
|
||||
{
|
||||
out_path = out_path.join(infer_file_name);
|
||||
}
|
||||
|
@ -447,7 +447,8 @@ async fn resolve_compile_executable_output_path(
|
|||
};
|
||||
|
||||
if output_flag.is_none() {
|
||||
output_path = infer_name_from_url(http_client_provider, &module_specifier)
|
||||
output_path = bin_name_resolver
|
||||
.infer_name_from_url(&module_specifier)
|
||||
.await
|
||||
.map(PathBuf::from)
|
||||
}
|
||||
|
@ -481,13 +482,18 @@ fn get_os_specific_filepath(
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use deno_npm::registry::TestNpmRegistryApi;
|
||||
|
||||
pub use super::*;
|
||||
use crate::http_util::HttpClientProvider;
|
||||
|
||||
#[tokio::test]
|
||||
async fn resolve_compile_executable_output_path_target_linux() {
|
||||
let http_client = HttpClientProvider::new(None, None);
|
||||
let npm_api = TestNpmRegistryApi::default();
|
||||
let bin_name_resolver = BinNameResolver::new(&http_client, &npm_api);
|
||||
let path = resolve_compile_executable_output_path(
|
||||
&http_client,
|
||||
&bin_name_resolver,
|
||||
&CompileFlags {
|
||||
source_file: "mod.ts".to_string(),
|
||||
output: Some(String::from("./file")),
|
||||
|
@ -513,8 +519,10 @@ mod test {
|
|||
#[tokio::test]
|
||||
async fn resolve_compile_executable_output_path_target_windows() {
|
||||
let http_client = HttpClientProvider::new(None, None);
|
||||
let npm_api = TestNpmRegistryApi::default();
|
||||
let bin_name_resolver = BinNameResolver::new(&http_client, &npm_api);
|
||||
let path = resolve_compile_executable_output_path(
|
||||
&http_client,
|
||||
&bin_name_resolver,
|
||||
&CompileFlags {
|
||||
source_file: "mod.ts".to_string(),
|
||||
output: Some(String::from("./file")),
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use deno_ast::swc::common::comments::CommentKind;
|
||||
use deno_ast::MediaType;
|
||||
use deno_ast::TextLines;
|
||||
use deno_ast::swc::common::comments::CommentKind;
|
||||
use deno_core::url::Url;
|
||||
|
||||
static COVERAGE_IGNORE_START_DIRECTIVE: &str = "deno-coverage-ignore-start";
|
||||
|
|
|
@ -209,7 +209,7 @@ impl<'a> Iterator for StartEventQueue<'a> {
|
|||
|
||||
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
|
||||
let pending_offset: Option<usize> = match &self.pending {
|
||||
Some(ref start_event) if !start_event.trees.is_empty() => {
|
||||
Some(start_event) if !start_event.trees.is_empty() => {
|
||||
Some(start_event.offset)
|
||||
}
|
||||
_ => None,
|
||||
|
@ -299,7 +299,7 @@ fn merge_range_tree_children<'a>(
|
|||
}
|
||||
None => {
|
||||
let mut open_range_end: usize = event.offset + 1;
|
||||
for (_, ref tree) in &event.trees {
|
||||
for (_, tree) in &event.trees {
|
||||
open_range_end = if tree.end > open_range_end {
|
||||
tree.end
|
||||
} else {
|
||||
|
|
|
@ -15,14 +15,14 @@ use deno_config::glob::FileCollector;
|
|||
use deno_config::glob::FilePatterns;
|
||||
use deno_config::glob::PathOrPattern;
|
||||
use deno_config::glob::PathOrPatternSet;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::LocalInspectorSession;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::CoreError;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::sourcemap::SourceMap;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::LocalInspectorSession;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_resolver::npm::DenoInNpmPackageChecker;
|
||||
use node_resolver::InNpmPackageChecker;
|
||||
|
@ -579,6 +579,7 @@ fn filter_coverages(
|
|||
|| e.url.starts_with("data:")
|
||||
|| e.url.ends_with("__anonymous__")
|
||||
|| e.url.ends_with("$deno$test.mjs")
|
||||
|| e.url.ends_with("$deno$stdin.mts")
|
||||
|| e.url.ends_with(".snap")
|
||||
|| is_supported_test_path(Path::new(e.url.as_str()))
|
||||
|| doc_test_re.is_match(e.url.as_str())
|
||||
|
|
|
@ -13,8 +13,8 @@ use deno_core::error::AnyError;
|
|||
use deno_core::url::Url;
|
||||
use deno_lib::version::DENO_VERSION_INFO;
|
||||
|
||||
use super::util;
|
||||
use super::CoverageReport;
|
||||
use super::util;
|
||||
use crate::args::CoverageType;
|
||||
use crate::colors;
|
||||
|
||||
|
|
|
@ -7,24 +7,24 @@ use std::sync::Arc;
|
|||
use deno_ast::diagnostics::Diagnostic;
|
||||
use deno_config::glob::FilePatterns;
|
||||
use deno_config::glob::PathOrPatternSet;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::serde_json;
|
||||
use deno_doc as doc;
|
||||
use deno_doc::html::UrlResolveKind;
|
||||
use deno_doc::html::UsageComposer;
|
||||
use deno_doc::html::UsageComposerEntry;
|
||||
use deno_graph::analysis::ModuleAnalyzer;
|
||||
use deno_graph::ast::EsParser;
|
||||
use deno_graph::source::NullFileSystem;
|
||||
use deno_graph::CheckJsOption;
|
||||
use deno_graph::GraphKind;
|
||||
use deno_graph::ModuleSpecifier;
|
||||
use deno_graph::analysis::ModuleAnalyzer;
|
||||
use deno_graph::ast::EsParser;
|
||||
use deno_graph::source::NullFileSystem;
|
||||
use deno_lib::version::DENO_VERSION_INFO;
|
||||
use deno_npm_installer::graph::NpmCachingStrategy;
|
||||
use doc::html::ShortPath;
|
||||
use doc::DocDiagnostic;
|
||||
use doc::html::ShortPath;
|
||||
use indexmap::IndexMap;
|
||||
|
||||
use crate::args::DocFlags;
|
||||
|
@ -34,9 +34,9 @@ use crate::args::Flags;
|
|||
use crate::colors;
|
||||
use crate::display;
|
||||
use crate::factory::CliFactory;
|
||||
use crate::graph_util::GraphWalkErrorsOptions;
|
||||
use crate::graph_util::graph_exit_integrity_errors;
|
||||
use crate::graph_util::graph_walk_errors;
|
||||
use crate::graph_util::GraphWalkErrorsOptions;
|
||||
use crate::sys::CliSys;
|
||||
use crate::tsc::get_types_declaration_file_text;
|
||||
use crate::util::fs::collect_specifiers;
|
||||
|
@ -85,6 +85,8 @@ async fn generate_doc_nodes_for_builtin_types(
|
|||
npm_resolver: None,
|
||||
reporter: None,
|
||||
resolver: None,
|
||||
unstable_bytes_imports: false,
|
||||
unstable_text_imports: false,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
@ -107,7 +109,7 @@ pub async fn doc(
|
|||
let factory = CliFactory::from_flags(flags);
|
||||
let cli_options = factory.cli_options()?;
|
||||
let module_info_cache = factory.module_info_cache()?;
|
||||
let parsed_source_cache = factory.parsed_source_cache();
|
||||
let parsed_source_cache = factory.parsed_source_cache()?;
|
||||
let capturing_parser = parsed_source_cache.as_capturing_parser();
|
||||
let analyzer = module_info_cache.as_module_analyzer();
|
||||
|
||||
|
|
311
cli/tools/fmt.rs
311
cli/tools/fmt.rs
|
@ -9,29 +9,28 @@
|
|||
|
||||
use std::borrow::Cow;
|
||||
use std::fs;
|
||||
use std::io::stdin;
|
||||
use std::io::stdout;
|
||||
use std::io::Read;
|
||||
use std::io::Write;
|
||||
use std::io::stdin;
|
||||
use std::io::stdout;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use deno_ast::ParsedSource;
|
||||
use deno_config::glob::FileCollector;
|
||||
use deno_config::glob::FilePatterns;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::unsync::spawn_blocking;
|
||||
use deno_core::url::Url;
|
||||
use deno_media_type::MediaType;
|
||||
use log::debug;
|
||||
use log::info;
|
||||
use log::warn;
|
||||
|
@ -301,7 +300,7 @@ fn format_markdown(
|
|||
"css" | "scss" | "sass" | "less" => {
|
||||
format_css(&fake_filename, text, fmt_options)
|
||||
}
|
||||
"html" => {
|
||||
"html" | "svg" | "xml" => {
|
||||
format_html(&fake_filename, text, fmt_options, unstable_options)
|
||||
}
|
||||
"svelte" | "vue" | "astro" | "vto" | "njk" => {
|
||||
|
@ -538,15 +537,16 @@ pub fn format_html(
|
|||
fn create_external_formatter_for_typescript(
|
||||
unstable_options: &UnstableFmtOptions,
|
||||
) -> impl Fn(
|
||||
MediaType,
|
||||
&str,
|
||||
String,
|
||||
&dprint_plugin_typescript::configuration::Configuration,
|
||||
) -> deno_core::anyhow::Result<Option<String>> {
|
||||
) -> deno_core::anyhow::Result<Option<String>>
|
||||
+ use<> {
|
||||
let unstable_sql = unstable_options.sql;
|
||||
move |media_type, text, config| match media_type {
|
||||
MediaType::Css => format_embedded_css(&text, config),
|
||||
MediaType::Html => format_embedded_html(&text, config),
|
||||
MediaType::Sql => {
|
||||
move |lang, text, config| match lang {
|
||||
"css" => format_embedded_css(&text, config),
|
||||
"html" | "xml" | "svg" => format_embedded_html(lang, &text, config),
|
||||
"sql" => {
|
||||
if unstable_sql {
|
||||
format_embedded_sql(&text, config)
|
||||
} else {
|
||||
|
@ -617,6 +617,8 @@ fn format_embedded_css(
|
|||
selector_override_comment_directive: "malva-selector-override".into(),
|
||||
ignore_comment_directive: "malva-ignore".into(),
|
||||
ignore_file_comment_directive: "malva-ignore-file".into(),
|
||||
declaration_order_group_by:
|
||||
config::DeclarationOrderGroupBy::NonDeclaration,
|
||||
},
|
||||
};
|
||||
// Wraps the text in a css block of `a { ... ;}`
|
||||
|
@ -662,10 +664,17 @@ fn format_embedded_css(
|
|||
|
||||
/// Formats the embedded HTML code blocks in JavaScript and TypeScript.
|
||||
fn format_embedded_html(
|
||||
lang: &str,
|
||||
text: &str,
|
||||
config: &dprint_plugin_typescript::configuration::Configuration,
|
||||
) -> deno_core::anyhow::Result<Option<String>> {
|
||||
use markup_fmt::config;
|
||||
|
||||
let language = match lang {
|
||||
"xml" | "svg" => markup_fmt::Language::Xml,
|
||||
_ => markup_fmt::Language::Html,
|
||||
};
|
||||
|
||||
let options = config::FormatOptions {
|
||||
layout: config::LayoutOptions {
|
||||
indent_width: config.indent_width as usize,
|
||||
|
@ -725,12 +734,9 @@ fn format_embedded_html(
|
|||
ignore_file_comment_directive: "deno-fmt-ignore-file".into(),
|
||||
},
|
||||
};
|
||||
let text = markup_fmt::format_text(
|
||||
text,
|
||||
markup_fmt::Language::Html,
|
||||
&options,
|
||||
|code, _| Ok::<_, std::convert::Infallible>(code.into()),
|
||||
)?;
|
||||
let text = markup_fmt::format_text(text, language, &options, |code, _| {
|
||||
Ok::<_, std::convert::Infallible>(code.into())
|
||||
})?;
|
||||
Ok(Some(text.to_string()))
|
||||
}
|
||||
|
||||
|
@ -802,7 +808,7 @@ pub fn format_sql(
|
|||
/// Formats a single TS, TSX, JS, JSX, JSONC, JSON, MD, IPYNB or SQL file.
|
||||
pub fn format_file(
|
||||
file_path: &Path,
|
||||
file_text: &str,
|
||||
file: &FileContents,
|
||||
fmt_options: &FmtOptionsConfig,
|
||||
unstable_options: &UnstableFmtOptions,
|
||||
ext: Option<String>,
|
||||
|
@ -811,34 +817,40 @@ pub fn format_file(
|
|||
.or_else(|| get_extension(file_path))
|
||||
.unwrap_or("ts".to_string());
|
||||
|
||||
match ext.as_str() {
|
||||
let maybe_result = match ext.as_str() {
|
||||
"md" | "mkd" | "mkdn" | "mdwn" | "mdown" | "markdown" => {
|
||||
format_markdown(file_text, fmt_options, unstable_options)
|
||||
format_markdown(&file.text, fmt_options, unstable_options)?
|
||||
}
|
||||
"json" | "jsonc" => format_json(file_path, file_text, fmt_options),
|
||||
"json" | "jsonc" => format_json(file_path, &file.text, fmt_options)?,
|
||||
"css" | "scss" | "sass" | "less" => {
|
||||
format_css(file_path, file_text, fmt_options)
|
||||
format_css(file_path, &file.text, fmt_options)?
|
||||
}
|
||||
"html" => format_html(file_path, file_text, fmt_options, unstable_options),
|
||||
"svelte" | "vue" | "astro" | "vto" | "njk" => {
|
||||
"html" | "xml" | "svg" => {
|
||||
format_html(file_path, &file.text, fmt_options, unstable_options)?
|
||||
}
|
||||
"svelte" | "vue" | "astro" | "vto" | "njk" | "mustache" => {
|
||||
if unstable_options.component {
|
||||
format_html(file_path, file_text, fmt_options, unstable_options)
|
||||
format_html(file_path, &file.text, fmt_options, unstable_options)?
|
||||
} else {
|
||||
Ok(None)
|
||||
None
|
||||
}
|
||||
}
|
||||
"yml" | "yaml" => format_yaml(file_text, fmt_options),
|
||||
"yml" | "yaml" => format_yaml(&file.text, fmt_options)?,
|
||||
"ipynb" => dprint_plugin_jupyter::format_text(
|
||||
file_text,
|
||||
&file.text,
|
||||
|file_path: &Path, file_text: String| {
|
||||
format_file(file_path, &file_text, fmt_options, unstable_options, None)
|
||||
let file = FileContents {
|
||||
had_bom: false,
|
||||
text: file_text.into(),
|
||||
};
|
||||
format_file(file_path, &file, fmt_options, unstable_options, None)
|
||||
},
|
||||
),
|
||||
)?,
|
||||
"sql" => {
|
||||
if unstable_options.sql {
|
||||
format_sql(file_text, fmt_options)
|
||||
format_sql(&file.text, fmt_options)?
|
||||
} else {
|
||||
Ok(None)
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
@ -847,15 +859,24 @@ pub fn format_file(
|
|||
dprint_plugin_typescript::FormatTextOptions {
|
||||
path: file_path,
|
||||
extension: Some(&ext),
|
||||
text: file_text.to_string(),
|
||||
text: file.text.to_string(),
|
||||
config: &config,
|
||||
external_formatter: Some(&create_external_formatter_for_typescript(
|
||||
unstable_options,
|
||||
)),
|
||||
},
|
||||
)
|
||||
)?
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(match maybe_result {
|
||||
Some(result) => Some(result),
|
||||
None if file.had_bom => {
|
||||
// return back the text without the BOM
|
||||
Some(file.text.to_string())
|
||||
}
|
||||
None => None,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn format_parsed_source(
|
||||
|
@ -908,16 +929,18 @@ impl Formatter for CheckFormatter {
|
|||
let checked_files_count = self.checked_files_count.clone();
|
||||
move |file_path| {
|
||||
checked_files_count.fetch_add(1, Ordering::Relaxed);
|
||||
let file_text = read_file_contents(&file_path)?.text;
|
||||
let file = read_file_contents(&file_path)?;
|
||||
|
||||
// skip checking the file if we know it's formatted
|
||||
if incremental_cache.is_file_same(&file_path, &file_text) {
|
||||
if !file.had_bom
|
||||
&& incremental_cache.is_file_same(&file_path, &file.text)
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
match format_file(
|
||||
&file_path,
|
||||
&file_text,
|
||||
&file,
|
||||
&fmt_options,
|
||||
&unstable_options,
|
||||
ext.clone(),
|
||||
|
@ -926,9 +949,12 @@ impl Formatter for CheckFormatter {
|
|||
not_formatted_files_count.fetch_add(1, Ordering::Relaxed);
|
||||
let _g = output_lock.lock();
|
||||
let diff =
|
||||
deno_resolver::display::diff(&file_text, &formatted_text);
|
||||
deno_resolver::display::diff(&file.text, &formatted_text);
|
||||
info!("");
|
||||
info!("{} {}:", colors::bold("from"), file_path.display());
|
||||
if file.had_bom {
|
||||
info!(" {}", colors::gray("File has strippable UTF-8 BOM."));
|
||||
}
|
||||
info!("{}", diff);
|
||||
}
|
||||
Ok(None) => {
|
||||
|
@ -937,7 +963,7 @@ impl Formatter for CheckFormatter {
|
|||
// formatting here. Additionally, ensure this is done during check
|
||||
// so that CIs that cache the DENO_DIR will get the benefit of
|
||||
// incremental formatting
|
||||
incremental_cache.update_file(&file_path, &file_text);
|
||||
incremental_cache.update_file(&file_path, &file.text);
|
||||
}
|
||||
Err(e) => {
|
||||
not_formatted_files_count.fetch_add(1, Ordering::Relaxed);
|
||||
|
@ -1010,41 +1036,33 @@ impl Formatter for RealFormatter {
|
|||
let checked_files_count = self.checked_files_count.clone();
|
||||
move |file_path| {
|
||||
checked_files_count.fetch_add(1, Ordering::Relaxed);
|
||||
let file_contents = read_file_contents(&file_path)?;
|
||||
let file = read_file_contents(&file_path)?;
|
||||
|
||||
// skip formatting the file if we know it's formatted
|
||||
if incremental_cache.is_file_same(&file_path, &file_contents.text) {
|
||||
if !file.had_bom
|
||||
&& incremental_cache.is_file_same(&file_path, &file.text)
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
match format_ensure_stable(
|
||||
&file_path,
|
||||
&file_contents.text,
|
||||
|file_path, file_text| {
|
||||
format_file(
|
||||
file_path,
|
||||
file_text,
|
||||
&fmt_options,
|
||||
&unstable_options,
|
||||
ext.clone(),
|
||||
)
|
||||
},
|
||||
) {
|
||||
match format_ensure_stable(&file_path, &file, |file_path, file| {
|
||||
format_file(
|
||||
file_path,
|
||||
file,
|
||||
&fmt_options,
|
||||
&unstable_options,
|
||||
ext.clone(),
|
||||
)
|
||||
}) {
|
||||
Ok(Some(formatted_text)) => {
|
||||
incremental_cache.update_file(&file_path, &formatted_text);
|
||||
write_file_contents(
|
||||
&file_path,
|
||||
FileContents {
|
||||
had_bom: file_contents.had_bom,
|
||||
text: formatted_text,
|
||||
},
|
||||
)?;
|
||||
write_file_contents(&file_path, &formatted_text)?;
|
||||
formatted_files_count.fetch_add(1, Ordering::Relaxed);
|
||||
let _g = output_lock.lock();
|
||||
info!("{}", file_path.to_string_lossy());
|
||||
}
|
||||
Ok(None) => {
|
||||
incremental_cache.update_file(&file_path, &file_contents.text);
|
||||
incremental_cache.update_file(&file_path, &file.text);
|
||||
}
|
||||
Err(e) => {
|
||||
failed_files_count.fetch_add(1, Ordering::Relaxed);
|
||||
|
@ -1098,16 +1116,22 @@ impl Formatter for RealFormatter {
|
|||
/// a user formats their code locally and it fails on the CI afterwards.
|
||||
fn format_ensure_stable(
|
||||
file_path: &Path,
|
||||
file_text: &str,
|
||||
fmt_func: impl Fn(&Path, &str) -> Result<Option<String>, AnyError>,
|
||||
file: &FileContents,
|
||||
fmt_func: impl Fn(&Path, &FileContents) -> Result<Option<String>, AnyError>,
|
||||
) -> Result<Option<String>, AnyError> {
|
||||
let formatted_text = fmt_func(file_path, file_text)?;
|
||||
let formatted_text = fmt_func(file_path, file)?;
|
||||
|
||||
match formatted_text {
|
||||
Some(mut current_text) => {
|
||||
let mut count = 0;
|
||||
loop {
|
||||
match fmt_func(file_path, ¤t_text) {
|
||||
match fmt_func(
|
||||
file_path,
|
||||
&FileContents {
|
||||
had_bom: false,
|
||||
text: (¤t_text).into(),
|
||||
},
|
||||
) {
|
||||
Ok(Some(next_pass_text)) => {
|
||||
// just in case
|
||||
if next_pass_text == current_text {
|
||||
|
@ -1159,10 +1183,14 @@ fn format_stdin(
|
|||
if stdin().read_to_string(&mut source).is_err() {
|
||||
bail!("Failed to read from stdin");
|
||||
}
|
||||
let file = FileContents {
|
||||
had_bom: false,
|
||||
text: source.into(),
|
||||
};
|
||||
let file_path = PathBuf::from(format!("_stdin.{ext}"));
|
||||
let formatted_text = format_file(
|
||||
&file_path,
|
||||
&source,
|
||||
&file,
|
||||
&fmt_options.options,
|
||||
&fmt_options.unstable,
|
||||
None,
|
||||
|
@ -1173,17 +1201,18 @@ fn format_stdin(
|
|||
println!("Not formatted stdin");
|
||||
}
|
||||
} else {
|
||||
stdout().write_all(formatted_text.unwrap_or(source).as_bytes())?;
|
||||
stdout().write_all(
|
||||
formatted_text
|
||||
.as_ref()
|
||||
.map(|t| t.as_bytes())
|
||||
.unwrap_or(file.text.as_bytes()),
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn files_str(len: usize) -> &'static str {
|
||||
if len == 1 {
|
||||
"file"
|
||||
} else {
|
||||
"files"
|
||||
}
|
||||
if len == 1 { "file" } else { "files" }
|
||||
}
|
||||
|
||||
fn get_typescript_config_builder(
|
||||
|
@ -1478,6 +1507,7 @@ fn get_resolved_malva_config(
|
|||
selector_override_comment_directive: "deno-fmt-selector-override".into(),
|
||||
ignore_comment_directive: "deno-fmt-ignore".into(),
|
||||
ignore_file_comment_directive: "deno-fmt-ignore-file".into(),
|
||||
declaration_order_group_by: DeclarationOrderGroupBy::NonDeclaration,
|
||||
};
|
||||
|
||||
FormatOptions {
|
||||
|
@ -1584,40 +1614,37 @@ fn get_resolved_yaml_config(
|
|||
}
|
||||
}
|
||||
|
||||
struct FileContents {
|
||||
text: String,
|
||||
had_bom: bool,
|
||||
pub struct FileContents<'a> {
|
||||
pub text: Cow<'a, str>,
|
||||
pub had_bom: bool,
|
||||
}
|
||||
|
||||
fn read_file_contents(file_path: &Path) -> Result<FileContents, AnyError> {
|
||||
let file_bytes = fs::read(file_path)
|
||||
.with_context(|| format!("Error reading {}", file_path.display()))?;
|
||||
let had_bom = file_bytes.starts_with(&[0xEF, 0xBB, 0xBF]);
|
||||
// will have the BOM stripped
|
||||
|
||||
let charset =
|
||||
deno_media_type::encoding::detect_charset_local_file(&file_bytes);
|
||||
let text =
|
||||
deno_media_type::encoding::decode_owned_source(charset, file_bytes)
|
||||
.with_context(|| {
|
||||
anyhow!("{} is not a valid UTF-8 file", file_path.display())
|
||||
})?;
|
||||
let text = deno_media_type::encoding::decode_owned_source(
|
||||
charset,
|
||||
file_bytes.to_vec(),
|
||||
)
|
||||
.with_context(|| {
|
||||
anyhow!("{} is not a valid UTF-8 file", file_path.display())
|
||||
})?;
|
||||
|
||||
Ok(FileContents { text, had_bom })
|
||||
Ok(FileContents {
|
||||
text: Cow::Owned(text),
|
||||
had_bom,
|
||||
})
|
||||
}
|
||||
|
||||
fn write_file_contents(
|
||||
file_path: &Path,
|
||||
mut file_contents: FileContents,
|
||||
file_contents: &str,
|
||||
) -> Result<(), AnyError> {
|
||||
let file_text = if file_contents.had_bom {
|
||||
// add back the BOM
|
||||
file_contents.text.insert(0, '\u{FEFF}');
|
||||
file_contents.text
|
||||
} else {
|
||||
file_contents.text
|
||||
};
|
||||
|
||||
Ok(fs::write(file_path, file_text)?)
|
||||
Ok(fs::write(file_path, file_contents)?)
|
||||
}
|
||||
|
||||
pub async fn run_parallelized<F>(
|
||||
|
@ -1656,10 +1683,9 @@ where
|
|||
.and_then(|handle_result| handle_result.err())
|
||||
});
|
||||
|
||||
if let Some(e) = errors.next() {
|
||||
Err(e)
|
||||
} else {
|
||||
Ok(())
|
||||
match errors.next() {
|
||||
Some(e) => Err(e),
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1699,6 +1725,9 @@ fn is_supported_ext_fmt(path: &Path) -> bool {
|
|||
| "yaml"
|
||||
| "ipynb"
|
||||
| "sql"
|
||||
| "xml"
|
||||
| "svg"
|
||||
| "mustache"
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -1768,11 +1797,15 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_format_ensure_stable_unstable_format() {
|
||||
let err =
|
||||
format_ensure_stable(&PathBuf::from("mod.ts"), "1", |_, file_text| {
|
||||
Ok(Some(format!("1{file_text}")))
|
||||
})
|
||||
.unwrap_err();
|
||||
let err = format_ensure_stable(
|
||||
&PathBuf::from("mod.ts"),
|
||||
&FileContents {
|
||||
had_bom: false,
|
||||
text: "1".into(),
|
||||
},
|
||||
|_, file| Ok(Some(format!("1{}", file.text))),
|
||||
)
|
||||
.unwrap_err();
|
||||
assert_starts_with!(
|
||||
err.to_string(),
|
||||
"Formatting not stable. Bailed after 5 tries."
|
||||
|
@ -1781,9 +1814,14 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_format_ensure_stable_error_first() {
|
||||
let err = format_ensure_stable(&PathBuf::from("mod.ts"), "1", |_, _| {
|
||||
bail!("Error formatting.")
|
||||
})
|
||||
let err = format_ensure_stable(
|
||||
&PathBuf::from("mod.ts"),
|
||||
&FileContents {
|
||||
had_bom: false,
|
||||
text: "1".into(),
|
||||
},
|
||||
|_, _| bail!("Error formatting."),
|
||||
)
|
||||
.unwrap_err();
|
||||
|
||||
assert_eq!(err.to_string(), "Error formatting.");
|
||||
|
@ -1791,15 +1829,21 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_format_ensure_stable_error_second() {
|
||||
let err =
|
||||
format_ensure_stable(&PathBuf::from("mod.ts"), "1", |_, file_text| {
|
||||
if file_text == "1" {
|
||||
let err = format_ensure_stable(
|
||||
&PathBuf::from("mod.ts"),
|
||||
&FileContents {
|
||||
had_bom: false,
|
||||
text: "1".into(),
|
||||
},
|
||||
|_, file| {
|
||||
if file.text == "1" {
|
||||
Ok(Some("11".to_string()))
|
||||
} else {
|
||||
bail!("Error formatting.")
|
||||
}
|
||||
})
|
||||
.unwrap_err();
|
||||
},
|
||||
)
|
||||
.unwrap_err();
|
||||
assert_starts_with!(
|
||||
err.to_string(),
|
||||
"Formatting succeeded initially, but failed when"
|
||||
|
@ -1808,17 +1852,23 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_format_stable_after_two() {
|
||||
let result =
|
||||
format_ensure_stable(&PathBuf::from("mod.ts"), "1", |_, file_text| {
|
||||
if file_text == "1" {
|
||||
let result = format_ensure_stable(
|
||||
&PathBuf::from("mod.ts"),
|
||||
&FileContents {
|
||||
had_bom: false,
|
||||
text: "1".into(),
|
||||
},
|
||||
|_, file| {
|
||||
if file.text == "1" {
|
||||
Ok(Some("11".to_string()))
|
||||
} else if file_text == "11" {
|
||||
} else if file.text == "11" {
|
||||
Ok(None)
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(result, Some("11".to_string()));
|
||||
}
|
||||
|
@ -1827,7 +1877,10 @@ mod test {
|
|||
fn test_single_quote_true_prefers_single_quote() {
|
||||
let file_text = format_file(
|
||||
&PathBuf::from("test.ts"),
|
||||
"console.log(\"there's\");\nconsole.log('hi');\nconsole.log(\"bye\")\n",
|
||||
&FileContents {
|
||||
had_bom: false,
|
||||
text: "console.log(\"there's\");\nconsole.log('hi');\nconsole.log(\"bye\")\n".into(),
|
||||
},
|
||||
&FmtOptionsConfig {
|
||||
single_quote: Some(true),
|
||||
..Default::default()
|
||||
|
@ -1843,4 +1896,24 @@ mod test {
|
|||
"console.log(\"there's\");\nconsole.log('hi');\nconsole.log('bye');\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_formated_removes_utf8_bom() {
|
||||
let file_text = format_file(
|
||||
&PathBuf::from("test.ts"),
|
||||
&FileContents {
|
||||
had_bom: true,
|
||||
text: "let a = 1;".into(),
|
||||
},
|
||||
&FmtOptionsConfig {
|
||||
single_quote: Some(true),
|
||||
..Default::default()
|
||||
},
|
||||
&UnstableFmtOptions::default(),
|
||||
None,
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(file_text, "let a = 1;\n",);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,17 +16,18 @@ use deno_graph::Dependency;
|
|||
use deno_graph::GraphKind;
|
||||
use deno_graph::Module;
|
||||
use deno_graph::ModuleError;
|
||||
use deno_graph::ModuleErrorKind;
|
||||
use deno_graph::ModuleGraph;
|
||||
use deno_graph::Resolution;
|
||||
use deno_lib::util::checksum;
|
||||
use deno_lib::version::DENO_VERSION_INFO;
|
||||
use deno_npm::npm_rc::ResolvedNpmRc;
|
||||
use deno_npm::resolution::NpmResolutionSnapshot;
|
||||
use deno_npm::NpmPackageId;
|
||||
use deno_npm::NpmResolutionPackage;
|
||||
use deno_npm::npm_rc::ResolvedNpmRc;
|
||||
use deno_npm::resolution::NpmResolutionSnapshot;
|
||||
use deno_npm_installer::graph::NpmCachingStrategy;
|
||||
use deno_resolver::display::DisplayTreeNode;
|
||||
use deno_resolver::DenoResolveErrorKind;
|
||||
use deno_resolver::display::DisplayTreeNode;
|
||||
use deno_semver::npm::NpmPackageNvReference;
|
||||
use deno_semver::npm::NpmPackageReqReference;
|
||||
use deno_semver::package::PackageNv;
|
||||
|
@ -59,12 +60,12 @@ pub async fn info(
|
|||
let cwd_url =
|
||||
url::Url::from_directory_path(cli_options.initial_cwd()).unwrap();
|
||||
|
||||
let maybe_import_specifier = if let Ok(resolved) = resolver.resolve(
|
||||
let maybe_import_specifier = match resolver.resolve(
|
||||
&specifier,
|
||||
&cwd_url,
|
||||
deno_resolver::workspace::ResolutionKind::Execution,
|
||||
) {
|
||||
match resolved {
|
||||
Ok(resolved) => match resolved {
|
||||
deno_resolver::workspace::MappedResolution::Normal {
|
||||
specifier,
|
||||
..
|
||||
|
@ -134,9 +135,8 @@ pub async fn info(
|
|||
))?)
|
||||
}
|
||||
},
|
||||
}
|
||||
} else {
|
||||
None
|
||||
},
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let specifier = match maybe_import_specifier {
|
||||
|
@ -221,7 +221,7 @@ fn print_cache_info(
|
|||
|
||||
if let Some(location) = &location {
|
||||
origin_dir =
|
||||
origin_dir.join(checksum::gen(&[location.to_string().as_bytes()]));
|
||||
origin_dir.join(checksum::r#gen(&[location.to_string().as_bytes()]));
|
||||
}
|
||||
|
||||
let local_storage_dir = origin_dir.join("local_storage");
|
||||
|
@ -550,7 +550,7 @@ impl<'a> GraphDisplayContext<'a> {
|
|||
Ok(())
|
||||
}
|
||||
Err(err) => {
|
||||
if let ModuleError::Missing { .. } = *err {
|
||||
if let ModuleErrorKind::Missing { .. } = err.as_kind() {
|
||||
bail!("module could not be found");
|
||||
} else {
|
||||
bail!("{:#}", err);
|
||||
|
@ -700,11 +700,11 @@ impl<'a> GraphDisplayContext<'a> {
|
|||
specifier: &ModuleSpecifier,
|
||||
) -> DisplayTreeNode {
|
||||
self.seen.insert(specifier.to_string());
|
||||
match err {
|
||||
ModuleError::InvalidTypeAssertion { .. } => {
|
||||
match err.as_kind() {
|
||||
ModuleErrorKind::InvalidTypeAssertion { .. } => {
|
||||
self.build_error_msg(specifier, "(invalid import attribute)")
|
||||
}
|
||||
ModuleError::Load { err, .. } => {
|
||||
ModuleErrorKind::Load { err, .. } => {
|
||||
use deno_graph::ModuleLoadError::*;
|
||||
let message = match err {
|
||||
HttpsChecksumIntegrity(_) => "(checksum integrity error)",
|
||||
|
@ -722,16 +722,17 @@ impl<'a> GraphDisplayContext<'a> {
|
|||
};
|
||||
self.build_error_msg(specifier, message.as_ref())
|
||||
}
|
||||
ModuleError::Parse { .. } | ModuleError::WasmParse { .. } => {
|
||||
ModuleErrorKind::Parse { .. } | ModuleErrorKind::WasmParse { .. } => {
|
||||
self.build_error_msg(specifier, "(parsing error)")
|
||||
}
|
||||
ModuleError::UnsupportedImportAttributeType { .. } => {
|
||||
ModuleErrorKind::UnsupportedImportAttributeType { .. } => {
|
||||
self.build_error_msg(specifier, "(unsupported import attribute)")
|
||||
}
|
||||
ModuleError::UnsupportedMediaType { .. } => {
|
||||
ModuleErrorKind::UnsupportedMediaType { .. } => {
|
||||
self.build_error_msg(specifier, "(unsupported)")
|
||||
}
|
||||
ModuleError::Missing { .. } | ModuleError::MissingDynamic { .. } => {
|
||||
ModuleErrorKind::Missing { .. }
|
||||
| ModuleErrorKind::MissingDynamic { .. } => {
|
||||
self.build_error_msg(specifier, "(missing)")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -299,13 +299,22 @@ async fn init_npm(name: &str, args: Vec<String>) -> Result<i32, AnyError> {
|
|||
let script_name = npm_name_to_create_package(name);
|
||||
|
||||
fn print_manual_usage(script_name: &str, args: &[String]) -> i32 {
|
||||
log::info!("{}", cformat!("You can initialize project manually by running <u>deno run {} {}</> and applying desired permissions.", script_name, args.join(" ")));
|
||||
log::info!(
|
||||
"{}",
|
||||
cformat!(
|
||||
"You can initialize project manually by running <u>deno run {} {}</> and applying desired permissions.",
|
||||
script_name,
|
||||
args.join(" ")
|
||||
)
|
||||
);
|
||||
1
|
||||
}
|
||||
|
||||
if std::io::stdin().is_terminal() {
|
||||
log::info!(
|
||||
cstr!("⚠️ Do you fully trust <y>{}</> package? Deno will invoke code from it with all permissions. Do you want to continue? <p(245)>[y/n]</>"),
|
||||
cstr!(
|
||||
"⚠️ Do you fully trust <y>{}</> package? Deno will invoke code from it with all permissions. Do you want to continue? <p(245)>[y/n]</>"
|
||||
),
|
||||
script_name
|
||||
);
|
||||
loop {
|
||||
|
|
308
cli/tools/installer/bin_name_resolver.rs
Normal file
308
cli/tools/installer/bin_name_resolver.rs
Normal file
|
@ -0,0 +1,308 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::url::Url;
|
||||
use deno_npm::registry::NpmPackageInfo;
|
||||
use deno_npm::registry::NpmRegistryApi;
|
||||
use deno_semver::npm::NpmPackageReqReference;
|
||||
|
||||
use crate::http_util::HttpClientProvider;
|
||||
|
||||
pub struct BinNameResolver<'a> {
|
||||
http_client_provider: &'a HttpClientProvider,
|
||||
npm_registry_api: &'a dyn NpmRegistryApi,
|
||||
}
|
||||
|
||||
impl<'a> BinNameResolver<'a> {
|
||||
pub fn new(
|
||||
http_client_provider: &'a HttpClientProvider,
|
||||
npm_registry_api: &'a dyn NpmRegistryApi,
|
||||
) -> Self {
|
||||
Self {
|
||||
http_client_provider,
|
||||
npm_registry_api,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn infer_name_from_url(&self, url: &Url) -> Option<String> {
|
||||
// If there's an absolute url with no path, eg. https://my-cli.com
|
||||
// perform a request, and see if it redirects another file instead.
|
||||
let mut url = url.clone();
|
||||
|
||||
if matches!(url.scheme(), "http" | "https") && url.path() == "/" {
|
||||
if let Ok(client) = self.http_client_provider.get_or_create() {
|
||||
if let Ok(redirected_url) = client
|
||||
.get_redirected_url(url.clone(), &Default::default())
|
||||
.await
|
||||
{
|
||||
url = redirected_url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(npm_ref) = NpmPackageReqReference::from_specifier(&url) {
|
||||
if let Some(sub_path) = npm_ref.sub_path() {
|
||||
if !sub_path.contains('/') {
|
||||
return Some(sub_path.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
match self.resolve_name_from_npm(&npm_ref).await {
|
||||
Ok(Some(value)) => return Some(value),
|
||||
Ok(None) => {}
|
||||
Err(err) => {
|
||||
log::warn!(
|
||||
"{} Failed resolving npm specifier information. {:#}",
|
||||
deno_runtime::colors::yellow("Warning"),
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if !npm_ref.req().name.contains('/') {
|
||||
return Some(npm_ref.into_inner().req.name.into_string());
|
||||
}
|
||||
if let Some(scope_and_pkg) = npm_ref.req().name.strip_prefix('@') {
|
||||
if let Some((scope, package)) = scope_and_pkg.split_once('/') {
|
||||
if package == "cli" {
|
||||
return Some(scope.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
|
||||
let percent_decode =
|
||||
percent_encoding::percent_decode(url.path().as_bytes());
|
||||
#[cfg(unix)]
|
||||
let path = {
|
||||
use std::os::unix::prelude::OsStringExt;
|
||||
PathBuf::from(std::ffi::OsString::from_vec(
|
||||
percent_decode.collect::<Vec<u8>>(),
|
||||
))
|
||||
};
|
||||
#[cfg(windows)]
|
||||
let path = PathBuf::from(percent_decode.decode_utf8_lossy().as_ref());
|
||||
|
||||
let mut stem = path.file_stem()?.to_string_lossy();
|
||||
if matches!(stem.as_ref(), "main" | "mod" | "index" | "cli") {
|
||||
if let Some(parent_name) = path.parent().and_then(|p| p.file_name()) {
|
||||
stem = parent_name.to_string_lossy();
|
||||
}
|
||||
}
|
||||
|
||||
// if atmark symbol appears in the index other than 0 (e.g. `foo@bar`) we use
|
||||
// the former part as the inferred name because the latter part is most likely
|
||||
// a version number.
|
||||
match stem.find('@') {
|
||||
Some(at_index) if at_index > 0 => {
|
||||
stem = stem.split_at(at_index).0.to_string().into();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Some(stem.to_string())
|
||||
}
|
||||
|
||||
async fn resolve_name_from_npm(
|
||||
&self,
|
||||
npm_ref: &NpmPackageReqReference,
|
||||
) -> Result<Option<String>, AnyError> {
|
||||
let package_info = self
|
||||
.npm_registry_api
|
||||
.package_info(&npm_ref.req().name)
|
||||
.await?;
|
||||
Ok(self.resolve_name_from_npm_package_info(&package_info, npm_ref))
|
||||
}
|
||||
|
||||
fn resolve_name_from_npm_package_info(
|
||||
&self,
|
||||
package_info: &NpmPackageInfo,
|
||||
npm_ref: &NpmPackageReqReference,
|
||||
) -> Option<String> {
|
||||
let version = crate::npm::version_from_package_info(
|
||||
package_info,
|
||||
&npm_ref.req().version_req,
|
||||
)?;
|
||||
let version_info = package_info.versions.get(version)?;
|
||||
let bin_entries = version_info.bin.as_ref()?;
|
||||
match bin_entries {
|
||||
deno_npm::registry::NpmPackageVersionBinEntry::String(_) => {}
|
||||
deno_npm::registry::NpmPackageVersionBinEntry::Map(data) => {
|
||||
if data.len() == 1 {
|
||||
return Some(data.keys().next().unwrap().clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::collections::HashMap;
|
||||
|
||||
use deno_core::url::Url;
|
||||
use deno_npm::registry::TestNpmRegistryApi;
|
||||
|
||||
use super::BinNameResolver;
|
||||
use crate::http_util::HttpClientProvider;
|
||||
|
||||
async fn infer_name_from_url(url: &Url) -> Option<String> {
|
||||
let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
|
||||
let http_client = HttpClientProvider::new(None, None);
|
||||
let registry_api = TestNpmRegistryApi::default();
|
||||
registry_api.with_version_info(("@google/gemini-cli", "1.0.0"), |info| {
|
||||
info.bin = Some(deno_npm::registry::NpmPackageVersionBinEntry::Map(
|
||||
HashMap::from([("gemini".to_string(), "./bin.js".to_string())]),
|
||||
))
|
||||
});
|
||||
let resolver = BinNameResolver::new(&http_client, ®istry_api);
|
||||
resolver.infer_name_from_url(url).await
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn install_infer_name_from_url() {
|
||||
assert_eq!(
|
||||
infer_name_from_url(
|
||||
&Url::parse("https://example.com/abc/server.ts").unwrap()
|
||||
)
|
||||
.await,
|
||||
Some("server".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(
|
||||
&Url::parse("https://example.com/abc/main.ts").unwrap()
|
||||
)
|
||||
.await,
|
||||
Some("abc".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(
|
||||
&Url::parse("https://example.com/abc/mod.ts").unwrap()
|
||||
)
|
||||
.await,
|
||||
Some("abc".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(
|
||||
&Url::parse("https://example.com/ab%20c/mod.ts").unwrap()
|
||||
)
|
||||
.await,
|
||||
Some("ab c".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(
|
||||
&Url::parse("https://example.com/abc/index.ts").unwrap()
|
||||
)
|
||||
.await,
|
||||
Some("abc".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(
|
||||
&Url::parse("https://example.com/abc/cli.ts").unwrap()
|
||||
)
|
||||
.await,
|
||||
Some("abc".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("https://example.com/main.ts").unwrap())
|
||||
.await,
|
||||
Some("main".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("https://example.com").unwrap()).await,
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("file:///abc/server.ts").unwrap()).await,
|
||||
Some("server".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("file:///abc/main.ts").unwrap()).await,
|
||||
Some("abc".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("file:///ab%20c/main.ts").unwrap()).await,
|
||||
Some("ab c".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("file:///main.ts").unwrap()).await,
|
||||
Some("main".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("file:///").unwrap()).await,
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(
|
||||
&Url::parse("https://example.com/abc@0.1.0").unwrap()
|
||||
)
|
||||
.await,
|
||||
Some("abc".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(
|
||||
&Url::parse("https://example.com/abc@0.1.0/main.ts").unwrap()
|
||||
)
|
||||
.await,
|
||||
Some("abc".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(
|
||||
&Url::parse("https://example.com/abc@def@ghi").unwrap()
|
||||
)
|
||||
.await,
|
||||
Some("abc".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("https://example.com/@abc.ts").unwrap())
|
||||
.await,
|
||||
Some("@abc".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(
|
||||
&Url::parse("https://example.com/@abc/mod.ts").unwrap()
|
||||
)
|
||||
.await,
|
||||
Some("@abc".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("file:///@abc.ts").unwrap()).await,
|
||||
Some("@abc".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("file:///@abc/cli.ts").unwrap()).await,
|
||||
Some("@abc".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("npm:cowsay@1.2/cowthink").unwrap())
|
||||
.await,
|
||||
Some("cowthink".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("npm:cowsay@1.2/cowthink/test").unwrap())
|
||||
.await,
|
||||
Some("cowsay".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("npm:cowsay@1.2").unwrap()).await,
|
||||
Some("cowsay".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("npm:@types/node@1.2").unwrap()).await,
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("npm:@slidev/cli@1.2").unwrap()).await,
|
||||
Some("slidev".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
infer_name_from_url(&Url::parse("npm:@google/gemini-cli").unwrap()).await,
|
||||
Some("gemini".to_string())
|
||||
);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue