mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
Merge branch 'main' into open-flag-on-serve
This commit is contained in:
commit
7dcb5606b0
204 changed files with 4630 additions and 453 deletions
2
.github/workflows/ci.generate.ts
vendored
2
.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.
|
// Bump this number when you want to purge the cache.
|
||||||
// Note: the tools/release/01_bump_crate_versions.ts script will update this version
|
// 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.
|
// automatically via regex, so ensure that this line maintains this format.
|
||||||
const cacheVersion = 25;
|
const cacheVersion = 26;
|
||||||
|
|
||||||
const ubuntuX86Runner = "ubuntu-24.04";
|
const ubuntuX86Runner = "ubuntu-24.04";
|
||||||
const ubuntuX86XlRunner = "ubuntu-24.04-xl";
|
const ubuntuX86XlRunner = "ubuntu-24.04-xl";
|
||||||
|
|
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
|
@ -361,8 +361,8 @@ jobs:
|
||||||
path: |-
|
path: |-
|
||||||
~/.cargo/registry/index
|
~/.cargo/registry/index
|
||||||
~/.cargo/registry/cache
|
~/.cargo/registry/cache
|
||||||
key: '25-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-${{ hashFiles(''Cargo.lock'') }}'
|
key: '26-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-${{ hashFiles(''Cargo.lock'') }}'
|
||||||
restore-keys: '25-cargo-home-${{ matrix.os }}-${{ matrix.arch }}'
|
restore-keys: '26-cargo-home-${{ matrix.os }}-${{ matrix.arch }}'
|
||||||
if: '!(matrix.skip)'
|
if: '!(matrix.skip)'
|
||||||
- name: Restore cache build output (PR)
|
- name: Restore cache build output (PR)
|
||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
|
@ -375,7 +375,7 @@ jobs:
|
||||||
!./target/*/*.zip
|
!./target/*/*.zip
|
||||||
!./target/*/*.tar.gz
|
!./target/*/*.tar.gz
|
||||||
key: never_saved
|
key: never_saved
|
||||||
restore-keys: '25-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-'
|
restore-keys: '26-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-'
|
||||||
- name: Apply and update mtime cache
|
- name: Apply and update mtime cache
|
||||||
if: '!(matrix.skip) && (!startsWith(github.ref, ''refs/tags/''))'
|
if: '!(matrix.skip) && (!startsWith(github.ref, ''refs/tags/''))'
|
||||||
uses: ./.github/mtime_cache
|
uses: ./.github/mtime_cache
|
||||||
|
@ -685,7 +685,7 @@ jobs:
|
||||||
!./target/*/*.zip
|
!./target/*/*.zip
|
||||||
!./target/*/*.sha256sum
|
!./target/*/*.sha256sum
|
||||||
!./target/*/*.tar.gz
|
!./target/*/*.tar.gz
|
||||||
key: '25-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-${{ github.sha }}'
|
key: '26-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-${{ github.sha }}'
|
||||||
publish-canary:
|
publish-canary:
|
||||||
name: publish canary
|
name: publish canary
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
|
|
91
Cargo.lock
generated
91
Cargo.lock
generated
|
@ -1201,7 +1201,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno"
|
name = "deno"
|
||||||
version = "2.0.6"
|
version = "2.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
@ -1232,6 +1232,7 @@ dependencies = [
|
||||||
"deno_resolver",
|
"deno_resolver",
|
||||||
"deno_runtime",
|
"deno_runtime",
|
||||||
"deno_semver",
|
"deno_semver",
|
||||||
|
"deno_sqlformat",
|
||||||
"deno_task_shell",
|
"deno_task_shell",
|
||||||
"deno_terminal 0.2.0",
|
"deno_terminal 0.2.0",
|
||||||
"deno_tower_lsp",
|
"deno_tower_lsp",
|
||||||
|
@ -1291,7 +1292,6 @@ dependencies = [
|
||||||
"sha2",
|
"sha2",
|
||||||
"shell-escape",
|
"shell-escape",
|
||||||
"spki",
|
"spki",
|
||||||
"sqlformat",
|
|
||||||
"strsim",
|
"strsim",
|
||||||
"tar",
|
"tar",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
|
@ -1371,7 +1371,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_bench_util"
|
name = "deno_bench_util"
|
||||||
version = "0.171.0"
|
version = "0.172.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bencher",
|
"bencher",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
@ -1380,7 +1380,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_broadcast_channel"
|
name = "deno_broadcast_channel"
|
||||||
version = "0.171.0"
|
version = "0.172.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
@ -1391,7 +1391,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_cache"
|
name = "deno_cache"
|
||||||
version = "0.109.0"
|
version = "0.110.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
@ -1424,7 +1424,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_canvas"
|
name = "deno_canvas"
|
||||||
version = "0.46.0"
|
version = "0.47.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
"deno_webgpu",
|
"deno_webgpu",
|
||||||
|
@ -1435,9 +1435,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_config"
|
name = "deno_config"
|
||||||
version = "0.39.1"
|
version = "0.39.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0a91aa99751ebe305a7edad12a3ad751f3b3b9f5ecddbfe4a0459e3cdc8493b6"
|
checksum = "38fb809500238be2b10eee42944a47b3ac38974e1edbb47f73afcfca7df143bf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"deno_package_json",
|
"deno_package_json",
|
||||||
|
@ -1459,7 +1459,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_console"
|
name = "deno_console"
|
||||||
version = "0.177.0"
|
version = "0.178.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
]
|
]
|
||||||
|
@ -1506,7 +1506,7 @@ checksum = "fe4dccb6147bb3f3ba0c7a48e993bfeb999d2c2e47a81badee80e2b370c8d695"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_cron"
|
name = "deno_cron"
|
||||||
version = "0.57.0"
|
version = "0.58.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
@ -1519,7 +1519,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_crypto"
|
name = "deno_crypto"
|
||||||
version = "0.191.0"
|
version = "0.192.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"aes-gcm",
|
"aes-gcm",
|
||||||
|
@ -1587,7 +1587,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_fetch"
|
name = "deno_fetch"
|
||||||
version = "0.201.0"
|
version = "0.202.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.21.7",
|
"base64 0.21.7",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
@ -1621,7 +1621,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_ffi"
|
name = "deno_ffi"
|
||||||
version = "0.164.0"
|
version = "0.165.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
"deno_permissions",
|
"deno_permissions",
|
||||||
|
@ -1641,7 +1641,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_fs"
|
name = "deno_fs"
|
||||||
version = "0.87.0"
|
version = "0.88.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"base32",
|
"base32",
|
||||||
|
@ -1694,7 +1694,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_http"
|
name = "deno_http"
|
||||||
version = "0.175.0"
|
version = "0.176.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-compression",
|
"async-compression",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
@ -1733,7 +1733,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_io"
|
name = "deno_io"
|
||||||
version = "0.87.0"
|
version = "0.88.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
@ -1754,7 +1754,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_kv"
|
name = "deno_kv"
|
||||||
version = "0.85.0"
|
version = "0.86.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
@ -1827,7 +1827,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_napi"
|
name = "deno_napi"
|
||||||
version = "0.108.0"
|
version = "0.109.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
"deno_permissions",
|
"deno_permissions",
|
||||||
|
@ -1855,7 +1855,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_net"
|
name = "deno_net"
|
||||||
version = "0.169.0"
|
version = "0.170.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
"deno_permissions",
|
"deno_permissions",
|
||||||
|
@ -1872,7 +1872,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_node"
|
name = "deno_node"
|
||||||
version = "0.114.0"
|
version = "0.115.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aead-gcm-stream",
|
"aead-gcm-stream",
|
||||||
"aes",
|
"aes",
|
||||||
|
@ -2024,7 +2024,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_permissions"
|
name = "deno_permissions"
|
||||||
version = "0.37.0"
|
version = "0.38.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
"deno_path_util",
|
"deno_path_util",
|
||||||
|
@ -2042,7 +2042,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_resolver"
|
name = "deno_resolver"
|
||||||
version = "0.9.0"
|
version = "0.10.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base32",
|
"base32",
|
||||||
|
@ -2061,7 +2061,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_runtime"
|
name = "deno_runtime"
|
||||||
version = "0.186.0"
|
version = "0.187.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"color-print",
|
"color-print",
|
||||||
|
@ -2147,6 +2147,18 @@ dependencies = [
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deno_sqlformat"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0e196799ec0cc240fac1fb5c5bf813ef92a9602740a059cfcbb20593b2deee52"
|
||||||
|
dependencies = [
|
||||||
|
"nom 7.1.3",
|
||||||
|
"once_cell",
|
||||||
|
"regex",
|
||||||
|
"unicode_categories",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_task_shell"
|
name = "deno_task_shell"
|
||||||
version = "0.18.1"
|
version = "0.18.1"
|
||||||
|
@ -2186,7 +2198,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_tls"
|
name = "deno_tls"
|
||||||
version = "0.164.0"
|
version = "0.165.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
"deno_native_certs",
|
"deno_native_certs",
|
||||||
|
@ -2235,7 +2247,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_url"
|
name = "deno_url"
|
||||||
version = "0.177.0"
|
version = "0.178.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_bench_util",
|
"deno_bench_util",
|
||||||
"deno_console",
|
"deno_console",
|
||||||
|
@ -2247,7 +2259,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_web"
|
name = "deno_web"
|
||||||
version = "0.208.0"
|
version = "0.209.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"base64-simd 0.8.0",
|
"base64-simd 0.8.0",
|
||||||
|
@ -2269,7 +2281,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_webgpu"
|
name = "deno_webgpu"
|
||||||
version = "0.144.0"
|
version = "0.145.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
|
@ -2282,7 +2294,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_webidl"
|
name = "deno_webidl"
|
||||||
version = "0.177.0"
|
version = "0.178.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_bench_util",
|
"deno_bench_util",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
@ -2290,7 +2302,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_websocket"
|
name = "deno_websocket"
|
||||||
version = "0.182.0"
|
version = "0.183.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
@ -2312,7 +2324,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_webstorage"
|
name = "deno_webstorage"
|
||||||
version = "0.172.0"
|
version = "0.173.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
"deno_web",
|
"deno_web",
|
||||||
|
@ -4562,9 +4574,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "markup_fmt"
|
name = "markup_fmt"
|
||||||
version = "0.15.0"
|
version = "0.16.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ebae65c91eab3d42231232bf48107f351e5a8d511454927218c53aeb68bbdb6f"
|
checksum = "f303c36143671ac6c54112eb5aa95649b169dae783fdb6ead2c0e88b408c425c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"css_dataset",
|
"css_dataset",
|
||||||
|
@ -4740,7 +4752,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "napi_sym"
|
name = "napi_sym"
|
||||||
version = "0.107.0"
|
version = "0.108.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -4795,7 +4807,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "node_resolver"
|
name = "node_resolver"
|
||||||
version = "0.16.0"
|
version = "0.17.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
@ -6797,17 +6809,6 @@ dependencies = [
|
||||||
"der",
|
"der",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "sqlformat"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "git+https://github.com/shssoichiro/sqlformat-rs.git?rev=827d639#827d639bef94d8e5a5a0e29b41185c8d572f24e6"
|
|
||||||
dependencies = [
|
|
||||||
"nom 7.1.3",
|
|
||||||
"once_cell",
|
|
||||||
"regex",
|
|
||||||
"unicode_categories",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stable_deref_trait"
|
name = "stable_deref_trait"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
|
58
Cargo.toml
58
Cargo.toml
|
@ -48,17 +48,17 @@ repository = "https://github.com/denoland/deno"
|
||||||
deno_ast = { version = "=0.43.3", features = ["transpiling"] }
|
deno_ast = { version = "=0.43.3", features = ["transpiling"] }
|
||||||
deno_core = { version = "0.321.0" }
|
deno_core = { version = "0.321.0" }
|
||||||
|
|
||||||
deno_bench_util = { version = "0.171.0", path = "./bench_util" }
|
deno_bench_util = { version = "0.172.0", path = "./bench_util" }
|
||||||
deno_config = { version = "=0.39.1", features = ["workspace", "sync"] }
|
deno_config = { version = "=0.39.2", features = ["workspace", "sync"] }
|
||||||
deno_lockfile = "=0.23.1"
|
deno_lockfile = "=0.23.1"
|
||||||
deno_media_type = { version = "0.2.0", features = ["module_specifier"] }
|
deno_media_type = { version = "0.2.0", features = ["module_specifier"] }
|
||||||
deno_npm = "=0.25.4"
|
deno_npm = "=0.25.4"
|
||||||
deno_path_util = "=0.2.1"
|
deno_path_util = "=0.2.1"
|
||||||
deno_permissions = { version = "0.37.0", path = "./runtime/permissions" }
|
deno_permissions = { version = "0.38.0", path = "./runtime/permissions" }
|
||||||
deno_runtime = { version = "0.186.0", path = "./runtime" }
|
deno_runtime = { version = "0.187.0", path = "./runtime" }
|
||||||
deno_semver = "=0.5.16"
|
deno_semver = "=0.5.16"
|
||||||
deno_terminal = "0.2.0"
|
deno_terminal = "0.2.0"
|
||||||
napi_sym = { version = "0.107.0", path = "./ext/napi/sym" }
|
napi_sym = { version = "0.108.0", path = "./ext/napi/sym" }
|
||||||
test_util = { package = "test_server", path = "./tests/util/server" }
|
test_util = { package = "test_server", path = "./tests/util/server" }
|
||||||
|
|
||||||
denokv_proto = "0.8.4"
|
denokv_proto = "0.8.4"
|
||||||
|
@ -67,32 +67,32 @@ denokv_remote = "0.8.4"
|
||||||
denokv_sqlite = { default-features = false, version = "0.8.4" }
|
denokv_sqlite = { default-features = false, version = "0.8.4" }
|
||||||
|
|
||||||
# exts
|
# exts
|
||||||
deno_broadcast_channel = { version = "0.171.0", path = "./ext/broadcast_channel" }
|
deno_broadcast_channel = { version = "0.172.0", path = "./ext/broadcast_channel" }
|
||||||
deno_cache = { version = "0.109.0", path = "./ext/cache" }
|
deno_cache = { version = "0.110.0", path = "./ext/cache" }
|
||||||
deno_canvas = { version = "0.46.0", path = "./ext/canvas" }
|
deno_canvas = { version = "0.47.0", path = "./ext/canvas" }
|
||||||
deno_console = { version = "0.177.0", path = "./ext/console" }
|
deno_console = { version = "0.178.0", path = "./ext/console" }
|
||||||
deno_cron = { version = "0.57.0", path = "./ext/cron" }
|
deno_cron = { version = "0.58.0", path = "./ext/cron" }
|
||||||
deno_crypto = { version = "0.191.0", path = "./ext/crypto" }
|
deno_crypto = { version = "0.192.0", path = "./ext/crypto" }
|
||||||
deno_fetch = { version = "0.201.0", path = "./ext/fetch" }
|
deno_fetch = { version = "0.202.0", path = "./ext/fetch" }
|
||||||
deno_ffi = { version = "0.164.0", path = "./ext/ffi" }
|
deno_ffi = { version = "0.165.0", path = "./ext/ffi" }
|
||||||
deno_fs = { version = "0.87.0", path = "./ext/fs" }
|
deno_fs = { version = "0.88.0", path = "./ext/fs" }
|
||||||
deno_http = { version = "0.175.0", path = "./ext/http" }
|
deno_http = { version = "0.176.0", path = "./ext/http" }
|
||||||
deno_io = { version = "0.87.0", path = "./ext/io" }
|
deno_io = { version = "0.88.0", path = "./ext/io" }
|
||||||
deno_kv = { version = "0.85.0", path = "./ext/kv" }
|
deno_kv = { version = "0.86.0", path = "./ext/kv" }
|
||||||
deno_napi = { version = "0.108.0", path = "./ext/napi" }
|
deno_napi = { version = "0.109.0", path = "./ext/napi" }
|
||||||
deno_net = { version = "0.169.0", path = "./ext/net" }
|
deno_net = { version = "0.170.0", path = "./ext/net" }
|
||||||
deno_node = { version = "0.114.0", path = "./ext/node" }
|
deno_node = { version = "0.115.0", path = "./ext/node" }
|
||||||
deno_tls = { version = "0.164.0", path = "./ext/tls" }
|
deno_tls = { version = "0.165.0", path = "./ext/tls" }
|
||||||
deno_url = { version = "0.177.0", path = "./ext/url" }
|
deno_url = { version = "0.178.0", path = "./ext/url" }
|
||||||
deno_web = { version = "0.208.0", path = "./ext/web" }
|
deno_web = { version = "0.209.0", path = "./ext/web" }
|
||||||
deno_webgpu = { version = "0.144.0", path = "./ext/webgpu" }
|
deno_webgpu = { version = "0.145.0", path = "./ext/webgpu" }
|
||||||
deno_webidl = { version = "0.177.0", path = "./ext/webidl" }
|
deno_webidl = { version = "0.178.0", path = "./ext/webidl" }
|
||||||
deno_websocket = { version = "0.182.0", path = "./ext/websocket" }
|
deno_websocket = { version = "0.183.0", path = "./ext/websocket" }
|
||||||
deno_webstorage = { version = "0.172.0", path = "./ext/webstorage" }
|
deno_webstorage = { version = "0.173.0", path = "./ext/webstorage" }
|
||||||
|
|
||||||
# resolvers
|
# resolvers
|
||||||
deno_resolver = { version = "0.9.0", path = "./resolvers/deno" }
|
deno_resolver = { version = "0.10.0", path = "./resolvers/deno" }
|
||||||
node_resolver = { version = "0.16.0", path = "./resolvers/node" }
|
node_resolver = { version = "0.17.0", path = "./resolvers/node" }
|
||||||
|
|
||||||
aes = "=0.8.3"
|
aes = "=0.8.3"
|
||||||
anyhow = "1.0.57"
|
anyhow = "1.0.57"
|
||||||
|
|
70
Releases.md
70
Releases.md
|
@ -6,6 +6,76 @@ https://github.com/denoland/deno/releases
|
||||||
We also have one-line install commands at:
|
We also have one-line install commands at:
|
||||||
https://github.com/denoland/deno_install
|
https://github.com/denoland/deno_install
|
||||||
|
|
||||||
|
### 2.1.0 / 2024.11.21
|
||||||
|
|
||||||
|
- feat(cli): add `--unstable-node-globals` flag (#26617)
|
||||||
|
- feat(cli): support multiple env file argument (#26527)
|
||||||
|
- feat(compile): ability to embed directory in executable (#26939)
|
||||||
|
- feat(compile): ability to embed local data files (#26934)
|
||||||
|
- feat(ext/fetch): Make fetch client parameters configurable (#26909)
|
||||||
|
- feat(ext/fetch): allow embedders to use `hickory_dns_resolver` instead of
|
||||||
|
default `GaiResolver` (#26740)
|
||||||
|
- feat(ext/fs): add ctime to Deno.stats and use it in node compat layer (#24801)
|
||||||
|
- feat(ext/http): Make http server parameters configurable (#26785)
|
||||||
|
- feat(ext/node): perf_hooks.monitorEventLoopDelay() (#26905)
|
||||||
|
- feat(fetch): accept async iterables for body (#26882)
|
||||||
|
- feat(fmt): support SQL (#26750)
|
||||||
|
- feat(info): show location for Web Cache (#26205)
|
||||||
|
- feat(init): add --npm flag to initialize npm projects (#26896)
|
||||||
|
- feat(jupyter): Add `Deno.jupyter.image` API (#26284)
|
||||||
|
- feat(lint): Add checked files list to the JSON output(#26936)
|
||||||
|
- feat(lsp): auto-imports with @deno-types directives (#26821)
|
||||||
|
- feat(node): stabilize detecting if CJS via `"type": "commonjs"` in a
|
||||||
|
package.json (#26439)
|
||||||
|
- feat(permission): support suffix wildcards in `--allow-env` flag (#25255)
|
||||||
|
- feat(publish): add `--set-version <version>` flag (#26141)
|
||||||
|
- feat(runtime): remove public OTEL trace API (#26854)
|
||||||
|
- feat(task): add --eval flag (#26943)
|
||||||
|
- feat(task): dependencies (#26467)
|
||||||
|
- feat(task): support object notation, remove support for JSDocs (#26886)
|
||||||
|
- feat(task): workspace support with --filter and --recursive (#26949)
|
||||||
|
- feat(watch): log which file changed on HMR or watch change (#25801)
|
||||||
|
- feat: OpenTelemetry Tracing API and Exporting (#26710)
|
||||||
|
- feat: Wasm module support (#26668)
|
||||||
|
- feat: fmt and lint respect .gitignore file (#26897)
|
||||||
|
- feat: permission stack traces in ops (#26938)
|
||||||
|
- feat: subcommand to view and update outdated dependencies (#26942)
|
||||||
|
- feat: upgrade V8 to 13.0 (#26851)
|
||||||
|
- fix(cli): preserve comments in doc tests (#26828)
|
||||||
|
- fix(cli): show prefix hint when installing a package globally (#26629)
|
||||||
|
- fix(ext/cache): gracefully error when cache creation failed (#26895)
|
||||||
|
- fix(ext/http): prefer brotli for `accept-encoding: gzip, deflate, br, zstd`
|
||||||
|
(#26814)
|
||||||
|
- fix(ext/node): New async setInterval function to improve the nodejs
|
||||||
|
compatibility (#26703)
|
||||||
|
- fix(ext/node): add autoSelectFamily option to net.createConnection (#26661)
|
||||||
|
- fix(ext/node): handle `--allow-sys=inspector` (#26836)
|
||||||
|
- fix(ext/node): increase tolerance for interval test (#26899)
|
||||||
|
- fix(ext/node): process.getBuiltinModule (#26833)
|
||||||
|
- fix(ext/node): use ERR_NOT_IMPLEMENTED for notImplemented (#26853)
|
||||||
|
- fix(ext/node): zlib.crc32() (#26856)
|
||||||
|
- fix(ext/webgpu): Create GPUQuerySet converter before usage (#26883)
|
||||||
|
- fix(ext/websocket): initialize `error` attribute of WebSocket ErrorEvent
|
||||||
|
(#26796)
|
||||||
|
- fix(ext/webstorage): use error class for sqlite error case (#26806)
|
||||||
|
- fix(fmt): error instead of panic on unstable format (#26859)
|
||||||
|
- fix(fmt): formatting of .svelte files (#26948)
|
||||||
|
- fix(install): percent encodings in interactive progress bar (#26600)
|
||||||
|
- fix(install): re-setup bin entries after running lifecycle scripts (#26752)
|
||||||
|
- fix(lockfile): track dependencies specified in TypeScript compiler options
|
||||||
|
(#26551)
|
||||||
|
- fix(lsp): ignore editor indent settings if deno.json is present (#26912)
|
||||||
|
- fix(lsp): skip code action edits that can't be converted (#26831)
|
||||||
|
- fix(node): handle resolving ".//<something>" in npm packages (#26920)
|
||||||
|
- fix(node/crypto): support promisify on generateKeyPair (#26913)
|
||||||
|
- fix(permissions): say to use --allow-run instead of --allow-all (#26842)
|
||||||
|
- fix(publish): improve error message when missing exports (#26945)
|
||||||
|
- fix: otel resiliency (#26857)
|
||||||
|
- fix: update message for unsupported schemes with npm and jsr (#26884)
|
||||||
|
- perf(compile): code cache (#26528)
|
||||||
|
- perf(windows): delay load webgpu and some other dlls (#26917)
|
||||||
|
- perf: use available system memory for v8 isolate memory limit (#26868)
|
||||||
|
|
||||||
### 2.0.6 / 2024.11.10
|
### 2.0.6 / 2024.11.10
|
||||||
|
|
||||||
- feat(ext/http): abort event when request is cancelled (#26781)
|
- feat(ext/http): abort event when request is cancelled (#26781)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_bench_util"
|
name = "deno_bench_util"
|
||||||
version = "0.171.0"
|
version = "0.172.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno"
|
name = "deno"
|
||||||
version = "2.0.6"
|
version = "2.1.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
default-run = "deno"
|
default-run = "deno"
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
|
@ -129,7 +129,7 @@ libz-sys.workspace = true
|
||||||
log = { workspace = true, features = ["serde"] }
|
log = { workspace = true, features = ["serde"] }
|
||||||
lsp-types.workspace = true
|
lsp-types.workspace = true
|
||||||
malva = "=0.11.0"
|
malva = "=0.11.0"
|
||||||
markup_fmt = "=0.15.0"
|
markup_fmt = "=0.16.0"
|
||||||
memmem.workspace = true
|
memmem.workspace = true
|
||||||
monch.workspace = true
|
monch.workspace = true
|
||||||
notify.workspace = true
|
notify.workspace = true
|
||||||
|
@ -151,8 +151,8 @@ serde_repr.workspace = true
|
||||||
sha2.workspace = true
|
sha2.workspace = true
|
||||||
shell-escape = "=0.1.5"
|
shell-escape = "=0.1.5"
|
||||||
spki = { version = "0.7", features = ["pem"] }
|
spki = { version = "0.7", features = ["pem"] }
|
||||||
# NOTE(bartlomieju): for now using github URL, because 0.3.2 with important fixes hasn't been released yet.
|
# NOTE(bartlomieju): using temporary fork for now, revert back to `sqlformat-rs` later
|
||||||
sqlformat = { git = "https://github.com/shssoichiro/sqlformat-rs.git", rev = "827d639" }
|
sqlformat = { package = "deno_sqlformat", version = "0.3.2" }
|
||||||
strsim = "0.11.1"
|
strsim = "0.11.1"
|
||||||
tar.workspace = true
|
tar.workspace = true
|
||||||
tempfile.workspace = true
|
tempfile.workspace = true
|
||||||
|
|
|
@ -222,6 +222,8 @@ impl FmtFlags {
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct InitFlags {
|
pub struct InitFlags {
|
||||||
|
pub package: Option<String>,
|
||||||
|
pub package_args: Vec<String>,
|
||||||
pub dir: Option<String>,
|
pub dir: Option<String>,
|
||||||
pub lib: bool,
|
pub lib: bool,
|
||||||
pub serve: bool,
|
pub serve: bool,
|
||||||
|
@ -382,6 +384,8 @@ pub struct TaskFlags {
|
||||||
pub cwd: Option<String>,
|
pub cwd: Option<String>,
|
||||||
pub task: Option<String>,
|
pub task: Option<String>,
|
||||||
pub is_run: bool,
|
pub is_run: bool,
|
||||||
|
pub recursive: bool,
|
||||||
|
pub filter: Option<String>,
|
||||||
pub eval: bool,
|
pub eval: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,6 +471,7 @@ pub enum DenoSubcommand {
|
||||||
Serve(ServeFlags),
|
Serve(ServeFlags),
|
||||||
Task(TaskFlags),
|
Task(TaskFlags),
|
||||||
Test(TestFlags),
|
Test(TestFlags),
|
||||||
|
Outdated(OutdatedFlags),
|
||||||
Types,
|
Types,
|
||||||
Upgrade(UpgradeFlags),
|
Upgrade(UpgradeFlags),
|
||||||
Vendor,
|
Vendor,
|
||||||
|
@ -474,6 +479,19 @@ pub enum DenoSubcommand {
|
||||||
Help(HelpFlags),
|
Help(HelpFlags),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub enum OutdatedKind {
|
||||||
|
Update { latest: bool },
|
||||||
|
PrintOutdated { compatible: bool },
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct OutdatedFlags {
|
||||||
|
pub filters: Vec<String>,
|
||||||
|
pub recursive: bool,
|
||||||
|
pub kind: OutdatedKind,
|
||||||
|
}
|
||||||
|
|
||||||
impl DenoSubcommand {
|
impl DenoSubcommand {
|
||||||
pub fn is_run(&self) -> bool {
|
pub fn is_run(&self) -> bool {
|
||||||
matches!(self, Self::Run(_))
|
matches!(self, Self::Run(_))
|
||||||
|
@ -1162,25 +1180,26 @@ static ENV_VARIABLES_HELP: &str = cstr!(
|
||||||
<y>Docs:</> <c>https://docs.deno.com/go/env-vars</>
|
<y>Docs:</> <c>https://docs.deno.com/go/env-vars</>
|
||||||
|
|
||||||
<g>DENO_AUTH_TOKENS</> A semi-colon separated list of bearer tokens and hostnames
|
<g>DENO_AUTH_TOKENS</> A semi-colon separated list of bearer tokens and hostnames
|
||||||
to use when fetching remote modules from private repositories
|
to use when fetching remote modules from private repositories
|
||||||
<p(245)>(e.g. "abcde12345@deno.land;54321edcba@github.com")</>
|
<p(245)>(e.g. "abcde12345@deno.land;54321edcba@github.com")</>
|
||||||
<g>DENO_CERT</> Load certificate authorities from PEM encoded file
|
<g>DENO_CERT</> Load certificate authorities from PEM encoded file
|
||||||
<g>DENO_DIR</> Set the cache directory
|
<g>DENO_DIR</> Set the cache directory
|
||||||
<g>DENO_INSTALL_ROOT</> Set deno install's output directory
|
<g>DENO_INSTALL_ROOT</> Set deno install's output directory
|
||||||
<p(245)>(defaults to $HOME/.deno/bin)</>
|
<p(245)>(defaults to $HOME/.deno/bin)</>
|
||||||
<g>DENO_NO_PACKAGE_JSON</> Disables auto-resolution of package.json
|
<g>DENO_NO_PACKAGE_JSON</> Disables auto-resolution of package.json
|
||||||
<g>DENO_NO_UPDATE_CHECK</> Set to disable checking if a newer Deno version is available
|
<g>DENO_NO_UPDATE_CHECK</> Set to disable checking if a newer Deno version is available
|
||||||
<g>DENO_TLS_CA_STORE</> Comma-separated list of order dependent certificate stores.
|
<g>DENO_TLS_CA_STORE</> Comma-separated list of order dependent certificate stores.
|
||||||
Possible values: "system", "mozilla".
|
<g>DENO_TRACE_PERMISSIONS</> Environmental variable to enable stack traces in permission prompts.
|
||||||
<p(245)>(defaults to "mozilla")</>
|
Possible values: "system", "mozilla".
|
||||||
<g>HTTP_PROXY</> Proxy address for HTTP requests
|
<p(245)>(defaults to "mozilla")</>
|
||||||
<p(245)>(module downloads, fetch)</>
|
<g>HTTP_PROXY</> Proxy address for HTTP requests
|
||||||
<g>HTTPS_PROXY</> Proxy address for HTTPS requests
|
<p(245)>(module downloads, fetch)</>
|
||||||
<p(245)>(module downloads, fetch)</>
|
<g>HTTPS_PROXY</> Proxy address for HTTPS requests
|
||||||
<g>NO_COLOR</> Set to disable color
|
<p(245)>(module downloads, fetch)</>
|
||||||
<g>NO_PROXY</> Comma-separated list of hosts which do not use a proxy
|
<g>NO_COLOR</> Set to disable color
|
||||||
<p(245)>(module downloads, fetch)</>
|
<g>NO_PROXY</> Comma-separated list of hosts which do not use a proxy
|
||||||
<g>NPM_CONFIG_REGISTRY</> URL to use for the npm registry."#
|
<p(245)>(module downloads, fetch)</>
|
||||||
|
<g>NPM_CONFIG_REGISTRY</> URL to use for the npm registry."#
|
||||||
);
|
);
|
||||||
|
|
||||||
static DENO_HELP: &str = cstr!(
|
static DENO_HELP: &str = cstr!(
|
||||||
|
@ -1204,6 +1223,7 @@ static DENO_HELP: &str = cstr!(
|
||||||
<p(245)>deno add jsr:@std/assert | deno add npm:express</>
|
<p(245)>deno add jsr:@std/assert | deno add npm:express</>
|
||||||
<g>install</> Installs dependencies either in the local project or globally to a bin directory
|
<g>install</> Installs dependencies either in the local project or globally to a bin directory
|
||||||
<g>uninstall</> Uninstalls a dependency or an executable script in the installation root's bin directory
|
<g>uninstall</> Uninstalls a dependency or an executable script in the installation root's bin directory
|
||||||
|
<g>outdated</> Find and update outdated dependencies
|
||||||
<g>remove</> Remove dependencies from the configuration file
|
<g>remove</> Remove dependencies from the configuration file
|
||||||
|
|
||||||
<y>Tooling:</>
|
<y>Tooling:</>
|
||||||
|
@ -1379,13 +1399,14 @@ pub fn flags_from_vec(args: Vec<OsString>) -> clap::error::Result<Flags> {
|
||||||
"doc" => doc_parse(&mut flags, &mut m)?,
|
"doc" => doc_parse(&mut flags, &mut m)?,
|
||||||
"eval" => eval_parse(&mut flags, &mut m)?,
|
"eval" => eval_parse(&mut flags, &mut m)?,
|
||||||
"fmt" => fmt_parse(&mut flags, &mut m)?,
|
"fmt" => fmt_parse(&mut flags, &mut m)?,
|
||||||
"init" => init_parse(&mut flags, &mut m),
|
"init" => init_parse(&mut flags, &mut m)?,
|
||||||
"info" => info_parse(&mut flags, &mut m)?,
|
"info" => info_parse(&mut flags, &mut m)?,
|
||||||
"install" => install_parse(&mut flags, &mut m)?,
|
"install" => install_parse(&mut flags, &mut m)?,
|
||||||
"json_reference" => json_reference_parse(&mut flags, &mut m, app),
|
"json_reference" => json_reference_parse(&mut flags, &mut m, app),
|
||||||
"jupyter" => jupyter_parse(&mut flags, &mut m),
|
"jupyter" => jupyter_parse(&mut flags, &mut m),
|
||||||
"lint" => lint_parse(&mut flags, &mut m)?,
|
"lint" => lint_parse(&mut flags, &mut m)?,
|
||||||
"lsp" => lsp_parse(&mut flags, &mut m),
|
"lsp" => lsp_parse(&mut flags, &mut m),
|
||||||
|
"outdated" => outdated_parse(&mut flags, &mut m)?,
|
||||||
"repl" => repl_parse(&mut flags, &mut m)?,
|
"repl" => repl_parse(&mut flags, &mut m)?,
|
||||||
"run" => run_parse(&mut flags, &mut m, app, false)?,
|
"run" => run_parse(&mut flags, &mut m, app, false)?,
|
||||||
"serve" => serve_parse(&mut flags, &mut m, app)?,
|
"serve" => serve_parse(&mut flags, &mut m, app)?,
|
||||||
|
@ -1628,6 +1649,7 @@ pub fn clap_root() -> Command {
|
||||||
.subcommand(json_reference_subcommand())
|
.subcommand(json_reference_subcommand())
|
||||||
.subcommand(jupyter_subcommand())
|
.subcommand(jupyter_subcommand())
|
||||||
.subcommand(uninstall_subcommand())
|
.subcommand(uninstall_subcommand())
|
||||||
|
.subcommand(outdated_subcommand())
|
||||||
.subcommand(lsp_subcommand())
|
.subcommand(lsp_subcommand())
|
||||||
.subcommand(lint_subcommand())
|
.subcommand(lint_subcommand())
|
||||||
.subcommand(publish_subcommand())
|
.subcommand(publish_subcommand())
|
||||||
|
@ -2430,7 +2452,19 @@ fn init_subcommand() -> Command {
|
||||||
command("init", "scaffolds a basic Deno project with a script, test, and configuration file", UnstableArgsConfig::None).defer(
|
command("init", "scaffolds a basic Deno project with a script, test, and configuration file", UnstableArgsConfig::None).defer(
|
||||||
|cmd| {
|
|cmd| {
|
||||||
cmd
|
cmd
|
||||||
.arg(Arg::new("dir").value_hint(ValueHint::DirPath))
|
.arg(Arg::new("args")
|
||||||
|
.num_args(0..)
|
||||||
|
.action(ArgAction::Append)
|
||||||
|
.value_name("DIRECTORY OR PACKAGE")
|
||||||
|
.trailing_var_arg(true)
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("npm")
|
||||||
|
.long("npm")
|
||||||
|
.help("Generate a npm create-* project")
|
||||||
|
.conflicts_with_all(["lib", "serve"])
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("lib")
|
Arg::new("lib")
|
||||||
.long("lib")
|
.long("lib")
|
||||||
|
@ -2618,6 +2652,83 @@ fn jupyter_subcommand() -> Command {
|
||||||
.conflicts_with("install"))
|
.conflicts_with("install"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn outdated_subcommand() -> Command {
|
||||||
|
command(
|
||||||
|
"outdated",
|
||||||
|
cstr!("Find and update outdated dependencies.
|
||||||
|
By default, outdated dependencies are only displayed.
|
||||||
|
|
||||||
|
Display outdated dependencies:
|
||||||
|
<p(245)>deno outdated</>
|
||||||
|
<p(245)>deno outdated --compatible</>
|
||||||
|
|
||||||
|
Update dependencies:
|
||||||
|
<p(245)>deno outdated --update</>
|
||||||
|
<p(245)>deno outdated --update --latest</>
|
||||||
|
<p(245)>deno outdated --update</>
|
||||||
|
|
||||||
|
Filters can be used to select which packages to act on. Filters can include wildcards (*) to match multiple packages.
|
||||||
|
<p(245)>deno outdated --update --latest \"@std/*\"</>
|
||||||
|
<p(245)>deno outdated --update --latest \"react*\"</>
|
||||||
|
Note that filters act on their aliases configured in deno.json / package.json, not the actual package names:
|
||||||
|
Given \"foobar\": \"npm:react@17.0.0\" in deno.json or package.json, the filter \"foobar\" would update npm:react to
|
||||||
|
the latest version.
|
||||||
|
<p(245)>deno outdated --update --latest foobar</>
|
||||||
|
Filters can be combined, and negative filters can be used to exclude results:
|
||||||
|
<p(245)>deno outdated --update --latest \"@std/*\" \"!@std/fmt*\"</>
|
||||||
|
|
||||||
|
Specific version requirements to update to can be specified:
|
||||||
|
<p(245)>deno outdated --update @std/fmt@^1.0.2</>
|
||||||
|
"),
|
||||||
|
UnstableArgsConfig::None,
|
||||||
|
)
|
||||||
|
.defer(|cmd| {
|
||||||
|
cmd
|
||||||
|
.arg(
|
||||||
|
Arg::new("filters")
|
||||||
|
.num_args(0..)
|
||||||
|
.action(ArgAction::Append)
|
||||||
|
.help(concat!("Filters selecting which packages to act on. Can include wildcards (*) to match multiple packages. ",
|
||||||
|
"If a version requirement is specified, the matching packages will be updated to the given requirement."),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.arg(no_lock_arg())
|
||||||
|
.arg(lock_arg())
|
||||||
|
.arg(
|
||||||
|
Arg::new("latest")
|
||||||
|
.long("latest")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
.help(
|
||||||
|
"Update to the latest version, regardless of semver constraints",
|
||||||
|
)
|
||||||
|
.requires("update")
|
||||||
|
.conflicts_with("compatible"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("update")
|
||||||
|
.long("update")
|
||||||
|
.short('u')
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
.conflicts_with("compatible")
|
||||||
|
.help("Update dependency versions"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("compatible")
|
||||||
|
.long("compatible")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
.help("Only output versions that satisfy semver requirements")
|
||||||
|
.conflicts_with("update"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("recursive")
|
||||||
|
.long("recursive")
|
||||||
|
.short('r')
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
.help("include all workspace members"),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn uninstall_subcommand() -> Command {
|
fn uninstall_subcommand() -> Command {
|
||||||
command(
|
command(
|
||||||
"uninstall",
|
"uninstall",
|
||||||
|
@ -2953,13 +3064,27 @@ Evaluate a task from string
|
||||||
.help("Specify the directory to run the task in")
|
.help("Specify the directory to run the task in")
|
||||||
.value_hint(ValueHint::DirPath),
|
.value_hint(ValueHint::DirPath),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("recursive")
|
||||||
|
.long("recursive")
|
||||||
|
.short('r')
|
||||||
|
.help("Run the task in all projects in the workspace")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("filter")
|
||||||
|
.long("filter")
|
||||||
|
.short('f')
|
||||||
|
.help("Filter members of the workspace by name - should be used with --recursive")
|
||||||
|
.value_parser(value_parser!(String)),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("eval")
|
Arg::new("eval")
|
||||||
.long("eval")
|
.long("eval")
|
||||||
.help(
|
.help(
|
||||||
"Evaluate the passed value as if, it was a task in a configuration file",
|
"Evaluate the passed value as if, it was a task in a configuration file",
|
||||||
).action(ArgAction::SetTrue)
|
).action(ArgAction::SetTrue)
|
||||||
)
|
)
|
||||||
.arg(node_modules_dir_arg())
|
.arg(node_modules_dir_arg())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -3348,6 +3473,8 @@ fn permission_args(app: Command, requires: Option<&'static str>) -> Command {
|
||||||
<p(245)>--deny-run | --deny-run="whoami,ps"</>
|
<p(245)>--deny-run | --deny-run="whoami,ps"</>
|
||||||
<g>--deny-ffi[=<<PATH>...]</> (Unstable) Deny loading dynamic libraries. Optionally specify denied directories or files.
|
<g>--deny-ffi[=<<PATH>...]</> (Unstable) Deny loading dynamic libraries. Optionally specify denied directories or files.
|
||||||
<p(245)>--deny-ffi | --deny-ffi="./libfoo.so"</>
|
<p(245)>--deny-ffi | --deny-ffi="./libfoo.so"</>
|
||||||
|
<g>DENO_TRACE_PERMISSIONS</> Environmental variable to enable stack traces in permission prompts.
|
||||||
|
<p(245)>DENO_TRACE_PERMISSIONS=1 deno run main.ts</>
|
||||||
"#))
|
"#))
|
||||||
.arg(
|
.arg(
|
||||||
{
|
{
|
||||||
|
@ -4352,6 +4479,31 @@ fn remove_parse(flags: &mut Flags, matches: &mut ArgMatches) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn outdated_parse(
|
||||||
|
flags: &mut Flags,
|
||||||
|
matches: &mut ArgMatches,
|
||||||
|
) -> clap::error::Result<()> {
|
||||||
|
let filters = match matches.remove_many::<String>("filters") {
|
||||||
|
Some(f) => f.collect(),
|
||||||
|
None => vec![],
|
||||||
|
};
|
||||||
|
let recursive = matches.get_flag("recursive");
|
||||||
|
let update = matches.get_flag("update");
|
||||||
|
let kind = if update {
|
||||||
|
let latest = matches.get_flag("latest");
|
||||||
|
OutdatedKind::Update { latest }
|
||||||
|
} else {
|
||||||
|
let compatible = matches.get_flag("compatible");
|
||||||
|
OutdatedKind::PrintOutdated { compatible }
|
||||||
|
};
|
||||||
|
flags.subcommand = DenoSubcommand::Outdated(OutdatedFlags {
|
||||||
|
filters,
|
||||||
|
recursive,
|
||||||
|
kind,
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn bench_parse(
|
fn bench_parse(
|
||||||
flags: &mut Flags,
|
flags: &mut Flags,
|
||||||
matches: &mut ArgMatches,
|
matches: &mut ArgMatches,
|
||||||
|
@ -4684,12 +4836,44 @@ fn fmt_parse(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_parse(flags: &mut Flags, matches: &mut ArgMatches) {
|
fn init_parse(
|
||||||
|
flags: &mut Flags,
|
||||||
|
matches: &mut ArgMatches,
|
||||||
|
) -> Result<(), clap::Error> {
|
||||||
|
let mut lib = matches.get_flag("lib");
|
||||||
|
let mut serve = matches.get_flag("serve");
|
||||||
|
let mut dir = None;
|
||||||
|
let mut package = None;
|
||||||
|
let mut package_args = vec![];
|
||||||
|
|
||||||
|
if let Some(mut args) = matches.remove_many::<String>("args") {
|
||||||
|
let name = args.next().unwrap();
|
||||||
|
let mut args = args.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if matches.get_flag("npm") {
|
||||||
|
package = Some(name);
|
||||||
|
package_args = args;
|
||||||
|
} else {
|
||||||
|
dir = Some(name);
|
||||||
|
|
||||||
|
if !args.is_empty() {
|
||||||
|
args.insert(0, "init".to_string());
|
||||||
|
let inner_matches = init_subcommand().try_get_matches_from_mut(args)?;
|
||||||
|
lib = inner_matches.get_flag("lib");
|
||||||
|
serve = inner_matches.get_flag("serve");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
flags.subcommand = DenoSubcommand::Init(InitFlags {
|
flags.subcommand = DenoSubcommand::Init(InitFlags {
|
||||||
dir: matches.remove_one::<String>("dir"),
|
package,
|
||||||
lib: matches.get_flag("lib"),
|
package_args,
|
||||||
serve: matches.get_flag("serve"),
|
dir,
|
||||||
|
lib,
|
||||||
|
serve,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn info_parse(
|
fn info_parse(
|
||||||
|
@ -5094,10 +5278,15 @@ fn task_parse(
|
||||||
unstable_args_parse(flags, matches, UnstableArgsConfig::ResolutionAndRuntime);
|
unstable_args_parse(flags, matches, UnstableArgsConfig::ResolutionAndRuntime);
|
||||||
node_modules_arg_parse(flags, matches);
|
node_modules_arg_parse(flags, matches);
|
||||||
|
|
||||||
|
let filter = matches.remove_one::<String>("filter");
|
||||||
|
let recursive = matches.get_flag("recursive") || filter.is_some();
|
||||||
|
|
||||||
let mut task_flags = TaskFlags {
|
let mut task_flags = TaskFlags {
|
||||||
cwd: matches.remove_one::<String>("cwd"),
|
cwd: matches.remove_one::<String>("cwd"),
|
||||||
task: None,
|
task: None,
|
||||||
is_run: false,
|
is_run: false,
|
||||||
|
recursive,
|
||||||
|
filter,
|
||||||
eval: matches.get_flag("eval"),
|
eval: matches.get_flag("eval"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10300,6 +10489,8 @@ mod tests {
|
||||||
cwd: None,
|
cwd: None,
|
||||||
task: Some("build".to_string()),
|
task: Some("build".to_string()),
|
||||||
is_run: false,
|
is_run: false,
|
||||||
|
recursive: false,
|
||||||
|
filter: None,
|
||||||
eval: false,
|
eval: false,
|
||||||
}),
|
}),
|
||||||
argv: svec!["hello", "world"],
|
argv: svec!["hello", "world"],
|
||||||
|
@ -10315,6 +10506,8 @@ mod tests {
|
||||||
cwd: None,
|
cwd: None,
|
||||||
task: Some("build".to_string()),
|
task: Some("build".to_string()),
|
||||||
is_run: false,
|
is_run: false,
|
||||||
|
recursive: false,
|
||||||
|
filter: None,
|
||||||
eval: false,
|
eval: false,
|
||||||
}),
|
}),
|
||||||
..Flags::default()
|
..Flags::default()
|
||||||
|
@ -10329,6 +10522,56 @@ mod tests {
|
||||||
cwd: Some("foo".to_string()),
|
cwd: Some("foo".to_string()),
|
||||||
task: Some("build".to_string()),
|
task: Some("build".to_string()),
|
||||||
is_run: false,
|
is_run: false,
|
||||||
|
recursive: false,
|
||||||
|
filter: None,
|
||||||
|
eval: false,
|
||||||
|
}),
|
||||||
|
..Flags::default()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
let r = flags_from_vec(svec!["deno", "task", "--filter", "*", "build"]);
|
||||||
|
assert_eq!(
|
||||||
|
r.unwrap(),
|
||||||
|
Flags {
|
||||||
|
subcommand: DenoSubcommand::Task(TaskFlags {
|
||||||
|
cwd: None,
|
||||||
|
task: Some("build".to_string()),
|
||||||
|
is_run: false,
|
||||||
|
recursive: true,
|
||||||
|
filter: Some("*".to_string()),
|
||||||
|
eval: false,
|
||||||
|
}),
|
||||||
|
..Flags::default()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
let r = flags_from_vec(svec!["deno", "task", "--recursive", "build"]);
|
||||||
|
assert_eq!(
|
||||||
|
r.unwrap(),
|
||||||
|
Flags {
|
||||||
|
subcommand: DenoSubcommand::Task(TaskFlags {
|
||||||
|
cwd: None,
|
||||||
|
task: Some("build".to_string()),
|
||||||
|
is_run: false,
|
||||||
|
recursive: true,
|
||||||
|
filter: None,
|
||||||
|
eval: false,
|
||||||
|
}),
|
||||||
|
..Flags::default()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
let r = flags_from_vec(svec!["deno", "task", "-r", "build"]);
|
||||||
|
assert_eq!(
|
||||||
|
r.unwrap(),
|
||||||
|
Flags {
|
||||||
|
subcommand: DenoSubcommand::Task(TaskFlags {
|
||||||
|
cwd: None,
|
||||||
|
task: Some("build".to_string()),
|
||||||
|
is_run: false,
|
||||||
|
recursive: true,
|
||||||
|
filter: None,
|
||||||
eval: false,
|
eval: false,
|
||||||
}),
|
}),
|
||||||
..Flags::default()
|
..Flags::default()
|
||||||
|
@ -10343,6 +10586,8 @@ mod tests {
|
||||||
cwd: None,
|
cwd: None,
|
||||||
task: Some("echo 1".to_string()),
|
task: Some("echo 1".to_string()),
|
||||||
is_run: false,
|
is_run: false,
|
||||||
|
recursive: false,
|
||||||
|
filter: None,
|
||||||
eval: true,
|
eval: true,
|
||||||
}),
|
}),
|
||||||
..Flags::default()
|
..Flags::default()
|
||||||
|
@ -10372,6 +10617,8 @@ mod tests {
|
||||||
cwd: None,
|
cwd: None,
|
||||||
task: Some("build".to_string()),
|
task: Some("build".to_string()),
|
||||||
is_run: false,
|
is_run: false,
|
||||||
|
recursive: false,
|
||||||
|
filter: None,
|
||||||
eval: false,
|
eval: false,
|
||||||
}),
|
}),
|
||||||
argv: svec!["--", "hello", "world"],
|
argv: svec!["--", "hello", "world"],
|
||||||
|
@ -10390,6 +10637,8 @@ mod tests {
|
||||||
cwd: Some("foo".to_string()),
|
cwd: Some("foo".to_string()),
|
||||||
task: Some("build".to_string()),
|
task: Some("build".to_string()),
|
||||||
is_run: false,
|
is_run: false,
|
||||||
|
recursive: false,
|
||||||
|
filter: None,
|
||||||
eval: false,
|
eval: false,
|
||||||
}),
|
}),
|
||||||
argv: svec!["--", "hello", "world"],
|
argv: svec!["--", "hello", "world"],
|
||||||
|
@ -10409,6 +10658,8 @@ mod tests {
|
||||||
cwd: None,
|
cwd: None,
|
||||||
task: Some("build".to_string()),
|
task: Some("build".to_string()),
|
||||||
is_run: false,
|
is_run: false,
|
||||||
|
recursive: false,
|
||||||
|
filter: None,
|
||||||
eval: false,
|
eval: false,
|
||||||
}),
|
}),
|
||||||
argv: svec!["--"],
|
argv: svec!["--"],
|
||||||
|
@ -10427,6 +10678,8 @@ mod tests {
|
||||||
cwd: None,
|
cwd: None,
|
||||||
task: Some("build".to_string()),
|
task: Some("build".to_string()),
|
||||||
is_run: false,
|
is_run: false,
|
||||||
|
recursive: false,
|
||||||
|
filter: None,
|
||||||
eval: false,
|
eval: false,
|
||||||
}),
|
}),
|
||||||
argv: svec!["-1", "--test"],
|
argv: svec!["-1", "--test"],
|
||||||
|
@ -10445,6 +10698,8 @@ mod tests {
|
||||||
cwd: None,
|
cwd: None,
|
||||||
task: Some("build".to_string()),
|
task: Some("build".to_string()),
|
||||||
is_run: false,
|
is_run: false,
|
||||||
|
recursive: false,
|
||||||
|
filter: None,
|
||||||
eval: false,
|
eval: false,
|
||||||
}),
|
}),
|
||||||
argv: svec!["--test"],
|
argv: svec!["--test"],
|
||||||
|
@ -10464,6 +10719,8 @@ mod tests {
|
||||||
cwd: None,
|
cwd: None,
|
||||||
task: Some("build".to_string()),
|
task: Some("build".to_string()),
|
||||||
is_run: false,
|
is_run: false,
|
||||||
|
recursive: false,
|
||||||
|
filter: None,
|
||||||
eval: false,
|
eval: false,
|
||||||
}),
|
}),
|
||||||
log_level: Some(log::Level::Error),
|
log_level: Some(log::Level::Error),
|
||||||
|
@ -10482,6 +10739,8 @@ mod tests {
|
||||||
cwd: None,
|
cwd: None,
|
||||||
task: None,
|
task: None,
|
||||||
is_run: false,
|
is_run: false,
|
||||||
|
recursive: false,
|
||||||
|
filter: None,
|
||||||
eval: false,
|
eval: false,
|
||||||
}),
|
}),
|
||||||
..Flags::default()
|
..Flags::default()
|
||||||
|
@ -10499,6 +10758,8 @@ mod tests {
|
||||||
cwd: None,
|
cwd: None,
|
||||||
task: None,
|
task: None,
|
||||||
is_run: false,
|
is_run: false,
|
||||||
|
recursive: false,
|
||||||
|
filter: None,
|
||||||
eval: false,
|
eval: false,
|
||||||
}),
|
}),
|
||||||
config_flag: ConfigFlag::Path("deno.jsonc".to_string()),
|
config_flag: ConfigFlag::Path("deno.jsonc".to_string()),
|
||||||
|
@ -10517,6 +10778,8 @@ mod tests {
|
||||||
cwd: None,
|
cwd: None,
|
||||||
task: None,
|
task: None,
|
||||||
is_run: false,
|
is_run: false,
|
||||||
|
recursive: false,
|
||||||
|
filter: None,
|
||||||
eval: false,
|
eval: false,
|
||||||
}),
|
}),
|
||||||
config_flag: ConfigFlag::Path("deno.jsonc".to_string()),
|
config_flag: ConfigFlag::Path("deno.jsonc".to_string()),
|
||||||
|
@ -10694,6 +10957,8 @@ mod tests {
|
||||||
r.unwrap(),
|
r.unwrap(),
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Init(InitFlags {
|
subcommand: DenoSubcommand::Init(InitFlags {
|
||||||
|
package: None,
|
||||||
|
package_args: vec![],
|
||||||
dir: None,
|
dir: None,
|
||||||
lib: false,
|
lib: false,
|
||||||
serve: false,
|
serve: false,
|
||||||
|
@ -10707,6 +10972,8 @@ mod tests {
|
||||||
r.unwrap(),
|
r.unwrap(),
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Init(InitFlags {
|
subcommand: DenoSubcommand::Init(InitFlags {
|
||||||
|
package: None,
|
||||||
|
package_args: vec![],
|
||||||
dir: Some(String::from("foo")),
|
dir: Some(String::from("foo")),
|
||||||
lib: false,
|
lib: false,
|
||||||
serve: false,
|
serve: false,
|
||||||
|
@ -10720,6 +10987,8 @@ mod tests {
|
||||||
r.unwrap(),
|
r.unwrap(),
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Init(InitFlags {
|
subcommand: DenoSubcommand::Init(InitFlags {
|
||||||
|
package: None,
|
||||||
|
package_args: vec![],
|
||||||
dir: None,
|
dir: None,
|
||||||
lib: false,
|
lib: false,
|
||||||
serve: false,
|
serve: false,
|
||||||
|
@ -10734,6 +11003,8 @@ mod tests {
|
||||||
r.unwrap(),
|
r.unwrap(),
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Init(InitFlags {
|
subcommand: DenoSubcommand::Init(InitFlags {
|
||||||
|
package: None,
|
||||||
|
package_args: vec![],
|
||||||
dir: None,
|
dir: None,
|
||||||
lib: true,
|
lib: true,
|
||||||
serve: false,
|
serve: false,
|
||||||
|
@ -10747,6 +11018,8 @@ mod tests {
|
||||||
r.unwrap(),
|
r.unwrap(),
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Init(InitFlags {
|
subcommand: DenoSubcommand::Init(InitFlags {
|
||||||
|
package: None,
|
||||||
|
package_args: vec![],
|
||||||
dir: None,
|
dir: None,
|
||||||
lib: false,
|
lib: false,
|
||||||
serve: true,
|
serve: true,
|
||||||
|
@ -10760,6 +11033,8 @@ mod tests {
|
||||||
r.unwrap(),
|
r.unwrap(),
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Init(InitFlags {
|
subcommand: DenoSubcommand::Init(InitFlags {
|
||||||
|
package: None,
|
||||||
|
package_args: vec![],
|
||||||
dir: Some(String::from("foo")),
|
dir: Some(String::from("foo")),
|
||||||
lib: true,
|
lib: true,
|
||||||
serve: false,
|
serve: false,
|
||||||
|
@ -10767,6 +11042,57 @@ mod tests {
|
||||||
..Flags::default()
|
..Flags::default()
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let r = flags_from_vec(svec!["deno", "init", "--lib", "--npm", "vite"]);
|
||||||
|
assert!(r.is_err());
|
||||||
|
|
||||||
|
let r = flags_from_vec(svec!["deno", "init", "--serve", "--npm", "vite"]);
|
||||||
|
assert!(r.is_err());
|
||||||
|
|
||||||
|
let r = flags_from_vec(svec!["deno", "init", "--npm", "vite", "--lib"]);
|
||||||
|
assert_eq!(
|
||||||
|
r.unwrap(),
|
||||||
|
Flags {
|
||||||
|
subcommand: DenoSubcommand::Init(InitFlags {
|
||||||
|
package: Some("vite".to_string()),
|
||||||
|
package_args: svec!["--lib"],
|
||||||
|
dir: None,
|
||||||
|
lib: false,
|
||||||
|
serve: false,
|
||||||
|
}),
|
||||||
|
..Flags::default()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
let r = flags_from_vec(svec!["deno", "init", "--npm", "vite", "--serve"]);
|
||||||
|
assert_eq!(
|
||||||
|
r.unwrap(),
|
||||||
|
Flags {
|
||||||
|
subcommand: DenoSubcommand::Init(InitFlags {
|
||||||
|
package: Some("vite".to_string()),
|
||||||
|
package_args: svec!["--serve"],
|
||||||
|
dir: None,
|
||||||
|
lib: false,
|
||||||
|
serve: false,
|
||||||
|
}),
|
||||||
|
..Flags::default()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
let r = flags_from_vec(svec!["deno", "init", "--npm", "vite", "new_dir"]);
|
||||||
|
assert_eq!(
|
||||||
|
r.unwrap(),
|
||||||
|
Flags {
|
||||||
|
subcommand: DenoSubcommand::Init(InitFlags {
|
||||||
|
package: Some("vite".to_string()),
|
||||||
|
package_args: svec!["new_dir"],
|
||||||
|
dir: None,
|
||||||
|
lib: false,
|
||||||
|
serve: false,
|
||||||
|
}),
|
||||||
|
..Flags::default()
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -11300,4 +11626,77 @@ Usage: deno repl [OPTIONS] [-- [ARGS]...]\n"
|
||||||
assert!(r.is_err());
|
assert!(r.is_err());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn outdated_subcommand() {
|
||||||
|
let cases = [
|
||||||
|
(
|
||||||
|
svec![],
|
||||||
|
OutdatedFlags {
|
||||||
|
filters: vec![],
|
||||||
|
kind: OutdatedKind::PrintOutdated { compatible: false },
|
||||||
|
recursive: false,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
svec!["--recursive"],
|
||||||
|
OutdatedFlags {
|
||||||
|
filters: vec![],
|
||||||
|
kind: OutdatedKind::PrintOutdated { compatible: false },
|
||||||
|
recursive: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
svec!["--recursive", "--compatible"],
|
||||||
|
OutdatedFlags {
|
||||||
|
filters: vec![],
|
||||||
|
kind: OutdatedKind::PrintOutdated { compatible: true },
|
||||||
|
recursive: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
svec!["--update"],
|
||||||
|
OutdatedFlags {
|
||||||
|
filters: vec![],
|
||||||
|
kind: OutdatedKind::Update { latest: false },
|
||||||
|
recursive: false,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
svec!["--update", "--latest"],
|
||||||
|
OutdatedFlags {
|
||||||
|
filters: vec![],
|
||||||
|
kind: OutdatedKind::Update { latest: true },
|
||||||
|
recursive: false,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
svec!["--update", "--recursive"],
|
||||||
|
OutdatedFlags {
|
||||||
|
filters: vec![],
|
||||||
|
kind: OutdatedKind::Update { latest: false },
|
||||||
|
recursive: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
svec!["--update", "@foo/bar"],
|
||||||
|
OutdatedFlags {
|
||||||
|
filters: svec!["@foo/bar"],
|
||||||
|
kind: OutdatedKind::Update { latest: false },
|
||||||
|
recursive: false,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
];
|
||||||
|
for (input, expected) in cases {
|
||||||
|
let mut args = svec!["deno", "outdated"];
|
||||||
|
args.extend(input);
|
||||||
|
let r = flags_from_vec(args.clone()).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
r.subcommand,
|
||||||
|
DenoSubcommand::Outdated(expected),
|
||||||
|
"incorrect result for args: {:?}",
|
||||||
|
args
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1628,8 +1628,10 @@ impl CliOptions {
|
||||||
DenoSubcommand::Install(_)
|
DenoSubcommand::Install(_)
|
||||||
| DenoSubcommand::Add(_)
|
| DenoSubcommand::Add(_)
|
||||||
| DenoSubcommand::Remove(_)
|
| DenoSubcommand::Remove(_)
|
||||||
|
| DenoSubcommand::Init(_)
|
||||||
|
| DenoSubcommand::Outdated(_)
|
||||||
) {
|
) {
|
||||||
// For `deno install/add/remove` we want to force the managed resolver so it can set up `node_modules/` directory.
|
// For `deno install/add/remove/init` we want to force the managed resolver so it can set up `node_modules/` directory.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if self.node_modules_dir().ok().flatten().is_none()
|
if self.node_modules_dir().ok().flatten().is_none()
|
||||||
|
@ -1912,6 +1914,10 @@ pub fn resolve_no_prompt(flags: &PermissionFlags) -> bool {
|
||||||
flags.no_prompt || has_flag_env_var("DENO_NO_PROMPT")
|
flags.no_prompt || has_flag_env_var("DENO_NO_PROMPT")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_trace_permissions_enabled() -> bool {
|
||||||
|
has_flag_env_var("DENO_TRACE_PERMISSIONS")
|
||||||
|
}
|
||||||
|
|
||||||
pub fn has_flag_env_var(name: &str) -> bool {
|
pub fn has_flag_env_var(name: &str) -> bool {
|
||||||
let value = env::var(name);
|
let value = env::var(name);
|
||||||
matches!(value.as_ref().map(|s| s.as_str()), Ok("1"))
|
matches!(value.as_ref().map(|s| s.as_str()), Ok("1"))
|
||||||
|
|
11
cli/main.rs
11
cli/main.rs
|
@ -144,9 +144,7 @@ async fn run_subcommand(flags: Arc<Flags>) -> Result<i32, AnyError> {
|
||||||
}
|
}
|
||||||
DenoSubcommand::Init(init_flags) => {
|
DenoSubcommand::Init(init_flags) => {
|
||||||
spawn_subcommand(async {
|
spawn_subcommand(async {
|
||||||
// make compiler happy since init_project is sync
|
tools::init::init_project(init_flags).await
|
||||||
tokio::task::yield_now().await;
|
|
||||||
tools::init::init_project(init_flags)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
DenoSubcommand::Info(info_flags) => {
|
DenoSubcommand::Info(info_flags) => {
|
||||||
|
@ -188,6 +186,11 @@ async fn run_subcommand(flags: Arc<Flags>) -> Result<i32, AnyError> {
|
||||||
tools::lint::lint(flags, lint_flags).await
|
tools::lint::lint(flags, lint_flags).await
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
DenoSubcommand::Outdated(update_flags) => {
|
||||||
|
spawn_subcommand(async move {
|
||||||
|
tools::registry::outdated(flags, update_flags).await
|
||||||
|
})
|
||||||
|
}
|
||||||
DenoSubcommand::Repl(repl_flags) => {
|
DenoSubcommand::Repl(repl_flags) => {
|
||||||
spawn_subcommand(async move { tools::repl::run(flags, repl_flags).await })
|
spawn_subcommand(async move { tools::repl::run(flags, repl_flags).await })
|
||||||
}
|
}
|
||||||
|
@ -238,6 +241,8 @@ async fn run_subcommand(flags: Arc<Flags>) -> Result<i32, AnyError> {
|
||||||
cwd: None,
|
cwd: None,
|
||||||
task: Some(run_flags.script.clone()),
|
task: Some(run_flags.script.clone()),
|
||||||
is_run: true,
|
is_run: true,
|
||||||
|
recursive: false,
|
||||||
|
filter: None,
|
||||||
eval: false,
|
eval: false,
|
||||||
};
|
};
|
||||||
new_flags.subcommand = DenoSubcommand::Task(task_flags.clone());
|
new_flags.subcommand = DenoSubcommand::Task(task_flags.clone());
|
||||||
|
|
|
@ -500,7 +500,7 @@ impl ManagedCliNpmResolver {
|
||||||
self.resolve_pkg_folder_from_pkg_id(&pkg_id)
|
self.resolve_pkg_folder_from_pkg_id(&pkg_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_pkg_id_from_pkg_req(
|
pub fn resolve_pkg_id_from_pkg_req(
|
||||||
&self,
|
&self,
|
||||||
req: &PackageReq,
|
req: &PackageReq,
|
||||||
) -> Result<NpmPackageId, PackageReqNotFoundError> {
|
) -> Result<NpmPackageId, PackageReqNotFoundError> {
|
||||||
|
|
|
@ -51,7 +51,7 @@ fn op_bench_get_origin(state: &mut OpState) -> String {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct PermissionsHolder(Uuid, PermissionsContainer);
|
struct PermissionsHolder(Uuid, PermissionsContainer);
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_pledge_test_permissions(
|
pub fn op_pledge_test_permissions(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
|
|
@ -46,7 +46,7 @@ deno_core::extension!(deno_test,
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct PermissionsHolder(Uuid, PermissionsContainer);
|
struct PermissionsHolder(Uuid, PermissionsContainer);
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_pledge_test_permissions(
|
pub fn op_pledge_test_permissions(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
|
|
@ -1,15 +1,28 @@
|
||||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
use crate::args::DenoSubcommand;
|
||||||
|
use crate::args::Flags;
|
||||||
use crate::args::InitFlags;
|
use crate::args::InitFlags;
|
||||||
|
use crate::args::PackagesAllowedScripts;
|
||||||
|
use crate::args::PermissionFlags;
|
||||||
|
use crate::args::RunFlags;
|
||||||
use crate::colors;
|
use crate::colors;
|
||||||
|
use color_print::cformat;
|
||||||
|
use color_print::cstr;
|
||||||
use deno_core::anyhow::Context;
|
use deno_core::anyhow::Context;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::serde_json::json;
|
use deno_core::serde_json::json;
|
||||||
|
use deno_runtime::WorkerExecutionMode;
|
||||||
use log::info;
|
use log::info;
|
||||||
|
use std::io::IsTerminal;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
pub fn init_project(init_flags: InitFlags) -> Result<(), AnyError> {
|
pub async fn init_project(init_flags: InitFlags) -> Result<i32, AnyError> {
|
||||||
|
if let Some(package) = &init_flags.package {
|
||||||
|
return init_npm(package, init_flags.package_args).await;
|
||||||
|
}
|
||||||
|
|
||||||
let cwd =
|
let cwd =
|
||||||
std::env::current_dir().context("Can't read current working directory.")?;
|
std::env::current_dir().context("Can't read current working directory.")?;
|
||||||
let dir = if let Some(dir) = &init_flags.dir {
|
let dir = if let Some(dir) = &init_flags.dir {
|
||||||
|
@ -235,7 +248,58 @@ Deno.test(function addTest() {
|
||||||
info!(" {}", colors::gray("# Run the tests"));
|
info!(" {}", colors::gray("# Run the tests"));
|
||||||
info!(" deno test");
|
info!(" deno test");
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn init_npm(name: &str, args: Vec<String>) -> Result<i32, AnyError> {
|
||||||
|
let script_name = format!("npm:create-{}", 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(" ")));
|
||||||
|
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]</>"),
|
||||||
|
script_name
|
||||||
|
);
|
||||||
|
loop {
|
||||||
|
let _ = std::io::stdout().write(b"> ")?;
|
||||||
|
std::io::stdout().flush()?;
|
||||||
|
let mut answer = String::new();
|
||||||
|
if std::io::stdin().read_line(&mut answer).is_ok() {
|
||||||
|
let answer = answer.trim().to_ascii_lowercase();
|
||||||
|
if answer != "y" {
|
||||||
|
return Ok(print_manual_usage(&script_name, &args));
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Ok(print_manual_usage(&script_name, &args));
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_flags = Flags {
|
||||||
|
permissions: PermissionFlags {
|
||||||
|
allow_all: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
allow_scripts: PackagesAllowedScripts::All,
|
||||||
|
argv: args,
|
||||||
|
subcommand: DenoSubcommand::Run(RunFlags {
|
||||||
|
script: script_name,
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
crate::tools::run::run_script(
|
||||||
|
WorkerExecutionMode::Run,
|
||||||
|
new_flags.into(),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_json_file(
|
fn create_json_file(
|
||||||
|
|
|
@ -175,6 +175,7 @@ struct JsonLintReporter {
|
||||||
version: u8,
|
version: u8,
|
||||||
diagnostics: Vec<JsonLintDiagnostic>,
|
diagnostics: Vec<JsonLintDiagnostic>,
|
||||||
errors: Vec<LintError>,
|
errors: Vec<LintError>,
|
||||||
|
checked_files: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JsonLintReporter {
|
impl JsonLintReporter {
|
||||||
|
@ -183,6 +184,7 @@ impl JsonLintReporter {
|
||||||
version: JSON_SCHEMA_VERSION,
|
version: JSON_SCHEMA_VERSION,
|
||||||
diagnostics: Vec::new(),
|
diagnostics: Vec::new(),
|
||||||
errors: Vec::new(),
|
errors: Vec::new(),
|
||||||
|
checked_files: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,6 +211,17 @@ impl LintReporter for JsonLintReporter {
|
||||||
code: d.code().to_string(),
|
code: d.code().to_string(),
|
||||||
hint: d.hint().map(|h| h.to_string()),
|
hint: d.hint().map(|h| h.to_string()),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let file_path = d
|
||||||
|
.specifier
|
||||||
|
.to_file_path()
|
||||||
|
.unwrap()
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
if !self.checked_files.contains(&file_path) {
|
||||||
|
self.checked_files.push(file_path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_error(&mut self, file_path: &str, err: &AnyError) {
|
fn visit_error(&mut self, file_path: &str, err: &AnyError) {
|
||||||
|
@ -216,10 +229,15 @@ impl LintReporter for JsonLintReporter {
|
||||||
file_path: file_path.to_string(),
|
file_path: file_path.to_string(),
|
||||||
message: err.to_string(),
|
message: err.to_string(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if !self.checked_files.contains(&file_path.to_string()) {
|
||||||
|
self.checked_files.push(file_path.to_string());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close(&mut self, _check_count: usize) {
|
fn close(&mut self, _check_count: usize) {
|
||||||
sort_diagnostics(&mut self.diagnostics);
|
sort_diagnostics(&mut self.diagnostics);
|
||||||
|
self.checked_files.sort();
|
||||||
let json = serde_json::to_string_pretty(&self);
|
let json = serde_json::to_string_pretty(&self);
|
||||||
#[allow(clippy::print_stdout)]
|
#[allow(clippy::print_stdout)]
|
||||||
{
|
{
|
||||||
|
|
|
@ -68,6 +68,7 @@ use auth::get_auth_method;
|
||||||
use auth::AuthMethod;
|
use auth::AuthMethod;
|
||||||
pub use pm::add;
|
pub use pm::add;
|
||||||
pub use pm::cache_top_level_deps;
|
pub use pm::cache_top_level_deps;
|
||||||
|
pub use pm::outdated;
|
||||||
pub use pm::remove;
|
pub use pm::remove;
|
||||||
pub use pm::AddCommandName;
|
pub use pm::AddCommandName;
|
||||||
pub use pm::AddRmPackageReq;
|
pub use pm::AddRmPackageReq;
|
||||||
|
|
|
@ -16,6 +16,7 @@ use deno_semver::package::PackageNv;
|
||||||
use deno_semver::package::PackageReq;
|
use deno_semver::package::PackageReq;
|
||||||
use deno_semver::Version;
|
use deno_semver::Version;
|
||||||
use deno_semver::VersionReq;
|
use deno_semver::VersionReq;
|
||||||
|
use deps::KeyPath;
|
||||||
use jsonc_parser::cst::CstObject;
|
use jsonc_parser::cst::CstObject;
|
||||||
use jsonc_parser::cst::CstObjectProp;
|
use jsonc_parser::cst::CstObjectProp;
|
||||||
use jsonc_parser::cst::CstRootNode;
|
use jsonc_parser::cst::CstRootNode;
|
||||||
|
@ -32,10 +33,13 @@ use crate::jsr::JsrFetchResolver;
|
||||||
use crate::npm::NpmFetchResolver;
|
use crate::npm::NpmFetchResolver;
|
||||||
|
|
||||||
mod cache_deps;
|
mod cache_deps;
|
||||||
|
pub(crate) mod deps;
|
||||||
|
mod outdated;
|
||||||
|
|
||||||
pub use cache_deps::cache_top_level_deps;
|
pub use cache_deps::cache_top_level_deps;
|
||||||
|
pub use outdated::outdated;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone, Hash)]
|
||||||
enum ConfigKind {
|
enum ConfigKind {
|
||||||
DenoJson,
|
DenoJson,
|
||||||
PackageJson,
|
PackageJson,
|
||||||
|
@ -86,6 +90,28 @@ impl ConfigUpdater {
|
||||||
self.cst.to_string()
|
self.cst.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_property_for_mutation(
|
||||||
|
&mut self,
|
||||||
|
key_path: &KeyPath,
|
||||||
|
) -> Option<CstObjectProp> {
|
||||||
|
let mut current_node = self.root_object.clone();
|
||||||
|
|
||||||
|
self.modified = true;
|
||||||
|
|
||||||
|
for (i, part) in key_path.parts.iter().enumerate() {
|
||||||
|
let s = part.as_str();
|
||||||
|
if i < key_path.parts.len().saturating_sub(1) {
|
||||||
|
let object = current_node.object_value(s)?;
|
||||||
|
current_node = object;
|
||||||
|
} else {
|
||||||
|
// last part
|
||||||
|
return current_node.get(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn add(&mut self, selected: SelectedPackage, dev: bool) {
|
fn add(&mut self, selected: SelectedPackage, dev: bool) {
|
||||||
fn insert_index(object: &CstObject, searching_name: &str) -> usize {
|
fn insert_index(object: &CstObject, searching_name: &str) -> usize {
|
||||||
object
|
object
|
||||||
|
@ -824,7 +850,7 @@ async fn npm_install_after_modification(
|
||||||
flags: Arc<Flags>,
|
flags: Arc<Flags>,
|
||||||
// explicitly provided to prevent redownloading
|
// explicitly provided to prevent redownloading
|
||||||
jsr_resolver: Option<Arc<crate::jsr::JsrFetchResolver>>,
|
jsr_resolver: Option<Arc<crate::jsr::JsrFetchResolver>>,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<CliFactory, AnyError> {
|
||||||
// clear the previously cached package.json from memory before reloading it
|
// clear the previously cached package.json from memory before reloading it
|
||||||
node_resolver::PackageJsonThreadLocalCache::clear();
|
node_resolver::PackageJsonThreadLocalCache::clear();
|
||||||
|
|
||||||
|
@ -842,7 +868,7 @@ async fn npm_install_after_modification(
|
||||||
lockfile.write_if_changed()?;
|
lockfile.write_if_changed()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(cli_factory)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -8,7 +8,7 @@ use crate::graph_container::ModuleGraphUpdatePermit;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::futures::stream::FuturesUnordered;
|
use deno_core::futures::stream::FuturesUnordered;
|
||||||
use deno_core::futures::StreamExt;
|
use deno_core::futures::StreamExt;
|
||||||
use deno_semver::package::PackageReq;
|
use deno_semver::jsr::JsrPackageReqReference;
|
||||||
|
|
||||||
pub async fn cache_top_level_deps(
|
pub async fn cache_top_level_deps(
|
||||||
// todo(dsherret): don't pass the factory into this function. Instead use ctor deps
|
// todo(dsherret): don't pass the factory into this function. Instead use ctor deps
|
||||||
|
@ -56,15 +56,20 @@ pub async fn cache_top_level_deps(
|
||||||
match specifier.scheme() {
|
match specifier.scheme() {
|
||||||
"jsr" => {
|
"jsr" => {
|
||||||
let specifier_str = specifier.as_str();
|
let specifier_str = specifier.as_str();
|
||||||
let specifier_str =
|
if let Ok(req) = JsrPackageReqReference::from_str(specifier_str) {
|
||||||
specifier_str.strip_prefix("jsr:").unwrap_or(specifier_str);
|
if let Some(sub_path) = req.sub_path() {
|
||||||
if let Ok(req) = PackageReq::from_str(specifier_str) {
|
if sub_path.ends_with('/') {
|
||||||
if !seen_reqs.insert(req.clone()) {
|
continue;
|
||||||
|
}
|
||||||
|
roots.push(specifier.clone());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if !seen_reqs.insert(req.req().clone()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let jsr_resolver = jsr_resolver.clone();
|
let jsr_resolver = jsr_resolver.clone();
|
||||||
info_futures.push(async move {
|
info_futures.push(async move {
|
||||||
if let Some(nv) = jsr_resolver.req_to_nv(&req).await {
|
if let Some(nv) = jsr_resolver.req_to_nv(req.req()).await {
|
||||||
if let Some(info) = jsr_resolver.package_version_info(&nv).await
|
if let Some(info) = jsr_resolver.package_version_info(&nv).await
|
||||||
{
|
{
|
||||||
return Some((specifier.clone(), info));
|
return Some((specifier.clone(), info));
|
||||||
|
|
964
cli/tools/registry/pm/deps.rs
Normal file
964
cli/tools/registry/pm/deps.rs
Normal file
|
@ -0,0 +1,964 @@
|
||||||
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::sync::atomic::AtomicBool;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use deno_ast::ModuleSpecifier;
|
||||||
|
use deno_config::deno_json::ConfigFile;
|
||||||
|
use deno_config::deno_json::ConfigFileRc;
|
||||||
|
use deno_config::workspace::Workspace;
|
||||||
|
use deno_config::workspace::WorkspaceDirectory;
|
||||||
|
use deno_core::anyhow::bail;
|
||||||
|
use deno_core::error::AnyError;
|
||||||
|
use deno_core::futures::future::try_join;
|
||||||
|
use deno_core::futures::stream::FuturesOrdered;
|
||||||
|
use deno_core::futures::stream::FuturesUnordered;
|
||||||
|
use deno_core::futures::FutureExt;
|
||||||
|
use deno_core::futures::StreamExt;
|
||||||
|
use deno_core::serde_json;
|
||||||
|
use deno_graph::FillFromLockfileOptions;
|
||||||
|
use deno_package_json::PackageJsonDepValue;
|
||||||
|
use deno_package_json::PackageJsonDepValueParseError;
|
||||||
|
use deno_package_json::PackageJsonRc;
|
||||||
|
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||||
|
use deno_semver::jsr::JsrPackageReqReference;
|
||||||
|
use deno_semver::npm::NpmPackageReqReference;
|
||||||
|
use deno_semver::package::PackageNv;
|
||||||
|
use deno_semver::package::PackageReq;
|
||||||
|
use deno_semver::package::PackageReqReference;
|
||||||
|
use deno_semver::VersionReq;
|
||||||
|
use import_map::ImportMap;
|
||||||
|
use import_map::ImportMapWithDiagnostics;
|
||||||
|
use import_map::SpecifierMapEntry;
|
||||||
|
use indexmap::IndexMap;
|
||||||
|
use tokio::sync::Semaphore;
|
||||||
|
|
||||||
|
use crate::args::CliLockfile;
|
||||||
|
use crate::graph_container::MainModuleGraphContainer;
|
||||||
|
use crate::graph_container::ModuleGraphContainer;
|
||||||
|
use crate::graph_container::ModuleGraphUpdatePermit;
|
||||||
|
use crate::jsr::JsrFetchResolver;
|
||||||
|
use crate::module_loader::ModuleLoadPreparer;
|
||||||
|
use crate::npm::CliNpmResolver;
|
||||||
|
use crate::npm::NpmFetchResolver;
|
||||||
|
|
||||||
|
use super::ConfigUpdater;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
pub enum ImportMapKind {
|
||||||
|
Inline,
|
||||||
|
Outline,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum DepLocation {
|
||||||
|
DenoJson(ConfigFileRc, KeyPath, ImportMapKind),
|
||||||
|
PackageJson(PackageJsonRc, KeyPath),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DepLocation {
|
||||||
|
pub fn is_deno_json(&self) -> bool {
|
||||||
|
matches!(self, DepLocation::DenoJson(..))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn file_path(&self) -> Cow<std::path::Path> {
|
||||||
|
match self {
|
||||||
|
DepLocation::DenoJson(arc, _, _) => {
|
||||||
|
Cow::Owned(arc.specifier.to_file_path().unwrap())
|
||||||
|
}
|
||||||
|
DepLocation::PackageJson(arc, _) => Cow::Borrowed(arc.path.as_ref()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn config_kind(&self) -> super::ConfigKind {
|
||||||
|
match self {
|
||||||
|
DepLocation::DenoJson(_, _, _) => super::ConfigKind::DenoJson,
|
||||||
|
DepLocation::PackageJson(_, _) => super::ConfigKind::PackageJson,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DebugAdapter<T>(T);
|
||||||
|
|
||||||
|
impl<'a> std::fmt::Debug for DebugAdapter<&'a ConfigFileRc> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("ConfigFile")
|
||||||
|
.field("specifier", &self.0.specifier)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'a> std::fmt::Debug for DebugAdapter<&'a PackageJsonRc> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("PackageJson")
|
||||||
|
.field("path", &self.0.path)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for DepLocation {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
DepLocation::DenoJson(arc, key_path, kind) => {
|
||||||
|
let mut debug = f.debug_tuple("DenoJson");
|
||||||
|
debug
|
||||||
|
.field(&DebugAdapter(arc))
|
||||||
|
.field(key_path)
|
||||||
|
.field(kind)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
DepLocation::PackageJson(arc, key_path) => {
|
||||||
|
let mut debug = f.debug_tuple("PackageJson");
|
||||||
|
debug.field(&DebugAdapter(arc)).field(key_path).finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub enum DepKind {
|
||||||
|
Jsr,
|
||||||
|
Npm,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DepKind {
|
||||||
|
pub fn scheme(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
DepKind::Npm => "npm",
|
||||||
|
DepKind::Jsr => "jsr",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum KeyPart {
|
||||||
|
Imports,
|
||||||
|
Scopes,
|
||||||
|
Dependencies,
|
||||||
|
DevDependencies,
|
||||||
|
String(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for KeyPart {
|
||||||
|
fn from(value: String) -> Self {
|
||||||
|
KeyPart::String(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<PackageJsonDepKind> for KeyPart {
|
||||||
|
fn from(value: PackageJsonDepKind) -> Self {
|
||||||
|
match value {
|
||||||
|
PackageJsonDepKind::Normal => Self::Dependencies,
|
||||||
|
PackageJsonDepKind::Dev => Self::DevDependencies,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KeyPart {
|
||||||
|
pub fn as_str(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
KeyPart::Imports => "imports",
|
||||||
|
KeyPart::Scopes => "scopes",
|
||||||
|
KeyPart::Dependencies => "dependencies",
|
||||||
|
KeyPart::DevDependencies => "devDependencies",
|
||||||
|
KeyPart::String(s) => s,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct KeyPath {
|
||||||
|
pub parts: Vec<KeyPart>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KeyPath {
|
||||||
|
fn from_parts(parts: impl IntoIterator<Item = KeyPart>) -> Self {
|
||||||
|
Self {
|
||||||
|
parts: parts.into_iter().collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn last(&self) -> Option<&KeyPart> {
|
||||||
|
self.parts.last()
|
||||||
|
}
|
||||||
|
fn push(&mut self, part: KeyPart) {
|
||||||
|
self.parts.push(part)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Dep {
|
||||||
|
pub req: PackageReq,
|
||||||
|
pub kind: DepKind,
|
||||||
|
pub location: DepLocation,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub id: DepId,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub alias: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn import_map_entries(
|
||||||
|
import_map: &ImportMap,
|
||||||
|
) -> impl Iterator<Item = (KeyPath, SpecifierMapEntry<'_>)> {
|
||||||
|
import_map
|
||||||
|
.imports()
|
||||||
|
.entries()
|
||||||
|
.map(|entry| {
|
||||||
|
(
|
||||||
|
KeyPath::from_parts([
|
||||||
|
KeyPart::Imports,
|
||||||
|
KeyPart::String(entry.raw_key.into()),
|
||||||
|
]),
|
||||||
|
entry,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.chain(import_map.scopes().flat_map(|scope| {
|
||||||
|
let path = KeyPath::from_parts([
|
||||||
|
KeyPart::Scopes,
|
||||||
|
scope.raw_key.to_string().into(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
scope.imports.entries().map(move |entry| {
|
||||||
|
let mut full_path = path.clone();
|
||||||
|
full_path.push(KeyPart::String(entry.raw_key.to_string()));
|
||||||
|
(full_path, entry)
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_import_map_value_from_imports(
|
||||||
|
deno_json: &ConfigFile,
|
||||||
|
) -> serde_json::Value {
|
||||||
|
let mut value = serde_json::Map::with_capacity(2);
|
||||||
|
if let Some(imports) = &deno_json.json.imports {
|
||||||
|
value.insert("imports".to_string(), imports.clone());
|
||||||
|
}
|
||||||
|
if let Some(scopes) = &deno_json.json.scopes {
|
||||||
|
value.insert("scopes".to_string(), scopes.clone());
|
||||||
|
}
|
||||||
|
serde_json::Value::Object(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deno_json_import_map(
|
||||||
|
deno_json: &ConfigFile,
|
||||||
|
) -> Result<Option<(ImportMapWithDiagnostics, ImportMapKind)>, AnyError> {
|
||||||
|
let (value, kind) =
|
||||||
|
if deno_json.json.imports.is_some() || deno_json.json.scopes.is_some() {
|
||||||
|
(
|
||||||
|
to_import_map_value_from_imports(deno_json),
|
||||||
|
ImportMapKind::Inline,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
match deno_json.to_import_map_path()? {
|
||||||
|
Some(path) => {
|
||||||
|
let text = std::fs::read_to_string(&path)?;
|
||||||
|
let value = serde_json::from_str(&text)?;
|
||||||
|
(value, ImportMapKind::Outline)
|
||||||
|
}
|
||||||
|
None => return Ok(None),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
import_map::parse_from_value(deno_json.specifier.clone(), value)
|
||||||
|
.map_err(Into::into)
|
||||||
|
.map(|import_map| Some((import_map, kind)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
enum PackageJsonDepKind {
|
||||||
|
Normal,
|
||||||
|
Dev,
|
||||||
|
}
|
||||||
|
|
||||||
|
type PackageJsonDeps = IndexMap<
|
||||||
|
String,
|
||||||
|
Result<
|
||||||
|
(PackageJsonDepKind, PackageJsonDepValue),
|
||||||
|
PackageJsonDepValueParseError,
|
||||||
|
>,
|
||||||
|
>;
|
||||||
|
|
||||||
|
/// Resolve the package.json's dependencies.
|
||||||
|
// TODO(nathanwhit): Remove once we update deno_package_json with dev deps split out
|
||||||
|
fn resolve_local_package_json_deps(
|
||||||
|
package_json: &PackageJsonRc,
|
||||||
|
) -> PackageJsonDeps {
|
||||||
|
/// Gets the name and raw version constraint for a registry info or
|
||||||
|
/// package.json dependency entry taking into account npm package aliases.
|
||||||
|
fn parse_dep_entry_name_and_raw_version<'a>(
|
||||||
|
key: &'a str,
|
||||||
|
value: &'a str,
|
||||||
|
) -> (&'a str, &'a str) {
|
||||||
|
if let Some(package_and_version) = value.strip_prefix("npm:") {
|
||||||
|
if let Some((name, version)) = package_and_version.rsplit_once('@') {
|
||||||
|
// if empty, then the name was scoped and there's no version
|
||||||
|
if name.is_empty() {
|
||||||
|
(package_and_version, "*")
|
||||||
|
} else {
|
||||||
|
(name, version)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(package_and_version, "*")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(key, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_entry(
|
||||||
|
key: &str,
|
||||||
|
value: &str,
|
||||||
|
) -> Result<PackageJsonDepValue, PackageJsonDepValueParseError> {
|
||||||
|
if let Some(workspace_key) = value.strip_prefix("workspace:") {
|
||||||
|
let version_req = VersionReq::parse_from_npm(workspace_key)?;
|
||||||
|
return Ok(PackageJsonDepValue::Workspace(version_req));
|
||||||
|
}
|
||||||
|
if value.starts_with("file:")
|
||||||
|
|| value.starts_with("git:")
|
||||||
|
|| value.starts_with("http:")
|
||||||
|
|| value.starts_with("https:")
|
||||||
|
{
|
||||||
|
return Err(PackageJsonDepValueParseError::Unsupported {
|
||||||
|
scheme: value.split(':').next().unwrap().to_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let (name, version_req) = parse_dep_entry_name_and_raw_version(key, value);
|
||||||
|
let result = VersionReq::parse_from_npm(version_req);
|
||||||
|
match result {
|
||||||
|
Ok(version_req) => Ok(PackageJsonDepValue::Req(PackageReq {
|
||||||
|
name: name.to_string(),
|
||||||
|
version_req,
|
||||||
|
})),
|
||||||
|
Err(err) => Err(PackageJsonDepValueParseError::VersionReq(err)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert_deps(
|
||||||
|
deps: Option<&IndexMap<String, String>>,
|
||||||
|
result: &mut PackageJsonDeps,
|
||||||
|
kind: PackageJsonDepKind,
|
||||||
|
) {
|
||||||
|
if let Some(deps) = deps {
|
||||||
|
for (key, value) in deps {
|
||||||
|
result.entry(key.to_string()).or_insert_with(|| {
|
||||||
|
parse_entry(key, value).map(|entry| (kind, entry))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let deps = package_json.dependencies.as_ref();
|
||||||
|
let dev_deps = package_json.dev_dependencies.as_ref();
|
||||||
|
let mut result = IndexMap::new();
|
||||||
|
|
||||||
|
// favors the deps over dev_deps
|
||||||
|
insert_deps(deps, &mut result, PackageJsonDepKind::Normal);
|
||||||
|
insert_deps(dev_deps, &mut result, PackageJsonDepKind::Dev);
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_deps_from_deno_json(
|
||||||
|
deno_json: &Arc<ConfigFile>,
|
||||||
|
mut filter: impl DepFilter,
|
||||||
|
deps: &mut Vec<Dep>,
|
||||||
|
) {
|
||||||
|
let (import_map, import_map_kind) = match deno_json_import_map(deno_json) {
|
||||||
|
Ok(Some((import_map, import_map_kind))) => (import_map, import_map_kind),
|
||||||
|
Ok(None) => return,
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!("failed to parse imports from {}: {e}", &deno_json.specifier);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (key_path, entry) in import_map_entries(&import_map.import_map) {
|
||||||
|
let Some(value) = entry.value else { continue };
|
||||||
|
let kind = match value.scheme() {
|
||||||
|
"npm" => DepKind::Npm,
|
||||||
|
"jsr" => DepKind::Jsr,
|
||||||
|
_ => continue,
|
||||||
|
};
|
||||||
|
let req = match parse_req_reference(value.as_str(), kind) {
|
||||||
|
Ok(req) => req.req.clone(),
|
||||||
|
Err(err) => {
|
||||||
|
log::warn!("failed to parse package req \"{}\": {err}", value.as_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let alias: &str = key_path.last().unwrap().as_str().trim_end_matches('/');
|
||||||
|
let alias = (alias != req.name).then(|| alias.to_string());
|
||||||
|
if !filter.should_include(alias.as_deref(), &req, kind) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let id = DepId(deps.len());
|
||||||
|
deps.push(Dep {
|
||||||
|
location: DepLocation::DenoJson(
|
||||||
|
deno_json.clone(),
|
||||||
|
key_path,
|
||||||
|
import_map_kind,
|
||||||
|
),
|
||||||
|
kind,
|
||||||
|
req,
|
||||||
|
id,
|
||||||
|
alias,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_deps_from_package_json(
|
||||||
|
package_json: &PackageJsonRc,
|
||||||
|
mut filter: impl DepFilter,
|
||||||
|
deps: &mut Vec<Dep>,
|
||||||
|
) {
|
||||||
|
let package_json_deps = resolve_local_package_json_deps(package_json);
|
||||||
|
for (k, v) in package_json_deps {
|
||||||
|
let (package_dep_kind, v) = match v {
|
||||||
|
Ok((k, v)) => (k, v),
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!("bad package json dep value: {e}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match v {
|
||||||
|
deno_package_json::PackageJsonDepValue::Req(req) => {
|
||||||
|
let alias = k.as_str();
|
||||||
|
let alias = (alias != req.name).then(|| alias.to_string());
|
||||||
|
if !filter.should_include(alias.as_deref(), &req, DepKind::Npm) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let id = DepId(deps.len());
|
||||||
|
deps.push(Dep {
|
||||||
|
id,
|
||||||
|
kind: DepKind::Npm,
|
||||||
|
location: DepLocation::PackageJson(
|
||||||
|
package_json.clone(),
|
||||||
|
KeyPath::from_parts([package_dep_kind.into(), k.into()]),
|
||||||
|
),
|
||||||
|
req,
|
||||||
|
alias,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
deno_package_json::PackageJsonDepValue::Workspace(_) => continue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deps_from_workspace(
|
||||||
|
workspace: &Arc<Workspace>,
|
||||||
|
dep_filter: impl DepFilter,
|
||||||
|
) -> Result<Vec<Dep>, AnyError> {
|
||||||
|
let mut deps = Vec::with_capacity(256);
|
||||||
|
for deno_json in workspace.deno_jsons() {
|
||||||
|
add_deps_from_deno_json(deno_json, dep_filter, &mut deps);
|
||||||
|
}
|
||||||
|
for package_json in workspace.package_jsons() {
|
||||||
|
add_deps_from_package_json(package_json, dep_filter, &mut deps);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(deps)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
|
pub struct DepId(usize);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum Change {
|
||||||
|
Update(DepId, VersionReq),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait DepFilter: Copy {
|
||||||
|
fn should_include(
|
||||||
|
&mut self,
|
||||||
|
alias: Option<&str>,
|
||||||
|
package_req: &PackageReq,
|
||||||
|
dep_kind: DepKind,
|
||||||
|
) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> DepFilter for T
|
||||||
|
where
|
||||||
|
T: FnMut(Option<&str>, &PackageReq, DepKind) -> bool + Copy,
|
||||||
|
{
|
||||||
|
fn should_include<'a>(
|
||||||
|
&mut self,
|
||||||
|
alias: Option<&'a str>,
|
||||||
|
package_req: &'a PackageReq,
|
||||||
|
dep_kind: DepKind,
|
||||||
|
) -> bool {
|
||||||
|
(*self)(alias, package_req, dep_kind)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct PackageLatestVersion {
|
||||||
|
pub semver_compatible: Option<PackageNv>,
|
||||||
|
pub latest: Option<PackageNv>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DepManager {
|
||||||
|
deps: Vec<Dep>,
|
||||||
|
resolved_versions: Vec<Option<PackageNv>>,
|
||||||
|
latest_versions: Vec<PackageLatestVersion>,
|
||||||
|
|
||||||
|
pending_changes: Vec<Change>,
|
||||||
|
|
||||||
|
dependencies_resolved: AtomicBool,
|
||||||
|
module_load_preparer: Arc<ModuleLoadPreparer>,
|
||||||
|
// TODO(nathanwhit): probably shouldn't be pub
|
||||||
|
pub(crate) jsr_fetch_resolver: Arc<JsrFetchResolver>,
|
||||||
|
pub(crate) npm_fetch_resolver: Arc<NpmFetchResolver>,
|
||||||
|
npm_resolver: Arc<dyn CliNpmResolver>,
|
||||||
|
permissions_container: PermissionsContainer,
|
||||||
|
main_module_graph_container: Arc<MainModuleGraphContainer>,
|
||||||
|
lockfile: Option<Arc<CliLockfile>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DepManagerArgs {
|
||||||
|
pub module_load_preparer: Arc<ModuleLoadPreparer>,
|
||||||
|
pub jsr_fetch_resolver: Arc<JsrFetchResolver>,
|
||||||
|
pub npm_fetch_resolver: Arc<NpmFetchResolver>,
|
||||||
|
pub npm_resolver: Arc<dyn CliNpmResolver>,
|
||||||
|
pub permissions_container: PermissionsContainer,
|
||||||
|
pub main_module_graph_container: Arc<MainModuleGraphContainer>,
|
||||||
|
pub lockfile: Option<Arc<CliLockfile>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DepManager {
|
||||||
|
pub fn reloaded_after_modification(self, args: DepManagerArgs) -> Self {
|
||||||
|
let mut new = Self::with_deps_args(self.deps, args);
|
||||||
|
new.latest_versions = self.latest_versions;
|
||||||
|
new
|
||||||
|
}
|
||||||
|
fn with_deps_args(deps: Vec<Dep>, args: DepManagerArgs) -> Self {
|
||||||
|
let DepManagerArgs {
|
||||||
|
module_load_preparer,
|
||||||
|
jsr_fetch_resolver,
|
||||||
|
npm_fetch_resolver,
|
||||||
|
npm_resolver,
|
||||||
|
permissions_container,
|
||||||
|
main_module_graph_container,
|
||||||
|
lockfile,
|
||||||
|
} = args;
|
||||||
|
Self {
|
||||||
|
deps,
|
||||||
|
resolved_versions: Vec::new(),
|
||||||
|
latest_versions: Vec::new(),
|
||||||
|
jsr_fetch_resolver,
|
||||||
|
dependencies_resolved: AtomicBool::new(false),
|
||||||
|
module_load_preparer,
|
||||||
|
npm_fetch_resolver,
|
||||||
|
npm_resolver,
|
||||||
|
permissions_container,
|
||||||
|
main_module_graph_container,
|
||||||
|
lockfile,
|
||||||
|
pending_changes: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn from_workspace_dir(
|
||||||
|
workspace_dir: &Arc<WorkspaceDirectory>,
|
||||||
|
dep_filter: impl DepFilter,
|
||||||
|
args: DepManagerArgs,
|
||||||
|
) -> Result<Self, AnyError> {
|
||||||
|
let mut deps = Vec::with_capacity(256);
|
||||||
|
if let Some(deno_json) = workspace_dir.maybe_deno_json() {
|
||||||
|
if deno_json.specifier.scheme() != "file" {
|
||||||
|
bail!("remote deno.json files are not supported");
|
||||||
|
}
|
||||||
|
let path = deno_json.specifier.to_file_path().unwrap();
|
||||||
|
if path.parent().unwrap() == workspace_dir.dir_path() {
|
||||||
|
add_deps_from_deno_json(deno_json, dep_filter, &mut deps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(package_json) = workspace_dir.maybe_pkg_json() {
|
||||||
|
add_deps_from_package_json(package_json, dep_filter, &mut deps);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self::with_deps_args(deps, args))
|
||||||
|
}
|
||||||
|
pub fn from_workspace(
|
||||||
|
workspace: &Arc<Workspace>,
|
||||||
|
dep_filter: impl DepFilter,
|
||||||
|
args: DepManagerArgs,
|
||||||
|
) -> Result<Self, AnyError> {
|
||||||
|
let deps = deps_from_workspace(workspace, dep_filter)?;
|
||||||
|
Ok(Self::with_deps_args(deps, args))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn run_dependency_resolution(&self) -> Result<(), AnyError> {
|
||||||
|
if self
|
||||||
|
.dependencies_resolved
|
||||||
|
.load(std::sync::atomic::Ordering::Relaxed)
|
||||||
|
{
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut graph_permit = self
|
||||||
|
.main_module_graph_container
|
||||||
|
.acquire_update_permit()
|
||||||
|
.await;
|
||||||
|
let graph = graph_permit.graph_mut();
|
||||||
|
// populate the information from the lockfile
|
||||||
|
if let Some(lockfile) = &self.lockfile {
|
||||||
|
let lockfile = lockfile.lock();
|
||||||
|
graph.fill_from_lockfile(FillFromLockfileOptions {
|
||||||
|
redirects: lockfile
|
||||||
|
.content
|
||||||
|
.redirects
|
||||||
|
.iter()
|
||||||
|
.map(|(from, to)| (from.as_str(), to.as_str())),
|
||||||
|
package_specifiers: lockfile
|
||||||
|
.content
|
||||||
|
.packages
|
||||||
|
.specifiers
|
||||||
|
.iter()
|
||||||
|
.map(|(dep, id)| (dep, id.as_str())),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let npm_resolver = self.npm_resolver.as_managed().unwrap();
|
||||||
|
if self.deps.iter().all(|dep| match dep.kind {
|
||||||
|
DepKind::Npm => {
|
||||||
|
npm_resolver.resolve_pkg_id_from_pkg_req(&dep.req).is_ok()
|
||||||
|
}
|
||||||
|
DepKind::Jsr => graph.packages.mappings().contains_key(&dep.req),
|
||||||
|
}) {
|
||||||
|
self
|
||||||
|
.dependencies_resolved
|
||||||
|
.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||||
|
graph_permit.commit();
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
npm_resolver.ensure_top_level_package_json_install().await?;
|
||||||
|
let mut roots = Vec::new();
|
||||||
|
let mut info_futures = FuturesUnordered::new();
|
||||||
|
for dep in &self.deps {
|
||||||
|
if dep.location.is_deno_json() {
|
||||||
|
match dep.kind {
|
||||||
|
DepKind::Npm => roots.push(
|
||||||
|
ModuleSpecifier::parse(&format!("npm:/{}/", dep.req)).unwrap(),
|
||||||
|
),
|
||||||
|
DepKind::Jsr => info_futures.push(async {
|
||||||
|
if let Some(nv) = self.jsr_fetch_resolver.req_to_nv(&dep.req).await
|
||||||
|
{
|
||||||
|
if let Some(info) =
|
||||||
|
self.jsr_fetch_resolver.package_version_info(&nv).await
|
||||||
|
{
|
||||||
|
let specifier =
|
||||||
|
ModuleSpecifier::parse(&format!("jsr:/{}/", dep.req))
|
||||||
|
.unwrap();
|
||||||
|
return Some((specifier, info));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while let Some(info_future) = info_futures.next().await {
|
||||||
|
if let Some((specifier, info)) = info_future {
|
||||||
|
let exports = info.exports();
|
||||||
|
for (k, _) in exports {
|
||||||
|
if let Ok(spec) = specifier.join(k) {
|
||||||
|
roots.push(spec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self
|
||||||
|
.module_load_preparer
|
||||||
|
.prepare_module_load(
|
||||||
|
graph,
|
||||||
|
&roots,
|
||||||
|
false,
|
||||||
|
deno_config::deno_json::TsTypeLib::DenoWindow,
|
||||||
|
self.permissions_container.clone(),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
graph_permit.commit();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resolved_version(&self, id: DepId) -> Option<&PackageNv> {
|
||||||
|
self.resolved_versions[id.0].as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn resolve_current_versions(&mut self) -> Result<(), AnyError> {
|
||||||
|
self.run_dependency_resolution().await?;
|
||||||
|
|
||||||
|
let graph = self.main_module_graph_container.graph();
|
||||||
|
|
||||||
|
let mut resolved = Vec::with_capacity(self.deps.len());
|
||||||
|
let snapshot = self.npm_resolver.as_managed().unwrap().snapshot();
|
||||||
|
let resolved_npm = snapshot.package_reqs();
|
||||||
|
let resolved_jsr = graph.packages.mappings();
|
||||||
|
for dep in &self.deps {
|
||||||
|
match dep.kind {
|
||||||
|
DepKind::Npm => {
|
||||||
|
let resolved_version = resolved_npm.get(&dep.req).cloned();
|
||||||
|
resolved.push(resolved_version);
|
||||||
|
}
|
||||||
|
DepKind::Jsr => {
|
||||||
|
let resolved_version = resolved_jsr.get(&dep.req).cloned();
|
||||||
|
resolved.push(resolved_version)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.resolved_versions = resolved;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn load_latest_versions(
|
||||||
|
&self,
|
||||||
|
) -> Result<Vec<PackageLatestVersion>, AnyError> {
|
||||||
|
if self.latest_versions.len() == self.deps.len() {
|
||||||
|
return Ok(self.latest_versions.clone());
|
||||||
|
}
|
||||||
|
let latest_tag_req = deno_semver::VersionReq::from_raw_text_and_inner(
|
||||||
|
"latest".into(),
|
||||||
|
deno_semver::RangeSetOrTag::Tag("latest".into()),
|
||||||
|
);
|
||||||
|
let mut latest_versions = Vec::with_capacity(self.deps.len());
|
||||||
|
|
||||||
|
let npm_sema = Semaphore::new(32);
|
||||||
|
let jsr_sema = Semaphore::new(32);
|
||||||
|
let mut futs = FuturesOrdered::new();
|
||||||
|
|
||||||
|
for dep in &self.deps {
|
||||||
|
match dep.kind {
|
||||||
|
DepKind::Npm => futs.push_back(
|
||||||
|
async {
|
||||||
|
let semver_req = &dep.req;
|
||||||
|
let latest_req = PackageReq {
|
||||||
|
name: dep.req.name.clone(),
|
||||||
|
version_req: latest_tag_req.clone(),
|
||||||
|
};
|
||||||
|
let _permit = npm_sema.acquire().await;
|
||||||
|
let semver_compatible =
|
||||||
|
self.npm_fetch_resolver.req_to_nv(semver_req).await;
|
||||||
|
let latest = self.npm_fetch_resolver.req_to_nv(&latest_req).await;
|
||||||
|
PackageLatestVersion {
|
||||||
|
latest,
|
||||||
|
semver_compatible,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.boxed_local(),
|
||||||
|
),
|
||||||
|
DepKind::Jsr => futs.push_back(
|
||||||
|
async {
|
||||||
|
let semver_req = &dep.req;
|
||||||
|
let latest_req = PackageReq {
|
||||||
|
name: dep.req.name.clone(),
|
||||||
|
version_req: deno_semver::WILDCARD_VERSION_REQ.clone(),
|
||||||
|
};
|
||||||
|
let _permit = jsr_sema.acquire().await;
|
||||||
|
let semver_compatible =
|
||||||
|
self.jsr_fetch_resolver.req_to_nv(semver_req).await;
|
||||||
|
let latest = self.jsr_fetch_resolver.req_to_nv(&latest_req).await;
|
||||||
|
PackageLatestVersion {
|
||||||
|
latest,
|
||||||
|
semver_compatible,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.boxed_local(),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while let Some(nv) = futs.next().await {
|
||||||
|
latest_versions.push(nv);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(latest_versions)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn resolve_versions(&mut self) -> Result<(), AnyError> {
|
||||||
|
let (_, latest_versions) = try_join(
|
||||||
|
self.run_dependency_resolution(),
|
||||||
|
self.load_latest_versions(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
self.latest_versions = latest_versions;
|
||||||
|
|
||||||
|
self.resolve_current_versions().await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deps_with_resolved_latest_versions(
|
||||||
|
&self,
|
||||||
|
) -> impl IntoIterator<Item = (DepId, Option<PackageNv>, PackageLatestVersion)> + '_
|
||||||
|
{
|
||||||
|
self
|
||||||
|
.resolved_versions
|
||||||
|
.iter()
|
||||||
|
.zip(self.latest_versions.iter())
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, (resolved, latest))| {
|
||||||
|
(DepId(i), resolved.clone(), latest.clone())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_dep(&self, id: DepId) -> &Dep {
|
||||||
|
&self.deps[id.0]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_dep(&mut self, dep_id: DepId, new_version_req: VersionReq) {
|
||||||
|
self
|
||||||
|
.pending_changes
|
||||||
|
.push(Change::Update(dep_id, new_version_req));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn commit_changes(&mut self) -> Result<(), AnyError> {
|
||||||
|
let changes = std::mem::take(&mut self.pending_changes);
|
||||||
|
let mut config_updaters = HashMap::new();
|
||||||
|
for change in changes {
|
||||||
|
match change {
|
||||||
|
Change::Update(dep_id, version_req) => {
|
||||||
|
// TODO: move most of this to ConfigUpdater
|
||||||
|
let dep = &mut self.deps[dep_id.0];
|
||||||
|
dep.req.version_req = version_req.clone();
|
||||||
|
match &dep.location {
|
||||||
|
DepLocation::DenoJson(arc, key_path, import_map_kind) => {
|
||||||
|
if matches!(import_map_kind, ImportMapKind::Outline) {
|
||||||
|
// not supported
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let updater =
|
||||||
|
get_or_create_updater(&mut config_updaters, &dep.location)?;
|
||||||
|
|
||||||
|
let Some(property) = updater.get_property_for_mutation(key_path)
|
||||||
|
else {
|
||||||
|
log::warn!(
|
||||||
|
"failed to find property at path {key_path:?} for file {}",
|
||||||
|
arc.specifier
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let Some(string_value) = cst_string_literal(&property) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let mut req_reference = match dep.kind {
|
||||||
|
DepKind::Npm => NpmPackageReqReference::from_str(&string_value)
|
||||||
|
.unwrap()
|
||||||
|
.into_inner(),
|
||||||
|
DepKind::Jsr => JsrPackageReqReference::from_str(&string_value)
|
||||||
|
.unwrap()
|
||||||
|
.into_inner(),
|
||||||
|
};
|
||||||
|
req_reference.req.version_req = version_req;
|
||||||
|
let mut new_value =
|
||||||
|
format!("{}:{}", dep.kind.scheme(), req_reference);
|
||||||
|
if string_value.ends_with('/') && !new_value.ends_with('/') {
|
||||||
|
// the display impl for PackageReqReference maps `/` to the root
|
||||||
|
// subpath, but for the import map the trailing `/` is significant
|
||||||
|
new_value.push('/');
|
||||||
|
}
|
||||||
|
if string_value
|
||||||
|
.trim_start_matches(format!("{}:", dep.kind.scheme()).as_str())
|
||||||
|
.starts_with('/')
|
||||||
|
{
|
||||||
|
// this is gross
|
||||||
|
new_value = new_value.replace(':', ":/");
|
||||||
|
}
|
||||||
|
property
|
||||||
|
.set_value(jsonc_parser::cst::CstInputValue::String(new_value));
|
||||||
|
}
|
||||||
|
DepLocation::PackageJson(arc, key_path) => {
|
||||||
|
let updater =
|
||||||
|
get_or_create_updater(&mut config_updaters, &dep.location)?;
|
||||||
|
let Some(property) = updater.get_property_for_mutation(key_path)
|
||||||
|
else {
|
||||||
|
log::warn!(
|
||||||
|
"failed to find property at path {key_path:?} for file {}",
|
||||||
|
arc.path.display()
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let Some(string_value) = cst_string_literal(&property) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let new_value = if string_value.starts_with("npm:") {
|
||||||
|
// aliased
|
||||||
|
let rest = string_value.trim_start_matches("npm:");
|
||||||
|
let mut parts = rest.split('@');
|
||||||
|
let first = parts.next().unwrap();
|
||||||
|
if first.is_empty() {
|
||||||
|
let scope_and_name = parts.next().unwrap();
|
||||||
|
format!("npm:@{scope_and_name}@{version_req}")
|
||||||
|
} else {
|
||||||
|
format!("npm:{first}@{version_req}")
|
||||||
|
}
|
||||||
|
} else if string_value.contains(":") {
|
||||||
|
bail!("Unexpected package json dependency string: \"{string_value}\" in {}", arc.path.display());
|
||||||
|
} else {
|
||||||
|
version_req.to_string()
|
||||||
|
};
|
||||||
|
property
|
||||||
|
.set_value(jsonc_parser::cst::CstInputValue::String(new_value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (_, updater) in config_updaters {
|
||||||
|
updater.commit()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_or_create_updater<'a>(
|
||||||
|
config_updaters: &'a mut HashMap<std::path::PathBuf, ConfigUpdater>,
|
||||||
|
location: &DepLocation,
|
||||||
|
) -> Result<&'a mut ConfigUpdater, AnyError> {
|
||||||
|
match config_updaters.entry(location.file_path().into_owned()) {
|
||||||
|
std::collections::hash_map::Entry::Occupied(occupied_entry) => {
|
||||||
|
Ok(occupied_entry.into_mut())
|
||||||
|
}
|
||||||
|
std::collections::hash_map::Entry::Vacant(vacant_entry) => {
|
||||||
|
let updater = ConfigUpdater::new(
|
||||||
|
location.config_kind(),
|
||||||
|
location.file_path().into_owned(),
|
||||||
|
)?;
|
||||||
|
Ok(vacant_entry.insert(updater))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cst_string_literal(
|
||||||
|
property: &jsonc_parser::cst::CstObjectProp,
|
||||||
|
) -> Option<String> {
|
||||||
|
// TODO(nathanwhit): ensure this unwrap is safe
|
||||||
|
let value = property.value().unwrap();
|
||||||
|
let Some(string) = value.as_string_lit() else {
|
||||||
|
log::warn!("malformed entry");
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
let Ok(string_value) = string.decoded_value() else {
|
||||||
|
log::warn!("malformed string: {string:?}");
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
Some(string_value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_req_reference(
|
||||||
|
input: &str,
|
||||||
|
kind: DepKind,
|
||||||
|
) -> Result<
|
||||||
|
PackageReqReference,
|
||||||
|
deno_semver::package::PackageReqReferenceParseError,
|
||||||
|
> {
|
||||||
|
Ok(match kind {
|
||||||
|
DepKind::Npm => NpmPackageReqReference::from_str(input)?.into_inner(),
|
||||||
|
DepKind::Jsr => JsrPackageReqReference::from_str(input)?.into_inner(),
|
||||||
|
})
|
||||||
|
}
|
661
cli/tools/registry/pm/outdated.rs
Normal file
661
cli/tools/registry/pm/outdated.rs
Normal file
|
@ -0,0 +1,661 @@
|
||||||
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use deno_core::error::AnyError;
|
||||||
|
use deno_semver::package::PackageNv;
|
||||||
|
use deno_semver::package::PackageReq;
|
||||||
|
use deno_semver::VersionReq;
|
||||||
|
use deno_terminal::colors;
|
||||||
|
|
||||||
|
use crate::args::CacheSetting;
|
||||||
|
use crate::args::CliOptions;
|
||||||
|
use crate::args::Flags;
|
||||||
|
use crate::args::OutdatedFlags;
|
||||||
|
use crate::factory::CliFactory;
|
||||||
|
use crate::file_fetcher::FileFetcher;
|
||||||
|
use crate::jsr::JsrFetchResolver;
|
||||||
|
use crate::npm::NpmFetchResolver;
|
||||||
|
use crate::tools::registry::pm::deps::DepKind;
|
||||||
|
|
||||||
|
use super::deps::Dep;
|
||||||
|
use super::deps::DepManager;
|
||||||
|
use super::deps::DepManagerArgs;
|
||||||
|
use super::deps::PackageLatestVersion;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
struct OutdatedPackage {
|
||||||
|
kind: DepKind,
|
||||||
|
latest: String,
|
||||||
|
semver_compatible: String,
|
||||||
|
current: String,
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::print_stdout)]
|
||||||
|
fn print_outdated_table(packages: &[OutdatedPackage]) {
|
||||||
|
const HEADINGS: &[&str] = &["Package", "Current", "Update", "Latest"];
|
||||||
|
|
||||||
|
let mut longest_package = 0;
|
||||||
|
let mut longest_current = 0;
|
||||||
|
let mut longest_update = 0;
|
||||||
|
let mut longest_latest = 0;
|
||||||
|
|
||||||
|
for package in packages {
|
||||||
|
let name_len = package.kind.scheme().len() + 1 + package.name.len();
|
||||||
|
longest_package = longest_package.max(name_len);
|
||||||
|
longest_current = longest_current.max(package.current.len());
|
||||||
|
longest_update = longest_update.max(package.semver_compatible.len());
|
||||||
|
longest_latest = longest_latest.max(package.latest.len());
|
||||||
|
}
|
||||||
|
|
||||||
|
let package_column_width = longest_package.max(HEADINGS[0].len()) + 2;
|
||||||
|
let current_column_width = longest_current.max(HEADINGS[1].len()) + 2;
|
||||||
|
let update_column_width = longest_update.max(HEADINGS[2].len()) + 2;
|
||||||
|
let latest_column_width = longest_latest.max(HEADINGS[3].len()) + 2;
|
||||||
|
|
||||||
|
let package_fill = "─".repeat(package_column_width);
|
||||||
|
let current_fill = "─".repeat(current_column_width);
|
||||||
|
let update_fill = "─".repeat(update_column_width);
|
||||||
|
let latest_fill = "─".repeat(latest_column_width);
|
||||||
|
|
||||||
|
println!("┌{package_fill}┬{current_fill}┬{update_fill}┬{latest_fill}┐");
|
||||||
|
println!(
|
||||||
|
"│ {}{} │ {}{} │ {}{} │ {}{} │",
|
||||||
|
colors::intense_blue(HEADINGS[0]),
|
||||||
|
" ".repeat(package_column_width - 2 - HEADINGS[0].len()),
|
||||||
|
colors::intense_blue(HEADINGS[1]),
|
||||||
|
" ".repeat(current_column_width - 2 - HEADINGS[1].len()),
|
||||||
|
colors::intense_blue(HEADINGS[2]),
|
||||||
|
" ".repeat(update_column_width - 2 - HEADINGS[2].len()),
|
||||||
|
colors::intense_blue(HEADINGS[3]),
|
||||||
|
" ".repeat(latest_column_width - 2 - HEADINGS[3].len())
|
||||||
|
);
|
||||||
|
for package in packages {
|
||||||
|
println!("├{package_fill}┼{current_fill}┼{update_fill}┼{latest_fill}┤",);
|
||||||
|
|
||||||
|
print!(
|
||||||
|
"│ {:<package_column_width$} ",
|
||||||
|
format!("{}:{}", package.kind.scheme(), package.name),
|
||||||
|
package_column_width = package_column_width - 2
|
||||||
|
);
|
||||||
|
print!(
|
||||||
|
"│ {:<current_column_width$} ",
|
||||||
|
package.current,
|
||||||
|
current_column_width = current_column_width - 2
|
||||||
|
);
|
||||||
|
print!(
|
||||||
|
"│ {:<update_column_width$} ",
|
||||||
|
package.semver_compatible,
|
||||||
|
update_column_width = update_column_width - 2
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"│ {:<latest_column_width$} │",
|
||||||
|
package.latest,
|
||||||
|
latest_column_width = latest_column_width - 2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("└{package_fill}┴{current_fill}┴{update_fill}┴{latest_fill}┘",);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_outdated(
|
||||||
|
deps: &mut DepManager,
|
||||||
|
compatible: bool,
|
||||||
|
) -> Result<(), AnyError> {
|
||||||
|
let mut outdated = Vec::new();
|
||||||
|
let mut seen = std::collections::BTreeSet::new();
|
||||||
|
for (dep_id, resolved, latest_versions) in
|
||||||
|
deps.deps_with_resolved_latest_versions()
|
||||||
|
{
|
||||||
|
let dep = deps.get_dep(dep_id);
|
||||||
|
|
||||||
|
let Some(resolved) = resolved else { continue };
|
||||||
|
|
||||||
|
let latest = {
|
||||||
|
let preferred = if compatible {
|
||||||
|
&latest_versions.semver_compatible
|
||||||
|
} else {
|
||||||
|
&latest_versions.latest
|
||||||
|
};
|
||||||
|
if let Some(v) = preferred {
|
||||||
|
v
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if latest > &resolved
|
||||||
|
&& seen.insert((dep.kind, dep.req.name.clone(), resolved.version.clone()))
|
||||||
|
{
|
||||||
|
outdated.push(OutdatedPackage {
|
||||||
|
kind: dep.kind,
|
||||||
|
name: dep.req.name.clone(),
|
||||||
|
current: resolved.version.to_string(),
|
||||||
|
latest: latest_versions
|
||||||
|
.latest
|
||||||
|
.map(|l| l.version.to_string())
|
||||||
|
.unwrap_or_default(),
|
||||||
|
semver_compatible: latest_versions
|
||||||
|
.semver_compatible
|
||||||
|
.map(|l| l.version.to_string())
|
||||||
|
.unwrap_or_default(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !outdated.is_empty() {
|
||||||
|
outdated.sort();
|
||||||
|
print_outdated_table(&outdated);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn outdated(
|
||||||
|
flags: Arc<Flags>,
|
||||||
|
update_flags: OutdatedFlags,
|
||||||
|
) -> Result<(), AnyError> {
|
||||||
|
let factory = CliFactory::from_flags(flags.clone());
|
||||||
|
let cli_options = factory.cli_options()?;
|
||||||
|
let workspace = cli_options.workspace();
|
||||||
|
let http_client = factory.http_client_provider();
|
||||||
|
let deps_http_cache = factory.global_http_cache()?;
|
||||||
|
let mut file_fetcher = FileFetcher::new(
|
||||||
|
deps_http_cache.clone(),
|
||||||
|
CacheSetting::RespectHeaders,
|
||||||
|
true,
|
||||||
|
http_client.clone(),
|
||||||
|
Default::default(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
file_fetcher.set_download_log_level(log::Level::Trace);
|
||||||
|
let file_fetcher = Arc::new(file_fetcher);
|
||||||
|
let npm_fetch_resolver = Arc::new(NpmFetchResolver::new(
|
||||||
|
file_fetcher.clone(),
|
||||||
|
cli_options.npmrc().clone(),
|
||||||
|
));
|
||||||
|
let jsr_fetch_resolver =
|
||||||
|
Arc::new(JsrFetchResolver::new(file_fetcher.clone()));
|
||||||
|
|
||||||
|
let args = dep_manager_args(
|
||||||
|
&factory,
|
||||||
|
cli_options,
|
||||||
|
npm_fetch_resolver.clone(),
|
||||||
|
jsr_fetch_resolver.clone(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let filter_set = filter::FilterSet::from_filter_strings(
|
||||||
|
update_flags.filters.iter().map(|s| s.as_str()),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let filter_fn = |alias: Option<&str>, req: &PackageReq, _: DepKind| {
|
||||||
|
if filter_set.is_empty() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
let name = alias.unwrap_or(&req.name);
|
||||||
|
filter_set.matches(name)
|
||||||
|
};
|
||||||
|
let mut deps = if update_flags.recursive {
|
||||||
|
super::deps::DepManager::from_workspace(workspace, filter_fn, args)?
|
||||||
|
} else {
|
||||||
|
super::deps::DepManager::from_workspace_dir(
|
||||||
|
&cli_options.start_dir,
|
||||||
|
filter_fn,
|
||||||
|
args,
|
||||||
|
)?
|
||||||
|
};
|
||||||
|
|
||||||
|
deps.resolve_versions().await?;
|
||||||
|
|
||||||
|
match update_flags.kind {
|
||||||
|
crate::args::OutdatedKind::Update { latest } => {
|
||||||
|
update(deps, latest, &filter_set, flags).await?;
|
||||||
|
}
|
||||||
|
crate::args::OutdatedKind::PrintOutdated { compatible } => {
|
||||||
|
print_outdated(&mut deps, compatible)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn choose_new_version_req(
|
||||||
|
dep: &Dep,
|
||||||
|
resolved: Option<&PackageNv>,
|
||||||
|
latest_versions: &PackageLatestVersion,
|
||||||
|
update_to_latest: bool,
|
||||||
|
filter_set: &filter::FilterSet,
|
||||||
|
) -> Option<VersionReq> {
|
||||||
|
let explicit_version_req = filter_set
|
||||||
|
.matching_filter(dep.alias.as_deref().unwrap_or(&dep.req.name))
|
||||||
|
.version_spec()
|
||||||
|
.cloned();
|
||||||
|
|
||||||
|
if let Some(version_req) = explicit_version_req {
|
||||||
|
if let Some(resolved) = resolved {
|
||||||
|
// todo(nathanwhit): handle tag
|
||||||
|
if version_req.tag().is_none() && version_req.matches(&resolved.version) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(version_req)
|
||||||
|
} else {
|
||||||
|
let preferred = if update_to_latest {
|
||||||
|
latest_versions.latest.as_ref()?
|
||||||
|
} else {
|
||||||
|
latest_versions.semver_compatible.as_ref()?
|
||||||
|
};
|
||||||
|
if preferred.version <= resolved?.version {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(
|
||||||
|
VersionReq::parse_from_specifier(
|
||||||
|
format!("^{}", preferred.version).as_str(),
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn update(
|
||||||
|
mut deps: DepManager,
|
||||||
|
update_to_latest: bool,
|
||||||
|
filter_set: &filter::FilterSet,
|
||||||
|
flags: Arc<Flags>,
|
||||||
|
) -> Result<(), AnyError> {
|
||||||
|
let mut updated = Vec::new();
|
||||||
|
|
||||||
|
for (dep_id, resolved, latest_versions) in deps
|
||||||
|
.deps_with_resolved_latest_versions()
|
||||||
|
.into_iter()
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
{
|
||||||
|
let dep = deps.get_dep(dep_id);
|
||||||
|
let new_version_req = choose_new_version_req(
|
||||||
|
dep,
|
||||||
|
resolved.as_ref(),
|
||||||
|
&latest_versions,
|
||||||
|
update_to_latest,
|
||||||
|
filter_set,
|
||||||
|
);
|
||||||
|
let Some(new_version_req) = new_version_req else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
updated.push((
|
||||||
|
dep_id,
|
||||||
|
format!("{}:{}", dep.kind.scheme(), dep.req.name),
|
||||||
|
deps.resolved_version(dep.id).cloned(),
|
||||||
|
new_version_req.clone(),
|
||||||
|
));
|
||||||
|
|
||||||
|
deps.update_dep(dep_id, new_version_req);
|
||||||
|
}
|
||||||
|
|
||||||
|
deps.commit_changes()?;
|
||||||
|
|
||||||
|
if !updated.is_empty() {
|
||||||
|
let factory = super::npm_install_after_modification(
|
||||||
|
flags.clone(),
|
||||||
|
Some(deps.jsr_fetch_resolver.clone()),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let mut updated_to_versions = HashSet::new();
|
||||||
|
let cli_options = factory.cli_options()?;
|
||||||
|
let args = dep_manager_args(
|
||||||
|
&factory,
|
||||||
|
cli_options,
|
||||||
|
deps.npm_fetch_resolver.clone(),
|
||||||
|
deps.jsr_fetch_resolver.clone(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let mut deps = deps.reloaded_after_modification(args);
|
||||||
|
deps.resolve_current_versions().await?;
|
||||||
|
for (dep_id, package_name, maybe_current_version, new_version_req) in
|
||||||
|
updated
|
||||||
|
{
|
||||||
|
if let Some(nv) = deps.resolved_version(dep_id) {
|
||||||
|
updated_to_versions.insert((
|
||||||
|
package_name,
|
||||||
|
maybe_current_version,
|
||||||
|
nv.version.clone(),
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
log::warn!(
|
||||||
|
"Failed to resolve version for new version requirement: {} -> {}",
|
||||||
|
package_name,
|
||||||
|
new_version_req
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log::info!(
|
||||||
|
"Updated {} dependenc{}:",
|
||||||
|
updated_to_versions.len(),
|
||||||
|
if updated_to_versions.len() == 1 {
|
||||||
|
"y"
|
||||||
|
} else {
|
||||||
|
"ies"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
let mut updated_to_versions =
|
||||||
|
updated_to_versions.into_iter().collect::<Vec<_>>();
|
||||||
|
updated_to_versions.sort_by(|(k, _, _), (k2, _, _)| k.cmp(k2));
|
||||||
|
let max_name = updated_to_versions
|
||||||
|
.iter()
|
||||||
|
.map(|(name, _, _)| name.len())
|
||||||
|
.max()
|
||||||
|
.unwrap_or(0);
|
||||||
|
let max_old = updated_to_versions
|
||||||
|
.iter()
|
||||||
|
.map(|(_, maybe_current, _)| {
|
||||||
|
maybe_current
|
||||||
|
.as_ref()
|
||||||
|
.map(|v| v.version.to_string().len())
|
||||||
|
.unwrap_or(0)
|
||||||
|
})
|
||||||
|
.max()
|
||||||
|
.unwrap_or(0);
|
||||||
|
let max_new = updated_to_versions
|
||||||
|
.iter()
|
||||||
|
.map(|(_, _, new_version)| new_version.to_string().len())
|
||||||
|
.max()
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
for (package_name, maybe_current_version, new_version) in
|
||||||
|
updated_to_versions
|
||||||
|
{
|
||||||
|
let current_version = if let Some(current_version) = maybe_current_version
|
||||||
|
{
|
||||||
|
current_version.version.to_string()
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
};
|
||||||
|
|
||||||
|
log::info!(
|
||||||
|
" - {}{} {}{} -> {}{}",
|
||||||
|
format!(
|
||||||
|
"{}{}",
|
||||||
|
colors::gray(package_name[0..4].to_string()),
|
||||||
|
package_name[4..].to_string()
|
||||||
|
),
|
||||||
|
" ".repeat(max_name - package_name.len()),
|
||||||
|
" ".repeat(max_old - current_version.len()),
|
||||||
|
colors::gray(¤t_version),
|
||||||
|
" ".repeat(max_new - new_version.to_string().len()),
|
||||||
|
colors::green(&new_version),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log::info!(
|
||||||
|
"All {}dependencies are up to date.",
|
||||||
|
if filter_set.is_empty() {
|
||||||
|
""
|
||||||
|
} else {
|
||||||
|
"matching "
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn dep_manager_args(
|
||||||
|
factory: &CliFactory,
|
||||||
|
cli_options: &CliOptions,
|
||||||
|
npm_fetch_resolver: Arc<NpmFetchResolver>,
|
||||||
|
jsr_fetch_resolver: Arc<JsrFetchResolver>,
|
||||||
|
) -> Result<DepManagerArgs, AnyError> {
|
||||||
|
Ok(DepManagerArgs {
|
||||||
|
module_load_preparer: factory.module_load_preparer().await?.clone(),
|
||||||
|
jsr_fetch_resolver,
|
||||||
|
npm_fetch_resolver,
|
||||||
|
npm_resolver: factory.npm_resolver().await?.clone(),
|
||||||
|
permissions_container: factory.root_permissions_container()?.clone(),
|
||||||
|
main_module_graph_container: factory
|
||||||
|
.main_module_graph_container()
|
||||||
|
.await?
|
||||||
|
.clone(),
|
||||||
|
lockfile: cli_options.maybe_lockfile().cloned(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
mod filter {
|
||||||
|
use deno_core::anyhow::anyhow;
|
||||||
|
use deno_core::anyhow::Context;
|
||||||
|
use deno_core::error::AnyError;
|
||||||
|
use deno_semver::VersionReq;
|
||||||
|
|
||||||
|
enum FilterKind {
|
||||||
|
Exclude,
|
||||||
|
Include,
|
||||||
|
}
|
||||||
|
pub struct Filter {
|
||||||
|
kind: FilterKind,
|
||||||
|
regex: regex::Regex,
|
||||||
|
version_spec: Option<VersionReq>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pattern_to_regex(pattern: &str) -> Result<regex::Regex, AnyError> {
|
||||||
|
let escaped = regex::escape(pattern);
|
||||||
|
let unescaped_star = escaped.replace(r"\*", ".*");
|
||||||
|
Ok(regex::Regex::new(&format!("^{}$", unescaped_star))?)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Filter {
|
||||||
|
pub fn version_spec(&self) -> Option<&VersionReq> {
|
||||||
|
self.version_spec.as_ref()
|
||||||
|
}
|
||||||
|
pub fn from_str(input: &str) -> Result<Self, AnyError> {
|
||||||
|
let (kind, first_idx) = if input.starts_with('!') {
|
||||||
|
(FilterKind::Exclude, 1)
|
||||||
|
} else {
|
||||||
|
(FilterKind::Include, 0)
|
||||||
|
};
|
||||||
|
let s = &input[first_idx..];
|
||||||
|
let (pattern, version_spec) =
|
||||||
|
if let Some(scope_name) = s.strip_prefix('@') {
|
||||||
|
if let Some(idx) = scope_name.find('@') {
|
||||||
|
let (pattern, version_spec) = s.split_at(idx + 1);
|
||||||
|
(
|
||||||
|
pattern,
|
||||||
|
Some(
|
||||||
|
VersionReq::parse_from_specifier(
|
||||||
|
version_spec.trim_start_matches('@'),
|
||||||
|
)
|
||||||
|
.with_context(|| format!("Invalid filter \"{input}\""))?,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(s, None)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let mut parts = s.split('@');
|
||||||
|
let Some(pattern) = parts.next() else {
|
||||||
|
return Err(anyhow!("Invalid filter \"{input}\""));
|
||||||
|
};
|
||||||
|
(
|
||||||
|
pattern,
|
||||||
|
parts
|
||||||
|
.next()
|
||||||
|
.map(VersionReq::parse_from_specifier)
|
||||||
|
.transpose()
|
||||||
|
.with_context(|| format!("Invalid filter \"{input}\""))?,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Filter {
|
||||||
|
kind,
|
||||||
|
regex: pattern_to_regex(pattern)
|
||||||
|
.with_context(|| format!("Invalid filter \"{input}\""))?,
|
||||||
|
version_spec,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn matches(&self, name: &str) -> bool {
|
||||||
|
self.regex.is_match(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FilterSet {
|
||||||
|
filters: Vec<Filter>,
|
||||||
|
has_exclude: bool,
|
||||||
|
has_include: bool,
|
||||||
|
}
|
||||||
|
impl FilterSet {
|
||||||
|
pub fn from_filter_strings<'a>(
|
||||||
|
filter_strings: impl IntoIterator<Item = &'a str>,
|
||||||
|
) -> Result<Self, AnyError> {
|
||||||
|
let filters = filter_strings
|
||||||
|
.into_iter()
|
||||||
|
.map(Filter::from_str)
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
let has_exclude = filters
|
||||||
|
.iter()
|
||||||
|
.any(|f| matches!(f.kind, FilterKind::Exclude));
|
||||||
|
let has_include = filters
|
||||||
|
.iter()
|
||||||
|
.any(|f| matches!(f.kind, FilterKind::Include));
|
||||||
|
Ok(FilterSet {
|
||||||
|
filters,
|
||||||
|
has_exclude,
|
||||||
|
has_include,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.filters.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn matches(&self, name: &str) -> bool {
|
||||||
|
self.matching_filter(name).is_included()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn matching_filter(&self, name: &str) -> MatchResult<'_> {
|
||||||
|
if self.filters.is_empty() {
|
||||||
|
return MatchResult::Included;
|
||||||
|
}
|
||||||
|
let mut matched = None;
|
||||||
|
for filter in &self.filters {
|
||||||
|
match filter.kind {
|
||||||
|
FilterKind::Include => {
|
||||||
|
if matched.is_none() && filter.matches(name) {
|
||||||
|
matched = Some(filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FilterKind::Exclude => {
|
||||||
|
if filter.matches(name) {
|
||||||
|
return MatchResult::Excluded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(filter) = matched {
|
||||||
|
MatchResult::Matches(filter)
|
||||||
|
} else if self.has_exclude && !self.has_include {
|
||||||
|
MatchResult::Included
|
||||||
|
} else {
|
||||||
|
MatchResult::Excluded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum MatchResult<'a> {
|
||||||
|
Matches(&'a Filter),
|
||||||
|
Included,
|
||||||
|
Excluded,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MatchResult<'_> {
|
||||||
|
pub fn version_spec(&self) -> Option<&VersionReq> {
|
||||||
|
match self {
|
||||||
|
MatchResult::Matches(filter) => filter.version_spec(),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn is_included(&self) -> bool {
|
||||||
|
matches!(self, MatchResult::Included | MatchResult::Matches(_))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
fn matches_filters<'a, 'b>(
|
||||||
|
filters: impl IntoIterator<Item = &'a str>,
|
||||||
|
name: &str,
|
||||||
|
) -> bool {
|
||||||
|
let filters = super::FilterSet::from_filter_strings(filters).unwrap();
|
||||||
|
filters.matches(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn version_spec(s: &str) -> deno_semver::VersionReq {
|
||||||
|
deno_semver::VersionReq::parse_from_specifier(s).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn basic_glob() {
|
||||||
|
assert!(matches_filters(["foo*"], "foo"));
|
||||||
|
assert!(matches_filters(["foo*"], "foobar"));
|
||||||
|
assert!(!matches_filters(["foo*"], "barfoo"));
|
||||||
|
|
||||||
|
assert!(matches_filters(["*foo"], "foo"));
|
||||||
|
assert!(matches_filters(["*foo"], "barfoo"));
|
||||||
|
assert!(!matches_filters(["*foo"], "foobar"));
|
||||||
|
|
||||||
|
assert!(matches_filters(["@scope/foo*"], "@scope/foobar"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn basic_glob_with_version() {
|
||||||
|
assert!(matches_filters(["foo*@1"], "foo",));
|
||||||
|
assert!(matches_filters(["foo*@1"], "foobar",));
|
||||||
|
assert!(matches_filters(["foo*@1"], "foo-bar",));
|
||||||
|
assert!(!matches_filters(["foo*@1"], "barfoo",));
|
||||||
|
assert!(matches_filters(["@scope/*@1"], "@scope/foo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn glob_exclude() {
|
||||||
|
assert!(!matches_filters(["!foo*"], "foo"));
|
||||||
|
assert!(!matches_filters(["!foo*"], "foobar"));
|
||||||
|
assert!(matches_filters(["!foo*"], "barfoo"));
|
||||||
|
|
||||||
|
assert!(!matches_filters(["!*foo"], "foo"));
|
||||||
|
assert!(!matches_filters(["!*foo"], "barfoo"));
|
||||||
|
assert!(matches_filters(["!*foo"], "foobar"));
|
||||||
|
|
||||||
|
assert!(!matches_filters(["!@scope/foo*"], "@scope/foobar"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn multiple_globs() {
|
||||||
|
assert!(matches_filters(["foo*", "bar*"], "foo"));
|
||||||
|
assert!(matches_filters(["foo*", "bar*"], "bar"));
|
||||||
|
assert!(!matches_filters(["foo*", "bar*"], "baz"));
|
||||||
|
|
||||||
|
assert!(matches_filters(["foo*", "!bar*"], "foo"));
|
||||||
|
assert!(!matches_filters(["foo*", "!bar*"], "bar"));
|
||||||
|
assert!(matches_filters(["foo*", "!bar*"], "foobar"));
|
||||||
|
assert!(!matches_filters(["foo*", "!*bar"], "foobar"));
|
||||||
|
assert!(!matches_filters(["foo*", "!*bar"], "baz"));
|
||||||
|
|
||||||
|
let filters =
|
||||||
|
super::FilterSet::from_filter_strings(["foo*@1", "bar*@2"]).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
filters.matching_filter("foo").version_spec().cloned(),
|
||||||
|
Some(version_spec("1"))
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
filters.matching_filter("bar").version_spec().cloned(),
|
||||||
|
Some(version_spec("2"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ use std::path::PathBuf;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use deno_config::workspace::FolderConfigs;
|
||||||
use deno_config::workspace::TaskDefinition;
|
use deno_config::workspace::TaskDefinition;
|
||||||
use deno_config::workspace::TaskOrScript;
|
use deno_config::workspace::TaskOrScript;
|
||||||
use deno_config::workspace::WorkspaceDirectory;
|
use deno_config::workspace::WorkspaceDirectory;
|
||||||
|
@ -25,6 +26,7 @@ use deno_path_util::normalize_path;
|
||||||
use deno_runtime::deno_node::NodeResolver;
|
use deno_runtime::deno_node::NodeResolver;
|
||||||
use deno_task_shell::ShellCommand;
|
use deno_task_shell::ShellCommand;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
use crate::args::CliOptions;
|
use crate::args::CliOptions;
|
||||||
use crate::args::Flags;
|
use crate::args::Flags;
|
||||||
|
@ -35,6 +37,12 @@ use crate::npm::CliNpmResolver;
|
||||||
use crate::task_runner;
|
use crate::task_runner;
|
||||||
use crate::util::fs::canonicalize_path;
|
use crate::util::fs::canonicalize_path;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct PackageTaskInfo {
|
||||||
|
matched_tasks: Vec<String>,
|
||||||
|
tasks_config: WorkspaceTasksConfig,
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn execute_script(
|
pub async fn execute_script(
|
||||||
flags: Arc<Flags>,
|
flags: Arc<Flags>,
|
||||||
task_flags: TaskFlags,
|
task_flags: TaskFlags,
|
||||||
|
@ -55,18 +63,145 @@ pub async fn execute_script(
|
||||||
v == "1"
|
v == "1"
|
||||||
})
|
})
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
let mut tasks_config = start_dir.to_tasks_config()?;
|
|
||||||
if force_use_pkg_json {
|
fn arg_to_regex(input: &str) -> Result<regex::Regex, regex::Error> {
|
||||||
tasks_config = tasks_config.with_only_pkg_json()
|
let mut regex_str = regex::escape(input);
|
||||||
|
regex_str = regex_str.replace("\\*", ".*");
|
||||||
|
|
||||||
|
Regex::new(®ex_str)
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(task_name) = &task_flags.task else {
|
let packages_task_configs: Vec<PackageTaskInfo> = if let Some(filter) =
|
||||||
print_available_tasks(
|
&task_flags.filter
|
||||||
&mut std::io::stdout(),
|
{
|
||||||
&cli_options.start_dir,
|
let task_name = task_flags.task.as_ref().unwrap();
|
||||||
&tasks_config,
|
|
||||||
)?;
|
// Filter based on package name
|
||||||
return Ok(0);
|
let package_regex = arg_to_regex(filter)?;
|
||||||
|
let task_regex = arg_to_regex(task_name)?;
|
||||||
|
|
||||||
|
let mut packages_task_info: Vec<PackageTaskInfo> = vec![];
|
||||||
|
|
||||||
|
fn matches_package(
|
||||||
|
config: &FolderConfigs,
|
||||||
|
force_use_pkg_json: bool,
|
||||||
|
regex: &Regex,
|
||||||
|
) -> bool {
|
||||||
|
if !force_use_pkg_json {
|
||||||
|
if let Some(deno_json) = &config.deno_json {
|
||||||
|
if let Some(name) = &deno_json.json.name {
|
||||||
|
if regex.is_match(name) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(package_json) = &config.pkg_json {
|
||||||
|
if let Some(name) = &package_json.name {
|
||||||
|
if regex.is_match(name) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
let workspace = cli_options.workspace();
|
||||||
|
for folder in workspace.config_folders() {
|
||||||
|
if !matches_package(folder.1, force_use_pkg_json, &package_regex) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let member_dir = workspace.resolve_member_dir(folder.0);
|
||||||
|
let mut tasks_config = member_dir.to_tasks_config()?;
|
||||||
|
if force_use_pkg_json {
|
||||||
|
tasks_config = tasks_config.with_only_pkg_json();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any of the matched tasks could be a child task of another matched
|
||||||
|
// one. Therefore we need to filter these out to ensure that every
|
||||||
|
// task is only run once.
|
||||||
|
let mut matched: HashSet<String> = HashSet::new();
|
||||||
|
let mut visited: HashSet<String> = HashSet::new();
|
||||||
|
|
||||||
|
fn visit_task(
|
||||||
|
tasks_config: &WorkspaceTasksConfig,
|
||||||
|
visited: &mut HashSet<String>,
|
||||||
|
name: &str,
|
||||||
|
) {
|
||||||
|
if visited.contains(name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
visited.insert(name.to_string());
|
||||||
|
|
||||||
|
if let Some((_, TaskOrScript::Task(_, task))) = &tasks_config.task(name)
|
||||||
|
{
|
||||||
|
for dep in &task.dependencies {
|
||||||
|
visit_task(tasks_config, visited, dep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match tasks in deno.json
|
||||||
|
for name in tasks_config.task_names() {
|
||||||
|
if task_regex.is_match(name) && !visited.contains(name) {
|
||||||
|
matched.insert(name.to_string());
|
||||||
|
visit_task(&tasks_config, &mut visited, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
packages_task_info.push(PackageTaskInfo {
|
||||||
|
matched_tasks: matched
|
||||||
|
.iter()
|
||||||
|
.map(|s| s.to_string())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
tasks_config,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logging every task definition would be too spammy. Pnpm only
|
||||||
|
// logs a simple message too.
|
||||||
|
if packages_task_info
|
||||||
|
.iter()
|
||||||
|
.all(|config| config.matched_tasks.is_empty())
|
||||||
|
{
|
||||||
|
log::warn!(
|
||||||
|
"{}",
|
||||||
|
colors::red(format!(
|
||||||
|
"No matching task or script '{}' found in selected packages.",
|
||||||
|
task_name
|
||||||
|
))
|
||||||
|
);
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Sort packages topologically
|
||||||
|
//
|
||||||
|
|
||||||
|
packages_task_info
|
||||||
|
} else {
|
||||||
|
let mut tasks_config = start_dir.to_tasks_config()?;
|
||||||
|
|
||||||
|
if force_use_pkg_json {
|
||||||
|
tasks_config = tasks_config.with_only_pkg_json()
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some(task_name) = &task_flags.task else {
|
||||||
|
print_available_tasks(
|
||||||
|
&mut std::io::stdout(),
|
||||||
|
&cli_options.start_dir,
|
||||||
|
&tasks_config,
|
||||||
|
)?;
|
||||||
|
return Ok(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
vec![PackageTaskInfo {
|
||||||
|
tasks_config,
|
||||||
|
matched_tasks: vec![task_name.to_string()],
|
||||||
|
}]
|
||||||
};
|
};
|
||||||
|
|
||||||
let npm_resolver = factory.npm_resolver().await?;
|
let npm_resolver = factory.npm_resolver().await?;
|
||||||
|
@ -81,7 +216,6 @@ pub async fn execute_script(
|
||||||
.unwrap_or_else(|| NonZeroUsize::new(2).unwrap());
|
.unwrap_or_else(|| NonZeroUsize::new(2).unwrap());
|
||||||
|
|
||||||
let task_runner = TaskRunner {
|
let task_runner = TaskRunner {
|
||||||
tasks_config,
|
|
||||||
task_flags: &task_flags,
|
task_flags: &task_flags,
|
||||||
npm_resolver: npm_resolver.as_ref(),
|
npm_resolver: npm_resolver.as_ref(),
|
||||||
node_resolver: node_resolver.as_ref(),
|
node_resolver: node_resolver.as_ref(),
|
||||||
|
@ -94,7 +228,7 @@ pub async fn execute_script(
|
||||||
return task_runner
|
return task_runner
|
||||||
.run_deno_task(
|
.run_deno_task(
|
||||||
&Url::from_directory_path(cli_options.initial_cwd()).unwrap(),
|
&Url::from_directory_path(cli_options.initial_cwd()).unwrap(),
|
||||||
&"".to_string(),
|
"",
|
||||||
&TaskDefinition {
|
&TaskDefinition {
|
||||||
command: task_flags.task.as_ref().unwrap().to_string(),
|
command: task_flags.task.as_ref().unwrap().to_string(),
|
||||||
dependencies: vec![],
|
dependencies: vec![],
|
||||||
|
@ -103,7 +237,15 @@ pub async fn execute_script(
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
task_runner.run_task(task_name).await
|
|
||||||
|
for task_config in &packages_task_configs {
|
||||||
|
let exit_code = task_runner.run_tasks(task_config).await?;
|
||||||
|
if exit_code > 0 {
|
||||||
|
return Ok(exit_code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RunSingleOptions<'a> {
|
struct RunSingleOptions<'a> {
|
||||||
|
@ -114,7 +256,6 @@ struct RunSingleOptions<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TaskRunner<'a> {
|
struct TaskRunner<'a> {
|
||||||
tasks_config: WorkspaceTasksConfig,
|
|
||||||
task_flags: &'a TaskFlags,
|
task_flags: &'a TaskFlags,
|
||||||
npm_resolver: &'a dyn CliNpmResolver,
|
npm_resolver: &'a dyn CliNpmResolver,
|
||||||
node_resolver: &'a NodeResolver,
|
node_resolver: &'a NodeResolver,
|
||||||
|
@ -124,12 +265,16 @@ struct TaskRunner<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TaskRunner<'a> {
|
impl<'a> TaskRunner<'a> {
|
||||||
pub async fn run_task(
|
pub async fn run_tasks(
|
||||||
&self,
|
&self,
|
||||||
task_name: &str,
|
pkg_tasks_config: &PackageTaskInfo,
|
||||||
) -> Result<i32, deno_core::anyhow::Error> {
|
) -> Result<i32, deno_core::anyhow::Error> {
|
||||||
match sort_tasks_topo(task_name, &self.tasks_config) {
|
match sort_tasks_topo(pkg_tasks_config) {
|
||||||
Ok(sorted) => self.run_tasks_in_parallel(sorted).await,
|
Ok(sorted) => {
|
||||||
|
self
|
||||||
|
.run_tasks_in_parallel(&pkg_tasks_config.tasks_config, sorted)
|
||||||
|
.await
|
||||||
|
}
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
TaskError::NotFound(name) => {
|
TaskError::NotFound(name) => {
|
||||||
if self.task_flags.is_run {
|
if self.task_flags.is_run {
|
||||||
|
@ -138,7 +283,7 @@ impl<'a> TaskRunner<'a> {
|
||||||
|
|
||||||
log::error!("Task not found: {}", name);
|
log::error!("Task not found: {}", name);
|
||||||
if log::log_enabled!(log::Level::Error) {
|
if log::log_enabled!(log::Level::Error) {
|
||||||
self.print_available_tasks()?;
|
self.print_available_tasks(&pkg_tasks_config.tasks_config)?;
|
||||||
}
|
}
|
||||||
Ok(1)
|
Ok(1)
|
||||||
}
|
}
|
||||||
|
@ -150,16 +295,20 @@ impl<'a> TaskRunner<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_available_tasks(&self) -> Result<(), std::io::Error> {
|
pub fn print_available_tasks(
|
||||||
|
&self,
|
||||||
|
tasks_config: &WorkspaceTasksConfig,
|
||||||
|
) -> Result<(), std::io::Error> {
|
||||||
print_available_tasks(
|
print_available_tasks(
|
||||||
&mut std::io::stderr(),
|
&mut std::io::stderr(),
|
||||||
&self.cli_options.start_dir,
|
&self.cli_options.start_dir,
|
||||||
&self.tasks_config,
|
tasks_config,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_tasks_in_parallel(
|
async fn run_tasks_in_parallel(
|
||||||
&self,
|
&self,
|
||||||
|
tasks_config: &WorkspaceTasksConfig,
|
||||||
task_names: Vec<String>,
|
task_names: Vec<String>,
|
||||||
) -> Result<i32, deno_core::anyhow::Error> {
|
) -> Result<i32, deno_core::anyhow::Error> {
|
||||||
struct PendingTasksContext {
|
struct PendingTasksContext {
|
||||||
|
@ -181,22 +330,23 @@ impl<'a> TaskRunner<'a> {
|
||||||
fn get_next_task<'a>(
|
fn get_next_task<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
runner: &'a TaskRunner<'a>,
|
runner: &'a TaskRunner<'a>,
|
||||||
|
tasks_config: &'a WorkspaceTasksConfig,
|
||||||
) -> Option<LocalBoxFuture<'a, Result<(i32, String), AnyError>>> {
|
) -> Option<LocalBoxFuture<'a, Result<(i32, String), AnyError>>> {
|
||||||
for name in &self.task_names {
|
for name in &self.task_names {
|
||||||
if self.completed.contains(name) || self.running.contains(name) {
|
if self.completed.contains(name) || self.running.contains(name) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let should_run = if let Ok((_, def)) = runner.get_task(name) {
|
let Some((folder_url, task_or_script)) = tasks_config.task(name)
|
||||||
match def {
|
else {
|
||||||
TaskOrScript::Task(_, def) => def
|
continue;
|
||||||
.dependencies
|
};
|
||||||
.iter()
|
let should_run = match task_or_script {
|
||||||
.all(|dep| self.completed.contains(dep)),
|
TaskOrScript::Task(_, def) => def
|
||||||
TaskOrScript::Script(_, _) => true,
|
.dependencies
|
||||||
}
|
.iter()
|
||||||
} else {
|
.all(|dep| self.completed.contains(dep)),
|
||||||
false
|
TaskOrScript::Script(_, _) => true,
|
||||||
};
|
};
|
||||||
|
|
||||||
if !should_run {
|
if !should_run {
|
||||||
|
@ -207,10 +357,15 @@ impl<'a> TaskRunner<'a> {
|
||||||
let name = name.clone();
|
let name = name.clone();
|
||||||
return Some(
|
return Some(
|
||||||
async move {
|
async move {
|
||||||
runner
|
match task_or_script {
|
||||||
.run_task_no_dependencies(&name)
|
TaskOrScript::Task(_, def) => {
|
||||||
.await
|
runner.run_deno_task(folder_url, &name, def).await
|
||||||
.map(|exit_code| (exit_code, name))
|
}
|
||||||
|
TaskOrScript::Script(scripts, _) => {
|
||||||
|
runner.run_npm_script(folder_url, &name, scripts).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.map(|exit_code| (exit_code, name))
|
||||||
}
|
}
|
||||||
.boxed_local(),
|
.boxed_local(),
|
||||||
);
|
);
|
||||||
|
@ -229,7 +384,7 @@ impl<'a> TaskRunner<'a> {
|
||||||
|
|
||||||
while context.has_remaining_tasks() {
|
while context.has_remaining_tasks() {
|
||||||
while queue.len() < self.concurrency {
|
while queue.len() < self.concurrency {
|
||||||
if let Some(task) = context.get_next_task(self) {
|
if let Some(task) = context.get_next_task(self, tasks_config) {
|
||||||
queue.push(task);
|
queue.push(task);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -253,37 +408,10 @@ impl<'a> TaskRunner<'a> {
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_task(
|
pub async fn run_deno_task(
|
||||||
&self,
|
|
||||||
task_name: &str,
|
|
||||||
) -> Result<(&Url, TaskOrScript), TaskError> {
|
|
||||||
let Some(result) = self.tasks_config.task(task_name) else {
|
|
||||||
return Err(TaskError::NotFound(task_name.to_string()));
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn run_task_no_dependencies(
|
|
||||||
&self,
|
|
||||||
task_name: &String,
|
|
||||||
) -> Result<i32, deno_core::anyhow::Error> {
|
|
||||||
let (dir_url, task_or_script) = self.get_task(task_name.as_str()).unwrap();
|
|
||||||
|
|
||||||
match task_or_script {
|
|
||||||
TaskOrScript::Task(_tasks, definition) => {
|
|
||||||
self.run_deno_task(dir_url, task_name, definition).await
|
|
||||||
}
|
|
||||||
TaskOrScript::Script(scripts, _script) => {
|
|
||||||
self.run_npm_script(dir_url, task_name, scripts).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn run_deno_task(
|
|
||||||
&self,
|
&self,
|
||||||
dir_url: &Url,
|
dir_url: &Url,
|
||||||
task_name: &String,
|
task_name: &str,
|
||||||
definition: &TaskDefinition,
|
definition: &TaskDefinition,
|
||||||
) -> Result<i32, deno_core::anyhow::Error> {
|
) -> Result<i32, deno_core::anyhow::Error> {
|
||||||
let cwd = match &self.task_flags.cwd {
|
let cwd = match &self.task_flags.cwd {
|
||||||
|
@ -306,10 +434,10 @@ impl<'a> TaskRunner<'a> {
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_npm_script(
|
pub async fn run_npm_script(
|
||||||
&self,
|
&self,
|
||||||
dir_url: &Url,
|
dir_url: &Url,
|
||||||
task_name: &String,
|
task_name: &str,
|
||||||
scripts: &IndexMap<String, String>,
|
scripts: &IndexMap<String, String>,
|
||||||
) -> Result<i32, deno_core::anyhow::Error> {
|
) -> Result<i32, deno_core::anyhow::Error> {
|
||||||
// ensure the npm packages are installed if using a managed resolver
|
// ensure the npm packages are installed if using a managed resolver
|
||||||
|
@ -327,7 +455,7 @@ impl<'a> TaskRunner<'a> {
|
||||||
// dealing with package.json here and not deno.json
|
// dealing with package.json here and not deno.json
|
||||||
let task_names = vec![
|
let task_names = vec![
|
||||||
format!("pre{}", task_name),
|
format!("pre{}", task_name),
|
||||||
task_name.clone(),
|
task_name.to_string(),
|
||||||
format!("post{}", task_name),
|
format!("post{}", task_name),
|
||||||
];
|
];
|
||||||
let custom_commands = task_runner::resolve_custom_commands(
|
let custom_commands = task_runner::resolve_custom_commands(
|
||||||
|
@ -394,8 +522,7 @@ enum TaskError {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sort_tasks_topo(
|
fn sort_tasks_topo(
|
||||||
name: &str,
|
pkg_task_config: &PackageTaskInfo,
|
||||||
task_config: &WorkspaceTasksConfig,
|
|
||||||
) -> Result<Vec<String>, TaskError> {
|
) -> Result<Vec<String>, TaskError> {
|
||||||
fn sort_visit<'a>(
|
fn sort_visit<'a>(
|
||||||
name: &'a str,
|
name: &'a str,
|
||||||
|
@ -416,12 +543,12 @@ fn sort_tasks_topo(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(def) = tasks_config.task(name) else {
|
let Some((_, task_or_script)) = tasks_config.task(name) else {
|
||||||
return Err(TaskError::NotFound(name.to_string()));
|
return Err(TaskError::NotFound(name.to_string()));
|
||||||
};
|
};
|
||||||
|
|
||||||
if let TaskOrScript::Task(_, actual_def) = def.1 {
|
if let TaskOrScript::Task(_, task) = task_or_script {
|
||||||
for dep in &actual_def.dependencies {
|
for dep in &task.dependencies {
|
||||||
let mut path = path.clone();
|
let mut path = path.clone();
|
||||||
path.push(name);
|
path.push(name);
|
||||||
sort_visit(dep, sorted, path, tasks_config)?
|
sort_visit(dep, sorted, path, tasks_config)?
|
||||||
|
@ -435,7 +562,9 @@ fn sort_tasks_topo(
|
||||||
|
|
||||||
let mut sorted: Vec<String> = vec![];
|
let mut sorted: Vec<String> = vec![];
|
||||||
|
|
||||||
sort_visit(name, &mut sorted, Vec::new(), task_config)?;
|
for name in &pkg_task_config.matched_tasks {
|
||||||
|
sort_visit(name, &mut sorted, Vec::new(), &pkg_task_config.tasks_config)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(sorted)
|
Ok(sorted)
|
||||||
}
|
}
|
||||||
|
|
58
cli/tsc/dts/lib.deno.shared_globals.d.ts
vendored
58
cli/tsc/dts/lib.deno.shared_globals.d.ts
vendored
|
@ -15,14 +15,14 @@
|
||||||
/// <reference lib="deno.crypto" />
|
/// <reference lib="deno.crypto" />
|
||||||
/// <reference lib="deno.ns" />
|
/// <reference lib="deno.ns" />
|
||||||
|
|
||||||
/** @category WASM */
|
/** @category Wasm */
|
||||||
declare namespace WebAssembly {
|
declare namespace WebAssembly {
|
||||||
/**
|
/**
|
||||||
* The `WebAssembly.CompileError` object indicates an error during WebAssembly decoding or validation.
|
* The `WebAssembly.CompileError` object indicates an error during WebAssembly decoding or validation.
|
||||||
*
|
*
|
||||||
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/CompileError)
|
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/CompileError)
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export class CompileError extends Error {
|
export class CompileError extends Error {
|
||||||
/** Creates a new `WebAssembly.CompileError` object. */
|
/** Creates a new `WebAssembly.CompileError` object. */
|
||||||
|
@ -36,7 +36,7 @@ declare namespace WebAssembly {
|
||||||
*
|
*
|
||||||
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Global)
|
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Global)
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export class Global {
|
export class Global {
|
||||||
/** Creates a new `Global` object. */
|
/** Creates a new `Global` object. */
|
||||||
|
@ -59,7 +59,7 @@ declare namespace WebAssembly {
|
||||||
*
|
*
|
||||||
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance)
|
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance)
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export class Instance {
|
export class Instance {
|
||||||
/** Creates a new Instance object. */
|
/** Creates a new Instance object. */
|
||||||
|
@ -79,7 +79,7 @@ declare namespace WebAssembly {
|
||||||
*
|
*
|
||||||
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/LinkError)
|
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/LinkError)
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export class LinkError extends Error {
|
export class LinkError extends Error {
|
||||||
/** Creates a new WebAssembly.LinkError object. */
|
/** Creates a new WebAssembly.LinkError object. */
|
||||||
|
@ -95,7 +95,7 @@ declare namespace WebAssembly {
|
||||||
*
|
*
|
||||||
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory)
|
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory)
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export class Memory {
|
export class Memory {
|
||||||
/** Creates a new `Memory` object. */
|
/** Creates a new `Memory` object. */
|
||||||
|
@ -117,7 +117,7 @@ declare namespace WebAssembly {
|
||||||
*
|
*
|
||||||
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module)
|
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module)
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export class Module {
|
export class Module {
|
||||||
/** Creates a new `Module` object. */
|
/** Creates a new `Module` object. */
|
||||||
|
@ -145,7 +145,7 @@ declare namespace WebAssembly {
|
||||||
*
|
*
|
||||||
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/RuntimeError)
|
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/RuntimeError)
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export class RuntimeError extends Error {
|
export class RuntimeError extends Error {
|
||||||
/** Creates a new `WebAssembly.RuntimeError` object. */
|
/** Creates a new `WebAssembly.RuntimeError` object. */
|
||||||
|
@ -160,7 +160,7 @@ declare namespace WebAssembly {
|
||||||
*
|
*
|
||||||
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table)
|
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table)
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export class Table {
|
export class Table {
|
||||||
/** Creates a new `Table` object. */
|
/** Creates a new `Table` object. */
|
||||||
|
@ -182,7 +182,7 @@ declare namespace WebAssembly {
|
||||||
/** The `GlobalDescriptor` describes the options you can pass to
|
/** The `GlobalDescriptor` describes the options you can pass to
|
||||||
* `new WebAssembly.Global()`.
|
* `new WebAssembly.Global()`.
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export interface GlobalDescriptor {
|
export interface GlobalDescriptor {
|
||||||
mutable?: boolean;
|
mutable?: boolean;
|
||||||
|
@ -192,7 +192,7 @@ declare namespace WebAssembly {
|
||||||
/** The `MemoryDescriptor` describes the options you can pass to
|
/** The `MemoryDescriptor` describes the options you can pass to
|
||||||
* `new WebAssembly.Memory()`.
|
* `new WebAssembly.Memory()`.
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export interface MemoryDescriptor {
|
export interface MemoryDescriptor {
|
||||||
initial: number;
|
initial: number;
|
||||||
|
@ -203,7 +203,7 @@ declare namespace WebAssembly {
|
||||||
/** A `ModuleExportDescriptor` is the description of a declared export in a
|
/** A `ModuleExportDescriptor` is the description of a declared export in a
|
||||||
* `WebAssembly.Module`.
|
* `WebAssembly.Module`.
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export interface ModuleExportDescriptor {
|
export interface ModuleExportDescriptor {
|
||||||
kind: ImportExportKind;
|
kind: ImportExportKind;
|
||||||
|
@ -213,7 +213,7 @@ declare namespace WebAssembly {
|
||||||
/** A `ModuleImportDescriptor` is the description of a declared import in a
|
/** A `ModuleImportDescriptor` is the description of a declared import in a
|
||||||
* `WebAssembly.Module`.
|
* `WebAssembly.Module`.
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export interface ModuleImportDescriptor {
|
export interface ModuleImportDescriptor {
|
||||||
kind: ImportExportKind;
|
kind: ImportExportKind;
|
||||||
|
@ -224,7 +224,7 @@ declare namespace WebAssembly {
|
||||||
/** The `TableDescriptor` describes the options you can pass to
|
/** The `TableDescriptor` describes the options you can pass to
|
||||||
* `new WebAssembly.Table()`.
|
* `new WebAssembly.Table()`.
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export interface TableDescriptor {
|
export interface TableDescriptor {
|
||||||
element: TableKind;
|
element: TableKind;
|
||||||
|
@ -234,7 +234,7 @@ declare namespace WebAssembly {
|
||||||
|
|
||||||
/** The value returned from `WebAssembly.instantiate`.
|
/** The value returned from `WebAssembly.instantiate`.
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export interface WebAssemblyInstantiatedSource {
|
export interface WebAssemblyInstantiatedSource {
|
||||||
/* A `WebAssembly.Instance` object that contains all the exported WebAssembly functions. */
|
/* A `WebAssembly.Instance` object that contains all the exported WebAssembly functions. */
|
||||||
|
@ -247,21 +247,21 @@ declare namespace WebAssembly {
|
||||||
module: Module;
|
module: Module;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @category WASM */
|
/** @category Wasm */
|
||||||
export type ImportExportKind = "function" | "global" | "memory" | "table";
|
export type ImportExportKind = "function" | "global" | "memory" | "table";
|
||||||
/** @category WASM */
|
/** @category Wasm */
|
||||||
export type TableKind = "anyfunc";
|
export type TableKind = "anyfunc";
|
||||||
/** @category WASM */
|
/** @category Wasm */
|
||||||
export type ValueType = "f32" | "f64" | "i32" | "i64";
|
export type ValueType = "f32" | "f64" | "i32" | "i64";
|
||||||
/** @category WASM */
|
/** @category Wasm */
|
||||||
export type ExportValue = Function | Global | Memory | Table;
|
export type ExportValue = Function | Global | Memory | Table;
|
||||||
/** @category WASM */
|
/** @category Wasm */
|
||||||
export type Exports = Record<string, ExportValue>;
|
export type Exports = Record<string, ExportValue>;
|
||||||
/** @category WASM */
|
/** @category Wasm */
|
||||||
export type ImportValue = ExportValue | number;
|
export type ImportValue = ExportValue | number;
|
||||||
/** @category WASM */
|
/** @category Wasm */
|
||||||
export type ModuleImports = Record<string, ImportValue>;
|
export type ModuleImports = Record<string, ImportValue>;
|
||||||
/** @category WASM */
|
/** @category Wasm */
|
||||||
export type Imports = Record<string, ModuleImports>;
|
export type Imports = Record<string, ModuleImports>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -272,7 +272,7 @@ declare namespace WebAssembly {
|
||||||
*
|
*
|
||||||
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/compile)
|
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/compile)
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export function compile(bytes: BufferSource): Promise<Module>;
|
export function compile(bytes: BufferSource): Promise<Module>;
|
||||||
|
|
||||||
|
@ -284,7 +284,7 @@ declare namespace WebAssembly {
|
||||||
*
|
*
|
||||||
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/compileStreaming)
|
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/compileStreaming)
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export function compileStreaming(
|
export function compileStreaming(
|
||||||
source: Response | Promise<Response>,
|
source: Response | Promise<Response>,
|
||||||
|
@ -301,7 +301,7 @@ declare namespace WebAssembly {
|
||||||
*
|
*
|
||||||
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate)
|
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate)
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export function instantiate(
|
export function instantiate(
|
||||||
bytes: BufferSource,
|
bytes: BufferSource,
|
||||||
|
@ -318,7 +318,7 @@ declare namespace WebAssembly {
|
||||||
*
|
*
|
||||||
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate)
|
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate)
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export function instantiate(
|
export function instantiate(
|
||||||
moduleObject: Module,
|
moduleObject: Module,
|
||||||
|
@ -332,7 +332,7 @@ declare namespace WebAssembly {
|
||||||
*
|
*
|
||||||
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming)
|
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming)
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export function instantiateStreaming(
|
export function instantiateStreaming(
|
||||||
response: Response | PromiseLike<Response>,
|
response: Response | PromiseLike<Response>,
|
||||||
|
@ -346,7 +346,7 @@ declare namespace WebAssembly {
|
||||||
*
|
*
|
||||||
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/validate)
|
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/validate)
|
||||||
*
|
*
|
||||||
* @category WASM
|
* @category Wasm
|
||||||
*/
|
*/
|
||||||
export function validate(bytes: BufferSource): boolean;
|
export function validate(bytes: BufferSource): boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -617,6 +617,8 @@ impl CliMainWorkerFactory {
|
||||||
origin_storage_dir,
|
origin_storage_dir,
|
||||||
stdio,
|
stdio,
|
||||||
skip_op_registration: shared.options.skip_op_registration,
|
skip_op_registration: shared.options.skip_op_registration,
|
||||||
|
enable_stack_trace_arg_in_ops: crate::args::has_trace_permissions_enabled(
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut worker = MainWorker::bootstrap_from_options(
|
let mut worker = MainWorker::bootstrap_from_options(
|
||||||
|
@ -813,6 +815,8 @@ fn create_web_worker_callback(
|
||||||
strace_ops: shared.options.strace_ops.clone(),
|
strace_ops: shared.options.strace_ops.clone(),
|
||||||
close_on_idle: args.close_on_idle,
|
close_on_idle: args.close_on_idle,
|
||||||
maybe_worker_metadata: args.maybe_worker_metadata,
|
maybe_worker_metadata: args.maybe_worker_metadata,
|
||||||
|
enable_stack_trace_arg_in_ops: crate::args::has_trace_permissions_enabled(
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
WebWorker::bootstrap_from_options(services, options)
|
WebWorker::bootstrap_from_options(services, options)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_broadcast_channel"
|
name = "deno_broadcast_channel"
|
||||||
version = "0.171.0"
|
version = "0.172.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
2
ext/cache/Cargo.toml
vendored
2
ext/cache/Cargo.toml
vendored
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_cache"
|
name = "deno_cache"
|
||||||
version = "0.109.0"
|
version = "0.110.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_canvas"
|
name = "deno_canvas"
|
||||||
version = "0.46.0"
|
version = "0.47.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_console"
|
name = "deno_console"
|
||||||
version = "0.177.0"
|
version = "0.178.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_cron"
|
name = "deno_cron"
|
||||||
version = "0.57.0"
|
version = "0.58.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_crypto"
|
name = "deno_crypto"
|
||||||
version = "0.191.0"
|
version = "0.192.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_fetch"
|
name = "deno_fetch"
|
||||||
version = "0.201.0"
|
version = "0.202.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -397,7 +397,7 @@ impl FetchPermissions for deno_permissions::PermissionsContainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn op_fetch<FP>(
|
pub fn op_fetch<FP>(
|
||||||
|
@ -866,7 +866,7 @@ fn default_true() -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[smi]
|
#[smi]
|
||||||
pub fn op_fetch_custom_client<FP>(
|
pub fn op_fetch_custom_client<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_ffi"
|
name = "deno_ffi"
|
||||||
version = "0.164.0"
|
version = "0.165.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -287,7 +287,7 @@ fn ffi_call(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_ffi_call_ptr_nonblocking<FP>(
|
pub fn op_ffi_call_ptr_nonblocking<FP>(
|
||||||
scope: &mut v8::HandleScope,
|
scope: &mut v8::HandleScope,
|
||||||
|
@ -385,7 +385,7 @@ pub fn op_ffi_call_nonblocking(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(reentrant)]
|
#[op2(reentrant, stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_ffi_call_ptr<FP>(
|
pub fn op_ffi_call_ptr<FP>(
|
||||||
scope: &mut v8::HandleScope,
|
scope: &mut v8::HandleScope,
|
||||||
|
|
|
@ -561,7 +561,7 @@ pub struct RegisterCallbackArgs {
|
||||||
result: NativeType,
|
result: NativeType,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
pub fn op_ffi_unsafe_callback_create<FP, 'scope>(
|
pub fn op_ffi_unsafe_callback_create<FP, 'scope>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
scope: &mut v8::HandleScope<'scope>,
|
scope: &mut v8::HandleScope<'scope>,
|
||||||
|
|
|
@ -124,7 +124,7 @@ pub struct FfiLoadArgs {
|
||||||
symbols: HashMap<String, ForeignSymbol>,
|
symbols: HashMap<String, ForeignSymbol>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
pub fn op_ffi_load<'scope, FP>(
|
pub fn op_ffi_load<'scope, FP>(
|
||||||
scope: &mut v8::HandleScope<'scope>,
|
scope: &mut v8::HandleScope<'scope>,
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
|
|
@ -49,7 +49,7 @@ pub enum ReprError {
|
||||||
Permission(#[from] deno_permissions::PermissionCheckError),
|
Permission(#[from] deno_permissions::PermissionCheckError),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_ffi_ptr_create<FP>(
|
pub fn op_ffi_ptr_create<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[bigint] ptr_number: usize,
|
#[bigint] ptr_number: usize,
|
||||||
|
@ -63,7 +63,7 @@ where
|
||||||
Ok(ptr_number as *mut c_void)
|
Ok(ptr_number as *mut c_void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_ffi_ptr_equals<FP>(
|
pub fn op_ffi_ptr_equals<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
a: *const c_void,
|
a: *const c_void,
|
||||||
|
@ -78,7 +78,7 @@ where
|
||||||
Ok(a == b)
|
Ok(a == b)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
pub fn op_ffi_ptr_of<FP>(
|
pub fn op_ffi_ptr_of<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[anybuffer] buf: *const u8,
|
#[anybuffer] buf: *const u8,
|
||||||
|
@ -92,7 +92,7 @@ where
|
||||||
Ok(buf as *mut c_void)
|
Ok(buf as *mut c_void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_ffi_ptr_of_exact<FP>(
|
pub fn op_ffi_ptr_of_exact<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
buf: v8::Local<v8::ArrayBufferView>,
|
buf: v8::Local<v8::ArrayBufferView>,
|
||||||
|
@ -112,7 +112,7 @@ where
|
||||||
Ok(buf.as_ptr() as _)
|
Ok(buf.as_ptr() as _)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_ffi_ptr_offset<FP>(
|
pub fn op_ffi_ptr_offset<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
ptr: *mut c_void,
|
ptr: *mut c_void,
|
||||||
|
@ -142,7 +142,7 @@ unsafe extern "C" fn noop_deleter_callback(
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
#[bigint]
|
#[bigint]
|
||||||
pub fn op_ffi_ptr_value<FP>(
|
pub fn op_ffi_ptr_value<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -157,7 +157,7 @@ where
|
||||||
Ok(ptr as usize)
|
Ok(ptr as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
pub fn op_ffi_get_buf<FP, 'scope>(
|
pub fn op_ffi_get_buf<FP, 'scope>(
|
||||||
scope: &mut v8::HandleScope<'scope>,
|
scope: &mut v8::HandleScope<'scope>,
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -189,7 +189,7 @@ where
|
||||||
Ok(array_buffer)
|
Ok(array_buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
pub fn op_ffi_buf_copy_into<FP>(
|
pub fn op_ffi_buf_copy_into<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
src: *mut c_void,
|
src: *mut c_void,
|
||||||
|
@ -219,7 +219,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
pub fn op_ffi_cstr_read<FP, 'scope>(
|
pub fn op_ffi_cstr_read<FP, 'scope>(
|
||||||
scope: &mut v8::HandleScope<'scope>,
|
scope: &mut v8::HandleScope<'scope>,
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -244,7 +244,7 @@ where
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_ffi_read_bool<FP>(
|
pub fn op_ffi_read_bool<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
ptr: *mut c_void,
|
ptr: *mut c_void,
|
||||||
|
@ -264,7 +264,7 @@ where
|
||||||
Ok(unsafe { ptr::read_unaligned::<bool>(ptr.offset(offset) as *const bool) })
|
Ok(unsafe { ptr::read_unaligned::<bool>(ptr.offset(offset) as *const bool) })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_ffi_read_u8<FP>(
|
pub fn op_ffi_read_u8<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
ptr: *mut c_void,
|
ptr: *mut c_void,
|
||||||
|
@ -286,7 +286,7 @@ where
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_ffi_read_i8<FP>(
|
pub fn op_ffi_read_i8<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
ptr: *mut c_void,
|
ptr: *mut c_void,
|
||||||
|
@ -308,7 +308,7 @@ where
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_ffi_read_u16<FP>(
|
pub fn op_ffi_read_u16<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
ptr: *mut c_void,
|
ptr: *mut c_void,
|
||||||
|
@ -330,7 +330,7 @@ where
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_ffi_read_i16<FP>(
|
pub fn op_ffi_read_i16<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
ptr: *mut c_void,
|
ptr: *mut c_void,
|
||||||
|
@ -352,7 +352,7 @@ where
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_ffi_read_u32<FP>(
|
pub fn op_ffi_read_u32<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
ptr: *mut c_void,
|
ptr: *mut c_void,
|
||||||
|
@ -372,7 +372,7 @@ where
|
||||||
Ok(unsafe { ptr::read_unaligned::<u32>(ptr.offset(offset) as *const u32) })
|
Ok(unsafe { ptr::read_unaligned::<u32>(ptr.offset(offset) as *const u32) })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_ffi_read_i32<FP>(
|
pub fn op_ffi_read_i32<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
ptr: *mut c_void,
|
ptr: *mut c_void,
|
||||||
|
@ -392,7 +392,7 @@ where
|
||||||
Ok(unsafe { ptr::read_unaligned::<i32>(ptr.offset(offset) as *const i32) })
|
Ok(unsafe { ptr::read_unaligned::<i32>(ptr.offset(offset) as *const i32) })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
#[bigint]
|
#[bigint]
|
||||||
pub fn op_ffi_read_u64<FP>(
|
pub fn op_ffi_read_u64<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -418,7 +418,7 @@ where
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
#[bigint]
|
#[bigint]
|
||||||
pub fn op_ffi_read_i64<FP>(
|
pub fn op_ffi_read_i64<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -444,7 +444,7 @@ where
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_ffi_read_f32<FP>(
|
pub fn op_ffi_read_f32<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
ptr: *mut c_void,
|
ptr: *mut c_void,
|
||||||
|
@ -464,7 +464,7 @@ where
|
||||||
Ok(unsafe { ptr::read_unaligned::<f32>(ptr.offset(offset) as *const f32) })
|
Ok(unsafe { ptr::read_unaligned::<f32>(ptr.offset(offset) as *const f32) })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_ffi_read_f64<FP>(
|
pub fn op_ffi_read_f64<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
ptr: *mut c_void,
|
ptr: *mut c_void,
|
||||||
|
@ -484,7 +484,7 @@ where
|
||||||
Ok(unsafe { ptr::read_unaligned::<f64>(ptr.offset(offset) as *const f64) })
|
Ok(unsafe { ptr::read_unaligned::<f64>(ptr.offset(offset) as *const f64) })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_ffi_read_ptr<FP>(
|
pub fn op_ffi_read_ptr<FP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
ptr: *mut c_void,
|
ptr: *mut c_void,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_fs"
|
name = "deno_fs"
|
||||||
version = "0.87.0"
|
version = "0.88.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -146,7 +146,7 @@ fn map_permission_error(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
pub fn op_fs_cwd<P>(state: &mut OpState) -> Result<String, FsOpsError>
|
pub fn op_fs_cwd<P>(state: &mut OpState) -> Result<String, FsOpsError>
|
||||||
where
|
where
|
||||||
|
@ -161,7 +161,7 @@ where
|
||||||
Ok(path_str)
|
Ok(path_str)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_fs_chdir<P>(
|
pub fn op_fs_chdir<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] directory: &str,
|
#[string] directory: &str,
|
||||||
|
@ -188,7 +188,7 @@ where
|
||||||
state.borrow::<FileSystemRc>().umask(mask).context("umask")
|
state.borrow::<FileSystemRc>().umask(mask).context("umask")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[smi]
|
#[smi]
|
||||||
pub fn op_fs_open_sync<P>(
|
pub fn op_fs_open_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -215,7 +215,7 @@ where
|
||||||
Ok(rid)
|
Ok(rid)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[smi]
|
#[smi]
|
||||||
pub async fn op_fs_open_async<P>(
|
pub async fn op_fs_open_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
@ -243,7 +243,7 @@ where
|
||||||
Ok(rid)
|
Ok(rid)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
pub fn op_fs_mkdir_sync<P>(
|
pub fn op_fs_mkdir_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
|
@ -266,7 +266,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
pub async fn op_fs_mkdir_async<P>(
|
pub async fn op_fs_mkdir_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
|
@ -291,7 +291,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_fs_chmod_sync<P>(
|
pub fn op_fs_chmod_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
|
@ -308,7 +308,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
pub async fn op_fs_chmod_async<P>(
|
pub async fn op_fs_chmod_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
|
@ -328,7 +328,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
pub fn op_fs_chown_sync<P>(
|
pub fn op_fs_chown_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
|
@ -347,7 +347,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
pub async fn op_fs_chown_async<P>(
|
pub async fn op_fs_chown_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
|
@ -368,7 +368,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_fs_remove_sync<P>(
|
pub fn op_fs_remove_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] path: &str,
|
#[string] path: &str,
|
||||||
|
@ -388,7 +388,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
pub async fn op_fs_remove_async<P>(
|
pub async fn op_fs_remove_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
|
@ -419,7 +419,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_fs_copy_file_sync<P>(
|
pub fn op_fs_copy_file_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] from: &str,
|
#[string] from: &str,
|
||||||
|
@ -439,7 +439,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
pub async fn op_fs_copy_file_async<P>(
|
pub async fn op_fs_copy_file_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[string] from: String,
|
#[string] from: String,
|
||||||
|
@ -463,7 +463,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_fs_stat_sync<P>(
|
pub fn op_fs_stat_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
|
@ -482,7 +482,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub async fn op_fs_stat_async<P>(
|
pub async fn op_fs_stat_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
@ -504,7 +504,7 @@ where
|
||||||
Ok(SerializableStat::from(stat))
|
Ok(SerializableStat::from(stat))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_fs_lstat_sync<P>(
|
pub fn op_fs_lstat_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
|
@ -523,7 +523,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub async fn op_fs_lstat_async<P>(
|
pub async fn op_fs_lstat_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
@ -545,7 +545,7 @@ where
|
||||||
Ok(SerializableStat::from(stat))
|
Ok(SerializableStat::from(stat))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
pub fn op_fs_realpath_sync<P>(
|
pub fn op_fs_realpath_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -568,7 +568,7 @@ where
|
||||||
Ok(path_string)
|
Ok(path_string)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
pub async fn op_fs_realpath_async<P>(
|
pub async fn op_fs_realpath_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
@ -596,7 +596,7 @@ where
|
||||||
Ok(path_string)
|
Ok(path_string)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_fs_read_dir_sync<P>(
|
pub fn op_fs_read_dir_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -615,7 +615,7 @@ where
|
||||||
Ok(entries)
|
Ok(entries)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub async fn op_fs_read_dir_async<P>(
|
pub async fn op_fs_read_dir_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
@ -640,7 +640,7 @@ where
|
||||||
Ok(entries)
|
Ok(entries)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_fs_rename_sync<P>(
|
pub fn op_fs_rename_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] oldpath: String,
|
#[string] oldpath: String,
|
||||||
|
@ -661,7 +661,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
pub async fn op_fs_rename_async<P>(
|
pub async fn op_fs_rename_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[string] oldpath: String,
|
#[string] oldpath: String,
|
||||||
|
@ -686,7 +686,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_fs_link_sync<P>(
|
pub fn op_fs_link_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] oldpath: &str,
|
#[string] oldpath: &str,
|
||||||
|
@ -708,7 +708,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
pub async fn op_fs_link_async<P>(
|
pub async fn op_fs_link_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[string] oldpath: String,
|
#[string] oldpath: String,
|
||||||
|
@ -734,7 +734,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
pub fn op_fs_symlink_sync<P>(
|
pub fn op_fs_symlink_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] oldpath: &str,
|
#[string] oldpath: &str,
|
||||||
|
@ -758,7 +758,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
pub async fn op_fs_symlink_async<P>(
|
pub async fn op_fs_symlink_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[string] oldpath: String,
|
#[string] oldpath: String,
|
||||||
|
@ -786,7 +786,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
pub fn op_fs_read_link_sync<P>(
|
pub fn op_fs_read_link_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -806,7 +806,7 @@ where
|
||||||
Ok(target_string)
|
Ok(target_string)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
pub async fn op_fs_read_link_async<P>(
|
pub async fn op_fs_read_link_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
@ -831,7 +831,7 @@ where
|
||||||
Ok(target_string)
|
Ok(target_string)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_fs_truncate_sync<P>(
|
pub fn op_fs_truncate_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] path: &str,
|
#[string] path: &str,
|
||||||
|
@ -851,7 +851,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
pub async fn op_fs_truncate_async<P>(
|
pub async fn op_fs_truncate_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
|
@ -875,7 +875,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_fs_utime_sync<P>(
|
pub fn op_fs_utime_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] path: &str,
|
#[string] path: &str,
|
||||||
|
@ -896,7 +896,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
pub async fn op_fs_utime_async<P>(
|
pub async fn op_fs_utime_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
|
@ -927,7 +927,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
pub fn op_fs_make_temp_dir_sync<P>(
|
pub fn op_fs_make_temp_dir_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -969,7 +969,7 @@ where
|
||||||
.context("tmpdir")
|
.context("tmpdir")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
pub async fn op_fs_make_temp_dir_async<P>(
|
pub async fn op_fs_make_temp_dir_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
@ -1015,7 +1015,7 @@ where
|
||||||
.context("tmpdir")
|
.context("tmpdir")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
pub fn op_fs_make_temp_file_sync<P>(
|
pub fn op_fs_make_temp_file_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -1063,7 +1063,7 @@ where
|
||||||
.context("tmpfile")
|
.context("tmpfile")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
pub async fn op_fs_make_temp_file_async<P>(
|
pub async fn op_fs_make_temp_file_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
@ -1235,7 +1235,7 @@ fn tmp_name(
|
||||||
Ok(path)
|
Ok(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
pub fn op_fs_write_file_sync<P>(
|
pub fn op_fs_write_file_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
|
@ -1261,7 +1261,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub async fn op_fs_write_file_async<P>(
|
pub async fn op_fs_write_file_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
@ -1315,7 +1315,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_fs_read_file_sync<P>(
|
pub fn op_fs_read_file_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -1336,7 +1336,7 @@ where
|
||||||
Ok(buf.into())
|
Ok(buf.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub async fn op_fs_read_file_async<P>(
|
pub async fn op_fs_read_file_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
@ -1378,7 +1378,7 @@ where
|
||||||
Ok(buf.into())
|
Ok(buf.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
pub fn op_fs_read_file_text_sync<P>(
|
pub fn op_fs_read_file_text_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -1399,7 +1399,7 @@ where
|
||||||
Ok(str)
|
Ok(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
pub async fn op_fs_read_file_text_async<P>(
|
pub async fn op_fs_read_file_text_async<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_http"
|
name = "deno_http"
|
||||||
version = "0.175.0"
|
version = "0.176.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_io"
|
name = "deno_io"
|
||||||
version = "0.87.0"
|
version = "0.88.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_kv"
|
name = "deno_kv"
|
||||||
version = "0.85.0"
|
version = "0.86.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -178,7 +178,7 @@ pub enum KvErrorKind {
|
||||||
InvalidRange,
|
InvalidRange,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[smi]
|
#[smi]
|
||||||
async fn op_kv_database_open<DBH>(
|
async fn op_kv_database_open<DBH>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_napi"
|
name = "deno_napi"
|
||||||
version = "0.108.0"
|
version = "0.109.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -530,7 +530,7 @@ static NAPI_LOADED_MODULES: std::sync::LazyLock<
|
||||||
RwLock<HashMap<PathBuf, NapiModuleHandle>>,
|
RwLock<HashMap<PathBuf, NapiModuleHandle>>,
|
||||||
> = std::sync::LazyLock::new(|| RwLock::new(HashMap::new()));
|
> = std::sync::LazyLock::new(|| RwLock::new(HashMap::new()));
|
||||||
|
|
||||||
#[op2(reentrant)]
|
#[op2(reentrant, stack_trace)]
|
||||||
fn op_napi_open<NP, 'scope>(
|
fn op_napi_open<NP, 'scope>(
|
||||||
scope: &mut v8::HandleScope<'scope>,
|
scope: &mut v8::HandleScope<'scope>,
|
||||||
isolate: *mut v8::Isolate,
|
isolate: *mut v8::Isolate,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "napi_sym"
|
name = "napi_sym"
|
||||||
version = "0.107.0"
|
version = "0.108.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_net"
|
name = "deno_net"
|
||||||
version = "0.169.0"
|
version = "0.170.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -182,7 +182,7 @@ pub async fn op_net_recv_udp(
|
||||||
Ok((nread, IpAddr::from(remote_addr)))
|
Ok((nread, IpAddr::from(remote_addr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[number]
|
#[number]
|
||||||
pub async fn op_net_send_udp<NP>(
|
pub async fn op_net_send_udp<NP>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
@ -343,7 +343,7 @@ pub async fn op_net_set_multi_ttl_udp(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub async fn op_net_connect_tcp<NP>(
|
pub async fn op_net_connect_tcp<NP>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
@ -401,7 +401,7 @@ impl Resource for UdpSocketResource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_net_listen_tcp<NP>(
|
pub fn op_net_listen_tcp<NP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -501,7 +501,7 @@ where
|
||||||
Ok((rid, IpAddr::from(local_addr)))
|
Ok((rid, IpAddr::from(local_addr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_net_listen_udp<NP>(
|
pub fn op_net_listen_udp<NP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -516,7 +516,7 @@ where
|
||||||
net_listen_udp::<NP>(state, addr, reuse_address, loopback)
|
net_listen_udp::<NP>(state, addr, reuse_address, loopback)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_node_unstable_net_listen_udp<NP>(
|
pub fn op_node_unstable_net_listen_udp<NP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -601,7 +601,7 @@ pub struct NameServer {
|
||||||
port: u16,
|
port: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub async fn op_dns_resolve<NP>(
|
pub async fn op_dns_resolve<NP>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
|
|
@ -251,7 +251,7 @@ pub fn op_tls_cert_resolver_resolve_error(
|
||||||
lookup.resolve(sni, Err(error))
|
lookup.resolve(sni, Err(error))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_tls_start<NP>(
|
pub fn op_tls_start<NP>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
@ -340,7 +340,7 @@ where
|
||||||
Ok((rid, IpAddr::from(local_addr), IpAddr::from(remote_addr)))
|
Ok((rid, IpAddr::from(local_addr), IpAddr::from(remote_addr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub async fn op_net_connect_tls<NP>(
|
pub async fn op_net_connect_tls<NP>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
@ -445,7 +445,7 @@ pub struct ListenTlsArgs {
|
||||||
load_balanced: bool,
|
load_balanced: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_net_listen_tls<NP>(
|
pub fn op_net_listen_tls<NP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
|
|
@ -85,7 +85,7 @@ pub async fn op_net_accept_unix(
|
||||||
Ok((rid, local_addr_path, remote_addr_path))
|
Ok((rid, local_addr_path, remote_addr_path))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub async fn op_net_connect_unix<NP>(
|
pub async fn op_net_connect_unix<NP>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
@ -118,7 +118,7 @@ where
|
||||||
Ok((rid, local_addr_path, remote_addr_path))
|
Ok((rid, local_addr_path, remote_addr_path))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub async fn op_net_recv_unixpacket(
|
pub async fn op_net_recv_unixpacket(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
@ -140,7 +140,7 @@ pub async fn op_net_recv_unixpacket(
|
||||||
Ok((nread, path))
|
Ok((nread, path))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[number]
|
#[number]
|
||||||
pub async fn op_net_send_unixpacket<NP>(
|
pub async fn op_net_send_unixpacket<NP>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
@ -171,7 +171,7 @@ where
|
||||||
Ok(nwritten)
|
Ok(nwritten)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_net_listen_unix<NP>(
|
pub fn op_net_listen_unix<NP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -222,7 +222,7 @@ where
|
||||||
Ok((rid, pathname))
|
Ok((rid, pathname))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_net_listen_unixpacket<NP>(
|
pub fn op_net_listen_unixpacket<NP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -235,7 +235,7 @@ where
|
||||||
net_listen_unixpacket::<NP>(state, path)
|
net_listen_unixpacket::<NP>(state, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_node_unstable_net_listen_unixpacket<NP>(
|
pub fn op_node_unstable_net_listen_unixpacket<NP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_node"
|
name = "deno_node"
|
||||||
version = "0.114.0"
|
version = "0.115.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -26,7 +26,7 @@ pub enum FsError {
|
||||||
Fs(#[from] deno_io::fs::FsError),
|
Fs(#[from] deno_io::fs::FsError),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_node_fs_exists_sync<P>(
|
pub fn op_node_fs_exists_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
|
@ -41,7 +41,7 @@ where
|
||||||
Ok(fs.exists_sync(&path))
|
Ok(fs.exists_sync(&path))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
pub async fn op_node_fs_exists<P>(
|
pub async fn op_node_fs_exists<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
|
@ -60,7 +60,7 @@ where
|
||||||
Ok(fs.exists_async(path).await?)
|
Ok(fs.exists_async(path).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_node_cp_sync<P>(
|
pub fn op_node_cp_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] path: &str,
|
#[string] path: &str,
|
||||||
|
@ -81,7 +81,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
pub async fn op_node_cp<P>(
|
pub async fn op_node_cp<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
|
@ -117,7 +117,7 @@ pub struct StatFs {
|
||||||
pub ffree: u64,
|
pub ffree: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_node_statfs<P>(
|
pub fn op_node_statfs<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
@ -258,7 +258,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_node_lutimes_sync<P>(
|
pub fn op_node_lutimes_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] path: &str,
|
#[string] path: &str,
|
||||||
|
@ -279,7 +279,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
pub async fn op_node_lutimes<P>(
|
pub async fn op_node_lutimes<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
|
@ -305,7 +305,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
pub fn op_node_lchown_sync<P>(
|
pub fn op_node_lchown_sync<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
|
@ -323,7 +323,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
pub async fn op_node_lchown<P>(
|
pub async fn op_node_lchown<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
|
|
|
@ -49,7 +49,7 @@ use std::cmp::min;
|
||||||
use tokio::io::AsyncReadExt;
|
use tokio::io::AsyncReadExt;
|
||||||
use tokio::io::AsyncWriteExt;
|
use tokio::io::AsyncWriteExt;
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_node_http_request<P>(
|
pub fn op_node_http_request<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub fn op_inspector_enabled() -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
pub fn op_inspector_open<P>(
|
pub fn op_inspector_open<P>(
|
||||||
_state: &mut OpState,
|
_state: &mut OpState,
|
||||||
_port: Option<u16>,
|
_port: Option<u16>,
|
||||||
|
@ -85,7 +85,7 @@ struct JSInspectorSession {
|
||||||
|
|
||||||
impl GarbageCollected for JSInspectorSession {}
|
impl GarbageCollected for JSInspectorSession {}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[cppgc]
|
#[cppgc]
|
||||||
pub fn op_inspector_connect<'s, P>(
|
pub fn op_inspector_connect<'s, P>(
|
||||||
isolate: *mut v8::Isolate,
|
isolate: *mut v8::Isolate,
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub enum OsError {
|
||||||
FailedToGetUserInfo(#[source] std::io::Error),
|
FailedToGetUserInfo(#[source] std::io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_node_os_get_priority<P>(
|
pub fn op_node_os_get_priority<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
pid: u32,
|
pid: u32,
|
||||||
|
@ -37,7 +37,7 @@ where
|
||||||
priority::get_priority(pid).map_err(OsError::Priority)
|
priority::get_priority(pid).map_err(OsError::Priority)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_node_os_set_priority<P>(
|
pub fn op_node_os_set_priority<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
pid: u32,
|
pid: u32,
|
||||||
|
@ -193,7 +193,7 @@ fn get_user_info(_uid: u32) -> Result<UserInfo, OsError> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_node_os_user_info<P>(
|
pub fn op_node_os_user_info<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -212,7 +212,7 @@ where
|
||||||
get_user_info(uid)
|
get_user_info(uid)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_geteuid<P>(
|
pub fn op_geteuid<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
) -> Result<u32, deno_core::error::AnyError>
|
) -> Result<u32, deno_core::error::AnyError>
|
||||||
|
@ -233,7 +233,7 @@ where
|
||||||
Ok(euid)
|
Ok(euid)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_getegid<P>(
|
pub fn op_getegid<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
) -> Result<u32, deno_core::error::AnyError>
|
) -> Result<u32, deno_core::error::AnyError>
|
||||||
|
@ -254,7 +254,7 @@ where
|
||||||
Ok(egid)
|
Ok(egid)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_cpus<P>(state: &mut OpState) -> Result<Vec<cpus::CpuInfo>, OsError>
|
pub fn op_cpus<P>(state: &mut OpState) -> Result<Vec<cpus::CpuInfo>, OsError>
|
||||||
where
|
where
|
||||||
|
@ -268,7 +268,7 @@ where
|
||||||
cpus::cpu_info().ok_or(OsError::FailedToGetCpuInfo)
|
cpus::cpu_info().ok_or(OsError::FailedToGetCpuInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
pub fn op_homedir<P>(
|
pub fn op_homedir<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
|
|
@ -45,7 +45,7 @@ fn kill(pid: i32, _sig: i32) -> i32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_node_process_kill(
|
pub fn op_node_process_kill(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[smi] pid: i32,
|
#[smi] pid: i32,
|
||||||
|
|
|
@ -125,7 +125,7 @@ pub fn op_require_init_paths() -> Vec<String> {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_require_node_module_paths<P>(
|
pub fn op_require_node_module_paths<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -295,7 +295,7 @@ pub fn op_require_path_is_absolute(#[string] p: String) -> bool {
|
||||||
PathBuf::from(p).is_absolute()
|
PathBuf::from(p).is_absolute()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_require_stat<P>(
|
pub fn op_require_stat<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
|
@ -317,7 +317,7 @@ where
|
||||||
Ok(-1)
|
Ok(-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
pub fn op_require_real_path<P>(
|
pub fn op_require_real_path<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -381,7 +381,7 @@ pub fn op_require_path_basename(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
pub fn op_require_try_self_parent_path<P>(
|
pub fn op_require_try_self_parent_path<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -412,7 +412,7 @@ where
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
pub fn op_require_try_self<P>(
|
pub fn op_require_try_self<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -476,7 +476,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
pub fn op_require_read_file<P>(
|
pub fn op_require_read_file<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -507,7 +507,7 @@ pub fn op_require_as_file_path(#[string] file_or_url: String) -> String {
|
||||||
file_or_url
|
file_or_url
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
pub fn op_require_resolve_exports<P>(
|
pub fn op_require_resolve_exports<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -583,7 +583,7 @@ pub fn op_require_is_maybe_cjs(
|
||||||
loader.is_maybe_cjs(&url)
|
loader.is_maybe_cjs(&url)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_require_read_package_scope<P>(
|
pub fn op_require_read_package_scope<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -604,7 +604,7 @@ where
|
||||||
.flatten()
|
.flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
pub fn op_require_package_imports_resolve<P>(
|
pub fn op_require_package_imports_resolve<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
|
|
@ -45,7 +45,7 @@ pub enum WorkerThreadsFilenameError {
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo(dsherret): we should remove this and do all this work inside op_create_worker
|
// todo(dsherret): we should remove this and do all this work inside op_create_worker
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
pub fn op_worker_threads_filename<P>(
|
pub fn op_worker_threads_filename<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_tls"
|
name = "deno_tls"
|
||||||
version = "0.164.0"
|
version = "0.165.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_url"
|
name = "deno_url"
|
||||||
version = "0.177.0"
|
version = "0.178.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_web"
|
name = "deno_web"
|
||||||
version = "0.208.0"
|
version = "0.209.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_webgpu"
|
name = "deno_webgpu"
|
||||||
version = "0.144.0"
|
version = "0.145.0"
|
||||||
authors = ["the Deno authors"]
|
authors = ["the Deno authors"]
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_webidl"
|
name = "deno_webidl"
|
||||||
version = "0.177.0"
|
version = "0.178.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_websocket"
|
name = "deno_websocket"
|
||||||
version = "0.182.0"
|
version = "0.183.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -148,7 +148,7 @@ impl Resource for WsCancelResource {
|
||||||
// This op is needed because creating a WS instance in JavaScript is a sync
|
// This op is needed because creating a WS instance in JavaScript is a sync
|
||||||
// operation and should throw error when permissions are not fulfilled,
|
// operation and should throw error when permissions are not fulfilled,
|
||||||
// but actual op that connects WS is async.
|
// but actual op that connects WS is async.
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[smi]
|
#[smi]
|
||||||
pub fn op_ws_check_permission_and_cancel_handle<WP>(
|
pub fn op_ws_check_permission_and_cancel_handle<WP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -443,7 +443,7 @@ fn populate_common_request_headers(
|
||||||
Ok(request)
|
Ok(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(async)]
|
#[op2(async, stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub async fn op_ws_create<WP>(
|
pub async fn op_ws_create<WP>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_webstorage"
|
name = "deno_webstorage"
|
||||||
version = "0.172.0"
|
version = "0.173.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_resolver"
|
name = "deno_resolver"
|
||||||
version = "0.9.0"
|
version = "0.10.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
@ -25,6 +25,7 @@ deno_package_json.features = ["sync"]
|
||||||
deno_path_util.workspace = true
|
deno_path_util.workspace = true
|
||||||
deno_semver.workspace = true
|
deno_semver.workspace = true
|
||||||
node_resolver.workspace = true
|
node_resolver.workspace = true
|
||||||
|
node_resolver.features = ["sync"]
|
||||||
thiserror.workspace = true
|
thiserror.workspace = true
|
||||||
url.workspace = true
|
url.workspace = true
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "node_resolver"
|
name = "node_resolver"
|
||||||
version = "0.16.0"
|
version = "0.17.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_runtime"
|
name = "deno_runtime"
|
||||||
version = "0.186.0"
|
version = "0.187.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -162,7 +162,7 @@ fn start_watcher(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[smi]
|
#[smi]
|
||||||
fn op_fs_events_open(
|
fn op_fs_events_open(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
|
|
@ -87,7 +87,7 @@ pub enum OsError {
|
||||||
Io(#[from] std::io::Error),
|
Io(#[from] std::io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
fn op_exec_path(state: &mut OpState) -> Result<String, OsError> {
|
fn op_exec_path(state: &mut OpState) -> Result<String, OsError> {
|
||||||
let current_exe = env::current_exe().unwrap();
|
let current_exe = env::current_exe().unwrap();
|
||||||
|
@ -103,7 +103,7 @@ fn op_exec_path(state: &mut OpState) -> Result<String, OsError> {
|
||||||
.map_err(OsError::InvalidUtf8)
|
.map_err(OsError::InvalidUtf8)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
fn op_set_env(
|
fn op_set_env(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] key: &str,
|
#[string] key: &str,
|
||||||
|
@ -123,7 +123,7 @@ fn op_set_env(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
fn op_env(
|
fn op_env(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -132,7 +132,7 @@ fn op_env(
|
||||||
Ok(env::vars().collect())
|
Ok(env::vars().collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
fn op_get_env(
|
fn op_get_env(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -159,7 +159,7 @@ fn op_get_env(
|
||||||
Ok(r)
|
Ok(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
fn op_delete_env(
|
fn op_delete_env(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] key: String,
|
#[string] key: String,
|
||||||
|
@ -189,7 +189,7 @@ fn op_exit(state: &mut OpState) {
|
||||||
crate::exit(code)
|
crate::exit(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
fn op_loadavg(
|
fn op_loadavg(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -200,7 +200,7 @@ fn op_loadavg(
|
||||||
Ok(sys_info::loadavg())
|
Ok(sys_info::loadavg())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace, stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
fn op_hostname(
|
fn op_hostname(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -211,7 +211,7 @@ fn op_hostname(
|
||||||
Ok(sys_info::hostname())
|
Ok(sys_info::hostname())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[string]
|
#[string]
|
||||||
fn op_os_release(
|
fn op_os_release(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -222,7 +222,7 @@ fn op_os_release(
|
||||||
Ok(sys_info::os_release())
|
Ok(sys_info::os_release())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
fn op_network_interfaces(
|
fn op_network_interfaces(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -274,7 +274,7 @@ impl From<netif::Interface> for NetworkInterface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
fn op_system_memory_info(
|
fn op_system_memory_info(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -286,7 +286,7 @@ fn op_system_memory_info(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[smi]
|
#[smi]
|
||||||
fn op_gid(
|
fn op_gid(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -302,7 +302,7 @@ fn op_gid(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[smi]
|
#[smi]
|
||||||
fn op_gid(
|
fn op_gid(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -314,7 +314,7 @@ fn op_gid(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[smi]
|
#[smi]
|
||||||
fn op_uid(
|
fn op_uid(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -330,7 +330,7 @@ fn op_uid(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[smi]
|
#[smi]
|
||||||
fn op_uid(
|
fn op_uid(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -519,7 +519,7 @@ fn os_uptime(state: &mut OpState) -> Result<u64, deno_core::error::AnyError> {
|
||||||
Ok(sys_info::os_uptime())
|
Ok(sys_info::os_uptime())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
#[number]
|
#[number]
|
||||||
fn op_os_uptime(
|
fn op_os_uptime(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
|
|
@ -99,7 +99,7 @@ pub fn op_revoke_permission(
|
||||||
Ok(PermissionStatus::from(perm))
|
Ok(PermissionStatus::from(perm))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_request_permission(
|
pub fn op_request_permission(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
|
|
@ -802,7 +802,7 @@ fn get_requires_allow_all_env_vars(env: &RunEnv) -> Vec<&str> {
|
||||||
found_envs
|
found_envs
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
fn op_spawn_child(
|
fn op_spawn_child(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -844,7 +844,7 @@ async fn op_spawn_wait(
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
fn op_spawn_sync(
|
fn op_spawn_sync(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -928,7 +928,7 @@ mod deprecated {
|
||||||
stderr_rid: Option<ResourceId>,
|
stderr_rid: Option<ResourceId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_run(
|
pub fn op_run(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -1129,7 +1129,7 @@ mod deprecated {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast, stack_trace)]
|
||||||
pub fn op_kill(
|
pub fn op_kill(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[smi] pid: i32,
|
#[smi] pid: i32,
|
||||||
|
|
|
@ -133,7 +133,7 @@ pub enum CreateWorkerError {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create worker as the host
|
/// Create worker as the host
|
||||||
#[op2]
|
#[op2(stack_trace)]
|
||||||
#[serde]
|
#[serde]
|
||||||
fn op_create_worker(
|
fn op_create_worker(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "deno_permissions"
|
name = "deno_permissions"
|
||||||
version = "0.37.0"
|
version = "0.38.0"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
|
@ -294,7 +294,7 @@ impl UnitPermission {
|
||||||
/// A normalized environment variable name. On Windows this will
|
/// A normalized environment variable name. On Windows this will
|
||||||
/// be uppercase and on other platforms it will stay as-is.
|
/// be uppercase and on other platforms it will stay as-is.
|
||||||
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
||||||
struct EnvVarName {
|
pub struct EnvVarName {
|
||||||
inner: String,
|
inner: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1114,15 +1114,37 @@ impl ImportDescriptor {
|
||||||
pub struct EnvDescriptorParseError;
|
pub struct EnvDescriptorParseError;
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
||||||
pub struct EnvDescriptor(EnvVarName);
|
pub enum EnvDescriptor {
|
||||||
|
Name(EnvVarName),
|
||||||
|
PrefixPattern(EnvVarName),
|
||||||
|
}
|
||||||
|
|
||||||
impl EnvDescriptor {
|
impl EnvDescriptor {
|
||||||
pub fn new(env: impl AsRef<str>) -> Self {
|
pub fn new(env: impl AsRef<str>) -> Self {
|
||||||
Self(EnvVarName::new(env))
|
if let Some(prefix_pattern) = env.as_ref().strip_suffix('*') {
|
||||||
|
Self::PrefixPattern(EnvVarName::new(prefix_pattern))
|
||||||
|
} else {
|
||||||
|
Self::Name(EnvVarName::new(env))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl QueryDescriptor for EnvDescriptor {
|
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
||||||
|
enum EnvQueryDescriptorInner {
|
||||||
|
Name(EnvVarName),
|
||||||
|
PrefixPattern(EnvVarName),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
||||||
|
pub struct EnvQueryDescriptor(EnvQueryDescriptorInner);
|
||||||
|
|
||||||
|
impl EnvQueryDescriptor {
|
||||||
|
pub fn new(env: impl AsRef<str>) -> Self {
|
||||||
|
Self(EnvQueryDescriptorInner::Name(EnvVarName::new(env)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QueryDescriptor for EnvQueryDescriptor {
|
||||||
type AllowDesc = EnvDescriptor;
|
type AllowDesc = EnvDescriptor;
|
||||||
type DenyDesc = EnvDescriptor;
|
type DenyDesc = EnvDescriptor;
|
||||||
|
|
||||||
|
@ -1131,19 +1153,45 @@ impl QueryDescriptor for EnvDescriptor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn display_name(&self) -> Cow<str> {
|
fn display_name(&self) -> Cow<str> {
|
||||||
Cow::from(self.0.as_ref())
|
Cow::from(match &self.0 {
|
||||||
|
EnvQueryDescriptorInner::Name(env_var_name) => env_var_name.as_ref(),
|
||||||
|
EnvQueryDescriptorInner::PrefixPattern(env_var_name) => {
|
||||||
|
env_var_name.as_ref()
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_allow(allow: &Self::AllowDesc) -> Self {
|
fn from_allow(allow: &Self::AllowDesc) -> Self {
|
||||||
allow.clone()
|
match allow {
|
||||||
|
Self::AllowDesc::Name(s) => {
|
||||||
|
Self(EnvQueryDescriptorInner::Name(s.clone()))
|
||||||
|
}
|
||||||
|
Self::AllowDesc::PrefixPattern(s) => {
|
||||||
|
Self(EnvQueryDescriptorInner::PrefixPattern(s.clone()))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_allow(&self) -> Option<Self::AllowDesc> {
|
fn as_allow(&self) -> Option<Self::AllowDesc> {
|
||||||
Some(self.clone())
|
Some(match &self.0 {
|
||||||
|
EnvQueryDescriptorInner::Name(env_var_name) => {
|
||||||
|
Self::AllowDesc::Name(env_var_name.clone())
|
||||||
|
}
|
||||||
|
EnvQueryDescriptorInner::PrefixPattern(env_var_name) => {
|
||||||
|
Self::AllowDesc::PrefixPattern(env_var_name.clone())
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_deny(&self) -> Self::DenyDesc {
|
fn as_deny(&self) -> Self::DenyDesc {
|
||||||
self.clone()
|
match &self.0 {
|
||||||
|
EnvQueryDescriptorInner::Name(env_var_name) => {
|
||||||
|
Self::DenyDesc::Name(env_var_name.clone())
|
||||||
|
}
|
||||||
|
EnvQueryDescriptorInner::PrefixPattern(env_var_name) => {
|
||||||
|
Self::DenyDesc::PrefixPattern(env_var_name.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_in_permission(
|
fn check_in_permission(
|
||||||
|
@ -1156,19 +1204,79 @@ impl QueryDescriptor for EnvDescriptor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn matches_allow(&self, other: &Self::AllowDesc) -> bool {
|
fn matches_allow(&self, other: &Self::AllowDesc) -> bool {
|
||||||
self == other
|
match other {
|
||||||
|
Self::AllowDesc::Name(n) => match &self.0 {
|
||||||
|
EnvQueryDescriptorInner::Name(env_var_name) => n == env_var_name,
|
||||||
|
EnvQueryDescriptorInner::PrefixPattern(env_var_name) => {
|
||||||
|
env_var_name.as_ref().starts_with(n.as_ref())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Self::AllowDesc::PrefixPattern(p) => match &self.0 {
|
||||||
|
EnvQueryDescriptorInner::Name(env_var_name) => {
|
||||||
|
env_var_name.as_ref().starts_with(p.as_ref())
|
||||||
|
}
|
||||||
|
EnvQueryDescriptorInner::PrefixPattern(env_var_name) => {
|
||||||
|
env_var_name.as_ref().starts_with(p.as_ref())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn matches_deny(&self, other: &Self::DenyDesc) -> bool {
|
fn matches_deny(&self, other: &Self::DenyDesc) -> bool {
|
||||||
self == other
|
match other {
|
||||||
|
Self::AllowDesc::Name(n) => match &self.0 {
|
||||||
|
EnvQueryDescriptorInner::Name(env_var_name) => n == env_var_name,
|
||||||
|
EnvQueryDescriptorInner::PrefixPattern(env_var_name) => {
|
||||||
|
env_var_name.as_ref().starts_with(n.as_ref())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Self::AllowDesc::PrefixPattern(p) => match &self.0 {
|
||||||
|
EnvQueryDescriptorInner::Name(env_var_name) => {
|
||||||
|
env_var_name.as_ref().starts_with(p.as_ref())
|
||||||
|
}
|
||||||
|
EnvQueryDescriptorInner::PrefixPattern(env_var_name) => {
|
||||||
|
p == env_var_name
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn revokes(&self, other: &Self::AllowDesc) -> bool {
|
fn revokes(&self, other: &Self::AllowDesc) -> bool {
|
||||||
self == other
|
match other {
|
||||||
|
Self::AllowDesc::Name(n) => match &self.0 {
|
||||||
|
EnvQueryDescriptorInner::Name(env_var_name) => n == env_var_name,
|
||||||
|
EnvQueryDescriptorInner::PrefixPattern(env_var_name) => {
|
||||||
|
env_var_name.as_ref().starts_with(n.as_ref())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Self::AllowDesc::PrefixPattern(p) => match &self.0 {
|
||||||
|
EnvQueryDescriptorInner::Name(env_var_name) => {
|
||||||
|
env_var_name.as_ref().starts_with(p.as_ref())
|
||||||
|
}
|
||||||
|
EnvQueryDescriptorInner::PrefixPattern(env_var_name) => {
|
||||||
|
p == env_var_name
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stronger_than_deny(&self, other: &Self::DenyDesc) -> bool {
|
fn stronger_than_deny(&self, other: &Self::DenyDesc) -> bool {
|
||||||
self == other
|
match other {
|
||||||
|
Self::AllowDesc::Name(n) => match &self.0 {
|
||||||
|
EnvQueryDescriptorInner::Name(env_var_name) => n == env_var_name,
|
||||||
|
EnvQueryDescriptorInner::PrefixPattern(env_var_name) => {
|
||||||
|
env_var_name.as_ref().starts_with(n.as_ref())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Self::AllowDesc::PrefixPattern(p) => match &self.0 {
|
||||||
|
EnvQueryDescriptorInner::Name(env_var_name) => {
|
||||||
|
env_var_name.as_ref().starts_with(p.as_ref())
|
||||||
|
}
|
||||||
|
EnvQueryDescriptorInner::PrefixPattern(env_var_name) => {
|
||||||
|
p == env_var_name
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn overlaps_deny(&self, _other: &Self::DenyDesc) -> bool {
|
fn overlaps_deny(&self, _other: &Self::DenyDesc) -> bool {
|
||||||
|
@ -1176,9 +1284,14 @@ impl QueryDescriptor for EnvDescriptor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsRef<str> for EnvDescriptor {
|
impl AsRef<str> for EnvQueryDescriptor {
|
||||||
fn as_ref(&self) -> &str {
|
fn as_ref(&self) -> &str {
|
||||||
self.0.as_ref()
|
match &self.0 {
|
||||||
|
EnvQueryDescriptorInner::Name(env_var_name) => env_var_name.as_ref(),
|
||||||
|
EnvQueryDescriptorInner::PrefixPattern(env_var_name) => {
|
||||||
|
env_var_name.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1749,20 +1862,20 @@ impl UnaryPermission<ImportDescriptor> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UnaryPermission<EnvDescriptor> {
|
impl UnaryPermission<EnvQueryDescriptor> {
|
||||||
pub fn query(&self, env: Option<&str>) -> PermissionState {
|
pub fn query(&self, env: Option<&str>) -> PermissionState {
|
||||||
self.query_desc(
|
self.query_desc(
|
||||||
env.map(EnvDescriptor::new).as_ref(),
|
env.map(EnvQueryDescriptor::new).as_ref(),
|
||||||
AllowPartial::TreatAsPartialGranted,
|
AllowPartial::TreatAsPartialGranted,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn request(&mut self, env: Option<&str>) -> PermissionState {
|
pub fn request(&mut self, env: Option<&str>) -> PermissionState {
|
||||||
self.request_desc(env.map(EnvDescriptor::new).as_ref())
|
self.request_desc(env.map(EnvQueryDescriptor::new).as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn revoke(&mut self, env: Option<&str>) -> PermissionState {
|
pub fn revoke(&mut self, env: Option<&str>) -> PermissionState {
|
||||||
self.revoke_desc(env.map(EnvDescriptor::new).as_ref())
|
self.revoke_desc(env.map(EnvQueryDescriptor::new).as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check(
|
pub fn check(
|
||||||
|
@ -1771,7 +1884,7 @@ impl UnaryPermission<EnvDescriptor> {
|
||||||
api_name: Option<&str>,
|
api_name: Option<&str>,
|
||||||
) -> Result<(), PermissionDeniedError> {
|
) -> Result<(), PermissionDeniedError> {
|
||||||
skip_check_if_is_permission_fully_granted!(self);
|
skip_check_if_is_permission_fully_granted!(self);
|
||||||
self.check_desc(Some(&EnvDescriptor::new(env)), false, api_name)
|
self.check_desc(Some(&EnvQueryDescriptor::new(env)), false, api_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_all(&mut self) -> Result<(), PermissionDeniedError> {
|
pub fn check_all(&mut self) -> Result<(), PermissionDeniedError> {
|
||||||
|
@ -1905,7 +2018,7 @@ pub struct Permissions {
|
||||||
pub read: UnaryPermission<ReadQueryDescriptor>,
|
pub read: UnaryPermission<ReadQueryDescriptor>,
|
||||||
pub write: UnaryPermission<WriteQueryDescriptor>,
|
pub write: UnaryPermission<WriteQueryDescriptor>,
|
||||||
pub net: UnaryPermission<NetDescriptor>,
|
pub net: UnaryPermission<NetDescriptor>,
|
||||||
pub env: UnaryPermission<EnvDescriptor>,
|
pub env: UnaryPermission<EnvQueryDescriptor>,
|
||||||
pub sys: UnaryPermission<SysDescriptor>,
|
pub sys: UnaryPermission<SysDescriptor>,
|
||||||
pub run: UnaryPermission<RunQueryDescriptor>,
|
pub run: UnaryPermission<RunQueryDescriptor>,
|
||||||
pub ffi: UnaryPermission<FfiQueryDescriptor>,
|
pub ffi: UnaryPermission<FfiQueryDescriptor>,
|
||||||
|
@ -4564,6 +4677,56 @@ mod tests {
|
||||||
assert_eq!(perms.env.revoke(Some("HomE")), PermissionState::Prompt);
|
assert_eq!(perms.env.revoke(Some("HomE")), PermissionState::Prompt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_env_wildcards() {
|
||||||
|
set_prompter(Box::new(TestPrompter));
|
||||||
|
let _prompt_value = PERMISSION_PROMPT_STUB_VALUE_SETTER.lock();
|
||||||
|
let mut perms = Permissions::allow_all();
|
||||||
|
perms.env = UnaryPermission {
|
||||||
|
granted_global: false,
|
||||||
|
..Permissions::new_unary(
|
||||||
|
Some(HashSet::from([EnvDescriptor::new("HOME_*")])),
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
assert_eq!(perms.env.query(Some("HOME")), PermissionState::Prompt);
|
||||||
|
assert_eq!(perms.env.query(Some("HOME_")), PermissionState::Granted);
|
||||||
|
assert_eq!(perms.env.query(Some("HOME_TEST")), PermissionState::Granted);
|
||||||
|
|
||||||
|
// assert no privilege escalation
|
||||||
|
let parser = TestPermissionDescriptorParser;
|
||||||
|
assert!(perms
|
||||||
|
.env
|
||||||
|
.create_child_permissions(
|
||||||
|
ChildUnaryPermissionArg::GrantedList(vec!["HOME_SUB".to_string()]),
|
||||||
|
|value| parser.parse_env_descriptor(value).map(Some),
|
||||||
|
)
|
||||||
|
.is_ok());
|
||||||
|
assert!(perms
|
||||||
|
.env
|
||||||
|
.create_child_permissions(
|
||||||
|
ChildUnaryPermissionArg::GrantedList(vec!["HOME*".to_string()]),
|
||||||
|
|value| parser.parse_env_descriptor(value).map(Some),
|
||||||
|
)
|
||||||
|
.is_err());
|
||||||
|
assert!(perms
|
||||||
|
.env
|
||||||
|
.create_child_permissions(
|
||||||
|
ChildUnaryPermissionArg::GrantedList(vec!["OUTSIDE".to_string()]),
|
||||||
|
|value| parser.parse_env_descriptor(value).map(Some),
|
||||||
|
)
|
||||||
|
.is_err());
|
||||||
|
assert!(perms
|
||||||
|
.env
|
||||||
|
.create_child_permissions(
|
||||||
|
// ok because this is a subset of HOME_*
|
||||||
|
ChildUnaryPermissionArg::GrantedList(vec!["HOME_S*".to_string()]),
|
||||||
|
|value| parser.parse_env_descriptor(value).map(Some),
|
||||||
|
)
|
||||||
|
.is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_check_partial_denied() {
|
fn test_check_partial_denied() {
|
||||||
let parser = TestPermissionDescriptorParser;
|
let parser = TestPermissionDescriptorParser;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
use crate::is_standalone;
|
||||||
|
use deno_core::error::JsStackFrame;
|
||||||
use deno_core::parking_lot::Mutex;
|
use deno_core::parking_lot::Mutex;
|
||||||
use deno_terminal::colors;
|
use deno_terminal::colors;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
@ -10,8 +12,6 @@ use std::io::StderrLock;
|
||||||
use std::io::StdinLock;
|
use std::io::StdinLock;
|
||||||
use std::io::Write as IoWrite;
|
use std::io::Write as IoWrite;
|
||||||
|
|
||||||
use crate::is_standalone;
|
|
||||||
|
|
||||||
/// Helper function to make control characters visible so users can see the underlying filename.
|
/// Helper function to make control characters visible so users can see the underlying filename.
|
||||||
fn escape_control_characters(s: &str) -> std::borrow::Cow<str> {
|
fn escape_control_characters(s: &str) -> std::borrow::Cow<str> {
|
||||||
if !s.contains(|c: char| c.is_ascii_control() || c.is_control()) {
|
if !s.contains(|c: char| c.is_ascii_control() || c.is_control()) {
|
||||||
|
@ -53,6 +53,13 @@ static MAYBE_BEFORE_PROMPT_CALLBACK: Lazy<Mutex<Option<PromptCallback>>> =
|
||||||
static MAYBE_AFTER_PROMPT_CALLBACK: Lazy<Mutex<Option<PromptCallback>>> =
|
static MAYBE_AFTER_PROMPT_CALLBACK: Lazy<Mutex<Option<PromptCallback>>> =
|
||||||
Lazy::new(|| Mutex::new(None));
|
Lazy::new(|| Mutex::new(None));
|
||||||
|
|
||||||
|
static MAYBE_CURRENT_STACKTRACE: Lazy<Mutex<Option<Vec<JsStackFrame>>>> =
|
||||||
|
Lazy::new(|| Mutex::new(None));
|
||||||
|
|
||||||
|
pub fn set_current_stacktrace(trace: Vec<JsStackFrame>) {
|
||||||
|
*MAYBE_CURRENT_STACKTRACE.lock() = Some(trace);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn permission_prompt(
|
pub fn permission_prompt(
|
||||||
message: &str,
|
message: &str,
|
||||||
flag: &str,
|
flag: &str,
|
||||||
|
@ -62,9 +69,10 @@ pub fn permission_prompt(
|
||||||
if let Some(before_callback) = MAYBE_BEFORE_PROMPT_CALLBACK.lock().as_mut() {
|
if let Some(before_callback) = MAYBE_BEFORE_PROMPT_CALLBACK.lock().as_mut() {
|
||||||
before_callback();
|
before_callback();
|
||||||
}
|
}
|
||||||
|
let stack = MAYBE_CURRENT_STACKTRACE.lock().take();
|
||||||
let r = PERMISSION_PROMPTER
|
let r = PERMISSION_PROMPTER
|
||||||
.lock()
|
.lock()
|
||||||
.prompt(message, flag, api_name, is_unary);
|
.prompt(message, flag, api_name, is_unary, stack);
|
||||||
if let Some(after_callback) = MAYBE_AFTER_PROMPT_CALLBACK.lock().as_mut() {
|
if let Some(after_callback) = MAYBE_AFTER_PROMPT_CALLBACK.lock().as_mut() {
|
||||||
after_callback();
|
after_callback();
|
||||||
}
|
}
|
||||||
|
@ -92,6 +100,7 @@ pub trait PermissionPrompter: Send + Sync {
|
||||||
name: &str,
|
name: &str,
|
||||||
api_name: Option<&str>,
|
api_name: Option<&str>,
|
||||||
is_unary: bool,
|
is_unary: bool,
|
||||||
|
stack: Option<Vec<JsStackFrame>>,
|
||||||
) -> PromptResponse;
|
) -> PromptResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,6 +307,7 @@ impl PermissionPrompter for TtyPrompter {
|
||||||
name: &str,
|
name: &str,
|
||||||
api_name: Option<&str>,
|
api_name: Option<&str>,
|
||||||
is_unary: bool,
|
is_unary: bool,
|
||||||
|
stack: Option<Vec<JsStackFrame>>,
|
||||||
) -> PromptResponse {
|
) -> PromptResponse {
|
||||||
if !std::io::stdin().is_terminal() || !std::io::stderr().is_terminal() {
|
if !std::io::stdin().is_terminal() || !std::io::stderr().is_terminal() {
|
||||||
return PromptResponse::Deny;
|
return PromptResponse::Deny;
|
||||||
|
@ -340,7 +350,7 @@ impl PermissionPrompter for TtyPrompter {
|
||||||
};
|
};
|
||||||
|
|
||||||
// output everything in one shot to make the tests more reliable
|
// output everything in one shot to make the tests more reliable
|
||||||
{
|
let stack_lines_count = {
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
write!(&mut output, "┏ {PERMISSION_EMOJI} ").unwrap();
|
write!(&mut output, "┏ {PERMISSION_EMOJI} ").unwrap();
|
||||||
write!(&mut output, "{}", colors::bold("Deno requests ")).unwrap();
|
write!(&mut output, "{}", colors::bold("Deno requests ")).unwrap();
|
||||||
|
@ -354,6 +364,27 @@ impl PermissionPrompter for TtyPrompter {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
let stack_lines_count = if let Some(stack) = stack {
|
||||||
|
let len = stack.len();
|
||||||
|
for (idx, frame) in stack.into_iter().enumerate() {
|
||||||
|
writeln!(
|
||||||
|
&mut output,
|
||||||
|
"┃ {} {}",
|
||||||
|
colors::gray(if idx != len - 1 { "├─" } else { "└─" }),
|
||||||
|
colors::gray(deno_core::error::format_frame::<
|
||||||
|
deno_core::error::NoAnsiColors,
|
||||||
|
>(&frame))
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
len
|
||||||
|
} else {
|
||||||
|
writeln!(
|
||||||
|
&mut output,
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.",
|
||||||
|
).unwrap();
|
||||||
|
1
|
||||||
|
};
|
||||||
let msg = format!(
|
let msg = format!(
|
||||||
"Learn more at: {}",
|
"Learn more at: {}",
|
||||||
colors::cyan_with_underline(&format!(
|
colors::cyan_with_underline(&format!(
|
||||||
|
@ -372,7 +403,9 @@ impl PermissionPrompter for TtyPrompter {
|
||||||
write!(&mut output, " {opts} > ").unwrap();
|
write!(&mut output, " {opts} > ").unwrap();
|
||||||
|
|
||||||
stderr_lock.write_all(output.as_bytes()).unwrap();
|
stderr_lock.write_all(output.as_bytes()).unwrap();
|
||||||
}
|
|
||||||
|
stack_lines_count
|
||||||
|
};
|
||||||
|
|
||||||
let value = loop {
|
let value = loop {
|
||||||
// Clear stdin each time we loop around in case the user accidentally pasted
|
// Clear stdin each time we loop around in case the user accidentally pasted
|
||||||
|
@ -391,30 +424,24 @@ impl PermissionPrompter for TtyPrompter {
|
||||||
if result.is_err() || input.len() != 1 {
|
if result.is_err() || input.len() != 1 {
|
||||||
break PromptResponse::Deny;
|
break PromptResponse::Deny;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let clear_n = if api_name.is_some() { 5 } else { 4 } + stack_lines_count;
|
||||||
|
|
||||||
match input.as_bytes()[0] as char {
|
match input.as_bytes()[0] as char {
|
||||||
'y' | 'Y' => {
|
'y' | 'Y' => {
|
||||||
clear_n_lines(
|
clear_n_lines(&mut stderr_lock, clear_n);
|
||||||
&mut stderr_lock,
|
|
||||||
if api_name.is_some() { 5 } else { 4 },
|
|
||||||
);
|
|
||||||
let msg = format!("Granted {message}.");
|
let msg = format!("Granted {message}.");
|
||||||
writeln!(stderr_lock, "✅ {}", colors::bold(&msg)).unwrap();
|
writeln!(stderr_lock, "✅ {}", colors::bold(&msg)).unwrap();
|
||||||
break PromptResponse::Allow;
|
break PromptResponse::Allow;
|
||||||
}
|
}
|
||||||
'n' | 'N' | '\x1b' => {
|
'n' | 'N' | '\x1b' => {
|
||||||
clear_n_lines(
|
clear_n_lines(&mut stderr_lock, clear_n);
|
||||||
&mut stderr_lock,
|
|
||||||
if api_name.is_some() { 5 } else { 4 },
|
|
||||||
);
|
|
||||||
let msg = format!("Denied {message}.");
|
let msg = format!("Denied {message}.");
|
||||||
writeln!(stderr_lock, "❌ {}", colors::bold(&msg)).unwrap();
|
writeln!(stderr_lock, "❌ {}", colors::bold(&msg)).unwrap();
|
||||||
break PromptResponse::Deny;
|
break PromptResponse::Deny;
|
||||||
}
|
}
|
||||||
'A' if is_unary => {
|
'A' if is_unary => {
|
||||||
clear_n_lines(
|
clear_n_lines(&mut stderr_lock, clear_n);
|
||||||
&mut stderr_lock,
|
|
||||||
if api_name.is_some() { 5 } else { 4 },
|
|
||||||
);
|
|
||||||
let msg = format!("Granted all {name} access.");
|
let msg = format!("Granted all {name} access.");
|
||||||
writeln!(stderr_lock, "✅ {}", colors::bold(&msg)).unwrap();
|
writeln!(stderr_lock, "✅ {}", colors::bold(&msg)).unwrap();
|
||||||
break PromptResponse::AllowAll;
|
break PromptResponse::AllowAll;
|
||||||
|
@ -475,6 +502,7 @@ pub mod tests {
|
||||||
_name: &str,
|
_name: &str,
|
||||||
_api_name: Option<&str>,
|
_api_name: Option<&str>,
|
||||||
_is_unary: bool,
|
_is_unary: bool,
|
||||||
|
_stack: Option<Vec<JsStackFrame>>,
|
||||||
) -> PromptResponse {
|
) -> PromptResponse {
|
||||||
if STUB_PROMPT_VALUE.load(Ordering::SeqCst) {
|
if STUB_PROMPT_VALUE.load(Ordering::SeqCst) {
|
||||||
PromptResponse::Allow
|
PromptResponse::Allow
|
||||||
|
|
|
@ -373,6 +373,7 @@ pub struct WebWorkerOptions {
|
||||||
pub strace_ops: Option<Vec<String>>,
|
pub strace_ops: Option<Vec<String>>,
|
||||||
pub close_on_idle: bool,
|
pub close_on_idle: bool,
|
||||||
pub maybe_worker_metadata: Option<WorkerMetadata>,
|
pub maybe_worker_metadata: Option<WorkerMetadata>,
|
||||||
|
pub enable_stack_trace_arg_in_ops: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This struct is an implementation of `Worker` Web API
|
/// This struct is an implementation of `Worker` Web API
|
||||||
|
@ -585,6 +586,13 @@ impl WebWorker {
|
||||||
validate_import_attributes_callback,
|
validate_import_attributes_callback,
|
||||||
)),
|
)),
|
||||||
import_assertions_support: deno_core::ImportAssertionsSupport::Error,
|
import_assertions_support: deno_core::ImportAssertionsSupport::Error,
|
||||||
|
maybe_op_stack_trace_callback: if options.enable_stack_trace_arg_in_ops {
|
||||||
|
Some(Box::new(|stack| {
|
||||||
|
deno_permissions::prompter::set_current_stacktrace(stack)
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -207,6 +207,7 @@ pub struct WorkerOptions {
|
||||||
pub cache_storage_dir: Option<std::path::PathBuf>,
|
pub cache_storage_dir: Option<std::path::PathBuf>,
|
||||||
pub origin_storage_dir: Option<std::path::PathBuf>,
|
pub origin_storage_dir: Option<std::path::PathBuf>,
|
||||||
pub stdio: Stdio,
|
pub stdio: Stdio,
|
||||||
|
pub enable_stack_trace_arg_in_ops: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for WorkerOptions {
|
impl Default for WorkerOptions {
|
||||||
|
@ -231,6 +232,7 @@ impl Default for WorkerOptions {
|
||||||
create_params: Default::default(),
|
create_params: Default::default(),
|
||||||
bootstrap: Default::default(),
|
bootstrap: Default::default(),
|
||||||
stdio: Default::default(),
|
stdio: Default::default(),
|
||||||
|
enable_stack_trace_arg_in_ops: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -544,6 +546,11 @@ impl MainWorker {
|
||||||
) as Box<dyn Fn(_, _, &_)>,
|
) as Box<dyn Fn(_, _, &_)>,
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
maybe_op_stack_trace_callback: if options.enable_stack_trace_arg_in_ops {
|
||||||
|
Some(Box::new(|stack| {
|
||||||
|
deno_permissions::prompter::set_current_stacktrace(stack)
|
||||||
|
}))
|
||||||
|
} else { None },
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -179,6 +179,7 @@ fn _090_run_permissions_request() {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests run access to \"ls\".\r\n",
|
"┏ ⚠️ Deno requests run access to \"ls\".\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-run\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-run\r\n",
|
||||||
"┠─ Run again with --allow-run to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-run to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)",
|
||||||
|
@ -189,6 +190,7 @@ fn _090_run_permissions_request() {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests run access to \"cat\".\r\n",
|
"┏ ⚠️ Deno requests run access to \"cat\".\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-run\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-run\r\n",
|
||||||
"┠─ Run again with --allow-run to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-run to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)",
|
||||||
|
@ -210,6 +212,7 @@ fn _090_run_permissions_request_sync() {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests run access to \"ls\".\r\n",
|
"┏ ⚠️ Deno requests run access to \"ls\".\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-run\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-run\r\n",
|
||||||
"┠─ Run again with --allow-run to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-run to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)",
|
||||||
|
@ -220,6 +223,7 @@ fn _090_run_permissions_request_sync() {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests run access to \"cat\".\r\n",
|
"┏ ⚠️ Deno requests run access to \"cat\".\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-run\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-run\r\n",
|
||||||
"┠─ Run again with --allow-run to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-run to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)",
|
||||||
|
@ -242,6 +246,7 @@ fn permissions_prompt_allow_all() {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests run access to \"FOO\".\r\n",
|
"┏ ⚠️ Deno requests run access to \"FOO\".\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-run\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-run\r\n",
|
||||||
"┠─ Run again with --allow-run to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-run to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)",
|
||||||
|
@ -253,6 +258,7 @@ fn permissions_prompt_allow_all() {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests read access to \"FOO\".\r\n",
|
"┏ ⚠️ Deno requests read access to \"FOO\".\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-read\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-read\r\n",
|
||||||
"┠─ Run again with --allow-read to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-read to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
|
||||||
|
@ -264,6 +270,7 @@ fn permissions_prompt_allow_all() {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests write access to \"FOO\".\r\n",
|
"┏ ⚠️ Deno requests write access to \"FOO\".\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-write\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-write\r\n",
|
||||||
"┠─ Run again with --allow-write to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-write to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all write permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all write permissions)",
|
||||||
|
@ -275,6 +282,7 @@ fn permissions_prompt_allow_all() {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests net access to \"foo\".\r\n",
|
"┏ ⚠️ Deno requests net access to \"foo\".\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-net\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-net\r\n",
|
||||||
"┠─ Run again with --allow-net to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-net to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all net permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all net permissions)",
|
||||||
|
@ -286,6 +294,7 @@ fn permissions_prompt_allow_all() {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests env access to \"FOO\".\r\n",
|
"┏ ⚠️ Deno requests env access to \"FOO\".\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-env\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-env\r\n",
|
||||||
"┠─ Run again with --allow-env to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-env to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)",
|
||||||
|
@ -297,6 +306,7 @@ fn permissions_prompt_allow_all() {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests sys access to \"loadavg\".\r\n",
|
"┏ ⚠️ Deno requests sys access to \"loadavg\".\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-sys\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-sys\r\n",
|
||||||
"┠─ Run again with --allow-sys to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-sys to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all sys permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all sys permissions)",
|
||||||
|
@ -308,6 +318,7 @@ fn permissions_prompt_allow_all() {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests ffi access to \"FOO\".\r\n",
|
"┏ ⚠️ Deno requests ffi access to \"FOO\".\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-ffi\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-ffi\r\n",
|
||||||
"┠─ Run again with --allow-ffi to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-ffi to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all ffi permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all ffi permissions)",
|
||||||
|
@ -328,6 +339,7 @@ fn permissions_prompt_allow_all_2() {
|
||||||
// "env" permissions
|
// "env" permissions
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests env access to \"FOO\".\r\n",
|
"┏ ⚠️ Deno requests env access to \"FOO\".\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-env\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-env\r\n",
|
||||||
"┠─ Run again with --allow-env to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-env to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)",
|
||||||
|
@ -340,6 +352,7 @@ fn permissions_prompt_allow_all_2() {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests sys access to \"loadavg\".\r\n",
|
"┏ ⚠️ Deno requests sys access to \"loadavg\".\r\n",
|
||||||
"┠─ Requested by `Deno.loadavg()` API.\r\n",
|
"┠─ Requested by `Deno.loadavg()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-sys\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-sys\r\n",
|
||||||
"┠─ Run again with --allow-sys to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-sys to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all sys permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all sys permissions)",
|
||||||
|
@ -352,6 +365,7 @@ fn permissions_prompt_allow_all_2() {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests read access to <CWD>.\r\n",
|
"┏ ⚠️ Deno requests read access to <CWD>.\r\n",
|
||||||
"┠─ Requested by `Deno.cwd()` API.\r\n",
|
"┠─ Requested by `Deno.cwd()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-read\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-read\r\n",
|
||||||
"┠─ Run again with --allow-read to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-read to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
|
||||||
|
@ -372,6 +386,7 @@ fn permissions_prompt_allow_all_lowercase_a() {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests run access to \"FOO\".\r\n",
|
"┏ ⚠️ Deno requests run access to \"FOO\".\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-run\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-run\r\n",
|
||||||
"┠─ Run again with --allow-run to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-run to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)",
|
||||||
|
@ -406,6 +421,7 @@ fn permissions_cache() {
|
||||||
"prompt\r\n",
|
"prompt\r\n",
|
||||||
"┏ ⚠️ Deno requests read access to \"foo\".\r\n",
|
"┏ ⚠️ Deno requests read access to \"foo\".\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-read\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-read\r\n",
|
||||||
"┠─ Run again with --allow-read to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-read to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
|
||||||
|
@ -418,6 +434,32 @@ fn permissions_cache() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn permissions_trace() {
|
||||||
|
TestContext::default()
|
||||||
|
.new_command()
|
||||||
|
.env("DENO_TRACE_PERMISSIONS", "1")
|
||||||
|
.args_vec(["run", "--quiet", "run/permissions_trace.ts"])
|
||||||
|
.with_pty(|mut console| {
|
||||||
|
let text = console.read_until("Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all sys permissions)");
|
||||||
|
test_util::assertions::assert_wildcard_match(&text, concat!(
|
||||||
|
"┏ ⚠️ Deno requests sys access to \"hostname\".\r\n",
|
||||||
|
"┠─ Requested by `Deno.hostname()` API.\r\n",
|
||||||
|
"┃ ├─ Object.hostname (ext:runtime/30_os.js:43:10)\r\n",
|
||||||
|
"┃ ├─ foo (file://[WILDCARD]/run/permissions_trace.ts:2:8)\r\n",
|
||||||
|
"┃ ├─ bar (file://[WILDCARD]/run/permissions_trace.ts:6:3)\r\n",
|
||||||
|
"┃ └─ file://[WILDCARD]/run/permissions_trace.ts:9:1\r\n",
|
||||||
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-sys\r\n",
|
||||||
|
"┠─ Run again with --allow-sys to bypass this prompt.\r\n",
|
||||||
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all sys permissions)",
|
||||||
|
));
|
||||||
|
|
||||||
|
console.human_delay();
|
||||||
|
console.write_line_raw("y");
|
||||||
|
console.expect("✅ Granted sys access to \"hostname\".");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
itest!(lock_write_fetch {
|
itest!(lock_write_fetch {
|
||||||
args:
|
args:
|
||||||
"run --quiet --allow-import --allow-read --allow-write --allow-env --allow-run run/lock_write_fetch/main.ts",
|
"run --quiet --allow-import --allow-read --allow-write --allow-env --allow-run run/lock_write_fetch/main.ts",
|
||||||
|
@ -1512,6 +1554,7 @@ mod permissions {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests read access to \"foo\".\r\n",
|
"┏ ⚠️ Deno requests read access to \"foo\".\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-read\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-read\r\n",
|
||||||
"┠─ Run again with --allow-read to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-read to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
|
||||||
|
@ -1521,6 +1564,7 @@ mod permissions {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests read access to \"bar\".\r\n",
|
"┏ ⚠️ Deno requests read access to \"bar\".\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-read\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-read\r\n",
|
||||||
"┠─ Run again with --allow-read to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-read to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
|
||||||
|
@ -1542,6 +1586,7 @@ mod permissions {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests read access to \"foo\".\r\n",
|
"┏ ⚠️ Deno requests read access to \"foo\".\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-read\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-read\r\n",
|
||||||
"┠─ Run again with --allow-read to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-read to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
|
||||||
|
@ -1551,6 +1596,7 @@ mod permissions {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests read access to \"bar\".\r\n",
|
"┏ ⚠️ Deno requests read access to \"bar\".\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-read\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-read\r\n",
|
||||||
"┠─ Run again with --allow-read to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-read to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
|
||||||
|
@ -1572,6 +1618,7 @@ mod permissions {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests read access.\r\n",
|
"┏ ⚠️ Deno requests read access.\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-read\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-read\r\n",
|
||||||
"┠─ Run again with --allow-read to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-read to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
|
||||||
|
@ -1596,6 +1643,7 @@ mod permissions {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests read access.\r\n",
|
"┏ ⚠️ Deno requests read access.\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-read\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-read\r\n",
|
||||||
"┠─ Run again with --allow-read to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-read to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
|
||||||
|
@ -1673,6 +1721,7 @@ fn issue9750() {
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests env access.\r\n",
|
"┏ ⚠️ Deno requests env access.\r\n",
|
||||||
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
"┠─ Requested by `Deno.permissions.request()` API.\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-env\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-env\r\n",
|
||||||
"┠─ Run again with --allow-env to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-env to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)",
|
||||||
|
@ -1682,6 +1731,7 @@ fn issue9750() {
|
||||||
console.expect("Denied env access.");
|
console.expect("Denied env access.");
|
||||||
console.expect(concat!(
|
console.expect(concat!(
|
||||||
"┏ ⚠️ Deno requests env access to \"SECRET\".\r\n",
|
"┏ ⚠️ Deno requests env access to \"SECRET\".\r\n",
|
||||||
|
"┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.\r\n",
|
||||||
"┠─ Learn more at: https://docs.deno.com/go/--allow-env\r\n",
|
"┠─ Learn more at: https://docs.deno.com/go/--allow-env\r\n",
|
||||||
"┠─ Run again with --allow-env to bypass this prompt.\r\n",
|
"┠─ Run again with --allow-env to bypass this prompt.\r\n",
|
||||||
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)",
|
"┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)",
|
||||||
|
@ -2723,7 +2773,7 @@ fn stdio_streams_are_locked_in_permission_prompt() {
|
||||||
console.human_delay();
|
console.human_delay();
|
||||||
console.write_line_raw("y");
|
console.write_line_raw("y");
|
||||||
// We ensure that nothing gets written here between the permission prompt and this text, despire the delay
|
// We ensure that nothing gets written here between the permission prompt and this text, despire the delay
|
||||||
console.expect_raw_next(format!("y{newline}\x1b[5A\x1b[0J✅ Granted read access to \""));
|
console.expect_raw_next(format!("y{newline}\x1b[6A\x1b[0J✅ Granted read access to \""));
|
||||||
|
|
||||||
// Back to spamming!
|
// Back to spamming!
|
||||||
console.expect(malicious_output);
|
console.expect(malicious_output);
|
||||||
|
|
4
tests/registry/jsr/@denotest/add/0.2.1/mod.ts
Normal file
4
tests/registry/jsr/@denotest/add/0.2.1/mod.ts
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
// This is renamed to `add()` in 1.0.0.
|
||||||
|
export function sum(a: number, b: number): number {
|
||||||
|
return a + b;
|
||||||
|
}
|
8
tests/registry/jsr/@denotest/add/0.2.1_meta.json
Normal file
8
tests/registry/jsr/@denotest/add/0.2.1_meta.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"exports": {
|
||||||
|
".": "./mod.ts"
|
||||||
|
},
|
||||||
|
"moduleGraph1": {
|
||||||
|
"/mod.ts": {}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
"yanked": true
|
"yanked": true
|
||||||
},
|
},
|
||||||
"1.0.0": {},
|
"1.0.0": {},
|
||||||
"0.2.0": {}
|
"0.2.0": {},
|
||||||
|
"0.2.1": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "jsr:@denotest/add@1";
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"a": 1
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "jsr:@denotest/subtract@1";
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"exports": {
|
||||||
|
"./add": "./add.ts",
|
||||||
|
"./subtract": "./subtract.ts",
|
||||||
|
"./data-json": "./data.json"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "jsr:@denotest/add@1";
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"a": 1
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "jsr:@denotest/subtract@1";
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"exports": {
|
||||||
|
"./add": "./add.ts",
|
||||||
|
"./subtract": "./subtract.ts",
|
||||||
|
"./data-json": "./data.json"
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
{
|
{
|
||||||
"versions": {
|
"versions": {
|
||||||
"1.0.0": {}
|
"1.0.0": {},
|
||||||
|
"0.5.0": {},
|
||||||
|
"0.2.0": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
3
tests/registry/jsr/@denotest/subtract/0.2.0/mod.ts
Normal file
3
tests/registry/jsr/@denotest/subtract/0.2.0/mod.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export function sub(a: number, b: number): number {
|
||||||
|
return a - b;
|
||||||
|
}
|
8
tests/registry/jsr/@denotest/subtract/0.2.0_meta.json
Normal file
8
tests/registry/jsr/@denotest/subtract/0.2.0_meta.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"exports": {
|
||||||
|
".": "./mod.ts"
|
||||||
|
},
|
||||||
|
"moduleGraph1": {
|
||||||
|
"/mod.ts": {}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
{
|
{
|
||||||
|
"latest": "1.0.0",
|
||||||
"versions": {
|
"versions": {
|
||||||
"1.0.0": {}
|
"1.0.0": {},
|
||||||
|
"0.2.0": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"name": "@denotest/has-patch-versions",
|
||||||
|
"version": "0.1.0"
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"name": "@denotest/has-patch-versions",
|
||||||
|
"version": "0.1.1"
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"name": "@denotest/has-patch-versions",
|
||||||
|
"version": "0.2.0"
|
||||||
|
}
|
6
tests/specs/init/npm/__test__.jsonc
Normal file
6
tests/specs/init/npm/__test__.jsonc
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"tempDir": true,
|
||||||
|
"args": "init --npm vite my-project",
|
||||||
|
"output": "init.out",
|
||||||
|
"exitCode": 1
|
||||||
|
}
|
1
tests/specs/init/npm/init.out
Normal file
1
tests/specs/init/npm/init.out
Normal file
|
@ -0,0 +1 @@
|
||||||
|
You can initialize project manually by running deno run npm:create-vite my-project and applying desired permissions.
|
|
@ -61,5 +61,10 @@
|
||||||
"file_path": "[WILDCARD]malformed.js",
|
"file_path": "[WILDCARD]malformed.js",
|
||||||
"message": "Expected '{', got 'B' at [WILDCARD]malformed.js:4:16\n\n export class A B C\n ~"
|
"message": "Expected '{', got 'B' at [WILDCARD]malformed.js:4:16\n\n export class A B C\n ~"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"checked_files": [
|
||||||
|
"[WILDCARD]file1.js",
|
||||||
|
"[WILDCARD]file2.ts",
|
||||||
|
"[WILDCARD]malformed.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue