mirror of
https://github.com/denoland/deno.git
synced 2025-02-01 12:16:11 -05:00
refactor: update deno_core for error refactor (#26867)
Closes #26171 --------- Co-authored-by: David Sherret <dsherret@gmail.com>
This commit is contained in:
parent
814da49dff
commit
ea30e188a8
214 changed files with 3787 additions and 4210 deletions
157
Cargo.lock
generated
157
Cargo.lock
generated
|
@ -1275,7 +1275,7 @@ dependencies = [
|
||||||
"deno_npm",
|
"deno_npm",
|
||||||
"deno_npm_cache",
|
"deno_npm_cache",
|
||||||
"deno_package_json",
|
"deno_package_json",
|
||||||
"deno_path_util 0.3.0",
|
"deno_path_util",
|
||||||
"deno_resolver",
|
"deno_resolver",
|
||||||
"deno_runtime",
|
"deno_runtime",
|
||||||
"deno_semver",
|
"deno_semver",
|
||||||
|
@ -1434,6 +1434,7 @@ version = "0.178.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"thiserror 2.0.3",
|
"thiserror 2.0.3",
|
||||||
"tokio",
|
"tokio",
|
||||||
"uuid",
|
"uuid",
|
||||||
|
@ -1445,6 +1446,7 @@ version = "0.116.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
"serde",
|
"serde",
|
||||||
"sha2",
|
"sha2",
|
||||||
|
@ -1467,7 +1469,7 @@ dependencies = [
|
||||||
"data-url",
|
"data-url",
|
||||||
"deno_error",
|
"deno_error",
|
||||||
"deno_media_type",
|
"deno_media_type",
|
||||||
"deno_path_util 0.3.0",
|
"deno_path_util",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
"indexmap 2.3.0",
|
"indexmap 2.3.0",
|
||||||
"log",
|
"log",
|
||||||
|
@ -1486,6 +1488,7 @@ name = "deno_canvas"
|
||||||
version = "0.53.0"
|
version = "0.53.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"deno_webgpu",
|
"deno_webgpu",
|
||||||
"image",
|
"image",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -1494,13 +1497,14 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_config"
|
name = "deno_config"
|
||||||
version = "0.42.0"
|
version = "0.43.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b45aaf31e58ca915d5c0746bf8e2d07b94635154ad9e5afe5ff265cae6187b19"
|
checksum = "6c4c11bd51ef6738cabfc3c53f16c209a0b8615cb1e4e5bf3b14e3b5deebfe21"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"boxed_error",
|
||||||
|
"deno_error",
|
||||||
"deno_package_json",
|
"deno_package_json",
|
||||||
"deno_path_util 0.3.0",
|
"deno_path_util",
|
||||||
"deno_semver",
|
"deno_semver",
|
||||||
"glob",
|
"glob",
|
||||||
"ignore",
|
"ignore",
|
||||||
|
@ -1513,7 +1517,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sys_traits",
|
"sys_traits",
|
||||||
"thiserror 1.0.64",
|
"thiserror 2.0.3",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1526,9 +1530,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_core"
|
name = "deno_core"
|
||||||
version = "0.327.0"
|
version = "0.330.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eaf8dff204b9c2415deb47b9f30d4d38b0925d0d88f1f9074e8e76f59e6d7ded"
|
checksum = "fd38bbbd68ed873165ccb630322704b44140d3a8c8d50f898beac4d1a8a3358c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"az",
|
"az",
|
||||||
|
@ -1539,6 +1543,7 @@ dependencies = [
|
||||||
"capacity_builder 0.1.3",
|
"capacity_builder 0.1.3",
|
||||||
"cooked-waker",
|
"cooked-waker",
|
||||||
"deno_core_icudata",
|
"deno_core_icudata",
|
||||||
|
"deno_error",
|
||||||
"deno_ops",
|
"deno_ops",
|
||||||
"deno_unsync",
|
"deno_unsync",
|
||||||
"futures",
|
"futures",
|
||||||
|
@ -1554,6 +1559,7 @@ dependencies = [
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"sourcemap 8.0.1",
|
"sourcemap 8.0.1",
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
|
"thiserror 2.0.3",
|
||||||
"tokio",
|
"tokio",
|
||||||
"url",
|
"url",
|
||||||
"v8",
|
"v8",
|
||||||
|
@ -1574,6 +1580,7 @@ dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"chrono",
|
"chrono",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"saffron",
|
"saffron",
|
||||||
"thiserror 2.0.3",
|
"thiserror 2.0.3",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
@ -1592,6 +1599,7 @@ dependencies = [
|
||||||
"ctr",
|
"ctr",
|
||||||
"curve25519-dalek",
|
"curve25519-dalek",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"deno_web",
|
"deno_web",
|
||||||
"ed448-goldilocks",
|
"ed448-goldilocks",
|
||||||
"elliptic-curve",
|
"elliptic-curve",
|
||||||
|
@ -1618,16 +1626,17 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_doc"
|
name = "deno_doc"
|
||||||
version = "0.161.3"
|
version = "0.164.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "353a39c70d248af04600928cefc8066a9e4535fb6e7d7c518411e5efc822819f"
|
checksum = "ad1edb02603c7e8a4003c84af2482a05e5eda3a14f1af275434fda89223f054d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"comrak",
|
"comrak",
|
||||||
"deno_ast",
|
"deno_ast",
|
||||||
"deno_graph",
|
"deno_graph",
|
||||||
"deno_path_util 0.2.2",
|
"deno_path_util",
|
||||||
|
"deno_terminal 0.2.0",
|
||||||
"handlebars",
|
"handlebars",
|
||||||
"html-escape",
|
"html-escape",
|
||||||
"import_map",
|
"import_map",
|
||||||
|
@ -1647,22 +1656,23 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_error"
|
name = "deno_error"
|
||||||
version = "0.5.2"
|
version = "0.5.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "199c66ffd17ee1a948904d33f3d3f364573951c1f9fb3f859bfe7770bf33862a"
|
checksum = "c4da6a58de6932a96f84e133c072fd3b525966ee122a71f3efd48bbff2eed5ac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_error_macro",
|
"deno_error_macro",
|
||||||
"libc",
|
"libc",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"tokio",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_error_macro"
|
name = "deno_error_macro"
|
||||||
version = "0.5.2"
|
version = "0.5.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3cd99df6ae75443907e1f959fc42ec6dcea67a7bd083e76cf23a117102c9a2ce"
|
checksum = "46351dff93aed2039407c91e2ded2a5591e42d2795ab3d111288625bb710d3d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -1677,7 +1687,8 @@ dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"data-url",
|
"data-url",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
"deno_path_util 0.3.0",
|
"deno_error",
|
||||||
|
"deno_path_util",
|
||||||
"deno_permissions",
|
"deno_permissions",
|
||||||
"deno_tls",
|
"deno_tls",
|
||||||
"dyn-clone",
|
"dyn-clone",
|
||||||
|
@ -1710,6 +1721,7 @@ name = "deno_ffi"
|
||||||
version = "0.171.0"
|
version = "0.171.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"deno_permissions",
|
"deno_permissions",
|
||||||
"dlopen2",
|
"dlopen2",
|
||||||
"dynasmrt",
|
"dynasmrt",
|
||||||
|
@ -1733,8 +1745,9 @@ dependencies = [
|
||||||
"base32",
|
"base32",
|
||||||
"boxed_error",
|
"boxed_error",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"deno_io",
|
"deno_io",
|
||||||
"deno_path_util 0.3.0",
|
"deno_path_util",
|
||||||
"deno_permissions",
|
"deno_permissions",
|
||||||
"filetime",
|
"filetime",
|
||||||
"junction",
|
"junction",
|
||||||
|
@ -1750,17 +1763,17 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_graph"
|
name = "deno_graph"
|
||||||
version = "0.86.9"
|
version = "0.87.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fa96b7d353c0d36b108ec504272b148792f48dccaf29f302b39c46b43457bb94"
|
checksum = "f56d4eb4b7c81ae920b6d18c45a1866924f93110caee80bbbc362dc28143f2bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"capacity_builder 0.5.0",
|
"capacity_builder 0.5.0",
|
||||||
"data-url",
|
"data-url",
|
||||||
"deno_ast",
|
"deno_ast",
|
||||||
|
"deno_error",
|
||||||
"deno_media_type",
|
"deno_media_type",
|
||||||
"deno_path_util 0.3.0",
|
"deno_path_util",
|
||||||
"deno_semver",
|
"deno_semver",
|
||||||
"deno_unsync",
|
"deno_unsync",
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
|
@ -1794,6 +1807,7 @@ dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"cache_control",
|
"cache_control",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"deno_net",
|
"deno_net",
|
||||||
"deno_websocket",
|
"deno_websocket",
|
||||||
"flate2",
|
"flate2",
|
||||||
|
@ -1827,6 +1841,7 @@ version = "0.94.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"filetime",
|
"filetime",
|
||||||
"fs3",
|
"fs3",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -1853,8 +1868,9 @@ dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"chrono",
|
"chrono",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"deno_fetch",
|
"deno_fetch",
|
||||||
"deno_path_util 0.3.0",
|
"deno_path_util",
|
||||||
"deno_permissions",
|
"deno_permissions",
|
||||||
"deno_tls",
|
"deno_tls",
|
||||||
"denokv_proto",
|
"denokv_proto",
|
||||||
|
@ -1920,6 +1936,7 @@ name = "deno_napi"
|
||||||
version = "0.115.0"
|
version = "0.115.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"deno_permissions",
|
"deno_permissions",
|
||||||
"libc",
|
"libc",
|
||||||
"libloading 0.7.4",
|
"libloading 0.7.4",
|
||||||
|
@ -1948,6 +1965,7 @@ name = "deno_net"
|
||||||
version = "0.176.0"
|
version = "0.176.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"deno_permissions",
|
"deno_permissions",
|
||||||
"deno_tls",
|
"deno_tls",
|
||||||
"hickory-proto",
|
"hickory-proto",
|
||||||
|
@ -1977,13 +1995,14 @@ dependencies = [
|
||||||
"const-oid",
|
"const-oid",
|
||||||
"data-encoding",
|
"data-encoding",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"deno_fetch",
|
"deno_fetch",
|
||||||
"deno_fs",
|
"deno_fs",
|
||||||
"deno_io",
|
"deno_io",
|
||||||
"deno_media_type",
|
"deno_media_type",
|
||||||
"deno_net",
|
"deno_net",
|
||||||
"deno_package_json",
|
"deno_package_json",
|
||||||
"deno_path_util 0.3.0",
|
"deno_path_util",
|
||||||
"deno_permissions",
|
"deno_permissions",
|
||||||
"deno_whoami",
|
"deno_whoami",
|
||||||
"der",
|
"der",
|
||||||
|
@ -2085,7 +2104,7 @@ dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
"deno_error",
|
"deno_error",
|
||||||
"deno_npm",
|
"deno_npm",
|
||||||
"deno_path_util 0.3.0",
|
"deno_path_util",
|
||||||
"deno_semver",
|
"deno_semver",
|
||||||
"deno_unsync",
|
"deno_unsync",
|
||||||
"faster-hex",
|
"faster-hex",
|
||||||
|
@ -2107,10 +2126,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_ops"
|
name = "deno_ops"
|
||||||
version = "0.203.0"
|
version = "0.206.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b146ca74cac431843486ade58e2accc16c11315fb2c6934590a52a73c56b7ec3"
|
checksum = "4c25ffa9d088ea00748dbef870bba110ac22ebf8cf7b2e9eb288409c5d852af3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"indexmap 2.3.0",
|
||||||
"proc-macro-rules",
|
"proc-macro-rules",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2118,7 +2138,7 @@ dependencies = [
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
"syn 2.0.87",
|
"syn 2.0.87",
|
||||||
"thiserror 1.0.64",
|
"thiserror 2.0.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2129,7 +2149,7 @@ checksum = "e1d3c0f699ba2040669204ce24ab73720499fc290af843e4ce0fc8a9b3d67735"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"boxed_error",
|
"boxed_error",
|
||||||
"deno_error",
|
"deno_error",
|
||||||
"deno_path_util 0.3.0",
|
"deno_path_util",
|
||||||
"deno_semver",
|
"deno_semver",
|
||||||
"indexmap 2.3.0",
|
"indexmap 2.3.0",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -2139,18 +2159,6 @@ dependencies = [
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "deno_path_util"
|
|
||||||
version = "0.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b02c7d341e1b2cf089daff0f4fb2b4be8f3b5511b1d96040b3f7ed63a66c737b"
|
|
||||||
dependencies = [
|
|
||||||
"deno_error",
|
|
||||||
"percent-encoding",
|
|
||||||
"thiserror 2.0.3",
|
|
||||||
"url",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_path_util"
|
name = "deno_path_util"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
@ -2170,7 +2178,8 @@ version = "0.43.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"capacity_builder 0.5.0",
|
"capacity_builder 0.5.0",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
"deno_path_util 0.3.0",
|
"deno_error",
|
||||||
|
"deno_path_util",
|
||||||
"deno_terminal 0.2.0",
|
"deno_terminal 0.2.0",
|
||||||
"fqdn",
|
"fqdn",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -2192,9 +2201,10 @@ dependencies = [
|
||||||
"boxed_error",
|
"boxed_error",
|
||||||
"dashmap",
|
"dashmap",
|
||||||
"deno_config",
|
"deno_config",
|
||||||
|
"deno_error",
|
||||||
"deno_media_type",
|
"deno_media_type",
|
||||||
"deno_package_json",
|
"deno_package_json",
|
||||||
"deno_path_util 0.3.0",
|
"deno_path_util",
|
||||||
"deno_semver",
|
"deno_semver",
|
||||||
"node_resolver",
|
"node_resolver",
|
||||||
"sys_traits",
|
"sys_traits",
|
||||||
|
@ -2216,6 +2226,7 @@ dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
"deno_cron",
|
"deno_cron",
|
||||||
"deno_crypto",
|
"deno_crypto",
|
||||||
|
"deno_error",
|
||||||
"deno_fetch",
|
"deno_fetch",
|
||||||
"deno_ffi",
|
"deno_ffi",
|
||||||
"deno_fs",
|
"deno_fs",
|
||||||
|
@ -2225,7 +2236,7 @@ dependencies = [
|
||||||
"deno_napi",
|
"deno_napi",
|
||||||
"deno_net",
|
"deno_net",
|
||||||
"deno_node",
|
"deno_node",
|
||||||
"deno_path_util 0.3.0",
|
"deno_path_util",
|
||||||
"deno_permissions",
|
"deno_permissions",
|
||||||
"deno_telemetry",
|
"deno_telemetry",
|
||||||
"deno_terminal 0.2.0",
|
"deno_terminal 0.2.0",
|
||||||
|
@ -2314,6 +2325,7 @@ version = "0.6.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"hyper 1.4.1",
|
"hyper 1.4.1",
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
|
@ -2326,6 +2338,7 @@ dependencies = [
|
||||||
"opentelemetry_sdk",
|
"opentelemetry_sdk",
|
||||||
"pin-project",
|
"pin-project",
|
||||||
"serde",
|
"serde",
|
||||||
|
"thiserror 2.0.3",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2354,6 +2367,7 @@ name = "deno_tls"
|
||||||
version = "0.171.0"
|
version = "0.171.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"deno_native_certs",
|
"deno_native_certs",
|
||||||
"rustls",
|
"rustls",
|
||||||
"rustls-pemfile",
|
"rustls-pemfile",
|
||||||
|
@ -2406,6 +2420,7 @@ dependencies = [
|
||||||
"deno_bench_util",
|
"deno_bench_util",
|
||||||
"deno_console",
|
"deno_console",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"deno_webidl",
|
"deno_webidl",
|
||||||
"thiserror 2.0.3",
|
"thiserror 2.0.3",
|
||||||
"urlpattern",
|
"urlpattern",
|
||||||
|
@ -2421,6 +2436,7 @@ dependencies = [
|
||||||
"deno_bench_util",
|
"deno_bench_util",
|
||||||
"deno_console",
|
"deno_console",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"deno_permissions",
|
"deno_permissions",
|
||||||
"deno_url",
|
"deno_url",
|
||||||
"deno_webidl",
|
"deno_webidl",
|
||||||
|
@ -2438,6 +2454,7 @@ name = "deno_webgpu"
|
||||||
version = "0.151.0"
|
version = "0.151.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror 2.0.3",
|
"thiserror 2.0.3",
|
||||||
|
@ -2460,6 +2477,7 @@ version = "0.189.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"deno_net",
|
"deno_net",
|
||||||
"deno_permissions",
|
"deno_permissions",
|
||||||
"deno_tls",
|
"deno_tls",
|
||||||
|
@ -2481,6 +2499,7 @@ name = "deno_webstorage"
|
||||||
version = "0.179.0"
|
version = "0.179.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"deno_error",
|
||||||
"deno_web",
|
"deno_web",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
"thiserror 2.0.3",
|
"thiserror 2.0.3",
|
||||||
|
@ -2498,13 +2517,13 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "denokv_proto"
|
name = "denokv_proto"
|
||||||
version = "0.8.4"
|
version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f7ba1f99ed11a9c11e868a8521b1f71a7e1aba785d7f42ea9ecbdc01146c89ec"
|
checksum = "d5b77de4d3b9215e14624d4f4eb16cb38c0810e3f5860ba3b3fc47d0537f9a4d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"deno_error",
|
||||||
"futures",
|
"futures",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"prost",
|
"prost",
|
||||||
|
@ -2514,15 +2533,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "denokv_remote"
|
name = "denokv_remote"
|
||||||
version = "0.8.4"
|
version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08ed833073189e8f6d03155fe3b05a024e75e29d8a28a4c2e9ec3b5c925e727b"
|
checksum = "c6497c28eec268ed99f1e8664f0842935f02d1508529c67d94c57ca5d893d743"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
|
||||||
"async-stream",
|
"async-stream",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"bytes",
|
"bytes",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"deno_error",
|
||||||
"denokv_proto",
|
"denokv_proto",
|
||||||
"futures",
|
"futures",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
|
@ -2531,6 +2550,7 @@ dependencies = [
|
||||||
"rand",
|
"rand",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"thiserror 2.0.3",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"url",
|
"url",
|
||||||
|
@ -2539,14 +2559,14 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "denokv_sqlite"
|
name = "denokv_sqlite"
|
||||||
version = "0.8.4"
|
version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b790f01d1302d53a0c3cbd27de88a06b3abd64ec8ab8673924e490541c7c713"
|
checksum = "dc0f21a450a35eb85760761401fddf9bfff9840127be07a6ca5c31863127913d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
|
||||||
"async-stream",
|
"async-stream",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"deno_error",
|
||||||
"denokv_proto",
|
"denokv_proto",
|
||||||
"futures",
|
"futures",
|
||||||
"hex",
|
"hex",
|
||||||
|
@ -2555,7 +2575,7 @@ dependencies = [
|
||||||
"rand",
|
"rand",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror 1.0.64",
|
"thiserror 2.0.3",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
"uuid",
|
"uuid",
|
||||||
|
@ -4331,16 +4351,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "import_map"
|
name = "import_map"
|
||||||
version = "0.20.1"
|
version = "0.21.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "351a787decc56f38d65d16d32687265045d6d6a4531b4a0e1b649def3590354e"
|
checksum = "1215d4d92511fbbdaea50e750e91f2429598ef817f02b579158e92803b52c00a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"boxed_error",
|
||||||
|
"deno_error",
|
||||||
"indexmap 2.3.0",
|
"indexmap 2.3.0",
|
||||||
"log",
|
"log",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror 1.0.64",
|
"thiserror 2.0.3",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -5106,9 +5128,10 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"boxed_error",
|
"boxed_error",
|
||||||
|
"deno_error",
|
||||||
"deno_media_type",
|
"deno_media_type",
|
||||||
"deno_package_json",
|
"deno_package_json",
|
||||||
"deno_path_util 0.3.0",
|
"deno_path_util",
|
||||||
"futures",
|
"futures",
|
||||||
"lazy-regex",
|
"lazy-regex",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
@ -6846,14 +6869,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_v8"
|
name = "serde_v8"
|
||||||
version = "0.236.0"
|
version = "0.239.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e23b3abce64010612f88f4ff689a959736f99eb3dc0dbf1c7903434b8bd8cda5"
|
checksum = "3caa6d882827148e5d9052d9d8d6d1c9d6ad426ed00cab46cafb8c07a0e7126a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"deno_error",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"serde",
|
"serde",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"thiserror 1.0.64",
|
"thiserror 2.0.3",
|
||||||
"v8",
|
"v8",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -8506,9 +8530,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "v8"
|
name = "v8"
|
||||||
version = "130.0.2"
|
version = "130.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2ee0be58935708fa4d7efb970c6cf9f2d9511d24ee24246481a65b6ee167348d"
|
checksum = "a511192602f7b435b0a241c1947aa743eb7717f20a9195f4b5e8ed1952e01db1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen",
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
|
@ -8706,11 +8730,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm_dep_analyzer"
|
name = "wasm_dep_analyzer"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f270206a91783fd90625c8bb0d8fbd459d0b1d1bf209b656f713f01ae7c04b8"
|
checksum = "2eeee3bdea6257cc36d756fa745a70f9d393571e47d69e0ed97581676a5369ca"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror 1.0.64",
|
"deno_error",
|
||||||
|
"thiserror 2.0.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
12
Cargo.toml
12
Cargo.toml
|
@ -48,10 +48,10 @@ repository = "https://github.com/denoland/deno"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
deno_ast = { version = "=0.44.0", features = ["transpiling"] }
|
deno_ast = { version = "=0.44.0", features = ["transpiling"] }
|
||||||
deno_core = { version = "0.327.0" }
|
deno_core = { version = "0.330.0" }
|
||||||
|
|
||||||
deno_bench_util = { version = "0.178.0", path = "./bench_util" }
|
deno_bench_util = { version = "0.178.0", path = "./bench_util" }
|
||||||
deno_config = { version = "=0.42.0", features = ["workspace", "sync"] }
|
deno_config = { version = "=0.43.0", features = ["workspace", "sync"] }
|
||||||
deno_lockfile = "=0.24.0"
|
deno_lockfile = "=0.24.0"
|
||||||
deno_media_type = { version = "0.2.3", features = ["module_specifier"] }
|
deno_media_type = { version = "0.2.3", features = ["module_specifier"] }
|
||||||
deno_npm = "=0.27.0"
|
deno_npm = "=0.27.0"
|
||||||
|
@ -63,10 +63,10 @@ deno_terminal = "0.2.0"
|
||||||
napi_sym = { version = "0.114.0", path = "./ext/napi/sym" }
|
napi_sym = { version = "0.114.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.9.0"
|
||||||
denokv_remote = "0.8.4"
|
denokv_remote = "0.9.0"
|
||||||
# denokv_sqlite brings in bundled sqlite if we don't disable the default features
|
# denokv_sqlite brings in bundled sqlite if we don't disable the default features
|
||||||
denokv_sqlite = { default-features = false, version = "0.8.4" }
|
denokv_sqlite = { default-features = false, version = "0.9.0" }
|
||||||
|
|
||||||
# exts
|
# exts
|
||||||
deno_broadcast_channel = { version = "0.178.0", path = "./ext/broadcast_channel" }
|
deno_broadcast_channel = { version = "0.178.0", path = "./ext/broadcast_channel" }
|
||||||
|
@ -119,7 +119,7 @@ dashmap = "5.5.3"
|
||||||
data-encoding = "2.3.3"
|
data-encoding = "2.3.3"
|
||||||
data-url = "=0.3.1"
|
data-url = "=0.3.1"
|
||||||
deno_cache_dir = "=0.16.0"
|
deno_cache_dir = "=0.16.0"
|
||||||
deno_error = "=0.5.2"
|
deno_error = "=0.5.3"
|
||||||
deno_package_json = { version = "0.4.0", default-features = false }
|
deno_package_json = { version = "0.4.0", default-features = false }
|
||||||
deno_unsync = "0.4.2"
|
deno_unsync = "0.4.2"
|
||||||
dlopen2 = "0.6.1"
|
dlopen2 = "0.6.1"
|
||||||
|
|
|
@ -62,6 +62,7 @@ serde_json.workspace = true
|
||||||
zstd.workspace = true
|
zstd.workspace = true
|
||||||
glibc_version = "0.1.2"
|
glibc_version = "0.1.2"
|
||||||
flate2 = { workspace = true, features = ["default"] }
|
flate2 = { workspace = true, features = ["default"] }
|
||||||
|
deno_error.workspace = true
|
||||||
|
|
||||||
[target.'cfg(windows)'.build-dependencies]
|
[target.'cfg(windows)'.build-dependencies]
|
||||||
winapi.workspace = true
|
winapi.workspace = true
|
||||||
|
@ -72,9 +73,9 @@ deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "proposa
|
||||||
deno_cache_dir.workspace = true
|
deno_cache_dir.workspace = true
|
||||||
deno_config.workspace = true
|
deno_config.workspace = true
|
||||||
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
||||||
deno_doc = { version = "=0.161.3", features = ["rust", "comrak"] }
|
deno_doc = { version = "=0.164.0", features = ["rust", "comrak"] }
|
||||||
deno_error.workspace = true
|
deno_error.workspace = true
|
||||||
deno_graph = { version = "=0.86.9" }
|
deno_graph = { version = "=0.87.0" }
|
||||||
deno_lint = { version = "=0.68.2", features = ["docs"] }
|
deno_lint = { version = "=0.68.2", features = ["docs"] }
|
||||||
deno_lockfile.workspace = true
|
deno_lockfile.workspace = true
|
||||||
deno_npm.workspace = true
|
deno_npm.workspace = true
|
||||||
|
@ -124,7 +125,7 @@ http.workspace = true
|
||||||
http-body.workspace = true
|
http-body.workspace = true
|
||||||
http-body-util.workspace = true
|
http-body-util.workspace = true
|
||||||
hyper-util.workspace = true
|
hyper-util.workspace = true
|
||||||
import_map = { version = "=0.20.1", features = ["ext"] }
|
import_map = { version = "=0.21.0", features = ["ext"] }
|
||||||
indexmap.workspace = true
|
indexmap.workspace = true
|
||||||
jsonc-parser = { workspace = true, features = ["cst", "serde"] }
|
jsonc-parser = { workspace = true, features = ["cst", "serde"] }
|
||||||
jupyter_runtime = { package = "runtimelib", version = "=0.19.0", features = ["tokio-runtime"] }
|
jupyter_runtime = { package = "runtimelib", version = "=0.19.0", features = ["tokio-runtime"] }
|
||||||
|
|
|
@ -10,6 +10,7 @@ use deno_core::error::AnyError;
|
||||||
use deno_core::parking_lot::Mutex;
|
use deno_core::parking_lot::Mutex;
|
||||||
use deno_core::parking_lot::MutexGuard;
|
use deno_core::parking_lot::MutexGuard;
|
||||||
use deno_core::serde_json;
|
use deno_core::serde_json;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_lockfile::Lockfile;
|
use deno_lockfile::Lockfile;
|
||||||
use deno_lockfile::WorkspaceMemberConfig;
|
use deno_lockfile::WorkspaceMemberConfig;
|
||||||
use deno_package_json::PackageJsonDepValue;
|
use deno_package_json::PackageJsonDepValue;
|
||||||
|
@ -59,6 +60,14 @@ impl<'a, T> std::ops::DerefMut for Guard<'a, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
#[error("Failed writing lockfile")]
|
||||||
|
#[class(inherit)]
|
||||||
|
struct AtomicWriteFileWithRetriesError {
|
||||||
|
#[source]
|
||||||
|
source: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
impl CliLockfile {
|
impl CliLockfile {
|
||||||
/// Get the inner deno_lockfile::Lockfile.
|
/// Get the inner deno_lockfile::Lockfile.
|
||||||
pub fn lock(&self) -> Guard<Lockfile> {
|
pub fn lock(&self) -> Guard<Lockfile> {
|
||||||
|
@ -78,7 +87,7 @@ impl CliLockfile {
|
||||||
self.lockfile.lock().overwrite
|
self.lockfile.lock().overwrite
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_if_changed(&self) -> Result<(), AnyError> {
|
pub fn write_if_changed(&self) -> Result<(), JsErrorBox> {
|
||||||
if self.skip_write {
|
if self.skip_write {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -96,7 +105,9 @@ impl CliLockfile {
|
||||||
&bytes,
|
&bytes,
|
||||||
cache::CACHE_PERM,
|
cache::CACHE_PERM,
|
||||||
)
|
)
|
||||||
.context("Failed writing lockfile.")?;
|
.map_err(|source| {
|
||||||
|
JsErrorBox::from_err(AtomicWriteFileWithRetriesError { source })
|
||||||
|
})?;
|
||||||
lockfile.has_content_changed = false;
|
lockfile.has_content_changed = false;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -255,7 +266,7 @@ impl CliLockfile {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn error_if_changed(&self) -> Result<(), AnyError> {
|
pub fn error_if_changed(&self) -> Result<(), JsErrorBox> {
|
||||||
if !self.frozen {
|
if !self.frozen {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -267,9 +278,7 @@ impl CliLockfile {
|
||||||
let diff = crate::util::diff::diff(&contents, &new_contents);
|
let diff = crate::util::diff::diff(&contents, &new_contents);
|
||||||
// has an extra newline at the end
|
// has an extra newline at the end
|
||||||
let diff = diff.trim_end();
|
let diff = diff.trim_end();
|
||||||
Err(deno_core::anyhow::anyhow!(
|
Err(JsErrorBox::generic(format!("The lockfile is out of date. Run `deno install --frozen=false`, or rerun with `--frozen=false` to update it.\nchanges:\n{diff}")))
|
||||||
"The lockfile is out of date. Run `deno install --frozen=false`, or rerun with `--frozen=false` to update it.\nchanges:\n{diff}"
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ use deno_ast::SourceMapOption;
|
||||||
use deno_cache_dir::file_fetcher::CacheSetting;
|
use deno_cache_dir::file_fetcher::CacheSetting;
|
||||||
pub use deno_config::deno_json::BenchConfig;
|
pub use deno_config::deno_json::BenchConfig;
|
||||||
pub use deno_config::deno_json::ConfigFile;
|
pub use deno_config::deno_json::ConfigFile;
|
||||||
|
use deno_config::deno_json::ConfigFileError;
|
||||||
use deno_config::deno_json::FmtConfig;
|
use deno_config::deno_json::FmtConfig;
|
||||||
pub use deno_config::deno_json::FmtOptionsConfig;
|
pub use deno_config::deno_json::FmtOptionsConfig;
|
||||||
use deno_config::deno_json::LintConfig;
|
use deno_config::deno_json::LintConfig;
|
||||||
|
@ -55,6 +56,7 @@ use deno_core::error::AnyError;
|
||||||
use deno_core::resolve_url_or_path;
|
use deno_core::resolve_url_or_path;
|
||||||
use deno_core::serde_json;
|
use deno_core::serde_json;
|
||||||
use deno_core::url::Url;
|
use deno_core::url::Url;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_graph::GraphKind;
|
use deno_graph::GraphKind;
|
||||||
pub use deno_json::check_warn_tsconfig;
|
pub use deno_json::check_warn_tsconfig;
|
||||||
use deno_lint::linter::LintConfig as DenoLintConfig;
|
use deno_lint::linter::LintConfig as DenoLintConfig;
|
||||||
|
@ -604,7 +606,8 @@ pub fn create_default_npmrc() -> Arc<ResolvedNpmRc> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug, Clone)]
|
#[derive(Error, Debug, Clone, deno_error::JsError)]
|
||||||
|
#[class(generic)]
|
||||||
pub enum RootCertStoreLoadError {
|
pub enum RootCertStoreLoadError {
|
||||||
#[error(
|
#[error(
|
||||||
"Unknown certificate store \"{0}\" specified (allowed: \"system,mozilla\")"
|
"Unknown certificate store \"{0}\" specified (allowed: \"system,mozilla\")"
|
||||||
|
@ -1104,7 +1107,7 @@ impl CliOptions {
|
||||||
pkg_json_dep_resolution,
|
pkg_json_dep_resolution,
|
||||||
specified_import_map: cli_arg_specified_import_map,
|
specified_import_map: cli_arg_specified_import_map,
|
||||||
},
|
},
|
||||||
|path| Ok(std::fs::read_to_string(path)?),
|
|path| std::fs::read_to_string(path).map_err(JsErrorBox::from_err),
|
||||||
)?)
|
)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1246,11 +1249,14 @@ impl CliOptions {
|
||||||
|
|
||||||
pub fn node_modules_dir(
|
pub fn node_modules_dir(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<Option<NodeModulesDirMode>, AnyError> {
|
) -> Result<
|
||||||
|
Option<NodeModulesDirMode>,
|
||||||
|
deno_config::deno_json::NodeModulesDirParseError,
|
||||||
|
> {
|
||||||
if let Some(flag) = self.flags.node_modules_dir {
|
if let Some(flag) = self.flags.node_modules_dir {
|
||||||
return Ok(Some(flag));
|
return Ok(Some(flag));
|
||||||
}
|
}
|
||||||
self.workspace().node_modules_dir().map_err(Into::into)
|
self.workspace().node_modules_dir()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vendor_dir_path(&self) -> Option<&PathBuf> {
|
pub fn vendor_dir_path(&self) -> Option<&PathBuf> {
|
||||||
|
@ -1260,7 +1266,7 @@ impl CliOptions {
|
||||||
pub fn resolve_ts_config_for_emit(
|
pub fn resolve_ts_config_for_emit(
|
||||||
&self,
|
&self,
|
||||||
config_type: TsConfigType,
|
config_type: TsConfigType,
|
||||||
) -> Result<TsConfigForEmit, AnyError> {
|
) -> Result<TsConfigForEmit, ConfigFileError> {
|
||||||
self.workspace().resolve_ts_config_for_emit(config_type)
|
self.workspace().resolve_ts_config_for_emit(config_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1289,7 +1295,7 @@ impl CliOptions {
|
||||||
|
|
||||||
pub fn to_compiler_option_types(
|
pub fn to_compiler_option_types(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<Vec<deno_graph::ReferrerImports>, AnyError> {
|
) -> Result<Vec<deno_graph::ReferrerImports>, serde_json::Error> {
|
||||||
self
|
self
|
||||||
.workspace()
|
.workspace()
|
||||||
.to_compiler_option_types()
|
.to_compiler_option_types()
|
||||||
|
|
18
cli/build.rs
18
cli/build.rs
|
@ -13,10 +13,9 @@ mod ts {
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use deno_core::error::custom_error;
|
|
||||||
use deno_core::error::AnyError;
|
|
||||||
use deno_core::op2;
|
use deno_core::op2;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -53,7 +52,7 @@ mod ts {
|
||||||
fn op_script_version(
|
fn op_script_version(
|
||||||
_state: &mut OpState,
|
_state: &mut OpState,
|
||||||
#[string] _arg: &str,
|
#[string] _arg: &str,
|
||||||
) -> Result<Option<String>, AnyError> {
|
) -> Result<Option<String>, JsErrorBox> {
|
||||||
Ok(Some("1".to_string()))
|
Ok(Some("1".to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +71,7 @@ mod ts {
|
||||||
fn op_load(
|
fn op_load(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] load_specifier: &str,
|
#[string] load_specifier: &str,
|
||||||
) -> Result<LoadResponse, AnyError> {
|
) -> Result<LoadResponse, JsErrorBox> {
|
||||||
let op_crate_libs = state.borrow::<HashMap<&str, PathBuf>>();
|
let op_crate_libs = state.borrow::<HashMap<&str, PathBuf>>();
|
||||||
let path_dts = state.borrow::<PathBuf>();
|
let path_dts = state.borrow::<PathBuf>();
|
||||||
let re_asset = lazy_regex::regex!(r"asset:/{3}lib\.(\S+)\.d\.ts");
|
let re_asset = lazy_regex::regex!(r"asset:/{3}lib\.(\S+)\.d\.ts");
|
||||||
|
@ -93,12 +92,15 @@ mod ts {
|
||||||
// if it comes from an op crate, we were supplied with the path to the
|
// if it comes from an op crate, we were supplied with the path to the
|
||||||
// file.
|
// file.
|
||||||
let path = if let Some(op_crate_lib) = op_crate_libs.get(lib) {
|
let path = if let Some(op_crate_lib) = op_crate_libs.get(lib) {
|
||||||
PathBuf::from(op_crate_lib).canonicalize()?
|
PathBuf::from(op_crate_lib)
|
||||||
|
.canonicalize()
|
||||||
|
.map_err(JsErrorBox::from_err)?
|
||||||
// otherwise we will generate the path ourself
|
// otherwise we will generate the path ourself
|
||||||
} else {
|
} else {
|
||||||
path_dts.join(format!("lib.{lib}.d.ts"))
|
path_dts.join(format!("lib.{lib}.d.ts"))
|
||||||
};
|
};
|
||||||
let data = std::fs::read_to_string(path)?;
|
let data =
|
||||||
|
std::fs::read_to_string(path).map_err(JsErrorBox::from_err)?;
|
||||||
Ok(LoadResponse {
|
Ok(LoadResponse {
|
||||||
data,
|
data,
|
||||||
version: "1".to_string(),
|
version: "1".to_string(),
|
||||||
|
@ -106,13 +108,13 @@ mod ts {
|
||||||
script_kind: 3,
|
script_kind: 3,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(custom_error(
|
Err(JsErrorBox::new(
|
||||||
"InvalidSpecifier",
|
"InvalidSpecifier",
|
||||||
format!("An invalid specifier was requested: {}", load_specifier),
|
format!("An invalid specifier was requested: {}", load_specifier),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(custom_error(
|
Err(JsErrorBox::new(
|
||||||
"InvalidSpecifier",
|
"InvalidSpecifier",
|
||||||
format!("An invalid specifier was requested: {}", load_specifier),
|
format!("An invalid specifier was requested: {}", load_specifier),
|
||||||
))
|
))
|
||||||
|
|
17
cli/cache/mod.rs
vendored
17
cli/cache/mod.rs
vendored
|
@ -8,7 +8,6 @@ use deno_ast::MediaType;
|
||||||
use deno_cache_dir::file_fetcher::CacheSetting;
|
use deno_cache_dir::file_fetcher::CacheSetting;
|
||||||
use deno_cache_dir::file_fetcher::FetchNoFollowErrorKind;
|
use deno_cache_dir::file_fetcher::FetchNoFollowErrorKind;
|
||||||
use deno_cache_dir::file_fetcher::FileOrRedirect;
|
use deno_cache_dir::file_fetcher::FileOrRedirect;
|
||||||
use deno_core::error::AnyError;
|
|
||||||
use deno_core::futures;
|
use deno_core::futures;
|
||||||
use deno_core::futures::FutureExt;
|
use deno_core::futures::FutureExt;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
|
@ -62,6 +61,7 @@ pub type GlobalHttpCache = deno_cache_dir::GlobalHttpCache<CliSys>;
|
||||||
pub type LocalHttpCache = deno_cache_dir::LocalHttpCache<CliSys>;
|
pub type LocalHttpCache = deno_cache_dir::LocalHttpCache<CliSys>;
|
||||||
pub type LocalLspHttpCache = deno_cache_dir::LocalLspHttpCache<CliSys>;
|
pub type LocalLspHttpCache = deno_cache_dir::LocalLspHttpCache<CliSys>;
|
||||||
pub use deno_cache_dir::HttpCache;
|
pub use deno_cache_dir::HttpCache;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
|
|
||||||
pub struct FetchCacherOptions {
|
pub struct FetchCacherOptions {
|
||||||
pub file_header_overrides: HashMap<ModuleSpecifier, HashMap<String, String>>,
|
pub file_header_overrides: HashMap<ModuleSpecifier, HashMap<String, String>>,
|
||||||
|
@ -194,9 +194,9 @@ impl Loader for FetchCacher {
|
||||||
LoaderCacheSetting::Use => None,
|
LoaderCacheSetting::Use => None,
|
||||||
LoaderCacheSetting::Reload => {
|
LoaderCacheSetting::Reload => {
|
||||||
if matches!(file_fetcher.cache_setting(), CacheSetting::Only) {
|
if matches!(file_fetcher.cache_setting(), CacheSetting::Only) {
|
||||||
return Err(deno_core::anyhow::anyhow!(
|
return Err(deno_graph::source::LoadError::Other(Arc::new(JsErrorBox::generic(
|
||||||
"Could not resolve version constraint using only cached data. Try running again without --cached-only"
|
"Could not resolve version constraint using only cached data. Try running again without --cached-only"
|
||||||
));
|
))));
|
||||||
}
|
}
|
||||||
Some(CacheSetting::ReloadAll)
|
Some(CacheSetting::ReloadAll)
|
||||||
}
|
}
|
||||||
|
@ -262,28 +262,27 @@ impl Loader for FetchCacher {
|
||||||
FetchNoFollowErrorKind::CacheSave { .. } |
|
FetchNoFollowErrorKind::CacheSave { .. } |
|
||||||
FetchNoFollowErrorKind::UnsupportedScheme { .. } |
|
FetchNoFollowErrorKind::UnsupportedScheme { .. } |
|
||||||
FetchNoFollowErrorKind::RedirectHeaderParse { .. } |
|
FetchNoFollowErrorKind::RedirectHeaderParse { .. } |
|
||||||
FetchNoFollowErrorKind::InvalidHeader { .. } => Err(AnyError::from(err)),
|
FetchNoFollowErrorKind::InvalidHeader { .. } => Err(deno_graph::source::LoadError::Other(Arc::new(JsErrorBox::from_err(err)))),
|
||||||
FetchNoFollowErrorKind::NotCached { .. } => {
|
FetchNoFollowErrorKind::NotCached { .. } => {
|
||||||
if options.cache_setting == LoaderCacheSetting::Only {
|
if options.cache_setting == LoaderCacheSetting::Only {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
} else {
|
} else {
|
||||||
Err(AnyError::from(err))
|
Err(deno_graph::source::LoadError::Other(Arc::new(JsErrorBox::from_err(err))))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
FetchNoFollowErrorKind::ChecksumIntegrity(err) => {
|
FetchNoFollowErrorKind::ChecksumIntegrity(err) => {
|
||||||
// convert to the equivalent deno_graph error so that it
|
// convert to the equivalent deno_graph error so that it
|
||||||
// enhances it if this is passed to deno_graph
|
// enhances it if this is passed to deno_graph
|
||||||
Err(
|
Err(
|
||||||
deno_graph::source::ChecksumIntegrityError {
|
deno_graph::source::LoadError::ChecksumIntegrity(deno_graph::source::ChecksumIntegrityError {
|
||||||
actual: err.actual,
|
actual: err.actual,
|
||||||
expected: err.expected,
|
expected: err.expected,
|
||||||
}
|
}),
|
||||||
.into(),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CliFetchNoFollowErrorKind::PermissionCheck(permission_check_error) => Err(AnyError::from(permission_check_error)),
|
CliFetchNoFollowErrorKind::PermissionCheck(permission_check_error) => Err(deno_graph::source::LoadError::Other(Arc::new(JsErrorBox::from_err(permission_check_error)))),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
48
cli/emit.rs
48
cli/emit.rs
|
@ -11,10 +11,12 @@ use deno_ast::SourceRangedForSpanned;
|
||||||
use deno_ast::TranspileModuleOptions;
|
use deno_ast::TranspileModuleOptions;
|
||||||
use deno_ast::TranspileResult;
|
use deno_ast::TranspileResult;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
use deno_core::error::CoreError;
|
||||||
use deno_core::futures::stream::FuturesUnordered;
|
use deno_core::futures::stream::FuturesUnordered;
|
||||||
use deno_core::futures::FutureExt;
|
use deno_core::futures::FutureExt;
|
||||||
use deno_core::futures::StreamExt;
|
use deno_core::futures::StreamExt;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_graph::MediaType;
|
use deno_graph::MediaType;
|
||||||
use deno_graph::Module;
|
use deno_graph::Module;
|
||||||
use deno_graph::ModuleGraph;
|
use deno_graph::ModuleGraph;
|
||||||
|
@ -124,7 +126,7 @@ impl Emitter {
|
||||||
let transpiled_source = deno_core::unsync::spawn_blocking({
|
let transpiled_source = deno_core::unsync::spawn_blocking({
|
||||||
let specifier = specifier.clone();
|
let specifier = specifier.clone();
|
||||||
let source = source.clone();
|
let source = source.clone();
|
||||||
move || -> Result<_, AnyError> {
|
move || {
|
||||||
EmitParsedSourceHelper::transpile(
|
EmitParsedSourceHelper::transpile(
|
||||||
&parsed_source_cache,
|
&parsed_source_cache,
|
||||||
&specifier,
|
&specifier,
|
||||||
|
@ -155,7 +157,7 @@ impl Emitter {
|
||||||
media_type: MediaType,
|
media_type: MediaType,
|
||||||
module_kind: deno_ast::ModuleKind,
|
module_kind: deno_ast::ModuleKind,
|
||||||
source: &Arc<str>,
|
source: &Arc<str>,
|
||||||
) -> Result<String, AnyError> {
|
) -> Result<String, EmitParsedSourceHelperError> {
|
||||||
// Note: keep this in sync with the async version above
|
// Note: keep this in sync with the async version above
|
||||||
let helper = EmitParsedSourceHelper(self);
|
let helper = EmitParsedSourceHelper(self);
|
||||||
match helper.pre_emit_parsed_source(specifier, module_kind, source) {
|
match helper.pre_emit_parsed_source(specifier, module_kind, source) {
|
||||||
|
@ -210,7 +212,7 @@ impl Emitter {
|
||||||
pub async fn load_and_emit_for_hmr(
|
pub async fn load_and_emit_for_hmr(
|
||||||
&self,
|
&self,
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
) -> Result<String, AnyError> {
|
) -> Result<String, CoreError> {
|
||||||
let media_type = MediaType::from_specifier(specifier);
|
let media_type = MediaType::from_specifier(specifier);
|
||||||
let source_code = tokio::fs::read_to_string(
|
let source_code = tokio::fs::read_to_string(
|
||||||
ModuleSpecifier::to_file_path(specifier).unwrap(),
|
ModuleSpecifier::to_file_path(specifier).unwrap(),
|
||||||
|
@ -225,17 +227,21 @@ impl Emitter {
|
||||||
let source_arc: Arc<str> = source_code.into();
|
let source_arc: Arc<str> = source_code.into();
|
||||||
let parsed_source = self
|
let parsed_source = self
|
||||||
.parsed_source_cache
|
.parsed_source_cache
|
||||||
.remove_or_parse_module(specifier, source_arc, media_type)?;
|
.remove_or_parse_module(specifier, source_arc, media_type)
|
||||||
|
.map_err(JsErrorBox::from_err)?;
|
||||||
// HMR doesn't work with embedded source maps for some reason, so set
|
// HMR doesn't work with embedded source maps for some reason, so set
|
||||||
// the option to not use them (though you should test this out because
|
// the option to not use them (though you should test this out because
|
||||||
// this statement is probably wrong)
|
// this statement is probably wrong)
|
||||||
let mut options = self.transpile_and_emit_options.1.clone();
|
let mut options = self.transpile_and_emit_options.1.clone();
|
||||||
options.source_map = SourceMapOption::None;
|
options.source_map = SourceMapOption::None;
|
||||||
let is_cjs = self.cjs_tracker.is_cjs_with_known_is_script(
|
let is_cjs = self
|
||||||
specifier,
|
.cjs_tracker
|
||||||
media_type,
|
.is_cjs_with_known_is_script(
|
||||||
parsed_source.compute_is_script(),
|
specifier,
|
||||||
)?;
|
media_type,
|
||||||
|
parsed_source.compute_is_script(),
|
||||||
|
)
|
||||||
|
.map_err(JsErrorBox::from_err)?;
|
||||||
let transpiled_source = parsed_source
|
let transpiled_source = parsed_source
|
||||||
.transpile(
|
.transpile(
|
||||||
&self.transpile_and_emit_options.0,
|
&self.transpile_and_emit_options.0,
|
||||||
|
@ -243,7 +249,8 @@ impl Emitter {
|
||||||
module_kind: Some(ModuleKind::from_is_cjs(is_cjs)),
|
module_kind: Some(ModuleKind::from_is_cjs(is_cjs)),
|
||||||
},
|
},
|
||||||
&options,
|
&options,
|
||||||
)?
|
)
|
||||||
|
.map_err(JsErrorBox::from_err)?
|
||||||
.into_source();
|
.into_source();
|
||||||
Ok(transpiled_source.text)
|
Ok(transpiled_source.text)
|
||||||
}
|
}
|
||||||
|
@ -282,6 +289,19 @@ enum PreEmitResult {
|
||||||
NotCached { source_hash: u64 },
|
NotCached { source_hash: u64 },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
pub enum EmitParsedSourceHelperError {
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
ParseDiagnostic(#[from] deno_ast::ParseDiagnostic),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
Transpile(#[from] deno_ast::TranspileError),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
Other(#[from] JsErrorBox),
|
||||||
|
}
|
||||||
|
|
||||||
/// Helper to share code between async and sync emit_parsed_source methods.
|
/// Helper to share code between async and sync emit_parsed_source methods.
|
||||||
struct EmitParsedSourceHelper<'a>(&'a Emitter);
|
struct EmitParsedSourceHelper<'a>(&'a Emitter);
|
||||||
|
|
||||||
|
@ -311,7 +331,7 @@ impl<'a> EmitParsedSourceHelper<'a> {
|
||||||
source: Arc<str>,
|
source: Arc<str>,
|
||||||
transpile_options: &deno_ast::TranspileOptions,
|
transpile_options: &deno_ast::TranspileOptions,
|
||||||
emit_options: &deno_ast::EmitOptions,
|
emit_options: &deno_ast::EmitOptions,
|
||||||
) -> Result<EmittedSourceText, AnyError> {
|
) -> Result<EmittedSourceText, EmitParsedSourceHelperError> {
|
||||||
// nothing else needs the parsed source at this point, so remove from
|
// nothing else needs the parsed source at this point, so remove from
|
||||||
// the cache in order to not transpile owned
|
// the cache in order to not transpile owned
|
||||||
let parsed_source = parsed_source_cache
|
let parsed_source = parsed_source_cache
|
||||||
|
@ -351,7 +371,7 @@ impl<'a> EmitParsedSourceHelper<'a> {
|
||||||
// todo(dsherret): this is a temporary measure until we have swc erroring for this
|
// todo(dsherret): this is a temporary measure until we have swc erroring for this
|
||||||
fn ensure_no_import_assertion(
|
fn ensure_no_import_assertion(
|
||||||
parsed_source: &deno_ast::ParsedSource,
|
parsed_source: &deno_ast::ParsedSource,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), JsErrorBox> {
|
||||||
fn has_import_assertion(text: &str) -> bool {
|
fn has_import_assertion(text: &str) -> bool {
|
||||||
// good enough
|
// good enough
|
||||||
text.contains(" assert ") && !text.contains(" with ")
|
text.contains(" assert ") && !text.contains(" with ")
|
||||||
|
@ -360,7 +380,7 @@ fn ensure_no_import_assertion(
|
||||||
fn create_err(
|
fn create_err(
|
||||||
parsed_source: &deno_ast::ParsedSource,
|
parsed_source: &deno_ast::ParsedSource,
|
||||||
range: SourceRange,
|
range: SourceRange,
|
||||||
) -> AnyError {
|
) -> JsErrorBox {
|
||||||
let text_info = parsed_source.text_info_lazy();
|
let text_info = parsed_source.text_info_lazy();
|
||||||
let loc = text_info.line_and_column_display(range.start);
|
let loc = text_info.line_and_column_display(range.start);
|
||||||
let mut msg = "Import assertions are deprecated. Use `with` keyword, instead of 'assert' keyword.".to_string();
|
let mut msg = "Import assertions are deprecated. Use `with` keyword, instead of 'assert' keyword.".to_string();
|
||||||
|
@ -373,7 +393,7 @@ fn ensure_no_import_assertion(
|
||||||
loc.line_number,
|
loc.line_number,
|
||||||
loc.column_number,
|
loc.column_number,
|
||||||
));
|
));
|
||||||
deno_core::anyhow::anyhow!("{}", msg)
|
JsErrorBox::generic(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
let deno_ast::ProgramRef::Module(module) = parsed_source.program_ref() else {
|
let deno_ast::ProgramRef::Module(module) = parsed_source.program_ref() else {
|
||||||
|
|
123
cli/errors.rs
123
cli/errors.rs
|
@ -1,123 +0,0 @@
|
||||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
|
||||||
|
|
||||||
//! There are many types of errors in Deno:
|
|
||||||
//! - AnyError: a generic wrapper that can encapsulate any type of error.
|
|
||||||
//! - JsError: a container for the error message and stack trace for exceptions
|
|
||||||
//! thrown in JavaScript code. We use this to pretty-print stack traces.
|
|
||||||
//! - Diagnostic: these are errors that originate in TypeScript's compiler.
|
|
||||||
//! They're similar to JsError, in that they have line numbers. But
|
|
||||||
//! Diagnostics are compile-time type errors, whereas JsErrors are runtime
|
|
||||||
//! exceptions.
|
|
||||||
|
|
||||||
use deno_ast::ParseDiagnostic;
|
|
||||||
use deno_core::error::AnyError;
|
|
||||||
use deno_graph::source::ResolveError;
|
|
||||||
use deno_graph::ModuleError;
|
|
||||||
use deno_graph::ModuleGraphError;
|
|
||||||
use deno_graph::ModuleLoadError;
|
|
||||||
use deno_graph::ResolutionError;
|
|
||||||
use import_map::ImportMapError;
|
|
||||||
|
|
||||||
fn get_import_map_error_class(_: &ImportMapError) -> &'static str {
|
|
||||||
"URIError"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_diagnostic_class(_: &ParseDiagnostic) -> &'static str {
|
|
||||||
"SyntaxError"
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_module_graph_error_class(err: &ModuleGraphError) -> &'static str {
|
|
||||||
match err {
|
|
||||||
ModuleGraphError::ResolutionError(err)
|
|
||||||
| ModuleGraphError::TypesResolutionError(err) => {
|
|
||||||
get_resolution_error_class(err)
|
|
||||||
}
|
|
||||||
ModuleGraphError::ModuleError(err) => get_module_error_class(err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_module_error_class(err: &ModuleError) -> &'static str {
|
|
||||||
use deno_graph::JsrLoadError;
|
|
||||||
use deno_graph::NpmLoadError;
|
|
||||||
|
|
||||||
match err {
|
|
||||||
ModuleError::InvalidTypeAssertion { .. } => "SyntaxError",
|
|
||||||
ModuleError::ParseErr(_, diagnostic) => get_diagnostic_class(diagnostic),
|
|
||||||
ModuleError::WasmParseErr(..) => "SyntaxError",
|
|
||||||
ModuleError::UnsupportedMediaType { .. }
|
|
||||||
| ModuleError::UnsupportedImportAttributeType { .. } => "TypeError",
|
|
||||||
ModuleError::Missing(_, _) | ModuleError::MissingDynamic(_, _) => {
|
|
||||||
"NotFound"
|
|
||||||
}
|
|
||||||
ModuleError::LoadingErr(_, _, err) => match err {
|
|
||||||
ModuleLoadError::Loader(err) => get_error_class_name(err.as_ref()),
|
|
||||||
ModuleLoadError::HttpsChecksumIntegrity(_)
|
|
||||||
| ModuleLoadError::TooManyRedirects => "Error",
|
|
||||||
ModuleLoadError::NodeUnknownBuiltinModule(_) => "NotFound",
|
|
||||||
ModuleLoadError::Decode(_) => "TypeError",
|
|
||||||
ModuleLoadError::Npm(err) => match err {
|
|
||||||
NpmLoadError::NotSupportedEnvironment
|
|
||||||
| NpmLoadError::PackageReqResolution(_)
|
|
||||||
| NpmLoadError::RegistryInfo(_) => "Error",
|
|
||||||
NpmLoadError::PackageReqReferenceParse(_) => "TypeError",
|
|
||||||
},
|
|
||||||
ModuleLoadError::Jsr(err) => match err {
|
|
||||||
JsrLoadError::UnsupportedManifestChecksum
|
|
||||||
| JsrLoadError::PackageFormat(_) => "TypeError",
|
|
||||||
JsrLoadError::ContentLoadExternalSpecifier
|
|
||||||
| JsrLoadError::ContentLoad(_)
|
|
||||||
| JsrLoadError::ContentChecksumIntegrity(_)
|
|
||||||
| JsrLoadError::PackageManifestLoad(_, _)
|
|
||||||
| JsrLoadError::PackageVersionManifestChecksumIntegrity(..)
|
|
||||||
| JsrLoadError::PackageVersionManifestLoad(_, _)
|
|
||||||
| JsrLoadError::RedirectInPackage(_) => "Error",
|
|
||||||
JsrLoadError::PackageNotFound(_)
|
|
||||||
| JsrLoadError::PackageReqNotFound(_)
|
|
||||||
| JsrLoadError::PackageVersionNotFound(_)
|
|
||||||
| JsrLoadError::UnknownExport { .. } => "NotFound",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_resolution_error_class(err: &ResolutionError) -> &'static str {
|
|
||||||
match err {
|
|
||||||
ResolutionError::ResolverError { error, .. } => {
|
|
||||||
use ResolveError::*;
|
|
||||||
match error.as_ref() {
|
|
||||||
Specifier(_) => "TypeError",
|
|
||||||
Other(e) => get_error_class_name(e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => "TypeError",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_try_from_int_error_class(_: &std::num::TryFromIntError) -> &'static str {
|
|
||||||
"TypeError"
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_error_class_name(e: &AnyError) -> &'static str {
|
|
||||||
deno_runtime::errors::get_error_class_name(e)
|
|
||||||
.or_else(|| {
|
|
||||||
e.downcast_ref::<ImportMapError>()
|
|
||||||
.map(get_import_map_error_class)
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
e.downcast_ref::<ParseDiagnostic>()
|
|
||||||
.map(get_diagnostic_class)
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
e.downcast_ref::<ModuleGraphError>()
|
|
||||||
.map(get_module_graph_error_class)
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
e.downcast_ref::<ResolutionError>()
|
|
||||||
.map(get_resolution_error_class)
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
e.downcast_ref::<std::num::TryFromIntError>()
|
|
||||||
.map(get_try_from_int_error_class)
|
|
||||||
})
|
|
||||||
.unwrap_or("Error")
|
|
||||||
}
|
|
|
@ -10,6 +10,7 @@ use deno_config::workspace::WorkspaceResolver;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::futures::FutureExt;
|
use deno_core::futures::FutureExt;
|
||||||
use deno_core::FeatureChecker;
|
use deno_core::FeatureChecker;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_resolver::cjs::IsCjsResolutionMode;
|
use deno_resolver::cjs::IsCjsResolutionMode;
|
||||||
use deno_resolver::npm::NpmReqResolverOptions;
|
use deno_resolver::npm::NpmReqResolverOptions;
|
||||||
use deno_resolver::DenoResolverOptions;
|
use deno_resolver::DenoResolverOptions;
|
||||||
|
@ -118,7 +119,7 @@ impl CliRootCertStoreProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RootCertStoreProvider for CliRootCertStoreProvider {
|
impl RootCertStoreProvider for CliRootCertStoreProvider {
|
||||||
fn get_or_try_init(&self) -> Result<&RootCertStore, AnyError> {
|
fn get_or_try_init(&self) -> Result<&RootCertStore, JsErrorBox> {
|
||||||
self
|
self
|
||||||
.cell
|
.cell
|
||||||
.get_or_try_init(|| {
|
.get_or_try_init(|| {
|
||||||
|
@ -128,7 +129,7 @@ impl RootCertStoreProvider for CliRootCertStoreProvider {
|
||||||
self.maybe_ca_data.clone(),
|
self.maybe_ca_data.clone(),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map_err(|e| e.into())
|
.map_err(JsErrorBox::from_err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,17 +2,18 @@
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::ops::Deref;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use deno_config::deno_json;
|
||||||
use deno_config::deno_json::JsxImportSourceConfig;
|
use deno_config::deno_json::JsxImportSourceConfig;
|
||||||
use deno_config::workspace::JsrPackageConfig;
|
use deno_config::workspace::JsrPackageConfig;
|
||||||
use deno_core::anyhow::bail;
|
|
||||||
use deno_core::error::custom_error;
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::parking_lot::Mutex;
|
use deno_core::parking_lot::Mutex;
|
||||||
|
use deno_core::serde_json;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
|
use deno_error::JsErrorClass;
|
||||||
use deno_graph::source::Loader;
|
use deno_graph::source::Loader;
|
||||||
use deno_graph::source::LoaderChecksum;
|
use deno_graph::source::LoaderChecksum;
|
||||||
use deno_graph::source::ResolutionKind;
|
use deno_graph::source::ResolutionKind;
|
||||||
|
@ -49,8 +50,6 @@ use crate::cache::GlobalHttpCache;
|
||||||
use crate::cache::ModuleInfoCache;
|
use crate::cache::ModuleInfoCache;
|
||||||
use crate::cache::ParsedSourceCache;
|
use crate::cache::ParsedSourceCache;
|
||||||
use crate::colors;
|
use crate::colors;
|
||||||
use crate::errors::get_error_class_name;
|
|
||||||
use crate::errors::get_module_graph_error_class;
|
|
||||||
use crate::file_fetcher::CliFileFetcher;
|
use crate::file_fetcher::CliFileFetcher;
|
||||||
use crate::npm::CliNpmResolver;
|
use crate::npm::CliNpmResolver;
|
||||||
use crate::resolver::CjsTracker;
|
use crate::resolver::CjsTracker;
|
||||||
|
@ -59,6 +58,7 @@ use crate::resolver::CliSloppyImportsResolver;
|
||||||
use crate::resolver::SloppyImportsCachedFs;
|
use crate::resolver::SloppyImportsCachedFs;
|
||||||
use crate::sys::CliSys;
|
use crate::sys::CliSys;
|
||||||
use crate::tools::check;
|
use crate::tools::check;
|
||||||
|
use crate::tools::check::CheckError;
|
||||||
use crate::tools::check::TypeChecker;
|
use crate::tools::check::TypeChecker;
|
||||||
use crate::util::file_watcher::WatcherCommunicator;
|
use crate::util::file_watcher::WatcherCommunicator;
|
||||||
use crate::util::fs::canonicalize_path;
|
use crate::util::fs::canonicalize_path;
|
||||||
|
@ -85,7 +85,7 @@ pub fn graph_valid(
|
||||||
sys: &CliSys,
|
sys: &CliSys,
|
||||||
roots: &[ModuleSpecifier],
|
roots: &[ModuleSpecifier],
|
||||||
options: GraphValidOptions,
|
options: GraphValidOptions,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), JsErrorBox> {
|
||||||
if options.exit_integrity_errors {
|
if options.exit_integrity_errors {
|
||||||
graph_exit_integrity_errors(graph);
|
graph_exit_integrity_errors(graph);
|
||||||
}
|
}
|
||||||
|
@ -104,9 +104,9 @@ pub fn graph_valid(
|
||||||
} else {
|
} else {
|
||||||
// finally surface the npm resolution result
|
// finally surface the npm resolution result
|
||||||
if let Err(err) = &graph.npm_dep_graph_result {
|
if let Err(err) = &graph.npm_dep_graph_result {
|
||||||
return Err(custom_error(
|
return Err(JsErrorBox::new(
|
||||||
get_error_class_name(err),
|
err.get_class(),
|
||||||
format_deno_graph_error(err.as_ref().deref()),
|
format_deno_graph_error(err),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -145,7 +145,7 @@ pub fn graph_walk_errors<'a>(
|
||||||
sys: &'a CliSys,
|
sys: &'a CliSys,
|
||||||
roots: &'a [ModuleSpecifier],
|
roots: &'a [ModuleSpecifier],
|
||||||
options: GraphWalkErrorsOptions,
|
options: GraphWalkErrorsOptions,
|
||||||
) -> impl Iterator<Item = AnyError> + 'a {
|
) -> impl Iterator<Item = JsErrorBox> + 'a {
|
||||||
graph
|
graph
|
||||||
.walk(
|
.walk(
|
||||||
roots.iter(),
|
roots.iter(),
|
||||||
|
@ -197,7 +197,7 @@ pub fn graph_walk_errors<'a>(
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(custom_error(get_module_graph_error_class(&error), message))
|
Some(JsErrorBox::new(error.get_class(), message))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,14 +437,14 @@ impl ModuleGraphCreator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn graph_valid(&self, graph: &ModuleGraph) -> Result<(), AnyError> {
|
pub fn graph_valid(&self, graph: &ModuleGraph) -> Result<(), JsErrorBox> {
|
||||||
self.module_graph_builder.graph_valid(graph)
|
self.module_graph_builder.graph_valid(graph)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn type_check_graph(
|
async fn type_check_graph(
|
||||||
&self,
|
&self,
|
||||||
graph: ModuleGraph,
|
graph: ModuleGraph,
|
||||||
) -> Result<Arc<ModuleGraph>, AnyError> {
|
) -> Result<Arc<ModuleGraph>, CheckError> {
|
||||||
self
|
self
|
||||||
.type_checker
|
.type_checker
|
||||||
.check(
|
.check(
|
||||||
|
@ -467,6 +467,27 @@ pub struct BuildFastCheckGraphOptions<'a> {
|
||||||
pub workspace_fast_check: deno_graph::WorkspaceFastCheckOption<'a>,
|
pub workspace_fast_check: deno_graph::WorkspaceFastCheckOption<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
pub enum BuildGraphWithNpmResolutionError {
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
SerdeJson(#[from] serde_json::Error),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
ToMaybeJsxImportSourceConfig(
|
||||||
|
#[from] deno_json::ToMaybeJsxImportSourceConfigError,
|
||||||
|
),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
NodeModulesDirParse(#[from] deno_json::NodeModulesDirParseError),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
Other(#[from] JsErrorBox),
|
||||||
|
#[class(generic)]
|
||||||
|
#[error("Resolving npm specifier entrypoints this way is currently not supported with \"nodeModules\": \"manual\". In the meantime, try with --node-modules-dir=auto instead")]
|
||||||
|
UnsupportedNpmSpecifierEntrypointResolutionWay,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct ModuleGraphBuilder {
|
pub struct ModuleGraphBuilder {
|
||||||
caches: Arc<cache::Caches>,
|
caches: Arc<cache::Caches>,
|
||||||
cjs_tracker: Arc<CjsTracker>,
|
cjs_tracker: Arc<CjsTracker>,
|
||||||
|
@ -524,7 +545,7 @@ impl ModuleGraphBuilder {
|
||||||
&self,
|
&self,
|
||||||
graph: &mut ModuleGraph,
|
graph: &mut ModuleGraph,
|
||||||
options: CreateGraphOptions<'a>,
|
options: CreateGraphOptions<'a>,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), BuildGraphWithNpmResolutionError> {
|
||||||
enum MutLoaderRef<'a> {
|
enum MutLoaderRef<'a> {
|
||||||
Borrowed(&'a mut dyn Loader),
|
Borrowed(&'a mut dyn Loader),
|
||||||
Owned(cache::FetchCacher),
|
Owned(cache::FetchCacher),
|
||||||
|
@ -652,7 +673,7 @@ impl ModuleGraphBuilder {
|
||||||
loader: &'a mut dyn deno_graph::source::Loader,
|
loader: &'a mut dyn deno_graph::source::Loader,
|
||||||
options: deno_graph::BuildOptions<'a>,
|
options: deno_graph::BuildOptions<'a>,
|
||||||
npm_caching: NpmCachingStrategy,
|
npm_caching: NpmCachingStrategy,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), BuildGraphWithNpmResolutionError> {
|
||||||
// ensure an "npm install" is done if the user has explicitly
|
// ensure an "npm install" is done if the user has explicitly
|
||||||
// opted into using a node_modules directory
|
// opted into using a node_modules directory
|
||||||
if self
|
if self
|
||||||
|
@ -689,7 +710,7 @@ impl ModuleGraphBuilder {
|
||||||
if roots.iter().any(|r| r.scheme() == "npm")
|
if roots.iter().any(|r| r.scheme() == "npm")
|
||||||
&& self.npm_resolver.as_byonm().is_some()
|
&& self.npm_resolver.as_byonm().is_some()
|
||||||
{
|
{
|
||||||
bail!("Resolving npm specifier entrypoints this way is currently not supported with \"nodeModules\": \"manual\". In the meantime, try with --node-modules-dir=auto instead");
|
return Err(BuildGraphWithNpmResolutionError::UnsupportedNpmSpecifierEntrypointResolutionWay);
|
||||||
}
|
}
|
||||||
|
|
||||||
graph.build(roots, loader, options).await;
|
graph.build(roots, loader, options).await;
|
||||||
|
@ -740,7 +761,7 @@ impl ModuleGraphBuilder {
|
||||||
&self,
|
&self,
|
||||||
graph: &mut ModuleGraph,
|
graph: &mut ModuleGraph,
|
||||||
options: BuildFastCheckGraphOptions,
|
options: BuildFastCheckGraphOptions,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), deno_json::ToMaybeJsxImportSourceConfigError> {
|
||||||
if !graph.graph_kind().include_types() {
|
if !graph.graph_kind().include_types() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -804,7 +825,7 @@ impl ModuleGraphBuilder {
|
||||||
/// Check if `roots` and their deps are available. Returns `Ok(())` if
|
/// Check if `roots` and their deps are available. Returns `Ok(())` if
|
||||||
/// so. Returns `Err(_)` if there is a known module graph or resolution
|
/// so. Returns `Err(_)` if there is a known module graph or resolution
|
||||||
/// error statically reachable from `roots` and not a dynamic import.
|
/// error statically reachable from `roots` and not a dynamic import.
|
||||||
pub fn graph_valid(&self, graph: &ModuleGraph) -> Result<(), AnyError> {
|
pub fn graph_valid(&self, graph: &ModuleGraph) -> Result<(), JsErrorBox> {
|
||||||
self.graph_roots_valid(
|
self.graph_roots_valid(
|
||||||
graph,
|
graph,
|
||||||
&graph.roots.iter().cloned().collect::<Vec<_>>(),
|
&graph.roots.iter().cloned().collect::<Vec<_>>(),
|
||||||
|
@ -815,7 +836,7 @@ impl ModuleGraphBuilder {
|
||||||
&self,
|
&self,
|
||||||
graph: &ModuleGraph,
|
graph: &ModuleGraph,
|
||||||
roots: &[ModuleSpecifier],
|
roots: &[ModuleSpecifier],
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), JsErrorBox> {
|
||||||
graph_valid(
|
graph_valid(
|
||||||
graph,
|
graph,
|
||||||
&self.sys,
|
&self.sys,
|
||||||
|
@ -832,7 +853,10 @@ impl ModuleGraphBuilder {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_graph_resolver(&self) -> Result<CliGraphResolver, AnyError> {
|
fn create_graph_resolver(
|
||||||
|
&self,
|
||||||
|
) -> Result<CliGraphResolver, deno_json::ToMaybeJsxImportSourceConfigError>
|
||||||
|
{
|
||||||
let jsx_import_source_config = self
|
let jsx_import_source_config = self
|
||||||
.cli_options
|
.cli_options
|
||||||
.workspace()
|
.workspace()
|
||||||
|
@ -1001,8 +1025,13 @@ fn get_resolution_error_bare_specifier(
|
||||||
Some(specifier.as_str())
|
Some(specifier.as_str())
|
||||||
} else if let ResolutionError::ResolverError { error, .. } = error {
|
} else if let ResolutionError::ResolverError { error, .. } = error {
|
||||||
if let ResolveError::Other(error) = (*error).as_ref() {
|
if let ResolveError::Other(error) = (*error).as_ref() {
|
||||||
if let Some(ImportMapError::UnmappedBareSpecifier(specifier, _)) =
|
if let Some(import_map::ImportMapErrorKind::UnmappedBareSpecifier(
|
||||||
error.downcast_ref::<ImportMapError>()
|
specifier,
|
||||||
|
_,
|
||||||
|
)) = error
|
||||||
|
.as_any()
|
||||||
|
.downcast_ref::<ImportMapError>()
|
||||||
|
.map(|e| &**e)
|
||||||
{
|
{
|
||||||
Some(specifier.as_str())
|
Some(specifier.as_str())
|
||||||
} else {
|
} else {
|
||||||
|
@ -1039,11 +1068,12 @@ fn get_import_prefix_missing_error(error: &ResolutionError) -> Option<&str> {
|
||||||
ResolveError::Other(other_error) => {
|
ResolveError::Other(other_error) => {
|
||||||
if let Some(SpecifierError::ImportPrefixMissing {
|
if let Some(SpecifierError::ImportPrefixMissing {
|
||||||
specifier, ..
|
specifier, ..
|
||||||
}) = other_error.downcast_ref::<SpecifierError>()
|
}) = other_error.as_any().downcast_ref::<SpecifierError>()
|
||||||
{
|
{
|
||||||
maybe_specifier = Some(specifier);
|
maybe_specifier = Some(specifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ResolveError::ImportMap(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1294,7 +1324,7 @@ mod test {
|
||||||
let specifier = ModuleSpecifier::parse("file:///file.ts").unwrap();
|
let specifier = ModuleSpecifier::parse("file:///file.ts").unwrap();
|
||||||
let err = import_map.resolve(input, &specifier).err().unwrap();
|
let err = import_map.resolve(input, &specifier).err().unwrap();
|
||||||
let err = ResolutionError::ResolverError {
|
let err = ResolutionError::ResolverError {
|
||||||
error: Arc::new(ResolveError::Other(err.into())),
|
error: Arc::new(ResolveError::Other(JsErrorBox::from_err(err))),
|
||||||
specifier: input.to_string(),
|
specifier: input.to_string(),
|
||||||
range: Range {
|
range: Range {
|
||||||
specifier,
|
specifier,
|
||||||
|
|
|
@ -6,13 +6,14 @@ use std::thread::ThreadId;
|
||||||
|
|
||||||
use boxed_error::Boxed;
|
use boxed_error::Boxed;
|
||||||
use deno_cache_dir::file_fetcher::RedirectHeaderParseError;
|
use deno_cache_dir::file_fetcher::RedirectHeaderParseError;
|
||||||
use deno_core::error::custom_error;
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::futures::StreamExt;
|
use deno_core::futures::StreamExt;
|
||||||
use deno_core::parking_lot::Mutex;
|
use deno_core::parking_lot::Mutex;
|
||||||
use deno_core::serde;
|
use deno_core::serde;
|
||||||
use deno_core::serde_json;
|
use deno_core::serde_json;
|
||||||
use deno_core::url::Url;
|
use deno_core::url::Url;
|
||||||
|
use deno_error::JsError;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_runtime::deno_fetch;
|
use deno_runtime::deno_fetch;
|
||||||
use deno_runtime::deno_fetch::create_http_client;
|
use deno_runtime::deno_fetch::create_http_client;
|
||||||
use deno_runtime::deno_fetch::CreateHttpClientOptions;
|
use deno_runtime::deno_fetch::CreateHttpClientOptions;
|
||||||
|
@ -94,34 +95,49 @@ impl HttpClientProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error, JsError)]
|
||||||
|
#[class(type)]
|
||||||
#[error("Bad response: {:?}{}", .status_code, .response_text.as_ref().map(|s| format!("\n\n{}", s)).unwrap_or_else(String::new))]
|
#[error("Bad response: {:?}{}", .status_code, .response_text.as_ref().map(|s| format!("\n\n{}", s)).unwrap_or_else(String::new))]
|
||||||
pub struct BadResponseError {
|
pub struct BadResponseError {
|
||||||
pub status_code: StatusCode,
|
pub status_code: StatusCode,
|
||||||
pub response_text: Option<String>,
|
pub response_text: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Boxed)]
|
#[derive(Debug, Boxed, JsError)]
|
||||||
pub struct DownloadError(pub Box<DownloadErrorKind>);
|
pub struct DownloadError(pub Box<DownloadErrorKind>);
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error, JsError)]
|
||||||
pub enum DownloadErrorKind {
|
pub enum DownloadErrorKind {
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Fetch(AnyError),
|
Fetch(deno_fetch::ClientSendError),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
UrlParse(#[from] deno_core::url::ParseError),
|
UrlParse(#[from] deno_core::url::ParseError),
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
HttpParse(#[from] http::Error),
|
HttpParse(#[from] http::Error),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Json(#[from] serde_json::Error),
|
Json(#[from] serde_json::Error),
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
ToStr(#[from] http::header::ToStrError),
|
ToStr(#[from] http::header::ToStrError),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
RedirectHeaderParse(RedirectHeaderParseError),
|
RedirectHeaderParse(RedirectHeaderParseError),
|
||||||
|
#[class(type)]
|
||||||
#[error("Too many redirects.")]
|
#[error("Too many redirects.")]
|
||||||
TooManyRedirects,
|
TooManyRedirects,
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
BadResponse(#[from] BadResponseError),
|
BadResponse(#[from] BadResponseError),
|
||||||
|
#[class("Http")]
|
||||||
|
#[error("Not Found.")]
|
||||||
|
NotFound,
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
Other(JsErrorBox),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -208,11 +224,11 @@ impl HttpClient {
|
||||||
Ok(String::from_utf8(bytes)?)
|
Ok(String::from_utf8(bytes)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn download(&self, url: Url) -> Result<Vec<u8>, AnyError> {
|
pub async fn download(&self, url: Url) -> Result<Vec<u8>, DownloadError> {
|
||||||
let maybe_bytes = self.download_inner(url, None, None).await?;
|
let maybe_bytes = self.download_inner(url, None, None).await?;
|
||||||
match maybe_bytes {
|
match maybe_bytes {
|
||||||
Some(bytes) => Ok(bytes),
|
Some(bytes) => Ok(bytes),
|
||||||
None => Err(custom_error("Http", "Not found.")),
|
None => Err(DownloadErrorKind::NotFound.into_box()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +292,7 @@ impl HttpClient {
|
||||||
get_response_body_with_progress(response, progress_guard)
|
get_response_body_with_progress(response, progress_guard)
|
||||||
.await
|
.await
|
||||||
.map(|(_, body)| Some(body))
|
.map(|(_, body)| Some(body))
|
||||||
.map_err(|err| DownloadErrorKind::Fetch(err).into_box())
|
.map_err(|err| DownloadErrorKind::Other(err).into_box())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_redirected_response(
|
async fn get_redirected_response(
|
||||||
|
@ -293,7 +309,7 @@ impl HttpClient {
|
||||||
.clone()
|
.clone()
|
||||||
.send(req)
|
.send(req)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| DownloadErrorKind::Fetch(e.into()).into_box())?;
|
.map_err(|e| DownloadErrorKind::Fetch(e).into_box())?;
|
||||||
let status = response.status();
|
let status = response.status();
|
||||||
if status.is_redirection() {
|
if status.is_redirection() {
|
||||||
for _ in 0..5 {
|
for _ in 0..5 {
|
||||||
|
@ -313,7 +329,7 @@ impl HttpClient {
|
||||||
.clone()
|
.clone()
|
||||||
.send(req)
|
.send(req)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| DownloadErrorKind::Fetch(e.into()).into_box())?;
|
.map_err(|e| DownloadErrorKind::Fetch(e).into_box())?;
|
||||||
let status = new_response.status();
|
let status = new_response.status();
|
||||||
if status.is_redirection() {
|
if status.is_redirection() {
|
||||||
response = new_response;
|
response = new_response;
|
||||||
|
@ -332,7 +348,7 @@ impl HttpClient {
|
||||||
pub async fn get_response_body_with_progress(
|
pub async fn get_response_body_with_progress(
|
||||||
response: http::Response<deno_fetch::ResBody>,
|
response: http::Response<deno_fetch::ResBody>,
|
||||||
progress_guard: Option<&UpdateGuard>,
|
progress_guard: Option<&UpdateGuard>,
|
||||||
) -> Result<(HeaderMap, Vec<u8>), AnyError> {
|
) -> Result<(HeaderMap, Vec<u8>), JsErrorBox> {
|
||||||
use http_body::Body as _;
|
use http_body::Body as _;
|
||||||
if let Some(progress_guard) = progress_guard {
|
if let Some(progress_guard) = progress_guard {
|
||||||
let mut total_size = response.body().size_hint().exact();
|
let mut total_size = response.body().size_hint().exact();
|
||||||
|
|
|
@ -10,13 +10,13 @@ use deno_ast::SourceRange;
|
||||||
use deno_ast::SourceRangedForSpanned;
|
use deno_ast::SourceRangedForSpanned;
|
||||||
use deno_ast::SourceTextInfo;
|
use deno_ast::SourceTextInfo;
|
||||||
use deno_config::workspace::MappedResolution;
|
use deno_config::workspace::MappedResolution;
|
||||||
use deno_core::error::custom_error;
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::serde::Deserialize;
|
use deno_core::serde::Deserialize;
|
||||||
use deno_core::serde::Serialize;
|
use deno_core::serde::Serialize;
|
||||||
use deno_core::serde_json;
|
use deno_core::serde_json;
|
||||||
use deno_core::serde_json::json;
|
use deno_core::serde_json::json;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_lint::diagnostic::LintDiagnosticRange;
|
use deno_lint::diagnostic::LintDiagnosticRange;
|
||||||
use deno_path_util::url_to_file_path;
|
use deno_path_util::url_to_file_path;
|
||||||
use deno_runtime::deno_node::PathClean;
|
use deno_runtime::deno_node::PathClean;
|
||||||
|
@ -1070,10 +1070,13 @@ impl CodeActionCollection {
|
||||||
// we wrap tsc, we can't handle the asynchronous response, so it is
|
// we wrap tsc, we can't handle the asynchronous response, so it is
|
||||||
// actually easier to return errors if we ever encounter one of these,
|
// actually easier to return errors if we ever encounter one of these,
|
||||||
// which we really wouldn't expect from the Deno lsp.
|
// which we really wouldn't expect from the Deno lsp.
|
||||||
return Err(custom_error(
|
return Err(
|
||||||
"UnsupportedFix",
|
JsErrorBox::new(
|
||||||
"The action returned from TypeScript is unsupported.",
|
"UnsupportedFix",
|
||||||
));
|
"The action returned from TypeScript is unsupported.",
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
let Some(action) =
|
let Some(action) =
|
||||||
fix_ts_import_action(specifier, resolution_mode, action, language_server)
|
fix_ts_import_action(specifier, resolution_mode, action, language_server)
|
||||||
|
|
|
@ -41,6 +41,7 @@ use deno_core::serde_json::json;
|
||||||
use deno_core::serde_json::Value;
|
use deno_core::serde_json::Value;
|
||||||
use deno_core::url::Url;
|
use deno_core::url::Url;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_lint::linter::LintConfig as DenoLintConfig;
|
use deno_lint::linter::LintConfig as DenoLintConfig;
|
||||||
use deno_npm::npm_rc::ResolvedNpmRc;
|
use deno_npm::npm_rc::ResolvedNpmRc;
|
||||||
use deno_package_json::PackageJsonCache;
|
use deno_package_json::PackageJsonCache;
|
||||||
|
@ -1575,7 +1576,7 @@ impl ConfigData {
|
||||||
pkg_json_dep_resolution,
|
pkg_json_dep_resolution,
|
||||||
specified_import_map,
|
specified_import_map,
|
||||||
},
|
},
|
||||||
|path| Ok(std::fs::read_to_string(path)?),
|
|path| std::fs::read_to_string(path).map_err(JsErrorBox::from_err),
|
||||||
)
|
)
|
||||||
.inspect_err(|err| {
|
.inspect_err(|err| {
|
||||||
lsp_warn!(
|
lsp_warn!(
|
||||||
|
|
|
@ -34,7 +34,7 @@ use deno_semver::jsr::JsrPackageReqReference;
|
||||||
use deno_semver::npm::NpmPackageReqReference;
|
use deno_semver::npm::NpmPackageReqReference;
|
||||||
use deno_semver::package::PackageReq;
|
use deno_semver::package::PackageReq;
|
||||||
use import_map::ImportMap;
|
use import_map::ImportMap;
|
||||||
use import_map::ImportMapError;
|
use import_map::ImportMapErrorKind;
|
||||||
use log::error;
|
use log::error;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
@ -1297,8 +1297,8 @@ impl DenoDiagnostic {
|
||||||
let mut message;
|
let mut message;
|
||||||
message = enhanced_resolution_error_message(err);
|
message = enhanced_resolution_error_message(err);
|
||||||
if let deno_graph::ResolutionError::ResolverError {error, ..} = err{
|
if let deno_graph::ResolutionError::ResolverError {error, ..} = err{
|
||||||
if let ResolveError::Other(resolve_error, ..) = (*error).as_ref() {
|
if let ResolveError::ImportMap(importmap) = (*error).as_ref() {
|
||||||
if let Some(ImportMapError::UnmappedBareSpecifier(specifier, _)) = resolve_error.downcast_ref::<ImportMapError>() {
|
if let ImportMapErrorKind::UnmappedBareSpecifier(specifier, _) = &**importmap {
|
||||||
if specifier.chars().next().unwrap_or('\0') == '@'{
|
if specifier.chars().next().unwrap_or('\0') == '@'{
|
||||||
let hint = format!("\nHint: Use [deno add {}] to add the dependency.", specifier);
|
let hint = format!("\nHint: Use [deno add {}] to add the dependency.", specifier);
|
||||||
message.push_str(hint.as_str());
|
message.push_str(hint.as_str());
|
||||||
|
|
|
@ -18,13 +18,13 @@ use deno_ast::swc::visit::VisitWith;
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
use deno_ast::ParsedSource;
|
use deno_ast::ParsedSource;
|
||||||
use deno_ast::SourceTextInfo;
|
use deno_ast::SourceTextInfo;
|
||||||
use deno_core::error::custom_error;
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::futures::future;
|
use deno_core::futures::future;
|
||||||
use deno_core::futures::future::Shared;
|
use deno_core::futures::future::Shared;
|
||||||
use deno_core::futures::FutureExt;
|
use deno_core::futures::FutureExt;
|
||||||
use deno_core::parking_lot::Mutex;
|
use deno_core::parking_lot::Mutex;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_graph::Resolution;
|
use deno_graph::Resolution;
|
||||||
use deno_path_util::url_to_file_path;
|
use deno_path_util::url_to_file_path;
|
||||||
use deno_runtime::deno_node;
|
use deno_runtime::deno_node;
|
||||||
|
@ -1081,7 +1081,7 @@ impl Documents {
|
||||||
.or_else(|| self.file_system_docs.remove_document(specifier))
|
.or_else(|| self.file_system_docs.remove_document(specifier))
|
||||||
.map(Ok)
|
.map(Ok)
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
Err(custom_error(
|
Err(JsErrorBox::new(
|
||||||
"NotFound",
|
"NotFound",
|
||||||
format!("The specifier \"{specifier}\" was not found."),
|
format!("The specifier \"{specifier}\" was not found."),
|
||||||
))
|
))
|
||||||
|
|
|
@ -122,7 +122,7 @@ use crate::util::sync::AsyncFlag;
|
||||||
struct LspRootCertStoreProvider(RootCertStore);
|
struct LspRootCertStoreProvider(RootCertStore);
|
||||||
|
|
||||||
impl RootCertStoreProvider for LspRootCertStoreProvider {
|
impl RootCertStoreProvider for LspRootCertStoreProvider {
|
||||||
fn get_or_try_init(&self) -> Result<&RootCertStore, AnyError> {
|
fn get_or_try_init(&self) -> Result<&RootCertStore, deno_error::JsErrorBox> {
|
||||||
Ok(&self.0)
|
Ok(&self.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use deno_core::error::custom_error;
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use dissimilar::diff;
|
use dissimilar::diff;
|
||||||
use dissimilar::Chunk;
|
use dissimilar::Chunk;
|
||||||
use text_size::TextRange;
|
use text_size::TextRange;
|
||||||
|
@ -137,7 +137,7 @@ impl LineIndex {
|
||||||
if let Some(line_offset) = self.utf8_offsets.get(position.line as usize) {
|
if let Some(line_offset) = self.utf8_offsets.get(position.line as usize) {
|
||||||
Ok(line_offset + col)
|
Ok(line_offset + col)
|
||||||
} else {
|
} else {
|
||||||
Err(custom_error("OutOfRange", "The position is out of range."))
|
Err(JsErrorBox::new("OutOfRange", "The position is out of range.").into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ impl LineIndex {
|
||||||
if let Some(line_offset) = self.utf16_offsets.get(position.line as usize) {
|
if let Some(line_offset) = self.utf16_offsets.get(position.line as usize) {
|
||||||
Ok(line_offset + TextSize::from(position.character))
|
Ok(line_offset + TextSize::from(position.character))
|
||||||
} else {
|
} else {
|
||||||
Err(custom_error("OutOfRange", "The position is out of range."))
|
Err(JsErrorBox::new("OutOfRange", "The position is out of range.").into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ use deno_core::anyhow::Context as _;
|
||||||
use deno_core::convert::Smi;
|
use deno_core::convert::Smi;
|
||||||
use deno_core::convert::ToV8;
|
use deno_core::convert::ToV8;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::error::StdAnyError;
|
|
||||||
use deno_core::futures::stream::FuturesOrdered;
|
use deno_core::futures::stream::FuturesOrdered;
|
||||||
use deno_core::futures::FutureExt;
|
use deno_core::futures::FutureExt;
|
||||||
use deno_core::futures::StreamExt;
|
use deno_core::futures::StreamExt;
|
||||||
|
@ -4331,7 +4330,7 @@ impl TscSpecifierMap {
|
||||||
pub fn normalize<S: AsRef<str>>(
|
pub fn normalize<S: AsRef<str>>(
|
||||||
&self,
|
&self,
|
||||||
specifier: S,
|
specifier: S,
|
||||||
) -> Result<ModuleSpecifier, AnyError> {
|
) -> Result<ModuleSpecifier, deno_core::url::ParseError> {
|
||||||
let original = specifier.as_ref();
|
let original = specifier.as_ref();
|
||||||
if let Some(specifier) = self.normalized_specifiers.get(original) {
|
if let Some(specifier) = self.normalized_specifiers.get(original) {
|
||||||
return Ok(specifier.clone());
|
return Ok(specifier.clone());
|
||||||
|
@ -4339,7 +4338,7 @@ impl TscSpecifierMap {
|
||||||
let specifier_str = original.replace(".d.ts.d.ts", ".d.ts");
|
let specifier_str = original.replace(".d.ts.d.ts", ".d.ts");
|
||||||
let specifier = match ModuleSpecifier::parse(&specifier_str) {
|
let specifier = match ModuleSpecifier::parse(&specifier_str) {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(err) => return Err(err.into()),
|
Err(err) => return Err(err),
|
||||||
};
|
};
|
||||||
if specifier.as_str() != original {
|
if specifier.as_str() != original {
|
||||||
self
|
self
|
||||||
|
@ -4437,6 +4436,16 @@ fn op_is_node_file(state: &mut OpState, #[string] path: String) -> bool {
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
enum LoadError {
|
||||||
|
#[error("{0}")]
|
||||||
|
#[class(inherit)]
|
||||||
|
UrlParse(#[from] deno_core::url::ParseError),
|
||||||
|
#[error("{0}")]
|
||||||
|
#[class(inherit)]
|
||||||
|
SerdeV8(#[from] serde_v8::Error),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
struct LoadResponse {
|
struct LoadResponse {
|
||||||
|
@ -4451,7 +4460,7 @@ fn op_load<'s>(
|
||||||
scope: &'s mut v8::HandleScope,
|
scope: &'s mut v8::HandleScope,
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] specifier: &str,
|
#[string] specifier: &str,
|
||||||
) -> Result<v8::Local<'s, v8::Value>, AnyError> {
|
) -> Result<v8::Local<'s, v8::Value>, LoadError> {
|
||||||
let state = state.borrow_mut::<State>();
|
let state = state.borrow_mut::<State>();
|
||||||
let mark = state
|
let mark = state
|
||||||
.performance
|
.performance
|
||||||
|
@ -4482,7 +4491,7 @@ fn op_load<'s>(
|
||||||
fn op_release(
|
fn op_release(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] specifier: &str,
|
#[string] specifier: &str,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), deno_core::url::ParseError> {
|
||||||
let state = state.borrow_mut::<State>();
|
let state = state.borrow_mut::<State>();
|
||||||
let mark = state
|
let mark = state
|
||||||
.performance
|
.performance
|
||||||
|
@ -4499,7 +4508,7 @@ fn op_resolve(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] base: String,
|
#[string] base: String,
|
||||||
#[serde] specifiers: Vec<(bool, String)>,
|
#[serde] specifiers: Vec<(bool, String)>,
|
||||||
) -> Result<Vec<Option<(String, String)>>, AnyError> {
|
) -> Result<Vec<Option<(String, String)>>, deno_core::url::ParseError> {
|
||||||
op_resolve_inner(state, ResolveArgs { base, specifiers })
|
op_resolve_inner(state, ResolveArgs { base, specifiers })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4511,7 +4520,7 @@ struct TscRequestArray {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ToV8<'a> for TscRequestArray {
|
impl<'a> ToV8<'a> for TscRequestArray {
|
||||||
type Error = StdAnyError;
|
type Error = serde_v8::Error;
|
||||||
|
|
||||||
fn to_v8(
|
fn to_v8(
|
||||||
self,
|
self,
|
||||||
|
@ -4526,9 +4535,7 @@ impl<'a> ToV8<'a> for TscRequestArray {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into();
|
.into();
|
||||||
let args = args.unwrap_or_else(|| v8::Array::new(scope, 0).into());
|
let args = args.unwrap_or_else(|| v8::Array::new(scope, 0).into());
|
||||||
let scope_url = serde_v8::to_v8(scope, self.scope)
|
let scope_url = serde_v8::to_v8(scope, self.scope)?;
|
||||||
.map_err(AnyError::from)
|
|
||||||
.map_err(StdAnyError::from)?;
|
|
||||||
|
|
||||||
let change = self.change.to_v8(scope).unwrap_infallible();
|
let change = self.change.to_v8(scope).unwrap_infallible();
|
||||||
|
|
||||||
|
@ -4586,7 +4593,7 @@ async fn op_poll_requests(
|
||||||
fn op_resolve_inner(
|
fn op_resolve_inner(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
args: ResolveArgs,
|
args: ResolveArgs,
|
||||||
) -> Result<Vec<Option<(String, String)>>, AnyError> {
|
) -> Result<Vec<Option<(String, String)>>, deno_core::url::ParseError> {
|
||||||
let state = state.borrow_mut::<State>();
|
let state = state.borrow_mut::<State>();
|
||||||
let mark = state.performance.mark_with_args("tsc.op.op_resolve", &args);
|
let mark = state.performance.mark_with_args("tsc.op.op_resolve", &args);
|
||||||
let referrer = state.specifier_map.normalize(&args.base)?;
|
let referrer = state.specifier_map.normalize(&args.base)?;
|
||||||
|
@ -4743,7 +4750,7 @@ fn op_script_names(state: &mut OpState) -> ScriptNames {
|
||||||
fn op_script_version(
|
fn op_script_version(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] specifier: &str,
|
#[string] specifier: &str,
|
||||||
) -> Result<Option<String>, AnyError> {
|
) -> Result<Option<String>, deno_core::url::ParseError> {
|
||||||
let state = state.borrow_mut::<State>();
|
let state = state.borrow_mut::<State>();
|
||||||
let mark = state.performance.mark("tsc.op.op_script_version");
|
let mark = state.performance.mark("tsc.op.op_script_version");
|
||||||
let specifier = state.specifier_map.normalize(specifier)?;
|
let specifier = state.specifier_map.normalize(specifier)?;
|
||||||
|
@ -5398,7 +5405,8 @@ impl TscRequest {
|
||||||
fn to_server_request<'s>(
|
fn to_server_request<'s>(
|
||||||
&self,
|
&self,
|
||||||
scope: &mut v8::HandleScope<'s>,
|
scope: &mut v8::HandleScope<'s>,
|
||||||
) -> Result<(&'static str, Option<v8::Local<'s, v8::Value>>), AnyError> {
|
) -> Result<(&'static str, Option<v8::Local<'s, v8::Value>>), serde_v8::Error>
|
||||||
|
{
|
||||||
let args = match self {
|
let args = match self {
|
||||||
TscRequest::GetDiagnostics(args) => {
|
TscRequest::GetDiagnostics(args) => {
|
||||||
("$getDiagnostics", Some(serde_v8::to_v8(scope, args)?))
|
("$getDiagnostics", Some(serde_v8::to_v8(scope, args)?))
|
||||||
|
|
13
cli/main.rs
13
cli/main.rs
|
@ -4,7 +4,6 @@ mod args;
|
||||||
mod cache;
|
mod cache;
|
||||||
mod cdp;
|
mod cdp;
|
||||||
mod emit;
|
mod emit;
|
||||||
mod errors;
|
|
||||||
mod factory;
|
mod factory;
|
||||||
mod file_fetcher;
|
mod file_fetcher;
|
||||||
mod graph_container;
|
mod graph_container;
|
||||||
|
@ -38,7 +37,7 @@ use std::sync::Arc;
|
||||||
use args::TaskFlags;
|
use args::TaskFlags;
|
||||||
use deno_core::anyhow::Context;
|
use deno_core::anyhow::Context;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::error::JsError;
|
use deno_core::error::CoreError;
|
||||||
use deno_core::futures::FutureExt;
|
use deno_core::futures::FutureExt;
|
||||||
use deno_core::unsync::JoinHandle;
|
use deno_core::unsync::JoinHandle;
|
||||||
use deno_npm::resolution::SnapshotFromLockfileError;
|
use deno_npm::resolution::SnapshotFromLockfileError;
|
||||||
|
@ -202,7 +201,7 @@ async fn run_subcommand(flags: Arc<Flags>) -> Result<i32, AnyError> {
|
||||||
match result {
|
match result {
|
||||||
Ok(v) => Ok(v),
|
Ok(v) => Ok(v),
|
||||||
Err(script_err) => {
|
Err(script_err) => {
|
||||||
if let Some(ResolvePkgFolderFromDenoReqError::Byonm(ByonmResolvePkgFolderFromDenoReqError::UnmatchedReq(_))) = script_err.downcast_ref::<ResolvePkgFolderFromDenoReqError>() {
|
if let Some(ResolvePkgFolderFromDenoReqError::Byonm(ByonmResolvePkgFolderFromDenoReqError::UnmatchedReq(_))) = util::result::any_and_jserrorbox_downcast_ref::<ResolvePkgFolderFromDenoReqError>(&script_err) {
|
||||||
if flags.node_modules_dir.is_none() {
|
if flags.node_modules_dir.is_none() {
|
||||||
let mut flags = flags.deref().clone();
|
let mut flags = flags.deref().clone();
|
||||||
let watch = match &flags.subcommand {
|
let watch = match &flags.subcommand {
|
||||||
|
@ -373,10 +372,14 @@ fn exit_for_error(error: AnyError) -> ! {
|
||||||
let mut error_string = format!("{error:?}");
|
let mut error_string = format!("{error:?}");
|
||||||
let mut error_code = 1;
|
let mut error_code = 1;
|
||||||
|
|
||||||
if let Some(e) = error.downcast_ref::<JsError>() {
|
if let Some(CoreError::Js(e)) =
|
||||||
|
util::result::any_and_jserrorbox_downcast_ref::<CoreError>(&error)
|
||||||
|
{
|
||||||
error_string = format_js_error(e);
|
error_string = format_js_error(e);
|
||||||
} else if let Some(SnapshotFromLockfileError::IntegrityCheckFailed(e)) =
|
} else if let Some(SnapshotFromLockfileError::IntegrityCheckFailed(e)) =
|
||||||
error.downcast_ref::<SnapshotFromLockfileError>()
|
util::result::any_and_jserrorbox_downcast_ref::<SnapshotFromLockfileError>(
|
||||||
|
&error,
|
||||||
|
)
|
||||||
{
|
{
|
||||||
error_string = e.to_string();
|
error_string = e.to_string();
|
||||||
error_code = 10;
|
error_code = 10;
|
||||||
|
|
|
@ -10,7 +10,6 @@ mod standalone;
|
||||||
mod args;
|
mod args;
|
||||||
mod cache;
|
mod cache;
|
||||||
mod emit;
|
mod emit;
|
||||||
mod errors;
|
|
||||||
mod file_fetcher;
|
mod file_fetcher;
|
||||||
mod http_util;
|
mod http_util;
|
||||||
mod js;
|
mod js;
|
||||||
|
@ -30,8 +29,8 @@ use std::env;
|
||||||
use std::env::current_exe;
|
use std::env::current_exe;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use deno_core::error::generic_error;
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
use deno_core::error::CoreError;
|
||||||
use deno_core::error::JsError;
|
use deno_core::error::JsError;
|
||||||
use deno_runtime::fmt_errors::format_js_error;
|
use deno_runtime::fmt_errors::format_js_error;
|
||||||
use deno_runtime::tokio_util::create_and_run_current_thread_with_maybe_metrics;
|
use deno_runtime::tokio_util::create_and_run_current_thread_with_maybe_metrics;
|
||||||
|
@ -41,6 +40,7 @@ use indexmap::IndexMap;
|
||||||
use standalone::DenoCompileFileSystem;
|
use standalone::DenoCompileFileSystem;
|
||||||
|
|
||||||
use crate::args::Flags;
|
use crate::args::Flags;
|
||||||
|
use crate::util::result::any_and_jserrorbox_downcast_ref;
|
||||||
|
|
||||||
pub(crate) fn unstable_exit_cb(feature: &str, api_name: &str) {
|
pub(crate) fn unstable_exit_cb(feature: &str, api_name: &str) {
|
||||||
log::error!(
|
log::error!(
|
||||||
|
@ -65,8 +65,10 @@ fn unwrap_or_exit<T>(result: Result<T, AnyError>) -> T {
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
let mut error_string = format!("{:?}", error);
|
let mut error_string = format!("{:?}", error);
|
||||||
|
|
||||||
if let Some(e) = error.downcast_ref::<JsError>() {
|
if let Some(CoreError::Js(js_error)) =
|
||||||
error_string = format_js_error(e);
|
any_and_jserrorbox_downcast_ref::<CoreError>(&error)
|
||||||
|
{
|
||||||
|
error_string = format_js_error(js_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit_with_message(&error_string, 1);
|
exit_with_message(&error_string, 1);
|
||||||
|
|
|
@ -14,11 +14,9 @@ use std::sync::Arc;
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
use deno_ast::ModuleKind;
|
use deno_ast::ModuleKind;
|
||||||
use deno_core::anyhow::anyhow;
|
use deno_core::anyhow::anyhow;
|
||||||
use deno_core::anyhow::bail;
|
|
||||||
use deno_core::anyhow::Context;
|
use deno_core::anyhow::Context;
|
||||||
use deno_core::error::custom_error;
|
|
||||||
use deno_core::error::generic_error;
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
use deno_core::error::ModuleLoaderError;
|
||||||
use deno_core::futures::future::FutureExt;
|
use deno_core::futures::future::FutureExt;
|
||||||
use deno_core::futures::Future;
|
use deno_core::futures::Future;
|
||||||
use deno_core::parking_lot::Mutex;
|
use deno_core::parking_lot::Mutex;
|
||||||
|
@ -31,6 +29,8 @@ use deno_core::ModuleSpecifier;
|
||||||
use deno_core::ModuleType;
|
use deno_core::ModuleType;
|
||||||
use deno_core::RequestedModuleType;
|
use deno_core::RequestedModuleType;
|
||||||
use deno_core::SourceCodeCacheInfo;
|
use deno_core::SourceCodeCacheInfo;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
|
use deno_error::JsErrorClass;
|
||||||
use deno_graph::GraphKind;
|
use deno_graph::GraphKind;
|
||||||
use deno_graph::JsModule;
|
use deno_graph::JsModule;
|
||||||
use deno_graph::JsonModule;
|
use deno_graph::JsonModule;
|
||||||
|
@ -59,7 +59,6 @@ use crate::cache::CodeCache;
|
||||||
use crate::cache::FastInsecureHasher;
|
use crate::cache::FastInsecureHasher;
|
||||||
use crate::cache::ParsedSourceCache;
|
use crate::cache::ParsedSourceCache;
|
||||||
use crate::emit::Emitter;
|
use crate::emit::Emitter;
|
||||||
use crate::errors::get_module_error_class;
|
|
||||||
use crate::graph_container::MainModuleGraphContainer;
|
use crate::graph_container::MainModuleGraphContainer;
|
||||||
use crate::graph_container::ModuleGraphContainer;
|
use crate::graph_container::ModuleGraphContainer;
|
||||||
use crate::graph_container::ModuleGraphUpdatePermit;
|
use crate::graph_container::ModuleGraphUpdatePermit;
|
||||||
|
@ -79,6 +78,7 @@ use crate::resolver::NotSupportedKindInNpmError;
|
||||||
use crate::resolver::NpmModuleLoader;
|
use crate::resolver::NpmModuleLoader;
|
||||||
use crate::sys::CliSys;
|
use crate::sys::CliSys;
|
||||||
use crate::tools::check;
|
use crate::tools::check;
|
||||||
|
use crate::tools::check::CheckError;
|
||||||
use crate::tools::check::TypeChecker;
|
use crate::tools::check::TypeChecker;
|
||||||
use crate::util::progress_bar::ProgressBar;
|
use crate::util::progress_bar::ProgressBar;
|
||||||
use crate::util::text_encoding::code_without_source_map;
|
use crate::util::text_encoding::code_without_source_map;
|
||||||
|
@ -86,6 +86,21 @@ use crate::util::text_encoding::source_map_from_code;
|
||||||
use crate::worker::CreateModuleLoaderResult;
|
use crate::worker::CreateModuleLoaderResult;
|
||||||
use crate::worker::ModuleLoaderFactory;
|
use crate::worker::ModuleLoaderFactory;
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
pub enum PrepareModuleLoadError {
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
BuildGraphWithNpmResolution(
|
||||||
|
#[from] crate::graph_util::BuildGraphWithNpmResolutionError,
|
||||||
|
),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
Check(#[from] CheckError),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
Other(#[from] JsErrorBox),
|
||||||
|
}
|
||||||
|
|
||||||
pub struct ModuleLoadPreparer {
|
pub struct ModuleLoadPreparer {
|
||||||
options: Arc<CliOptions>,
|
options: Arc<CliOptions>,
|
||||||
lockfile: Option<Arc<CliLockfile>>,
|
lockfile: Option<Arc<CliLockfile>>,
|
||||||
|
@ -125,7 +140,7 @@ impl ModuleLoadPreparer {
|
||||||
lib: TsTypeLib,
|
lib: TsTypeLib,
|
||||||
permissions: PermissionsContainer,
|
permissions: PermissionsContainer,
|
||||||
ext_overwrite: Option<&String>,
|
ext_overwrite: Option<&String>,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), PrepareModuleLoadError> {
|
||||||
log::debug!("Preparing module load.");
|
log::debug!("Preparing module load.");
|
||||||
let _pb_clear_guard = self.progress_bar.clear_guard();
|
let _pb_clear_guard = self.progress_bar.clear_guard();
|
||||||
|
|
||||||
|
@ -206,7 +221,7 @@ impl ModuleLoadPreparer {
|
||||||
&self,
|
&self,
|
||||||
graph: &ModuleGraph,
|
graph: &ModuleGraph,
|
||||||
roots: &[ModuleSpecifier],
|
roots: &[ModuleSpecifier],
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), JsErrorBox> {
|
||||||
self.module_graph_builder.graph_roots_valid(graph, roots)
|
self.module_graph_builder.graph_roots_valid(graph, roots)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -423,7 +438,7 @@ impl<TGraphContainer: ModuleGraphContainer>
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
maybe_referrer: Option<&ModuleSpecifier>,
|
maybe_referrer: Option<&ModuleSpecifier>,
|
||||||
requested_module_type: RequestedModuleType,
|
requested_module_type: RequestedModuleType,
|
||||||
) -> Result<ModuleSource, AnyError> {
|
) -> Result<ModuleSource, ModuleLoaderError> {
|
||||||
let code_source = self.load_code_source(specifier, maybe_referrer).await?;
|
let code_source = self.load_code_source(specifier, maybe_referrer).await?;
|
||||||
let code = if self.shared.is_inspecting
|
let code = if self.shared.is_inspecting
|
||||||
|| code_source.media_type == MediaType::Wasm
|
|| code_source.media_type == MediaType::Wasm
|
||||||
|
@ -446,7 +461,7 @@ impl<TGraphContainer: ModuleGraphContainer>
|
||||||
if module_type == ModuleType::Json
|
if module_type == ModuleType::Json
|
||||||
&& requested_module_type != RequestedModuleType::Json
|
&& requested_module_type != RequestedModuleType::Json
|
||||||
{
|
{
|
||||||
return Err(generic_error("Attempted to load JSON module without specifying \"type\": \"json\" attribute in the import statement."));
|
return Err(JsErrorBox::generic("Attempted to load JSON module without specifying \"type\": \"json\" attribute in the import statement.").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let code_cache = if module_type == ModuleType::JavaScript {
|
let code_cache = if module_type == ModuleType::JavaScript {
|
||||||
|
@ -507,7 +522,7 @@ impl<TGraphContainer: ModuleGraphContainer>
|
||||||
fn resolve_referrer(
|
fn resolve_referrer(
|
||||||
&self,
|
&self,
|
||||||
referrer: &str,
|
referrer: &str,
|
||||||
) -> Result<ModuleSpecifier, AnyError> {
|
) -> Result<ModuleSpecifier, ModuleLoaderError> {
|
||||||
let referrer = if referrer.is_empty() && self.shared.is_repl {
|
let referrer = if referrer.is_empty() && self.shared.is_repl {
|
||||||
// FIXME(bartlomieju): this is a hacky way to provide compatibility with REPL
|
// FIXME(bartlomieju): this is a hacky way to provide compatibility with REPL
|
||||||
// and `Deno.core.evalContext` API. Ideally we should always have a referrer filled
|
// and `Deno.core.evalContext` API. Ideally we should always have a referrer filled
|
||||||
|
@ -533,7 +548,7 @@ impl<TGraphContainer: ModuleGraphContainer>
|
||||||
&self,
|
&self,
|
||||||
raw_specifier: &str,
|
raw_specifier: &str,
|
||||||
referrer: &ModuleSpecifier,
|
referrer: &ModuleSpecifier,
|
||||||
) -> Result<ModuleSpecifier, AnyError> {
|
) -> Result<ModuleSpecifier, ModuleLoaderError> {
|
||||||
let graph = self.graph_container.graph();
|
let graph = self.graph_container.graph();
|
||||||
let resolution = match graph.get(referrer) {
|
let resolution = match graph.get(referrer) {
|
||||||
Some(Module::Js(module)) => module
|
Some(Module::Js(module)) => module
|
||||||
|
@ -547,19 +562,25 @@ impl<TGraphContainer: ModuleGraphContainer>
|
||||||
let specifier = match resolution {
|
let specifier = match resolution {
|
||||||
Resolution::Ok(resolved) => Cow::Borrowed(&resolved.specifier),
|
Resolution::Ok(resolved) => Cow::Borrowed(&resolved.specifier),
|
||||||
Resolution::Err(err) => {
|
Resolution::Err(err) => {
|
||||||
return Err(custom_error(
|
return Err(
|
||||||
"TypeError",
|
JsErrorBox::type_error(format!("{}\n", err.to_string_with_range()))
|
||||||
format!("{}\n", err.to_string_with_range()),
|
.into(),
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
Resolution::None => Cow::Owned(self.shared.resolver.resolve(
|
Resolution::None => Cow::Owned(
|
||||||
raw_specifier,
|
self
|
||||||
referrer,
|
.shared
|
||||||
deno_graph::Position::zeroed(),
|
.resolver
|
||||||
// if we're here, that means it's resolving a dynamic import
|
.resolve(
|
||||||
ResolutionMode::Import,
|
raw_specifier,
|
||||||
NodeResolutionKind::Execution,
|
referrer,
|
||||||
)?),
|
deno_graph::Position::zeroed(),
|
||||||
|
// if we're here, that means it's resolving a dynamic import
|
||||||
|
ResolutionMode::Import,
|
||||||
|
NodeResolutionKind::Execution,
|
||||||
|
)
|
||||||
|
.map_err(JsErrorBox::from_err)?,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.shared.is_repl {
|
if self.shared.is_repl {
|
||||||
|
@ -574,7 +595,7 @@ impl<TGraphContainer: ModuleGraphContainer>
|
||||||
ResolutionMode::Import,
|
ResolutionMode::Import,
|
||||||
NodeResolutionKind::Execution,
|
NodeResolutionKind::Execution,
|
||||||
)
|
)
|
||||||
.map_err(AnyError::from);
|
.map_err(|e| JsErrorBox::from_err(e).into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,7 +606,8 @@ impl<TGraphContainer: ModuleGraphContainer>
|
||||||
.npm_resolver
|
.npm_resolver
|
||||||
.as_managed()
|
.as_managed()
|
||||||
.unwrap() // byonm won't create a Module::Npm
|
.unwrap() // byonm won't create a Module::Npm
|
||||||
.resolve_pkg_folder_from_deno_module(module.nv_reference.nv())?;
|
.resolve_pkg_folder_from_deno_module(module.nv_reference.nv())
|
||||||
|
.map_err(JsErrorBox::from_err)?;
|
||||||
self
|
self
|
||||||
.shared
|
.shared
|
||||||
.node_resolver
|
.node_resolver
|
||||||
|
@ -701,7 +723,7 @@ impl<TGraphContainer: ModuleGraphContainer>
|
||||||
&self,
|
&self,
|
||||||
graph: &'graph ModuleGraph,
|
graph: &'graph ModuleGraph,
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
) -> Result<Option<CodeOrDeferredEmit<'graph>>, AnyError> {
|
) -> Result<Option<CodeOrDeferredEmit<'graph>>, JsErrorBox> {
|
||||||
if specifier.scheme() == "node" {
|
if specifier.scheme() == "node" {
|
||||||
// Node built-in modules should be handled internally.
|
// Node built-in modules should be handled internally.
|
||||||
unreachable!("Deno bug. {} was misconfigured internally.", specifier);
|
unreachable!("Deno bug. {} was misconfigured internally.", specifier);
|
||||||
|
@ -710,8 +732,8 @@ impl<TGraphContainer: ModuleGraphContainer>
|
||||||
let maybe_module = match graph.try_get(specifier) {
|
let maybe_module = match graph.try_get(specifier) {
|
||||||
Ok(module) => module,
|
Ok(module) => module,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return Err(custom_error(
|
return Err(JsErrorBox::new(
|
||||||
get_module_error_class(err),
|
err.get_class(),
|
||||||
enhance_graph_error(
|
enhance_graph_error(
|
||||||
&self.shared.sys,
|
&self.shared.sys,
|
||||||
&ModuleGraphError::ModuleError(err.clone()),
|
&ModuleGraphError::ModuleError(err.clone()),
|
||||||
|
@ -739,11 +761,12 @@ impl<TGraphContainer: ModuleGraphContainer>
|
||||||
is_script,
|
is_script,
|
||||||
..
|
..
|
||||||
})) => {
|
})) => {
|
||||||
if self.shared.cjs_tracker.is_cjs_with_known_is_script(
|
if self
|
||||||
specifier,
|
.shared
|
||||||
*media_type,
|
.cjs_tracker
|
||||||
*is_script,
|
.is_cjs_with_known_is_script(specifier, *media_type, *is_script)
|
||||||
)? {
|
.map_err(JsErrorBox::from_err)?
|
||||||
|
{
|
||||||
return Ok(Some(CodeOrDeferredEmit::Cjs {
|
return Ok(Some(CodeOrDeferredEmit::Cjs {
|
||||||
specifier,
|
specifier,
|
||||||
media_type: *media_type,
|
media_type: *media_type,
|
||||||
|
@ -875,16 +898,16 @@ impl<TGraphContainer: ModuleGraphContainer> ModuleLoader
|
||||||
specifier: &str,
|
specifier: &str,
|
||||||
referrer: &str,
|
referrer: &str,
|
||||||
_kind: deno_core::ResolutionKind,
|
_kind: deno_core::ResolutionKind,
|
||||||
) -> Result<ModuleSpecifier, AnyError> {
|
) -> Result<ModuleSpecifier, ModuleLoaderError> {
|
||||||
fn ensure_not_jsr_non_jsr_remote_import(
|
fn ensure_not_jsr_non_jsr_remote_import(
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
referrer: &ModuleSpecifier,
|
referrer: &ModuleSpecifier,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), JsErrorBox> {
|
||||||
if referrer.as_str().starts_with(jsr_url().as_str())
|
if referrer.as_str().starts_with(jsr_url().as_str())
|
||||||
&& !specifier.as_str().starts_with(jsr_url().as_str())
|
&& !specifier.as_str().starts_with(jsr_url().as_str())
|
||||||
&& matches!(specifier.scheme(), "http" | "https")
|
&& matches!(specifier.scheme(), "http" | "https")
|
||||||
{
|
{
|
||||||
bail!("Importing {} blocked. JSR packages cannot import non-JSR remote modules for security reasons.", specifier);
|
return Err(JsErrorBox::generic(format!("Importing {} blocked. JSR packages cannot import non-JSR remote modules for security reasons.", specifier)));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -937,7 +960,7 @@ impl<TGraphContainer: ModuleGraphContainer> ModuleLoader
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
_maybe_referrer: Option<String>,
|
_maybe_referrer: Option<String>,
|
||||||
is_dynamic: bool,
|
is_dynamic: bool,
|
||||||
) -> Pin<Box<dyn Future<Output = Result<(), AnyError>>>> {
|
) -> Pin<Box<dyn Future<Output = Result<(), ModuleLoaderError>>>> {
|
||||||
self.0.shared.in_flight_loads_tracker.increase();
|
self.0.shared.in_flight_loads_tracker.increase();
|
||||||
if self.0.shared.in_npm_pkg_checker.in_npm_package(specifier) {
|
if self.0.shared.in_npm_pkg_checker.in_npm_package(specifier) {
|
||||||
return Box::pin(deno_core::futures::future::ready(Ok(())));
|
return Box::pin(deno_core::futures::future::ready(Ok(())));
|
||||||
|
@ -986,7 +1009,8 @@ impl<TGraphContainer: ModuleGraphContainer> ModuleLoader
|
||||||
permissions,
|
permissions,
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.await?;
|
.await
|
||||||
|
.map_err(JsErrorBox::from_err)?;
|
||||||
update_permit.commit();
|
update_permit.commit();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1130,35 +1154,37 @@ impl<TGraphContainer: ModuleGraphContainer> NodeRequireLoader
|
||||||
&self,
|
&self,
|
||||||
permissions: &mut dyn deno_runtime::deno_node::NodePermissions,
|
permissions: &mut dyn deno_runtime::deno_node::NodePermissions,
|
||||||
path: &'a Path,
|
path: &'a Path,
|
||||||
) -> Result<std::borrow::Cow<'a, Path>, AnyError> {
|
) -> Result<Cow<'a, Path>, JsErrorBox> {
|
||||||
if let Ok(url) = deno_path_util::url_from_file_path(path) {
|
if let Ok(url) = deno_path_util::url_from_file_path(path) {
|
||||||
// allow reading if it's in the module graph
|
// allow reading if it's in the module graph
|
||||||
if self.graph_container.graph().get(&url).is_some() {
|
if self.graph_container.graph().get(&url).is_some() {
|
||||||
return Ok(std::borrow::Cow::Borrowed(path));
|
return Ok(Cow::Borrowed(path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
.npm_registry_permission_checker
|
.npm_registry_permission_checker
|
||||||
.ensure_read_permission(permissions, path)
|
.ensure_read_permission(permissions, path)
|
||||||
|
.map_err(JsErrorBox::from_err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_text_file_lossy(
|
fn load_text_file_lossy(
|
||||||
&self,
|
&self,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
) -> Result<Cow<'static, str>, AnyError> {
|
) -> Result<Cow<'static, str>, JsErrorBox> {
|
||||||
// todo(dsherret): use the preloaded module from the graph if available?
|
// todo(dsherret): use the preloaded module from the graph if available?
|
||||||
let media_type = MediaType::from_path(path);
|
let media_type = MediaType::from_path(path);
|
||||||
let text = self.sys.fs_read_to_string_lossy(path)?;
|
let text = self
|
||||||
|
.sys
|
||||||
|
.fs_read_to_string_lossy(path)
|
||||||
|
.map_err(JsErrorBox::from_err)?;
|
||||||
if media_type.is_emittable() {
|
if media_type.is_emittable() {
|
||||||
let specifier = deno_path_util::url_from_file_path(path)?;
|
let specifier = deno_path_util::url_from_file_path(path)
|
||||||
|
.map_err(JsErrorBox::from_err)?;
|
||||||
if self.in_npm_pkg_checker.in_npm_package(&specifier) {
|
if self.in_npm_pkg_checker.in_npm_package(&specifier) {
|
||||||
return Err(
|
return Err(JsErrorBox::from_err(NotSupportedKindInNpmError {
|
||||||
NotSupportedKindInNpmError {
|
media_type,
|
||||||
media_type,
|
specifier,
|
||||||
specifier,
|
}));
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
.emitter
|
.emitter
|
||||||
|
@ -1172,6 +1198,7 @@ impl<TGraphContainer: ModuleGraphContainer> NodeRequireLoader
|
||||||
&text.into(),
|
&text.into(),
|
||||||
)
|
)
|
||||||
.map(Cow::Owned)
|
.map(Cow::Owned)
|
||||||
|
.map_err(JsErrorBox::from_err)
|
||||||
} else {
|
} else {
|
||||||
Ok(text)
|
Ok(text)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ use deno_core::anyhow::Context;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::serde_json;
|
use deno_core::serde_json;
|
||||||
use deno_core::url::Url;
|
use deno_core::url::Url;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_npm::npm_rc::ResolvedNpmRc;
|
use deno_npm::npm_rc::ResolvedNpmRc;
|
||||||
use deno_npm::registry::NpmPackageInfo;
|
use deno_npm::registry::NpmPackageInfo;
|
||||||
use deno_npm::registry::NpmRegistryApi;
|
use deno_npm::registry::NpmRegistryApi;
|
||||||
|
@ -322,6 +323,28 @@ impl std::fmt::Debug for ManagedCliNpmResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
pub enum ResolvePkgFolderFromPkgIdError {
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("{0}")]
|
||||||
|
NpmPackageFsResolverPackageFolder(
|
||||||
|
#[from] resolvers::NpmPackageFsResolverPackageFolderError,
|
||||||
|
),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("{0}")]
|
||||||
|
Io(#[from] std::io::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
pub enum ResolvePkgFolderFromDenoModuleError {
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("{0}")]
|
||||||
|
PackageNvNotFound(#[from] deno_npm::resolution::PackageNvNotFoundError),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("{0}")]
|
||||||
|
ResolvePkgFolderFromPkgId(#[from] ResolvePkgFolderFromPkgIdError),
|
||||||
|
}
|
||||||
|
|
||||||
impl ManagedCliNpmResolver {
|
impl ManagedCliNpmResolver {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
@ -356,7 +379,7 @@ impl ManagedCliNpmResolver {
|
||||||
pub fn resolve_pkg_folder_from_pkg_id(
|
pub fn resolve_pkg_folder_from_pkg_id(
|
||||||
&self,
|
&self,
|
||||||
pkg_id: &NpmPackageId,
|
pkg_id: &NpmPackageId,
|
||||||
) -> Result<PathBuf, AnyError> {
|
) -> Result<PathBuf, ResolvePkgFolderFromPkgIdError> {
|
||||||
let path = self.fs_resolver.package_folder(pkg_id)?;
|
let path = self.fs_resolver.package_folder(pkg_id)?;
|
||||||
let path = canonicalize_path_maybe_not_exists(&self.sys, &path)?;
|
let path = canonicalize_path_maybe_not_exists(&self.sys, &path)?;
|
||||||
log::debug!(
|
log::debug!(
|
||||||
|
@ -423,7 +446,7 @@ impl ManagedCliNpmResolver {
|
||||||
pub async fn add_and_cache_package_reqs(
|
pub async fn add_and_cache_package_reqs(
|
||||||
&self,
|
&self,
|
||||||
packages: &[PackageReq],
|
packages: &[PackageReq],
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), JsErrorBox> {
|
||||||
self
|
self
|
||||||
.add_package_reqs_raw(
|
.add_package_reqs_raw(
|
||||||
packages,
|
packages,
|
||||||
|
@ -436,7 +459,7 @@ impl ManagedCliNpmResolver {
|
||||||
pub async fn add_package_reqs_no_cache(
|
pub async fn add_package_reqs_no_cache(
|
||||||
&self,
|
&self,
|
||||||
packages: &[PackageReq],
|
packages: &[PackageReq],
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), JsErrorBox> {
|
||||||
self
|
self
|
||||||
.add_package_reqs_raw(packages, None)
|
.add_package_reqs_raw(packages, None)
|
||||||
.await
|
.await
|
||||||
|
@ -447,7 +470,7 @@ impl ManagedCliNpmResolver {
|
||||||
&self,
|
&self,
|
||||||
packages: &[PackageReq],
|
packages: &[PackageReq],
|
||||||
caching: PackageCaching<'_>,
|
caching: PackageCaching<'_>,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), JsErrorBox> {
|
||||||
self
|
self
|
||||||
.add_package_reqs_raw(packages, Some(caching))
|
.add_package_reqs_raw(packages, Some(caching))
|
||||||
.await
|
.await
|
||||||
|
@ -517,7 +540,7 @@ impl ManagedCliNpmResolver {
|
||||||
|
|
||||||
pub async fn inject_synthetic_types_node_package(
|
pub async fn inject_synthetic_types_node_package(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), JsErrorBox> {
|
||||||
let reqs = &[PackageReq::from_str("@types/node").unwrap()];
|
let reqs = &[PackageReq::from_str("@types/node").unwrap()];
|
||||||
// add and ensure this isn't added to the lockfile
|
// add and ensure this isn't added to the lockfile
|
||||||
self
|
self
|
||||||
|
@ -530,16 +553,16 @@ impl ManagedCliNpmResolver {
|
||||||
pub async fn cache_packages(
|
pub async fn cache_packages(
|
||||||
&self,
|
&self,
|
||||||
caching: PackageCaching<'_>,
|
caching: PackageCaching<'_>,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), JsErrorBox> {
|
||||||
self.fs_resolver.cache_packages(caching).await
|
self.fs_resolver.cache_packages(caching).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_pkg_folder_from_deno_module(
|
pub fn resolve_pkg_folder_from_deno_module(
|
||||||
&self,
|
&self,
|
||||||
nv: &PackageNv,
|
nv: &PackageNv,
|
||||||
) -> Result<PathBuf, AnyError> {
|
) -> Result<PathBuf, ResolvePkgFolderFromDenoModuleError> {
|
||||||
let pkg_id = self.resolution.resolve_pkg_id_from_deno_module(nv)?;
|
let pkg_id = self.resolution.resolve_pkg_id_from_deno_module(nv)?;
|
||||||
self.resolve_pkg_folder_from_pkg_id(&pkg_id)
|
Ok(self.resolve_pkg_folder_from_pkg_id(&pkg_id)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_pkg_id_from_pkg_req(
|
pub fn resolve_pkg_id_from_pkg_req(
|
||||||
|
@ -580,7 +603,7 @@ impl ManagedCliNpmResolver {
|
||||||
/// return value of `false` means that new packages were added to the NPM resolution.
|
/// return value of `false` means that new packages were added to the NPM resolution.
|
||||||
pub async fn ensure_top_level_package_json_install(
|
pub async fn ensure_top_level_package_json_install(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<bool, AnyError> {
|
) -> Result<bool, JsErrorBox> {
|
||||||
if !self.top_level_install_flag.raise() {
|
if !self.top_level_install_flag.raise() {
|
||||||
return Ok(true); // already did this
|
return Ok(true); // already did this
|
||||||
}
|
}
|
||||||
|
@ -687,12 +710,12 @@ impl CliNpmReqResolver for ManagedCliNpmResolver {
|
||||||
req: &PackageReq,
|
req: &PackageReq,
|
||||||
_referrer: &ModuleSpecifier,
|
_referrer: &ModuleSpecifier,
|
||||||
) -> Result<PathBuf, ResolvePkgFolderFromDenoReqError> {
|
) -> Result<PathBuf, ResolvePkgFolderFromDenoReqError> {
|
||||||
let pkg_id = self
|
let pkg_id = self.resolve_pkg_id_from_pkg_req(req).map_err(|err| {
|
||||||
.resolve_pkg_id_from_pkg_req(req)
|
ResolvePkgFolderFromDenoReqError::Managed(Box::new(err))
|
||||||
.map_err(|err| ResolvePkgFolderFromDenoReqError::Managed(err.into()))?;
|
})?;
|
||||||
self
|
self
|
||||||
.resolve_pkg_folder_from_pkg_id(&pkg_id)
|
.resolve_pkg_folder_from_pkg_id(&pkg_id)
|
||||||
.map_err(ResolvePkgFolderFromDenoReqError::Managed)
|
.map_err(|err| ResolvePkgFolderFromDenoReqError::Managed(Box::new(err)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use capacity_builder::StringBuilder;
|
use capacity_builder::StringBuilder;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_lockfile::NpmPackageDependencyLockfileInfo;
|
use deno_lockfile::NpmPackageDependencyLockfileInfo;
|
||||||
use deno_lockfile::NpmPackageLockfileInfo;
|
use deno_lockfile::NpmPackageLockfileInfo;
|
||||||
use deno_npm::registry::NpmRegistryApi;
|
use deno_npm::registry::NpmRegistryApi;
|
||||||
|
@ -39,7 +40,7 @@ pub struct AddPkgReqsResult {
|
||||||
/// package requirements.
|
/// package requirements.
|
||||||
pub results: Vec<Result<PackageNv, NpmResolutionError>>,
|
pub results: Vec<Result<PackageNv, NpmResolutionError>>,
|
||||||
/// The final result of resolving and caching all the package requirements.
|
/// The final result of resolving and caching all the package requirements.
|
||||||
pub dependencies_result: Result<(), AnyError>,
|
pub dependencies_result: Result<(), JsErrorBox>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles updating and storing npm resolution in memory where the underlying
|
/// Handles updating and storing npm resolution in memory where the underlying
|
||||||
|
@ -106,7 +107,7 @@ impl NpmResolution {
|
||||||
*snapshot_lock.write() = snapshot;
|
*snapshot_lock.write() = snapshot;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(err) => Err(err.into()),
|
Err(err) => Err(JsErrorBox::from_err(err)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,18 @@ use std::path::PathBuf;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use deno_ast::ModuleSpecifier;
|
use deno_ast::ModuleSpecifier;
|
||||||
use deno_core::error::AnyError;
|
use deno_error::JsErrorBox;
|
||||||
use deno_npm::NpmPackageCacheFolderId;
|
use deno_npm::NpmPackageCacheFolderId;
|
||||||
use deno_npm::NpmPackageId;
|
use deno_npm::NpmPackageId;
|
||||||
use node_resolver::errors::PackageFolderResolveError;
|
use node_resolver::errors::PackageFolderResolveError;
|
||||||
|
|
||||||
use super::super::PackageCaching;
|
use super::super::PackageCaching;
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
#[class(generic)]
|
||||||
|
#[error("Package folder not found for '{0}'")]
|
||||||
|
pub struct NpmPackageFsResolverPackageFolderError(deno_semver::StackString);
|
||||||
|
|
||||||
/// Part of the resolution that interacts with the file system.
|
/// Part of the resolution that interacts with the file system.
|
||||||
#[async_trait(?Send)]
|
#[async_trait(?Send)]
|
||||||
pub trait NpmPackageFsResolver: Send + Sync {
|
pub trait NpmPackageFsResolver: Send + Sync {
|
||||||
|
@ -26,12 +31,9 @@ pub trait NpmPackageFsResolver: Send + Sync {
|
||||||
fn package_folder(
|
fn package_folder(
|
||||||
&self,
|
&self,
|
||||||
package_id: &NpmPackageId,
|
package_id: &NpmPackageId,
|
||||||
) -> Result<PathBuf, AnyError> {
|
) -> Result<PathBuf, NpmPackageFsResolverPackageFolderError> {
|
||||||
self.maybe_package_folder(package_id).ok_or_else(|| {
|
self.maybe_package_folder(package_id).ok_or_else(|| {
|
||||||
deno_core::anyhow::anyhow!(
|
NpmPackageFsResolverPackageFolderError(package_id.as_serialized())
|
||||||
"Package folder not found for '{}'",
|
|
||||||
package_id.as_serialized()
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,10 +46,10 @@ pub trait NpmPackageFsResolver: Send + Sync {
|
||||||
fn resolve_package_cache_folder_id_from_specifier(
|
fn resolve_package_cache_folder_id_from_specifier(
|
||||||
&self,
|
&self,
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
) -> Result<Option<NpmPackageCacheFolderId>, AnyError>;
|
) -> Result<Option<NpmPackageCacheFolderId>, std::io::Error>;
|
||||||
|
|
||||||
async fn cache_packages<'a>(
|
async fn cache_packages<'a>(
|
||||||
&self,
|
&self,
|
||||||
caching: PackageCaching<'a>,
|
caching: PackageCaching<'a>,
|
||||||
) -> Result<(), AnyError>;
|
) -> Result<(), JsErrorBox>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,6 @@ use std::collections::VecDeque;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use deno_core::anyhow::Context;
|
|
||||||
use deno_core::error::AnyError;
|
|
||||||
use deno_npm::resolution::NpmResolutionSnapshot;
|
use deno_npm::resolution::NpmResolutionSnapshot;
|
||||||
use deno_npm::NpmPackageId;
|
use deno_npm::NpmPackageId;
|
||||||
|
|
||||||
|
@ -50,6 +48,48 @@ pub fn warn_missing_entrypoint(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
pub enum BinEntriesError {
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("Creating '{path}'")]
|
||||||
|
Creating {
|
||||||
|
path: PathBuf,
|
||||||
|
#[source]
|
||||||
|
#[inherit]
|
||||||
|
source: std::io::Error,
|
||||||
|
},
|
||||||
|
#[cfg(unix)]
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("Setting permissions on '{path}'")]
|
||||||
|
Permissions {
|
||||||
|
path: PathBuf,
|
||||||
|
#[source]
|
||||||
|
#[inherit]
|
||||||
|
source: std::io::Error,
|
||||||
|
},
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("Can't set up '{name}' bin at {path}")]
|
||||||
|
SetUpBin {
|
||||||
|
name: String,
|
||||||
|
path: PathBuf,
|
||||||
|
#[source]
|
||||||
|
#[inherit]
|
||||||
|
source: Box<Self>,
|
||||||
|
},
|
||||||
|
#[cfg(unix)]
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("Setting permissions on '{path}'")]
|
||||||
|
RemoveBinSymlink {
|
||||||
|
path: PathBuf,
|
||||||
|
#[source]
|
||||||
|
#[inherit]
|
||||||
|
source: std::io::Error,
|
||||||
|
},
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
Io(#[from] std::io::Error),
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> BinEntries<'a> {
|
impl<'a> BinEntries<'a> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::default()
|
Self::default()
|
||||||
|
@ -92,15 +132,15 @@ impl<'a> BinEntries<'a> {
|
||||||
mut already_seen: impl FnMut(
|
mut already_seen: impl FnMut(
|
||||||
&Path,
|
&Path,
|
||||||
&str, // bin script
|
&str, // bin script
|
||||||
) -> Result<(), AnyError>,
|
) -> Result<(), BinEntriesError>,
|
||||||
mut new: impl FnMut(
|
mut new: impl FnMut(
|
||||||
&NpmResolutionPackage,
|
&NpmResolutionPackage,
|
||||||
&Path,
|
&Path,
|
||||||
&str, // bin name
|
&str, // bin name
|
||||||
&str, // bin script
|
&str, // bin script
|
||||||
) -> Result<(), AnyError>,
|
) -> Result<(), BinEntriesError>,
|
||||||
mut filter: impl FnMut(&NpmResolutionPackage) -> bool,
|
mut filter: impl FnMut(&NpmResolutionPackage) -> bool,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), BinEntriesError> {
|
||||||
if !self.collisions.is_empty() && !self.sorted {
|
if !self.collisions.is_empty() && !self.sorted {
|
||||||
// walking the dependency tree to find out the depth of each package
|
// walking the dependency tree to find out the depth of each package
|
||||||
// is sort of expensive, so we only do it if there's a collision
|
// is sort of expensive, so we only do it if there's a collision
|
||||||
|
@ -168,11 +208,14 @@ impl<'a> BinEntries<'a> {
|
||||||
bin_node_modules_dir_path: &Path,
|
bin_node_modules_dir_path: &Path,
|
||||||
filter: impl FnMut(&NpmResolutionPackage) -> bool,
|
filter: impl FnMut(&NpmResolutionPackage) -> bool,
|
||||||
mut handler: impl FnMut(&EntrySetupOutcome<'_>),
|
mut handler: impl FnMut(&EntrySetupOutcome<'_>),
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), BinEntriesError> {
|
||||||
if !self.entries.is_empty() && !bin_node_modules_dir_path.exists() {
|
if !self.entries.is_empty() && !bin_node_modules_dir_path.exists() {
|
||||||
std::fs::create_dir_all(bin_node_modules_dir_path).with_context(
|
std::fs::create_dir_all(bin_node_modules_dir_path).map_err(|source| {
|
||||||
|| format!("Creating '{}'", bin_node_modules_dir_path.display()),
|
BinEntriesError::Creating {
|
||||||
)?;
|
path: bin_node_modules_dir_path.to_path_buf(),
|
||||||
|
source,
|
||||||
|
}
|
||||||
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.for_each_entry(
|
self.for_each_entry(
|
||||||
|
@ -209,7 +252,7 @@ impl<'a> BinEntries<'a> {
|
||||||
snapshot: &NpmResolutionSnapshot,
|
snapshot: &NpmResolutionSnapshot,
|
||||||
bin_node_modules_dir_path: &Path,
|
bin_node_modules_dir_path: &Path,
|
||||||
handler: impl FnMut(&EntrySetupOutcome<'_>),
|
handler: impl FnMut(&EntrySetupOutcome<'_>),
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), BinEntriesError> {
|
||||||
self.set_up_entries_filtered(
|
self.set_up_entries_filtered(
|
||||||
snapshot,
|
snapshot,
|
||||||
bin_node_modules_dir_path,
|
bin_node_modules_dir_path,
|
||||||
|
@ -226,7 +269,7 @@ impl<'a> BinEntries<'a> {
|
||||||
bin_node_modules_dir_path: &Path,
|
bin_node_modules_dir_path: &Path,
|
||||||
handler: impl FnMut(&EntrySetupOutcome<'_>),
|
handler: impl FnMut(&EntrySetupOutcome<'_>),
|
||||||
only: &HashSet<&NpmPackageId>,
|
only: &HashSet<&NpmPackageId>,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), BinEntriesError> {
|
||||||
self.set_up_entries_filtered(
|
self.set_up_entries_filtered(
|
||||||
snapshot,
|
snapshot,
|
||||||
bin_node_modules_dir_path,
|
bin_node_modules_dir_path,
|
||||||
|
@ -301,7 +344,7 @@ pub fn set_up_bin_entry<'a>(
|
||||||
#[allow(unused_variables)] bin_script: &str,
|
#[allow(unused_variables)] bin_script: &str,
|
||||||
#[allow(unused_variables)] package_path: &'a Path,
|
#[allow(unused_variables)] package_path: &'a Path,
|
||||||
bin_node_modules_dir_path: &Path,
|
bin_node_modules_dir_path: &Path,
|
||||||
) -> Result<EntrySetupOutcome<'a>, AnyError> {
|
) -> Result<EntrySetupOutcome<'a>, BinEntriesError> {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
set_up_bin_shim(package, bin_name, bin_node_modules_dir_path)?;
|
set_up_bin_shim(package, bin_name, bin_node_modules_dir_path)?;
|
||||||
|
@ -324,14 +367,16 @@ fn set_up_bin_shim(
|
||||||
package: &NpmResolutionPackage,
|
package: &NpmResolutionPackage,
|
||||||
bin_name: &str,
|
bin_name: &str,
|
||||||
bin_node_modules_dir_path: &Path,
|
bin_node_modules_dir_path: &Path,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), BinEntriesError> {
|
||||||
use std::fs;
|
use std::fs;
|
||||||
let mut cmd_shim = bin_node_modules_dir_path.join(bin_name);
|
let mut cmd_shim = bin_node_modules_dir_path.join(bin_name);
|
||||||
|
|
||||||
cmd_shim.set_extension("cmd");
|
cmd_shim.set_extension("cmd");
|
||||||
let shim = format!("@deno run -A npm:{}/{bin_name} %*", package.id.nv);
|
let shim = format!("@deno run -A npm:{}/{bin_name} %*", package.id.nv);
|
||||||
fs::write(&cmd_shim, shim).with_context(|| {
|
fs::write(&cmd_shim, shim).map_err(|err| BinEntriesError::SetUpBin {
|
||||||
format!("Can't set up '{}' bin at {}", bin_name, cmd_shim.display())
|
name: bin_name.to_string(),
|
||||||
|
path: cmd_shim.clone(),
|
||||||
|
source: Box::new(err.into()),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -340,7 +385,7 @@ fn set_up_bin_shim(
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
/// Make the file at `path` executable if it exists.
|
/// Make the file at `path` executable if it exists.
|
||||||
/// Returns `true` if the file exists, `false` otherwise.
|
/// Returns `true` if the file exists, `false` otherwise.
|
||||||
fn make_executable_if_exists(path: &Path) -> Result<bool, AnyError> {
|
fn make_executable_if_exists(path: &Path) -> Result<bool, BinEntriesError> {
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::os::unix::fs::PermissionsExt;
|
use std::os::unix::fs::PermissionsExt;
|
||||||
let mut perms = match std::fs::metadata(path) {
|
let mut perms = match std::fs::metadata(path) {
|
||||||
|
@ -355,8 +400,11 @@ fn make_executable_if_exists(path: &Path) -> Result<bool, AnyError> {
|
||||||
if perms.mode() & 0o111 == 0 {
|
if perms.mode() & 0o111 == 0 {
|
||||||
// if the original file is not executable, make it executable
|
// if the original file is not executable, make it executable
|
||||||
perms.set_mode(perms.mode() | 0o111);
|
perms.set_mode(perms.mode() | 0o111);
|
||||||
std::fs::set_permissions(path, perms).with_context(|| {
|
std::fs::set_permissions(path, perms).map_err(|source| {
|
||||||
format!("Setting permissions on '{}'", path.display())
|
BinEntriesError::Permissions {
|
||||||
|
path: path.to_path_buf(),
|
||||||
|
source,
|
||||||
|
}
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,14 +443,18 @@ fn symlink_bin_entry<'a>(
|
||||||
bin_script: &str,
|
bin_script: &str,
|
||||||
package_path: &'a Path,
|
package_path: &'a Path,
|
||||||
bin_node_modules_dir_path: &Path,
|
bin_node_modules_dir_path: &Path,
|
||||||
) -> Result<EntrySetupOutcome<'a>, AnyError> {
|
) -> Result<EntrySetupOutcome<'a>, BinEntriesError> {
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::os::unix::fs::symlink;
|
use std::os::unix::fs::symlink;
|
||||||
let link = bin_node_modules_dir_path.join(bin_name);
|
let link = bin_node_modules_dir_path.join(bin_name);
|
||||||
let original = package_path.join(bin_script);
|
let original = package_path.join(bin_script);
|
||||||
|
|
||||||
let found = make_executable_if_exists(&original).with_context(|| {
|
let found = make_executable_if_exists(&original).map_err(|source| {
|
||||||
format!("Can't set up '{}' bin at {}", bin_name, original.display())
|
BinEntriesError::SetUpBin {
|
||||||
|
name: bin_name.to_string(),
|
||||||
|
path: original.to_path_buf(),
|
||||||
|
source: Box::new(source),
|
||||||
|
}
|
||||||
})?;
|
})?;
|
||||||
if !found {
|
if !found {
|
||||||
return Ok(EntrySetupOutcome::MissingEntrypoint {
|
return Ok(EntrySetupOutcome::MissingEntrypoint {
|
||||||
|
@ -420,27 +472,25 @@ fn symlink_bin_entry<'a>(
|
||||||
if let Err(err) = symlink(&original_relative, &link) {
|
if let Err(err) = symlink(&original_relative, &link) {
|
||||||
if err.kind() == io::ErrorKind::AlreadyExists {
|
if err.kind() == io::ErrorKind::AlreadyExists {
|
||||||
// remove and retry
|
// remove and retry
|
||||||
std::fs::remove_file(&link).with_context(|| {
|
std::fs::remove_file(&link).map_err(|source| {
|
||||||
format!(
|
BinEntriesError::RemoveBinSymlink {
|
||||||
"Failed to remove existing bin symlink at {}",
|
path: link.clone(),
|
||||||
link.display()
|
source,
|
||||||
)
|
}
|
||||||
})?;
|
})?;
|
||||||
symlink(&original_relative, &link).with_context(|| {
|
symlink(&original_relative, &link).map_err(|source| {
|
||||||
format!(
|
BinEntriesError::SetUpBin {
|
||||||
"Can't set up '{}' bin at {}",
|
name: bin_name.to_string(),
|
||||||
bin_name,
|
path: original_relative.to_path_buf(),
|
||||||
original_relative.display()
|
source: Box::new(source.into()),
|
||||||
)
|
}
|
||||||
})?;
|
})?;
|
||||||
return Ok(EntrySetupOutcome::Success);
|
return Ok(EntrySetupOutcome::Success);
|
||||||
}
|
}
|
||||||
return Err(err).with_context(|| {
|
return Err(BinEntriesError::SetUpBin {
|
||||||
format!(
|
name: bin_name.to_string(),
|
||||||
"Can't set up '{}' bin at {}",
|
path: original_relative.to_path_buf(),
|
||||||
bin_name,
|
source: Box::new(err.into()),
|
||||||
original_relative.display()
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use deno_core::anyhow::Context;
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_npm::resolution::NpmResolutionSnapshot;
|
use deno_npm::resolution::NpmResolutionSnapshot;
|
||||||
use deno_npm::NpmResolutionPackage;
|
use deno_npm::NpmResolutionPackage;
|
||||||
|
@ -29,7 +28,7 @@ pub trait LifecycleScriptsStrategy {
|
||||||
fn warn_on_scripts_not_run(
|
fn warn_on_scripts_not_run(
|
||||||
&self,
|
&self,
|
||||||
packages: &[(&NpmResolutionPackage, PathBuf)],
|
packages: &[(&NpmResolutionPackage, PathBuf)],
|
||||||
) -> Result<(), AnyError>;
|
) -> Result<(), std::io::Error>;
|
||||||
|
|
||||||
fn has_warned(&self, package: &NpmResolutionPackage) -> bool;
|
fn has_warned(&self, package: &NpmResolutionPackage) -> bool;
|
||||||
|
|
||||||
|
@ -38,7 +37,7 @@ pub trait LifecycleScriptsStrategy {
|
||||||
fn did_run_scripts(
|
fn did_run_scripts(
|
||||||
&self,
|
&self,
|
||||||
package: &NpmResolutionPackage,
|
package: &NpmResolutionPackage,
|
||||||
) -> Result<(), AnyError>;
|
) -> Result<(), std::io::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LifecycleScripts<'a> {
|
pub struct LifecycleScripts<'a> {
|
||||||
|
@ -84,6 +83,27 @@ fn is_broken_default_install_script(script: &str, package_path: &Path) -> bool {
|
||||||
script == "node-gyp rebuild" && !package_path.join("binding.gyp").exists()
|
script == "node-gyp rebuild" && !package_path.join("binding.gyp").exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
pub enum LifecycleScriptsError {
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
Io(#[from] std::io::Error),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
BinEntries(#[from] super::bin_entries::BinEntriesError),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(
|
||||||
|
"failed to create npm process state tempfile for running lifecycle scripts"
|
||||||
|
)]
|
||||||
|
CreateNpmProcessState(#[source] std::io::Error),
|
||||||
|
#[class(generic)]
|
||||||
|
#[error(transparent)]
|
||||||
|
Task(AnyError),
|
||||||
|
#[class(generic)]
|
||||||
|
#[error("failed to run scripts for packages: {}", .0.join(", "))]
|
||||||
|
RunScripts(Vec<String>),
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> LifecycleScripts<'a> {
|
impl<'a> LifecycleScripts<'a> {
|
||||||
pub fn can_run_scripts(&self, package_nv: &PackageNv) -> bool {
|
pub fn can_run_scripts(&self, package_nv: &PackageNv) -> bool {
|
||||||
if !self.strategy.can_run_scripts() {
|
if !self.strategy.can_run_scripts() {
|
||||||
|
@ -141,7 +161,7 @@ impl<'a> LifecycleScripts<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn warn_not_run_scripts(&self) -> Result<(), AnyError> {
|
pub fn warn_not_run_scripts(&self) -> Result<(), std::io::Error> {
|
||||||
if !self.packages_with_scripts_not_run.is_empty() {
|
if !self.packages_with_scripts_not_run.is_empty() {
|
||||||
self
|
self
|
||||||
.strategy
|
.strategy
|
||||||
|
@ -156,7 +176,7 @@ impl<'a> LifecycleScripts<'a> {
|
||||||
packages: &[NpmResolutionPackage],
|
packages: &[NpmResolutionPackage],
|
||||||
root_node_modules_dir_path: &Path,
|
root_node_modules_dir_path: &Path,
|
||||||
progress_bar: &ProgressBar,
|
progress_bar: &ProgressBar,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), LifecycleScriptsError> {
|
||||||
let kill_signal = KillSignal::default();
|
let kill_signal = KillSignal::default();
|
||||||
let _drop_signal = kill_signal.clone().drop_guard();
|
let _drop_signal = kill_signal.clone().drop_guard();
|
||||||
// we don't run with signals forwarded because once signals
|
// we don't run with signals forwarded because once signals
|
||||||
|
@ -179,7 +199,7 @@ impl<'a> LifecycleScripts<'a> {
|
||||||
root_node_modules_dir_path: &Path,
|
root_node_modules_dir_path: &Path,
|
||||||
progress_bar: &ProgressBar,
|
progress_bar: &ProgressBar,
|
||||||
kill_signal: KillSignal,
|
kill_signal: KillSignal,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), LifecycleScriptsError> {
|
||||||
self.warn_not_run_scripts()?;
|
self.warn_not_run_scripts()?;
|
||||||
let get_package_path =
|
let get_package_path =
|
||||||
|p: &NpmResolutionPackage| self.strategy.package_path(p);
|
|p: &NpmResolutionPackage| self.strategy.package_path(p);
|
||||||
|
@ -198,7 +218,7 @@ impl<'a> LifecycleScripts<'a> {
|
||||||
snapshot,
|
snapshot,
|
||||||
packages,
|
packages,
|
||||||
get_package_path,
|
get_package_path,
|
||||||
)?;
|
);
|
||||||
let init_cwd = &self.config.initial_cwd;
|
let init_cwd = &self.config.initial_cwd;
|
||||||
let process_state = crate::npm::managed::npm_process_state(
|
let process_state = crate::npm::managed::npm_process_state(
|
||||||
snapshot.as_valid_serialized(),
|
snapshot.as_valid_serialized(),
|
||||||
|
@ -222,7 +242,8 @@ impl<'a> LifecycleScripts<'a> {
|
||||||
let temp_file_fd =
|
let temp_file_fd =
|
||||||
deno_runtime::ops::process::npm_process_state_tempfile(
|
deno_runtime::ops::process::npm_process_state_tempfile(
|
||||||
process_state.as_bytes(),
|
process_state.as_bytes(),
|
||||||
).context("failed to create npm process state tempfile for running lifecycle scripts")?;
|
)
|
||||||
|
.map_err(LifecycleScriptsError::CreateNpmProcessState)?;
|
||||||
// SAFETY: fd/handle is valid
|
// SAFETY: fd/handle is valid
|
||||||
let _temp_file =
|
let _temp_file =
|
||||||
unsafe { std::fs::File::from_raw_io_handle(temp_file_fd) }; // make sure the file gets closed
|
unsafe { std::fs::File::from_raw_io_handle(temp_file_fd) }; // make sure the file gets closed
|
||||||
|
@ -240,7 +261,7 @@ impl<'a> LifecycleScripts<'a> {
|
||||||
package,
|
package,
|
||||||
snapshot,
|
snapshot,
|
||||||
get_package_path,
|
get_package_path,
|
||||||
)?;
|
);
|
||||||
for script_name in ["preinstall", "install", "postinstall"] {
|
for script_name in ["preinstall", "install", "postinstall"] {
|
||||||
if let Some(script) = package.scripts.get(script_name) {
|
if let Some(script) = package.scripts.get(script_name) {
|
||||||
if script_name == "install"
|
if script_name == "install"
|
||||||
|
@ -273,7 +294,8 @@ impl<'a> LifecycleScripts<'a> {
|
||||||
kill_signal: kill_signal.clone(),
|
kill_signal: kill_signal.clone(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await?;
|
.await
|
||||||
|
.map_err(LifecycleScriptsError::Task)?;
|
||||||
let stdout = stdout.unwrap();
|
let stdout = stdout.unwrap();
|
||||||
let stderr = stderr.unwrap();
|
let stderr = stderr.unwrap();
|
||||||
if exit_code != 0 {
|
if exit_code != 0 {
|
||||||
|
@ -322,14 +344,12 @@ impl<'a> LifecycleScripts<'a> {
|
||||||
if failed_packages.is_empty() {
|
if failed_packages.is_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(AnyError::msg(format!(
|
Err(LifecycleScriptsError::RunScripts(
|
||||||
"failed to run scripts for packages: {}",
|
|
||||||
failed_packages
|
failed_packages
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| p.to_string())
|
.map(|p| p.to_string())
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>(),
|
||||||
.join(", ")
|
))
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,7 +369,7 @@ fn resolve_baseline_custom_commands<'a>(
|
||||||
snapshot: &'a NpmResolutionSnapshot,
|
snapshot: &'a NpmResolutionSnapshot,
|
||||||
packages: &'a [NpmResolutionPackage],
|
packages: &'a [NpmResolutionPackage],
|
||||||
get_package_path: impl Fn(&NpmResolutionPackage) -> PathBuf,
|
get_package_path: impl Fn(&NpmResolutionPackage) -> PathBuf,
|
||||||
) -> Result<crate::task_runner::TaskCustomCommands, AnyError> {
|
) -> crate::task_runner::TaskCustomCommands {
|
||||||
let mut custom_commands = crate::task_runner::TaskCustomCommands::new();
|
let mut custom_commands = crate::task_runner::TaskCustomCommands::new();
|
||||||
custom_commands
|
custom_commands
|
||||||
.insert("npx".to_string(), Rc::new(crate::task_runner::NpxCommand));
|
.insert("npx".to_string(), Rc::new(crate::task_runner::NpxCommand));
|
||||||
|
@ -390,7 +410,7 @@ fn resolve_custom_commands_from_packages<
|
||||||
snapshot: &'a NpmResolutionSnapshot,
|
snapshot: &'a NpmResolutionSnapshot,
|
||||||
packages: P,
|
packages: P,
|
||||||
get_package_path: impl Fn(&'a NpmResolutionPackage) -> PathBuf,
|
get_package_path: impl Fn(&'a NpmResolutionPackage) -> PathBuf,
|
||||||
) -> Result<crate::task_runner::TaskCustomCommands, AnyError> {
|
) -> crate::task_runner::TaskCustomCommands {
|
||||||
for package in packages {
|
for package in packages {
|
||||||
let package_path = get_package_path(package);
|
let package_path = get_package_path(package);
|
||||||
|
|
||||||
|
@ -409,7 +429,7 @@ fn resolve_custom_commands_from_packages<
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(commands)
|
commands
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolves the custom commands from the dependencies of a package
|
// resolves the custom commands from the dependencies of a package
|
||||||
|
@ -420,7 +440,7 @@ fn resolve_custom_commands_from_deps(
|
||||||
package: &NpmResolutionPackage,
|
package: &NpmResolutionPackage,
|
||||||
snapshot: &NpmResolutionSnapshot,
|
snapshot: &NpmResolutionSnapshot,
|
||||||
get_package_path: impl Fn(&NpmResolutionPackage) -> PathBuf,
|
get_package_path: impl Fn(&NpmResolutionPackage) -> PathBuf,
|
||||||
) -> Result<crate::task_runner::TaskCustomCommands, AnyError> {
|
) -> crate::task_runner::TaskCustomCommands {
|
||||||
let mut bin_entries = BinEntries::new();
|
let mut bin_entries = BinEntries::new();
|
||||||
resolve_custom_commands_from_packages(
|
resolve_custom_commands_from_packages(
|
||||||
&mut bin_entries,
|
&mut bin_entries,
|
||||||
|
|
|
@ -9,9 +9,9 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use deno_ast::ModuleSpecifier;
|
use deno_ast::ModuleSpecifier;
|
||||||
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_error::JsErrorBox;
|
||||||
use deno_npm::NpmPackageCacheFolderId;
|
use deno_npm::NpmPackageCacheFolderId;
|
||||||
use deno_npm::NpmPackageId;
|
use deno_npm::NpmPackageId;
|
||||||
use deno_npm::NpmResolutionPackage;
|
use deno_npm::NpmResolutionPackage;
|
||||||
|
@ -134,7 +134,7 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver {
|
||||||
fn resolve_package_cache_folder_id_from_specifier(
|
fn resolve_package_cache_folder_id_from_specifier(
|
||||||
&self,
|
&self,
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
) -> Result<Option<NpmPackageCacheFolderId>, AnyError> {
|
) -> Result<Option<NpmPackageCacheFolderId>, std::io::Error> {
|
||||||
Ok(
|
Ok(
|
||||||
self
|
self
|
||||||
.cache
|
.cache
|
||||||
|
@ -145,7 +145,7 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver {
|
||||||
async fn cache_packages<'a>(
|
async fn cache_packages<'a>(
|
||||||
&self,
|
&self,
|
||||||
caching: PackageCaching<'a>,
|
caching: PackageCaching<'a>,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), JsErrorBox> {
|
||||||
let package_partitions = match caching {
|
let package_partitions = match caching {
|
||||||
PackageCaching::All => self
|
PackageCaching::All => self
|
||||||
.resolution
|
.resolution
|
||||||
|
@ -155,13 +155,16 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver {
|
||||||
.subset(&reqs)
|
.subset(&reqs)
|
||||||
.all_system_packages_partitioned(&self.system_info),
|
.all_system_packages_partitioned(&self.system_info),
|
||||||
};
|
};
|
||||||
cache_packages(&package_partitions.packages, &self.tarball_cache).await?;
|
cache_packages(&package_partitions.packages, &self.tarball_cache)
|
||||||
|
.await
|
||||||
|
.map_err(JsErrorBox::from_err)?;
|
||||||
|
|
||||||
// create the copy package folders
|
// create the copy package folders
|
||||||
for copy in package_partitions.copy_packages {
|
for copy in package_partitions.copy_packages {
|
||||||
self
|
self
|
||||||
.cache
|
.cache
|
||||||
.ensure_copy_package(©.get_package_cache_folder_id())?;
|
.ensure_copy_package(©.get_package_cache_folder_id())
|
||||||
|
.map_err(JsErrorBox::from_err)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut lifecycle_scripts =
|
let mut lifecycle_scripts =
|
||||||
|
@ -174,7 +177,9 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver {
|
||||||
lifecycle_scripts.add(package, Cow::Borrowed(&package_folder));
|
lifecycle_scripts.add(package, Cow::Borrowed(&package_folder));
|
||||||
}
|
}
|
||||||
|
|
||||||
lifecycle_scripts.warn_not_run_scripts()?;
|
lifecycle_scripts
|
||||||
|
.warn_not_run_scripts()
|
||||||
|
.map_err(JsErrorBox::from_err)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -183,7 +188,7 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver {
|
||||||
async fn cache_packages(
|
async fn cache_packages(
|
||||||
packages: &[NpmResolutionPackage],
|
packages: &[NpmResolutionPackage],
|
||||||
tarball_cache: &Arc<CliNpmTarballCache>,
|
tarball_cache: &Arc<CliNpmTarballCache>,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), deno_npm_cache::EnsurePackageError> {
|
||||||
let mut futures_unordered = FuturesUnordered::new();
|
let mut futures_unordered = FuturesUnordered::new();
|
||||||
for package in packages {
|
for package in packages {
|
||||||
futures_unordered.push(async move {
|
futures_unordered.push(async move {
|
||||||
|
@ -235,7 +240,7 @@ impl<'a> super::common::lifecycle_scripts::LifecycleScriptsStrategy
|
||||||
fn warn_on_scripts_not_run(
|
fn warn_on_scripts_not_run(
|
||||||
&self,
|
&self,
|
||||||
packages: &[(&NpmResolutionPackage, PathBuf)],
|
packages: &[(&NpmResolutionPackage, PathBuf)],
|
||||||
) -> std::result::Result<(), deno_core::anyhow::Error> {
|
) -> std::result::Result<(), std::io::Error> {
|
||||||
log::warn!("{} The following packages contained npm lifecycle scripts ({}) that were not executed:", colors::yellow("Warning"), colors::gray("preinstall/install/postinstall"));
|
log::warn!("{} The following packages contained npm lifecycle scripts ({}) that were not executed:", colors::yellow("Warning"), colors::gray("preinstall/install/postinstall"));
|
||||||
for (package, _) in packages {
|
for (package, _) in packages {
|
||||||
log::warn!("┠─ {}", colors::gray(format!("npm:{}", package.id.nv)));
|
log::warn!("┠─ {}", colors::gray(format!("npm:{}", package.id.nv)));
|
||||||
|
@ -261,7 +266,7 @@ impl<'a> super::common::lifecycle_scripts::LifecycleScriptsStrategy
|
||||||
fn did_run_scripts(
|
fn did_run_scripts(
|
||||||
&self,
|
&self,
|
||||||
_package: &NpmResolutionPackage,
|
_package: &NpmResolutionPackage,
|
||||||
) -> std::result::Result<(), deno_core::anyhow::Error> {
|
) -> Result<(), std::io::Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,12 +19,11 @@ use std::sync::Arc;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use deno_ast::ModuleSpecifier;
|
use deno_ast::ModuleSpecifier;
|
||||||
use deno_cache_dir::npm::mixed_case_package_name_decode;
|
use deno_cache_dir::npm::mixed_case_package_name_decode;
|
||||||
use deno_core::anyhow::Context;
|
|
||||||
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_core::parking_lot::Mutex;
|
use deno_core::parking_lot::Mutex;
|
||||||
use deno_core::url::Url;
|
use deno_core::url::Url;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_npm::resolution::NpmResolutionSnapshot;
|
use deno_npm::resolution::NpmResolutionSnapshot;
|
||||||
use deno_npm::NpmPackageCacheFolderId;
|
use deno_npm::NpmPackageCacheFolderId;
|
||||||
use deno_npm::NpmPackageId;
|
use deno_npm::NpmPackageId;
|
||||||
|
@ -140,7 +139,7 @@ impl LocalNpmPackageResolver {
|
||||||
fn resolve_package_folder_from_specifier(
|
fn resolve_package_folder_from_specifier(
|
||||||
&self,
|
&self,
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
) -> Result<Option<PathBuf>, AnyError> {
|
) -> Result<Option<PathBuf>, std::io::Error> {
|
||||||
let Some(local_path) = self.resolve_folder_for_specifier(specifier)? else {
|
let Some(local_path) = self.resolve_folder_for_specifier(specifier)? else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
|
@ -225,7 +224,7 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
|
||||||
fn resolve_package_cache_folder_id_from_specifier(
|
fn resolve_package_cache_folder_id_from_specifier(
|
||||||
&self,
|
&self,
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
) -> Result<Option<NpmPackageCacheFolderId>, AnyError> {
|
) -> Result<Option<NpmPackageCacheFolderId>, std::io::Error> {
|
||||||
let Some(folder_path) =
|
let Some(folder_path) =
|
||||||
self.resolve_package_folder_from_specifier(specifier)?
|
self.resolve_package_folder_from_specifier(specifier)?
|
||||||
else {
|
else {
|
||||||
|
@ -251,7 +250,7 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
|
||||||
async fn cache_packages<'a>(
|
async fn cache_packages<'a>(
|
||||||
&self,
|
&self,
|
||||||
caching: PackageCaching<'a>,
|
caching: PackageCaching<'a>,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), JsErrorBox> {
|
||||||
let snapshot = match caching {
|
let snapshot = match caching {
|
||||||
PackageCaching::All => self.resolution.snapshot(),
|
PackageCaching::All => self.resolution.snapshot(),
|
||||||
PackageCaching::Only(reqs) => self.resolution.subset(&reqs),
|
PackageCaching::Only(reqs) => self.resolution.subset(&reqs),
|
||||||
|
@ -267,6 +266,7 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
|
||||||
&self.lifecycle_scripts,
|
&self.lifecycle_scripts,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
.map_err(JsErrorBox::from_err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,6 +285,38 @@ fn local_node_modules_package_contents_path(
|
||||||
.join(&package.id.nv.name)
|
.join(&package.id.nv.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
pub enum SyncResolutionWithFsError {
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("Creating '{path}'")]
|
||||||
|
Creating {
|
||||||
|
path: PathBuf,
|
||||||
|
#[source]
|
||||||
|
#[inherit]
|
||||||
|
source: std::io::Error,
|
||||||
|
},
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
CopyDirRecursive(#[from] crate::util::fs::CopyDirRecursiveError),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
SymlinkPackageDir(#[from] SymlinkPackageDirError),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
BinEntries(#[from] bin_entries::BinEntriesError),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
LifecycleScripts(
|
||||||
|
#[from] super::common::lifecycle_scripts::LifecycleScriptsError,
|
||||||
|
),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
Io(#[from] std::io::Error),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
Other(#[from] JsErrorBox),
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a pnpm style folder structure.
|
/// Creates a pnpm style folder structure.
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
async fn sync_resolution_with_fs(
|
async fn sync_resolution_with_fs(
|
||||||
|
@ -296,7 +328,7 @@ async fn sync_resolution_with_fs(
|
||||||
root_node_modules_dir_path: &Path,
|
root_node_modules_dir_path: &Path,
|
||||||
system_info: &NpmSystemInfo,
|
system_info: &NpmSystemInfo,
|
||||||
lifecycle_scripts: &LifecycleScriptsConfig,
|
lifecycle_scripts: &LifecycleScriptsConfig,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), SyncResolutionWithFsError> {
|
||||||
if snapshot.is_empty()
|
if snapshot.is_empty()
|
||||||
&& npm_install_deps_provider.workspace_pkgs().is_empty()
|
&& npm_install_deps_provider.workspace_pkgs().is_empty()
|
||||||
{
|
{
|
||||||
|
@ -311,12 +343,18 @@ async fn sync_resolution_with_fs(
|
||||||
|
|
||||||
let deno_local_registry_dir = root_node_modules_dir_path.join(".deno");
|
let deno_local_registry_dir = root_node_modules_dir_path.join(".deno");
|
||||||
let deno_node_modules_dir = deno_local_registry_dir.join("node_modules");
|
let deno_node_modules_dir = deno_local_registry_dir.join("node_modules");
|
||||||
fs::create_dir_all(&deno_node_modules_dir).with_context(|| {
|
fs::create_dir_all(&deno_node_modules_dir).map_err(|source| {
|
||||||
format!("Creating '{}'", deno_local_registry_dir.display())
|
SyncResolutionWithFsError::Creating {
|
||||||
|
path: deno_local_registry_dir.to_path_buf(),
|
||||||
|
source,
|
||||||
|
}
|
||||||
})?;
|
})?;
|
||||||
let bin_node_modules_dir_path = root_node_modules_dir_path.join(".bin");
|
let bin_node_modules_dir_path = root_node_modules_dir_path.join(".bin");
|
||||||
fs::create_dir_all(&bin_node_modules_dir_path).with_context(|| {
|
fs::create_dir_all(&bin_node_modules_dir_path).map_err(|source| {
|
||||||
format!("Creating '{}'", bin_node_modules_dir_path.display())
|
SyncResolutionWithFsError::Creating {
|
||||||
|
path: deno_local_registry_dir.to_path_buf(),
|
||||||
|
source,
|
||||||
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let single_process_lock = LaxSingleProcessFsFlag::lock(
|
let single_process_lock = LaxSingleProcessFsFlag::lock(
|
||||||
|
@ -420,7 +458,8 @@ async fn sync_resolution_with_fs(
|
||||||
cache_futures.push(async move {
|
cache_futures.push(async move {
|
||||||
tarball_cache
|
tarball_cache
|
||||||
.ensure_package(&package.id.nv, &package.dist)
|
.ensure_package(&package.id.nv, &package.dist)
|
||||||
.await?;
|
.await
|
||||||
|
.map_err(JsErrorBox::from_err)?;
|
||||||
let pb_guard = progress_bar.update_with_prompt(
|
let pb_guard = progress_bar.update_with_prompt(
|
||||||
ProgressMessagePrompt::Initialize,
|
ProgressMessagePrompt::Initialize,
|
||||||
&package.id.nv.to_string(),
|
&package.id.nv.to_string(),
|
||||||
|
@ -441,10 +480,12 @@ async fn sync_resolution_with_fs(
|
||||||
// write out a file that indicates this folder has been initialized
|
// write out a file that indicates this folder has been initialized
|
||||||
fs::write(initialized_file, tags)?;
|
fs::write(initialized_file, tags)?;
|
||||||
|
|
||||||
Ok::<_, AnyError>(())
|
Ok::<_, SyncResolutionWithFsError>(())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.await??;
|
.await
|
||||||
|
.map_err(JsErrorBox::from_err)?
|
||||||
|
.map_err(JsErrorBox::from_err)?;
|
||||||
|
|
||||||
if package.bin.is_some() {
|
if package.bin.is_some() {
|
||||||
bin_entries_to_setup.borrow_mut().add(package, package_path);
|
bin_entries_to_setup.borrow_mut().add(package, package_path);
|
||||||
|
@ -458,7 +499,7 @@ async fn sync_resolution_with_fs(
|
||||||
|
|
||||||
// finally stop showing the progress bar
|
// finally stop showing the progress bar
|
||||||
drop(pb_guard); // explicit for clarity
|
drop(pb_guard); // explicit for clarity
|
||||||
Ok::<_, AnyError>(())
|
Ok::<_, JsErrorBox>(())
|
||||||
});
|
});
|
||||||
} else if matches!(package_state, PackageFolderState::TagsOutdated) {
|
} else if matches!(package_state, PackageFolderState::TagsOutdated) {
|
||||||
fs::write(initialized_file, tags)?;
|
fs::write(initialized_file, tags)?;
|
||||||
|
@ -597,8 +638,11 @@ async fn sync_resolution_with_fs(
|
||||||
// symlink the dep into the package's child node_modules folder
|
// symlink the dep into the package's child node_modules folder
|
||||||
let dest_node_modules = remote.base_dir.join("node_modules");
|
let dest_node_modules = remote.base_dir.join("node_modules");
|
||||||
if !existing_child_node_modules_dirs.contains(&dest_node_modules) {
|
if !existing_child_node_modules_dirs.contains(&dest_node_modules) {
|
||||||
fs::create_dir_all(&dest_node_modules).with_context(|| {
|
fs::create_dir_all(&dest_node_modules).map_err(|source| {
|
||||||
format!("Creating '{}'", dest_node_modules.display())
|
SyncResolutionWithFsError::Creating {
|
||||||
|
path: dest_node_modules.clone(),
|
||||||
|
source,
|
||||||
|
}
|
||||||
})?;
|
})?;
|
||||||
existing_child_node_modules_dirs.insert(dest_node_modules.clone());
|
existing_child_node_modules_dirs.insert(dest_node_modules.clone());
|
||||||
}
|
}
|
||||||
|
@ -813,7 +857,7 @@ impl<'a> super::common::lifecycle_scripts::LifecycleScriptsStrategy
|
||||||
fn did_run_scripts(
|
fn did_run_scripts(
|
||||||
&self,
|
&self,
|
||||||
package: &NpmResolutionPackage,
|
package: &NpmResolutionPackage,
|
||||||
) -> std::result::Result<(), deno_core::anyhow::Error> {
|
) -> std::result::Result<(), std::io::Error> {
|
||||||
std::fs::write(self.ran_scripts_file(package), "")?;
|
std::fs::write(self.ran_scripts_file(package), "")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -821,7 +865,7 @@ impl<'a> super::common::lifecycle_scripts::LifecycleScriptsStrategy
|
||||||
fn warn_on_scripts_not_run(
|
fn warn_on_scripts_not_run(
|
||||||
&self,
|
&self,
|
||||||
packages: &[(&NpmResolutionPackage, std::path::PathBuf)],
|
packages: &[(&NpmResolutionPackage, std::path::PathBuf)],
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), std::io::Error> {
|
||||||
if !packages.is_empty() {
|
if !packages.is_empty() {
|
||||||
log::warn!("{} The following packages contained npm lifecycle scripts ({}) that were not executed:", colors::yellow("Warning"), colors::gray("preinstall/install/postinstall"));
|
log::warn!("{} The following packages contained npm lifecycle scripts ({}) that were not executed:", colors::yellow("Warning"), colors::gray("preinstall/install/postinstall"));
|
||||||
|
|
||||||
|
@ -1041,15 +1085,42 @@ fn get_package_folder_id_from_folder_name(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
pub enum SymlinkPackageDirError {
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("Creating '{parent}'")]
|
||||||
|
Creating {
|
||||||
|
parent: PathBuf,
|
||||||
|
#[source]
|
||||||
|
#[inherit]
|
||||||
|
source: std::io::Error,
|
||||||
|
},
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
Other(#[from] std::io::Error),
|
||||||
|
#[cfg(windows)]
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("Creating junction in node_modules folder")]
|
||||||
|
FailedCreatingJunction {
|
||||||
|
#[source]
|
||||||
|
#[inherit]
|
||||||
|
source: std::io::Error,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
fn symlink_package_dir(
|
fn symlink_package_dir(
|
||||||
old_path: &Path,
|
old_path: &Path,
|
||||||
new_path: &Path,
|
new_path: &Path,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), SymlinkPackageDirError> {
|
||||||
let new_parent = new_path.parent().unwrap();
|
let new_parent = new_path.parent().unwrap();
|
||||||
if new_parent.file_name().unwrap() != "node_modules" {
|
if new_parent.file_name().unwrap() != "node_modules" {
|
||||||
// create the parent folder that will contain the symlink
|
// create the parent folder that will contain the symlink
|
||||||
fs::create_dir_all(new_parent)
|
fs::create_dir_all(new_parent).map_err(|source| {
|
||||||
.with_context(|| format!("Creating '{}'", new_parent.display()))?;
|
SymlinkPackageDirError::Creating {
|
||||||
|
parent: new_parent.to_path_buf(),
|
||||||
|
source,
|
||||||
|
}
|
||||||
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to delete the previous symlink before creating a new one
|
// need to delete the previous symlink before creating a new one
|
||||||
|
@ -1075,7 +1146,7 @@ fn junction_or_symlink_dir(
|
||||||
old_path_relative: &Path,
|
old_path_relative: &Path,
|
||||||
old_path: &Path,
|
old_path: &Path,
|
||||||
new_path: &Path,
|
new_path: &Path,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), SymlinkPackageDirError> {
|
||||||
static USE_JUNCTIONS: std::sync::atomic::AtomicBool =
|
static USE_JUNCTIONS: std::sync::atomic::AtomicBool =
|
||||||
std::sync::atomic::AtomicBool::new(false);
|
std::sync::atomic::AtomicBool::new(false);
|
||||||
|
|
||||||
|
@ -1084,8 +1155,9 @@ fn junction_or_symlink_dir(
|
||||||
// needing to elevate privileges on Windows.
|
// needing to elevate privileges on Windows.
|
||||||
// Note: junctions don't support relative paths, so we need to use the
|
// Note: junctions don't support relative paths, so we need to use the
|
||||||
// absolute path here.
|
// absolute path here.
|
||||||
return junction::create(old_path, new_path)
|
return junction::create(old_path, new_path).map_err(|source| {
|
||||||
.context("Failed creating junction in node_modules folder");
|
SymlinkPackageDirError::FailedCreatingJunction { source }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
match symlink_dir(&crate::sys::CliSys::default(), old_path_relative, new_path)
|
match symlink_dir(&crate::sys::CliSys::default(), old_path_relative, new_path)
|
||||||
|
@ -1095,8 +1167,9 @@ fn junction_or_symlink_dir(
|
||||||
if symlink_err.kind() == std::io::ErrorKind::PermissionDenied =>
|
if symlink_err.kind() == std::io::ErrorKind::PermissionDenied =>
|
||||||
{
|
{
|
||||||
USE_JUNCTIONS.store(true, std::sync::atomic::Ordering::Relaxed);
|
USE_JUNCTIONS.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||||
junction::create(old_path, new_path)
|
junction::create(old_path, new_path).map_err(|source| {
|
||||||
.context("Failed creating junction in node_modules folder")
|
SymlinkPackageDirError::FailedCreatingJunction { source }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
Err(symlink_err) => {
|
Err(symlink_err) => {
|
||||||
log::warn!(
|
log::warn!(
|
||||||
|
@ -1104,8 +1177,9 @@ fn junction_or_symlink_dir(
|
||||||
colors::yellow("Warning")
|
colors::yellow("Warning")
|
||||||
);
|
);
|
||||||
USE_JUNCTIONS.store(true, std::sync::atomic::Ordering::Relaxed);
|
USE_JUNCTIONS.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||||
junction::create(old_path, new_path)
|
junction::create(old_path, new_path).map_err(|source| {
|
||||||
.context("Failed creating junction in node_modules folder")
|
SymlinkPackageDirError::FailedCreatingJunction { source }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ use std::sync::Arc;
|
||||||
use deno_npm::NpmSystemInfo;
|
use deno_npm::NpmSystemInfo;
|
||||||
|
|
||||||
pub use self::common::NpmPackageFsResolver;
|
pub use self::common::NpmPackageFsResolver;
|
||||||
|
pub use self::common::NpmPackageFsResolverPackageFolderError;
|
||||||
use self::global::GlobalNpmPackageResolver;
|
use self::global::GlobalNpmPackageResolver;
|
||||||
use self::local::LocalNpmPackageResolver;
|
use self::local::LocalNpmPackageResolver;
|
||||||
use super::resolution::NpmResolution;
|
use super::resolution::NpmResolution;
|
||||||
|
|
|
@ -33,6 +33,7 @@ pub use self::managed::CliManagedNpmResolverCreateOptions;
|
||||||
pub use self::managed::CliNpmResolverManagedSnapshotOption;
|
pub use self::managed::CliNpmResolverManagedSnapshotOption;
|
||||||
pub use self::managed::ManagedCliNpmResolver;
|
pub use self::managed::ManagedCliNpmResolver;
|
||||||
pub use self::managed::PackageCaching;
|
pub use self::managed::PackageCaching;
|
||||||
|
pub use self::managed::ResolvePkgFolderFromDenoModuleError;
|
||||||
pub use self::permission_checker::NpmRegistryReadPermissionChecker;
|
pub use self::permission_checker::NpmRegistryReadPermissionChecker;
|
||||||
pub use self::permission_checker::NpmRegistryReadPermissionCheckerMode;
|
pub use self::permission_checker::NpmRegistryReadPermissionCheckerMode;
|
||||||
use crate::file_fetcher::CliFileFetcher;
|
use crate::file_fetcher::CliFileFetcher;
|
||||||
|
@ -90,7 +91,9 @@ impl deno_npm_cache::NpmCacheHttpClient for CliNpmCacheHttpClient {
|
||||||
| Json { .. }
|
| Json { .. }
|
||||||
| ToStr { .. }
|
| ToStr { .. }
|
||||||
| RedirectHeaderParse { .. }
|
| RedirectHeaderParse { .. }
|
||||||
| TooManyRedirects => None,
|
| TooManyRedirects
|
||||||
|
| NotFound
|
||||||
|
| Other(_) => None,
|
||||||
BadResponse(bad_response_error) => {
|
BadResponse(bad_response_error) => {
|
||||||
Some(bad_response_error.status_code)
|
Some(bad_response_error.status_code)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,8 @@ use std::io::ErrorKind;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use deno_core::anyhow::Context;
|
|
||||||
use deno_core::error::AnyError;
|
|
||||||
use deno_core::parking_lot::Mutex;
|
use deno_core::parking_lot::Mutex;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_runtime::deno_node::NodePermissions;
|
use deno_runtime::deno_node::NodePermissions;
|
||||||
use sys_traits::FsCanonicalize;
|
use sys_traits::FsCanonicalize;
|
||||||
|
|
||||||
|
@ -28,6 +27,16 @@ pub struct NpmRegistryReadPermissionChecker {
|
||||||
mode: NpmRegistryReadPermissionCheckerMode,
|
mode: NpmRegistryReadPermissionCheckerMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("failed canonicalizing '{path}'")]
|
||||||
|
struct EnsureRegistryReadPermissionError {
|
||||||
|
path: PathBuf,
|
||||||
|
#[source]
|
||||||
|
#[inherit]
|
||||||
|
source: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
impl NpmRegistryReadPermissionChecker {
|
impl NpmRegistryReadPermissionChecker {
|
||||||
pub fn new(sys: CliSys, mode: NpmRegistryReadPermissionCheckerMode) -> Self {
|
pub fn new(sys: CliSys, mode: NpmRegistryReadPermissionCheckerMode) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -42,7 +51,7 @@ impl NpmRegistryReadPermissionChecker {
|
||||||
&self,
|
&self,
|
||||||
permissions: &mut dyn NodePermissions,
|
permissions: &mut dyn NodePermissions,
|
||||||
path: &'a Path,
|
path: &'a Path,
|
||||||
) -> Result<Cow<'a, Path>, AnyError> {
|
) -> Result<Cow<'a, Path>, JsErrorBox> {
|
||||||
if permissions.query_read_all() {
|
if permissions.query_read_all() {
|
||||||
return Ok(Cow::Borrowed(path)); // skip permissions checks below
|
return Ok(Cow::Borrowed(path)); // skip permissions checks below
|
||||||
}
|
}
|
||||||
|
@ -52,7 +61,9 @@ impl NpmRegistryReadPermissionChecker {
|
||||||
if path.components().any(|c| c.as_os_str() == "node_modules") {
|
if path.components().any(|c| c.as_os_str() == "node_modules") {
|
||||||
Ok(Cow::Borrowed(path))
|
Ok(Cow::Borrowed(path))
|
||||||
} else {
|
} else {
|
||||||
permissions.check_read_path(path).map_err(Into::into)
|
permissions
|
||||||
|
.check_read_path(path)
|
||||||
|
.map_err(JsErrorBox::from_err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NpmRegistryReadPermissionCheckerMode::Global(registry_path)
|
NpmRegistryReadPermissionCheckerMode::Global(registry_path)
|
||||||
|
@ -66,7 +77,7 @@ impl NpmRegistryReadPermissionChecker {
|
||||||
if is_path_in_node_modules {
|
if is_path_in_node_modules {
|
||||||
let mut cache = self.cache.lock();
|
let mut cache = self.cache.lock();
|
||||||
let mut canonicalize =
|
let mut canonicalize =
|
||||||
|path: &Path| -> Result<Option<PathBuf>, AnyError> {
|
|path: &Path| -> Result<Option<PathBuf>, JsErrorBox> {
|
||||||
match cache.get(path) {
|
match cache.get(path) {
|
||||||
Some(canon) => Ok(Some(canon.clone())),
|
Some(canon) => Ok(Some(canon.clone())),
|
||||||
None => match self.sys.fs_canonicalize(path) {
|
None => match self.sys.fs_canonicalize(path) {
|
||||||
|
@ -78,9 +89,12 @@ impl NpmRegistryReadPermissionChecker {
|
||||||
if e.kind() == ErrorKind::NotFound {
|
if e.kind() == ErrorKind::NotFound {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
Err(AnyError::from(e)).with_context(|| {
|
Err(JsErrorBox::from_err(
|
||||||
format!("failed canonicalizing '{}'", path.display())
|
EnsureRegistryReadPermissionError {
|
||||||
})
|
path: path.to_path_buf(),
|
||||||
|
source: e,
|
||||||
|
},
|
||||||
|
))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -98,7 +112,9 @@ impl NpmRegistryReadPermissionChecker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
permissions.check_read_path(path).map_err(Into::into)
|
permissions
|
||||||
|
.check_read_path(path)
|
||||||
|
.map_err(JsErrorBox::from_err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,11 @@
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
use deno_core::error::generic_error;
|
|
||||||
use deno_core::error::type_error;
|
|
||||||
use deno_core::error::AnyError;
|
|
||||||
use deno_core::op2;
|
use deno_core::op2;
|
||||||
use deno_core::v8;
|
use deno_core::v8;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_runtime::deno_permissions::ChildPermissionsArg;
|
use deno_runtime::deno_permissions::ChildPermissionsArg;
|
||||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||||
use deno_runtime::deno_web::StartTime;
|
use deno_runtime::deno_web::StartTime;
|
||||||
|
@ -78,7 +76,7 @@ pub fn op_pledge_test_permissions(
|
||||||
pub fn op_restore_test_permissions(
|
pub fn op_restore_test_permissions(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[serde] token: Uuid,
|
#[serde] token: Uuid,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), JsErrorBox> {
|
||||||
if let Some(permissions_holder) = state.try_take::<PermissionsHolder>() {
|
if let Some(permissions_holder) = state.try_take::<PermissionsHolder>() {
|
||||||
if token != permissions_holder.0 {
|
if token != permissions_holder.0 {
|
||||||
panic!("restore test permissions token does not match the stored token");
|
panic!("restore test permissions token does not match the stored token");
|
||||||
|
@ -88,7 +86,7 @@ pub fn op_restore_test_permissions(
|
||||||
state.put::<PermissionsContainer>(permissions);
|
state.put::<PermissionsContainer>(permissions);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(generic_error("no permissions to restore"))
|
Err(JsErrorBox::generic("no permissions to restore"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,9 +104,9 @@ fn op_register_bench(
|
||||||
only: bool,
|
only: bool,
|
||||||
warmup: bool,
|
warmup: bool,
|
||||||
#[buffer] ret_buf: &mut [u8],
|
#[buffer] ret_buf: &mut [u8],
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), JsErrorBox> {
|
||||||
if ret_buf.len() != 4 {
|
if ret_buf.len() != 4 {
|
||||||
return Err(type_error(format!(
|
return Err(JsErrorBox::type_error(format!(
|
||||||
"Invalid ret_buf length: {}",
|
"Invalid ret_buf length: {}",
|
||||||
ret_buf.len()
|
ret_buf.len()
|
||||||
)));
|
)));
|
||||||
|
|
|
@ -94,10 +94,12 @@ pub fn op_jupyter_input(
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum JupyterBroadcastError {
|
pub enum JupyterBroadcastError {
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
SerdeJson(serde_json::Error),
|
SerdeJson(serde_json::Error),
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
ZeroMq(AnyError),
|
ZeroMq(AnyError),
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,25 +2,36 @@
|
||||||
|
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
use deno_ast::ModuleSpecifier;
|
use deno_ast::ModuleSpecifier;
|
||||||
use deno_core::error::generic_error;
|
use deno_ast::ParseDiagnostic;
|
||||||
use deno_core::error::AnyError;
|
|
||||||
use deno_core::op2;
|
use deno_core::op2;
|
||||||
|
|
||||||
use crate::tools::lint;
|
use crate::tools::lint;
|
||||||
|
|
||||||
deno_core::extension!(deno_lint, ops = [op_lint_create_serialized_ast,],);
|
deno_core::extension!(deno_lint, ops = [op_lint_create_serialized_ast,],);
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
pub enum LintError {
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
Io(#[from] std::io::Error),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
ParseDiagnostic(#[from] ParseDiagnostic),
|
||||||
|
#[class(type)]
|
||||||
|
#[error("Failed to parse path as URL: {0}")]
|
||||||
|
PathParse(std::path::PathBuf),
|
||||||
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2]
|
||||||
#[buffer]
|
#[buffer]
|
||||||
fn op_lint_create_serialized_ast(
|
fn op_lint_create_serialized_ast(
|
||||||
#[string] file_name: &str,
|
#[string] file_name: &str,
|
||||||
#[string] source: String,
|
#[string] source: String,
|
||||||
) -> Result<Vec<u8>, AnyError> {
|
) -> Result<Vec<u8>, LintError> {
|
||||||
let file_text = deno_ast::strip_bom(source);
|
let file_text = deno_ast::strip_bom(source);
|
||||||
let path = std::env::current_dir()?.join(file_name);
|
let path = std::env::current_dir()?.join(file_name);
|
||||||
let specifier = ModuleSpecifier::from_file_path(&path).map_err(|_| {
|
let specifier = ModuleSpecifier::from_file_path(&path)
|
||||||
generic_error(format!("Failed to parse path as URL: {}", path.display()))
|
.map_err(|_| LintError::PathParse(path))?;
|
||||||
})?;
|
|
||||||
let media_type = MediaType::from_specifier(&specifier);
|
let media_type = MediaType::from_specifier(&specifier);
|
||||||
let parsed_source = deno_ast::parse_program(deno_ast::ParseParams {
|
let parsed_source = deno_ast::parse_program(deno_ast::ParseParams {
|
||||||
specifier,
|
specifier,
|
||||||
|
|
|
@ -3,13 +3,11 @@
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
use deno_core::error::generic_error;
|
|
||||||
use deno_core::error::type_error;
|
|
||||||
use deno_core::error::AnyError;
|
|
||||||
use deno_core::op2;
|
use deno_core::op2;
|
||||||
use deno_core::v8;
|
use deno_core::v8;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_runtime::deno_permissions::ChildPermissionsArg;
|
use deno_runtime::deno_permissions::ChildPermissionsArg;
|
||||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -73,7 +71,7 @@ pub fn op_pledge_test_permissions(
|
||||||
pub fn op_restore_test_permissions(
|
pub fn op_restore_test_permissions(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[serde] token: Uuid,
|
#[serde] token: Uuid,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), JsErrorBox> {
|
||||||
if let Some(permissions_holder) = state.try_take::<PermissionsHolder>() {
|
if let Some(permissions_holder) = state.try_take::<PermissionsHolder>() {
|
||||||
if token != permissions_holder.0 {
|
if token != permissions_holder.0 {
|
||||||
panic!("restore test permissions token does not match the stored token");
|
panic!("restore test permissions token does not match the stored token");
|
||||||
|
@ -83,7 +81,7 @@ pub fn op_restore_test_permissions(
|
||||||
state.put::<PermissionsContainer>(permissions);
|
state.put::<PermissionsContainer>(permissions);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(generic_error("no permissions to restore"))
|
Err(JsErrorBox::generic("no permissions to restore"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,9 +101,9 @@ fn op_register_test(
|
||||||
#[smi] line_number: u32,
|
#[smi] line_number: u32,
|
||||||
#[smi] column_number: u32,
|
#[smi] column_number: u32,
|
||||||
#[buffer] ret_buf: &mut [u8],
|
#[buffer] ret_buf: &mut [u8],
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), JsErrorBox> {
|
||||||
if ret_buf.len() != 4 {
|
if ret_buf.len() != 4 {
|
||||||
return Err(type_error(format!(
|
return Err(JsErrorBox::type_error(format!(
|
||||||
"Invalid ret_buf length: {}",
|
"Invalid ret_buf length: {}",
|
||||||
ret_buf.len()
|
ret_buf.len()
|
||||||
)));
|
)));
|
||||||
|
|
|
@ -11,12 +11,12 @@ use dashmap::DashSet;
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
use deno_config::workspace::MappedResolutionDiagnostic;
|
use deno_config::workspace::MappedResolutionDiagnostic;
|
||||||
use deno_config::workspace::MappedResolutionError;
|
use deno_config::workspace::MappedResolutionError;
|
||||||
use deno_core::anyhow::anyhow;
|
|
||||||
use deno_core::anyhow::Context;
|
use deno_core::anyhow::Context;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::url::Url;
|
use deno_core::url::Url;
|
||||||
use deno_core::ModuleSourceCode;
|
use deno_core::ModuleSourceCode;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_graph::source::ResolveError;
|
use deno_graph::source::ResolveError;
|
||||||
use deno_graph::source::UnknownBuiltInNodeModuleError;
|
use deno_graph::source::UnknownBuiltInNodeModuleError;
|
||||||
use deno_graph::NpmLoadError;
|
use deno_graph::NpmLoadError;
|
||||||
|
@ -61,7 +61,8 @@ pub struct ModuleCodeStringSource {
|
||||||
pub media_type: MediaType,
|
pub media_type: MediaType,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error, deno_error::JsError)]
|
||||||
|
#[class(type)]
|
||||||
#[error("{media_type} files are not supported in npm packages: {specifier}")]
|
#[error("{media_type} files are not supported in npm packages: {specifier}")]
|
||||||
pub struct NotSupportedKindInNpmError {
|
pub struct NotSupportedKindInNpmError {
|
||||||
pub media_type: MediaType,
|
pub media_type: MediaType,
|
||||||
|
@ -225,10 +226,12 @@ impl CliResolver {
|
||||||
) => match mapped_resolution_error {
|
) => match mapped_resolution_error {
|
||||||
MappedResolutionError::Specifier(e) => ResolveError::Specifier(e),
|
MappedResolutionError::Specifier(e) => ResolveError::Specifier(e),
|
||||||
// deno_graph checks specifically for an ImportMapError
|
// deno_graph checks specifically for an ImportMapError
|
||||||
MappedResolutionError::ImportMap(e) => ResolveError::Other(e.into()),
|
MappedResolutionError::ImportMap(e) => ResolveError::ImportMap(e),
|
||||||
err => ResolveError::Other(err.into()),
|
MappedResolutionError::Workspace(e) => {
|
||||||
|
ResolveError::Other(JsErrorBox::from_err(e))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
err => ResolveError::Other(err.into()),
|
err => ResolveError::Other(JsErrorBox::from_err(err)),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if resolution.found_package_json_dep {
|
if resolution.found_package_json_dep {
|
||||||
|
@ -356,26 +359,28 @@ impl<'a> deno_graph::source::NpmResolver for WorkerCliNpmGraphResolver<'a> {
|
||||||
.map(|r| {
|
.map(|r| {
|
||||||
r.map_err(|err| match err {
|
r.map_err(|err| match err {
|
||||||
NpmResolutionError::Registry(e) => {
|
NpmResolutionError::Registry(e) => {
|
||||||
NpmLoadError::RegistryInfo(Arc::new(e.into()))
|
NpmLoadError::RegistryInfo(Arc::new(e))
|
||||||
}
|
}
|
||||||
NpmResolutionError::Resolution(e) => {
|
NpmResolutionError::Resolution(e) => {
|
||||||
NpmLoadError::PackageReqResolution(Arc::new(e.into()))
|
NpmLoadError::PackageReqResolution(Arc::new(e))
|
||||||
}
|
}
|
||||||
NpmResolutionError::DependencyEntry(e) => {
|
NpmResolutionError::DependencyEntry(e) => {
|
||||||
NpmLoadError::PackageReqResolution(Arc::new(e.into()))
|
NpmLoadError::PackageReqResolution(Arc::new(e))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
dep_graph_result: match top_level_result {
|
dep_graph_result: match top_level_result {
|
||||||
Ok(()) => result.dependencies_result.map_err(Arc::new),
|
Ok(()) => result
|
||||||
|
.dependencies_result
|
||||||
|
.map_err(|e| Arc::new(e) as Arc<dyn deno_error::JsErrorClass>),
|
||||||
Err(err) => Err(Arc::new(err)),
|
Err(err) => Err(Arc::new(err)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let err = Arc::new(anyhow!(
|
let err = Arc::new(JsErrorBox::generic(
|
||||||
"npm specifiers were requested; but --no-npm is specified"
|
"npm specifiers were requested; but --no-npm is specified",
|
||||||
));
|
));
|
||||||
NpmResolvePkgReqsResult {
|
NpmResolvePkgReqsResult {
|
||||||
results: package_reqs
|
results: package_reqs
|
||||||
|
|
|
@ -21,9 +21,8 @@ use deno_config::workspace::MappedResolutionError;
|
||||||
use deno_config::workspace::ResolverWorkspaceJsrPackage;
|
use deno_config::workspace::ResolverWorkspaceJsrPackage;
|
||||||
use deno_config::workspace::WorkspaceResolver;
|
use deno_config::workspace::WorkspaceResolver;
|
||||||
use deno_core::anyhow::Context;
|
use deno_core::anyhow::Context;
|
||||||
use deno_core::error::generic_error;
|
|
||||||
use deno_core::error::type_error;
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
use deno_core::error::ModuleLoaderError;
|
||||||
use deno_core::futures::future::LocalBoxFuture;
|
use deno_core::futures::future::LocalBoxFuture;
|
||||||
use deno_core::futures::FutureExt;
|
use deno_core::futures::FutureExt;
|
||||||
use deno_core::v8_set_flags;
|
use deno_core::v8_set_flags;
|
||||||
|
@ -36,6 +35,7 @@ use deno_core::ModuleType;
|
||||||
use deno_core::RequestedModuleType;
|
use deno_core::RequestedModuleType;
|
||||||
use deno_core::ResolutionKind;
|
use deno_core::ResolutionKind;
|
||||||
use deno_core::SourceCodeCacheInfo;
|
use deno_core::SourceCodeCacheInfo;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_npm::npm_rc::ResolvedNpmRc;
|
use deno_npm::npm_rc::ResolvedNpmRc;
|
||||||
use deno_package_json::PackageJsonDepValue;
|
use deno_package_json::PackageJsonDepValue;
|
||||||
use deno_resolver::cjs::IsCjsResolutionMode;
|
use deno_resolver::cjs::IsCjsResolutionMode;
|
||||||
|
@ -182,25 +182,32 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
||||||
raw_specifier: &str,
|
raw_specifier: &str,
|
||||||
referrer: &str,
|
referrer: &str,
|
||||||
kind: ResolutionKind,
|
kind: ResolutionKind,
|
||||||
) -> Result<ModuleSpecifier, AnyError> {
|
) -> Result<ModuleSpecifier, ModuleLoaderError> {
|
||||||
let referrer = if referrer == "." {
|
let referrer = if referrer == "." {
|
||||||
if kind != ResolutionKind::MainModule {
|
if kind != ResolutionKind::MainModule {
|
||||||
return Err(generic_error(format!(
|
return Err(
|
||||||
"Expected to resolve main module, got {:?} instead.",
|
JsErrorBox::generic(format!(
|
||||||
kind
|
"Expected to resolve main module, got {:?} instead.",
|
||||||
)));
|
kind
|
||||||
|
))
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
let current_dir = std::env::current_dir().unwrap();
|
let current_dir = std::env::current_dir().unwrap();
|
||||||
deno_core::resolve_path(".", ¤t_dir)?
|
deno_core::resolve_path(".", ¤t_dir)?
|
||||||
} else {
|
} else {
|
||||||
ModuleSpecifier::parse(referrer).map_err(|err| {
|
ModuleSpecifier::parse(referrer).map_err(|err| {
|
||||||
type_error(format!("Referrer uses invalid specifier: {}", err))
|
JsErrorBox::type_error(format!(
|
||||||
|
"Referrer uses invalid specifier: {}",
|
||||||
|
err
|
||||||
|
))
|
||||||
})?
|
})?
|
||||||
};
|
};
|
||||||
let referrer_kind = if self
|
let referrer_kind = if self
|
||||||
.shared
|
.shared
|
||||||
.cjs_tracker
|
.cjs_tracker
|
||||||
.is_maybe_cjs(&referrer, MediaType::from_specifier(&referrer))?
|
.is_maybe_cjs(&referrer, MediaType::from_specifier(&referrer))
|
||||||
|
.map_err(JsErrorBox::from_err)?
|
||||||
{
|
{
|
||||||
ResolutionMode::Require
|
ResolutionMode::Require
|
||||||
} else {
|
} else {
|
||||||
|
@ -217,7 +224,8 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
||||||
&referrer,
|
&referrer,
|
||||||
referrer_kind,
|
referrer_kind,
|
||||||
NodeResolutionKind::Execution,
|
NodeResolutionKind::Execution,
|
||||||
)?
|
)
|
||||||
|
.map_err(JsErrorBox::from_err)?
|
||||||
.into_url(),
|
.into_url(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -245,14 +253,18 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
||||||
Some(&referrer),
|
Some(&referrer),
|
||||||
referrer_kind,
|
referrer_kind,
|
||||||
NodeResolutionKind::Execution,
|
NodeResolutionKind::Execution,
|
||||||
)?,
|
)
|
||||||
|
.map_err(JsErrorBox::from_err)?,
|
||||||
),
|
),
|
||||||
Ok(MappedResolution::PackageJson {
|
Ok(MappedResolution::PackageJson {
|
||||||
dep_result,
|
dep_result,
|
||||||
sub_path,
|
sub_path,
|
||||||
alias,
|
alias,
|
||||||
..
|
..
|
||||||
}) => match dep_result.as_ref().map_err(|e| AnyError::from(e.clone()))? {
|
}) => match dep_result
|
||||||
|
.as_ref()
|
||||||
|
.map_err(|e| JsErrorBox::from_err(e.clone()))?
|
||||||
|
{
|
||||||
PackageJsonDepValue::Req(req) => self
|
PackageJsonDepValue::Req(req) => self
|
||||||
.shared
|
.shared
|
||||||
.npm_req_resolver
|
.npm_req_resolver
|
||||||
|
@ -263,7 +275,7 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
||||||
referrer_kind,
|
referrer_kind,
|
||||||
NodeResolutionKind::Execution,
|
NodeResolutionKind::Execution,
|
||||||
)
|
)
|
||||||
.map_err(AnyError::from),
|
.map_err(|e| JsErrorBox::from_err(e).into()),
|
||||||
PackageJsonDepValue::Workspace(version_req) => {
|
PackageJsonDepValue::Workspace(version_req) => {
|
||||||
let pkg_folder = self
|
let pkg_folder = self
|
||||||
.shared
|
.shared
|
||||||
|
@ -271,7 +283,8 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
||||||
.resolve_workspace_pkg_json_folder_for_pkg_json_dep(
|
.resolve_workspace_pkg_json_folder_for_pkg_json_dep(
|
||||||
alias,
|
alias,
|
||||||
version_req,
|
version_req,
|
||||||
)?;
|
)
|
||||||
|
.map_err(JsErrorBox::from_err)?;
|
||||||
Ok(
|
Ok(
|
||||||
self
|
self
|
||||||
.shared
|
.shared
|
||||||
|
@ -282,7 +295,8 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
||||||
Some(&referrer),
|
Some(&referrer),
|
||||||
referrer_kind,
|
referrer_kind,
|
||||||
NodeResolutionKind::Execution,
|
NodeResolutionKind::Execution,
|
||||||
)?,
|
)
|
||||||
|
.map_err(JsErrorBox::from_err)?,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -291,12 +305,18 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
||||||
if let Ok(reference) =
|
if let Ok(reference) =
|
||||||
NpmPackageReqReference::from_specifier(&specifier)
|
NpmPackageReqReference::from_specifier(&specifier)
|
||||||
{
|
{
|
||||||
return Ok(self.shared.npm_req_resolver.resolve_req_reference(
|
return Ok(
|
||||||
&reference,
|
self
|
||||||
&referrer,
|
.shared
|
||||||
referrer_kind,
|
.npm_req_resolver
|
||||||
NodeResolutionKind::Execution,
|
.resolve_req_reference(
|
||||||
)?);
|
&reference,
|
||||||
|
&referrer,
|
||||||
|
referrer_kind,
|
||||||
|
NodeResolutionKind::Execution,
|
||||||
|
)
|
||||||
|
.map_err(JsErrorBox::from_err)?,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if specifier.scheme() == "jsr" {
|
if specifier.scheme() == "jsr" {
|
||||||
|
@ -318,18 +338,22 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
||||||
Err(err)
|
Err(err)
|
||||||
if err.is_unmapped_bare_specifier() && referrer.scheme() == "file" =>
|
if err.is_unmapped_bare_specifier() && referrer.scheme() == "file" =>
|
||||||
{
|
{
|
||||||
let maybe_res = self.shared.npm_req_resolver.resolve_if_for_npm_pkg(
|
let maybe_res = self
|
||||||
raw_specifier,
|
.shared
|
||||||
&referrer,
|
.npm_req_resolver
|
||||||
referrer_kind,
|
.resolve_if_for_npm_pkg(
|
||||||
NodeResolutionKind::Execution,
|
raw_specifier,
|
||||||
)?;
|
&referrer,
|
||||||
|
referrer_kind,
|
||||||
|
NodeResolutionKind::Execution,
|
||||||
|
)
|
||||||
|
.map_err(JsErrorBox::from_err)?;
|
||||||
if let Some(res) = maybe_res {
|
if let Some(res) = maybe_res {
|
||||||
return Ok(res.into_url());
|
return Ok(res.into_url());
|
||||||
}
|
}
|
||||||
Err(err.into())
|
Err(JsErrorBox::from_err(err).into())
|
||||||
}
|
}
|
||||||
Err(err) => Err(err.into()),
|
Err(err) => Err(JsErrorBox::from_err(err).into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,9 +384,9 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
||||||
{
|
{
|
||||||
Ok(response) => response,
|
Ok(response) => response,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return deno_core::ModuleLoadResponse::Sync(Err(type_error(
|
return deno_core::ModuleLoadResponse::Sync(Err(
|
||||||
format!("{:#}", err),
|
JsErrorBox::type_error(format!("{:#}", err)).into(),
|
||||||
)));
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return deno_core::ModuleLoadResponse::Sync(Ok(
|
return deno_core::ModuleLoadResponse::Sync(Ok(
|
||||||
|
@ -420,9 +444,9 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
||||||
{
|
{
|
||||||
Ok(is_maybe_cjs) => is_maybe_cjs,
|
Ok(is_maybe_cjs) => is_maybe_cjs,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return deno_core::ModuleLoadResponse::Sync(Err(type_error(
|
return deno_core::ModuleLoadResponse::Sync(Err(
|
||||||
format!("{:?}", err),
|
JsErrorBox::type_error(format!("{:?}", err)).into(),
|
||||||
)));
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if is_maybe_cjs {
|
if is_maybe_cjs {
|
||||||
|
@ -482,12 +506,16 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(None) => deno_core::ModuleLoadResponse::Sync(Err(type_error(
|
Ok(None) => deno_core::ModuleLoadResponse::Sync(Err(
|
||||||
format!("{MODULE_NOT_FOUND}: {}", original_specifier),
|
JsErrorBox::type_error(format!(
|
||||||
))),
|
"{MODULE_NOT_FOUND}: {}",
|
||||||
Err(err) => deno_core::ModuleLoadResponse::Sync(Err(type_error(
|
original_specifier
|
||||||
format!("{:?}", err),
|
))
|
||||||
))),
|
.into(),
|
||||||
|
)),
|
||||||
|
Err(err) => deno_core::ModuleLoadResponse::Sync(Err(
|
||||||
|
JsErrorBox::type_error(format!("{:?}", err)).into(),
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,7 +581,7 @@ impl NodeRequireLoader for EmbeddedModuleLoader {
|
||||||
&self,
|
&self,
|
||||||
permissions: &mut dyn deno_runtime::deno_node::NodePermissions,
|
permissions: &mut dyn deno_runtime::deno_node::NodePermissions,
|
||||||
path: &'a std::path::Path,
|
path: &'a std::path::Path,
|
||||||
) -> Result<Cow<'a, std::path::Path>, AnyError> {
|
) -> Result<Cow<'a, std::path::Path>, JsErrorBox> {
|
||||||
if self.shared.modules.has_file(path) {
|
if self.shared.modules.has_file(path) {
|
||||||
// allow reading if the file is in the snapshot
|
// allow reading if the file is in the snapshot
|
||||||
return Ok(Cow::Borrowed(path));
|
return Ok(Cow::Borrowed(path));
|
||||||
|
@ -563,17 +591,23 @@ impl NodeRequireLoader for EmbeddedModuleLoader {
|
||||||
.shared
|
.shared
|
||||||
.npm_registry_permission_checker
|
.npm_registry_permission_checker
|
||||||
.ensure_read_permission(permissions, path)
|
.ensure_read_permission(permissions, path)
|
||||||
|
.map_err(JsErrorBox::from_err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_text_file_lossy(
|
fn load_text_file_lossy(
|
||||||
&self,
|
&self,
|
||||||
path: &std::path::Path,
|
path: &std::path::Path,
|
||||||
) -> Result<Cow<'static, str>, AnyError> {
|
) -> Result<Cow<'static, str>, JsErrorBox> {
|
||||||
let file_entry = self.shared.vfs.file_entry(path)?;
|
let file_entry = self
|
||||||
|
.shared
|
||||||
|
.vfs
|
||||||
|
.file_entry(path)
|
||||||
|
.map_err(JsErrorBox::from_err)?;
|
||||||
let file_bytes = self
|
let file_bytes = self
|
||||||
.shared
|
.shared
|
||||||
.vfs
|
.vfs
|
||||||
.read_file_all(file_entry, VfsFileSubDataKind::ModuleGraph)?;
|
.read_file_all(file_entry, VfsFileSubDataKind::ModuleGraph)
|
||||||
|
.map_err(JsErrorBox::from_err)?;
|
||||||
Ok(from_utf8_lossy_cow(file_bytes))
|
Ok(from_utf8_lossy_cow(file_bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -626,10 +660,10 @@ struct StandaloneRootCertStoreProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RootCertStoreProvider for StandaloneRootCertStoreProvider {
|
impl RootCertStoreProvider for StandaloneRootCertStoreProvider {
|
||||||
fn get_or_try_init(&self) -> Result<&RootCertStore, AnyError> {
|
fn get_or_try_init(&self) -> Result<&RootCertStore, JsErrorBox> {
|
||||||
self.cell.get_or_try_init(|| {
|
self.cell.get_or_try_init(|| {
|
||||||
get_root_cert_store(None, self.ca_stores.clone(), self.ca_data.clone())
|
get_root_cert_store(None, self.ca_stores.clone(), self.ca_data.clone())
|
||||||
.map_err(|err| err.into())
|
.map_err(JsErrorBox::from_err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,9 @@ use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use deno_config::glob::WalkEntry;
|
use deno_config::glob::WalkEntry;
|
||||||
use deno_core::error::generic_error;
|
use deno_core::anyhow::anyhow;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
use deno_core::error::CoreError;
|
||||||
use deno_core::error::JsError;
|
use deno_core::error::JsError;
|
||||||
use deno_core::futures::future;
|
use deno_core::futures::future;
|
||||||
use deno_core::futures::stream;
|
use deno_core::futures::stream;
|
||||||
|
@ -18,6 +19,7 @@ use deno_core::unsync::spawn_blocking;
|
||||||
use deno_core::v8;
|
use deno_core::v8;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
use deno_core::PollEventLoopOptions;
|
use deno_core::PollEventLoopOptions;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_runtime::deno_permissions::Permissions;
|
use deno_runtime::deno_permissions::Permissions;
|
||||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||||
use deno_runtime::permissions::RuntimePermissionDescriptorParser;
|
use deno_runtime::permissions::RuntimePermissionDescriptorParser;
|
||||||
|
@ -162,17 +164,14 @@ async fn bench_specifier(
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(()) => Ok(()),
|
Ok(()) => Ok(()),
|
||||||
Err(error) => {
|
Err(CoreError::Js(error)) => {
|
||||||
if error.is::<JsError>() {
|
sender.send(BenchEvent::UncaughtError(
|
||||||
sender.send(BenchEvent::UncaughtError(
|
specifier.to_string(),
|
||||||
specifier.to_string(),
|
Box::new(error),
|
||||||
Box::new(error.downcast::<JsError>().unwrap()),
|
))?;
|
||||||
))?;
|
Ok(())
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Err(e) => Err(e.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +182,7 @@ async fn bench_specifier_inner(
|
||||||
specifier: ModuleSpecifier,
|
specifier: ModuleSpecifier,
|
||||||
sender: &UnboundedSender<BenchEvent>,
|
sender: &UnboundedSender<BenchEvent>,
|
||||||
filter: TestFilter,
|
filter: TestFilter,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), CoreError> {
|
||||||
let mut worker = worker_factory
|
let mut worker = worker_factory
|
||||||
.create_custom_worker(
|
.create_custom_worker(
|
||||||
WorkerExecutionMode::Bench,
|
WorkerExecutionMode::Bench,
|
||||||
|
@ -230,14 +229,18 @@ async fn bench_specifier_inner(
|
||||||
.partial_cmp(&groups.get_index_of(&d2.group).unwrap())
|
.partial_cmp(&groups.get_index_of(&d2.group).unwrap())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
sender.send(BenchEvent::Plan(BenchPlan {
|
sender
|
||||||
origin: specifier.to_string(),
|
.send(BenchEvent::Plan(BenchPlan {
|
||||||
total: benchmarks.len(),
|
origin: specifier.to_string(),
|
||||||
used_only,
|
total: benchmarks.len(),
|
||||||
names: benchmarks.iter().map(|(d, _)| d.name.clone()).collect(),
|
used_only,
|
||||||
}))?;
|
names: benchmarks.iter().map(|(d, _)| d.name.clone()).collect(),
|
||||||
|
}))
|
||||||
|
.map_err(JsErrorBox::from_err)?;
|
||||||
for (desc, function) in benchmarks {
|
for (desc, function) in benchmarks {
|
||||||
sender.send(BenchEvent::Wait(desc.id))?;
|
sender
|
||||||
|
.send(BenchEvent::Wait(desc.id))
|
||||||
|
.map_err(JsErrorBox::from_err)?;
|
||||||
let call = worker.js_runtime.call(&function);
|
let call = worker.js_runtime.call(&function);
|
||||||
let result = worker
|
let result = worker
|
||||||
.js_runtime
|
.js_runtime
|
||||||
|
@ -245,8 +248,11 @@ async fn bench_specifier_inner(
|
||||||
.await?;
|
.await?;
|
||||||
let scope = &mut worker.js_runtime.handle_scope();
|
let scope = &mut worker.js_runtime.handle_scope();
|
||||||
let result = v8::Local::new(scope, result);
|
let result = v8::Local::new(scope, result);
|
||||||
let result = serde_v8::from_v8::<BenchResult>(scope, result)?;
|
let result = serde_v8::from_v8::<BenchResult>(scope, result)
|
||||||
sender.send(BenchEvent::Result(desc.id, result))?;
|
.map_err(JsErrorBox::from_err)?;
|
||||||
|
sender
|
||||||
|
.send(BenchEvent::Result(desc.id, result))
|
||||||
|
.map_err(JsErrorBox::from_err)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore `defaultPrevented` of the `beforeunload` event. We don't allow the
|
// Ignore `defaultPrevented` of the `beforeunload` event. We don't allow the
|
||||||
|
@ -356,13 +362,13 @@ async fn bench_specifiers(
|
||||||
reporter.report_end(&report);
|
reporter.report_end(&report);
|
||||||
|
|
||||||
if used_only {
|
if used_only {
|
||||||
return Err(generic_error(
|
return Err(anyhow!(
|
||||||
"Bench failed because the \"only\" option was used",
|
"Bench failed because the \"only\" option was used",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if report.failed > 0 {
|
if report.failed > 0 {
|
||||||
return Err(generic_error("Bench failed"));
|
return Err(anyhow!("Bench failed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -440,7 +446,7 @@ pub async fn run_benchmarks(
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if specifiers.is_empty() {
|
if specifiers.is_empty() {
|
||||||
return Err(generic_error("No bench modules found"));
|
return Err(anyhow!("No bench modules found"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let main_graph_container = factory.main_module_graph_container().await?;
|
let main_graph_container = factory.main_module_graph_container().await?;
|
||||||
|
|
|
@ -6,7 +6,9 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
use deno_ast::ModuleSpecifier;
|
use deno_ast::ModuleSpecifier;
|
||||||
|
use deno_config::deno_json;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_graph::Module;
|
use deno_graph::Module;
|
||||||
use deno_graph::ModuleError;
|
use deno_graph::ModuleError;
|
||||||
use deno_graph::ModuleGraph;
|
use deno_graph::ModuleGraph;
|
||||||
|
@ -112,6 +114,27 @@ pub struct TypeChecker {
|
||||||
sys: CliSys,
|
sys: CliSys,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
pub enum CheckError {
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
Diagnostics(#[from] Diagnostics),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
ConfigFile(#[from] deno_json::ConfigFileError),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
ToMaybeJsxImportSourceConfig(
|
||||||
|
#[from] deno_json::ToMaybeJsxImportSourceConfigError,
|
||||||
|
),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
TscExec(#[from] tsc::ExecError),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
Other(#[from] JsErrorBox),
|
||||||
|
}
|
||||||
|
|
||||||
impl TypeChecker {
|
impl TypeChecker {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
caches: Arc<Caches>,
|
caches: Arc<Caches>,
|
||||||
|
@ -141,7 +164,7 @@ impl TypeChecker {
|
||||||
&self,
|
&self,
|
||||||
graph: ModuleGraph,
|
graph: ModuleGraph,
|
||||||
options: CheckOptions,
|
options: CheckOptions,
|
||||||
) -> Result<Arc<ModuleGraph>, AnyError> {
|
) -> Result<Arc<ModuleGraph>, CheckError> {
|
||||||
let (graph, mut diagnostics) =
|
let (graph, mut diagnostics) =
|
||||||
self.check_diagnostics(graph, options).await?;
|
self.check_diagnostics(graph, options).await?;
|
||||||
diagnostics.emit_warnings();
|
diagnostics.emit_warnings();
|
||||||
|
@ -160,7 +183,7 @@ impl TypeChecker {
|
||||||
&self,
|
&self,
|
||||||
mut graph: ModuleGraph,
|
mut graph: ModuleGraph,
|
||||||
options: CheckOptions,
|
options: CheckOptions,
|
||||||
) -> Result<(Arc<ModuleGraph>, Diagnostics), AnyError> {
|
) -> Result<(Arc<ModuleGraph>, Diagnostics), CheckError> {
|
||||||
if !options.type_check_mode.is_true() || graph.roots.is_empty() {
|
if !options.type_check_mode.is_true() || graph.roots.is_empty() {
|
||||||
return Ok((graph.into(), Default::default()));
|
return Ok((graph.into(), Default::default()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,9 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
use deno_ast::ModuleSpecifier;
|
use deno_ast::ModuleSpecifier;
|
||||||
|
use deno_core::anyhow::anyhow;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::bail;
|
||||||
use deno_core::anyhow::Context;
|
use deno_core::anyhow::Context;
|
||||||
use deno_core::error::generic_error;
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::resolve_url_or_path;
|
use deno_core::resolve_url_or_path;
|
||||||
use deno_graph::GraphKind;
|
use deno_graph::GraphKind;
|
||||||
|
@ -330,7 +330,7 @@ async fn resolve_compile_executable_output_path(
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
output_path.ok_or_else(|| generic_error(
|
output_path.ok_or_else(|| anyhow!(
|
||||||
"An executable name was not provided. One could not be inferred from the URL. Aborting.",
|
"An executable name was not provided. One could not be inferred from the URL. Aborting.",
|
||||||
)).map(|output_path| {
|
)).map(|output_path| {
|
||||||
get_os_specific_filepath(output_path, &compile_flags.target)
|
get_os_specific_filepath(output_path, &compile_flags.target)
|
||||||
|
|
|
@ -17,7 +17,6 @@ use deno_config::glob::PathOrPattern;
|
||||||
use deno_config::glob::PathOrPatternSet;
|
use deno_config::glob::PathOrPatternSet;
|
||||||
use deno_core::anyhow::anyhow;
|
use deno_core::anyhow::anyhow;
|
||||||
use deno_core::anyhow::Context;
|
use deno_core::anyhow::Context;
|
||||||
use deno_core::error::generic_error;
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::serde_json;
|
use deno_core::serde_json;
|
||||||
use deno_core::sourcemap::SourceMap;
|
use deno_core::sourcemap::SourceMap;
|
||||||
|
@ -430,7 +429,7 @@ fn collect_coverages(
|
||||||
.ignore_git_folder()
|
.ignore_git_folder()
|
||||||
.ignore_node_modules()
|
.ignore_node_modules()
|
||||||
.set_vendor_folder(cli_options.vendor_dir_path().map(ToOwned::to_owned))
|
.set_vendor_folder(cli_options.vendor_dir_path().map(ToOwned::to_owned))
|
||||||
.collect_file_patterns(&CliSys::default(), file_patterns)?;
|
.collect_file_patterns(&CliSys::default(), file_patterns);
|
||||||
|
|
||||||
let coverage_patterns = FilePatterns {
|
let coverage_patterns = FilePatterns {
|
||||||
base: initial_cwd.to_path_buf(),
|
base: initial_cwd.to_path_buf(),
|
||||||
|
@ -505,7 +504,7 @@ pub fn cover_files(
|
||||||
coverage_flags: CoverageFlags,
|
coverage_flags: CoverageFlags,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
if coverage_flags.files.include.is_empty() {
|
if coverage_flags.files.include.is_empty() {
|
||||||
return Err(generic_error("No matching coverage profiles found"));
|
return Err(anyhow!("No matching coverage profiles found"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let factory = CliFactory::from_flags(flags);
|
let factory = CliFactory::from_flags(flags);
|
||||||
|
@ -527,7 +526,7 @@ pub fn cover_files(
|
||||||
cli_options.initial_cwd(),
|
cli_options.initial_cwd(),
|
||||||
)?;
|
)?;
|
||||||
if script_coverages.is_empty() {
|
if script_coverages.is_empty() {
|
||||||
return Err(generic_error("No coverage files found"));
|
return Err(anyhow!("No coverage files found"));
|
||||||
}
|
}
|
||||||
let script_coverages = filter_coverages(
|
let script_coverages = filter_coverages(
|
||||||
script_coverages,
|
script_coverages,
|
||||||
|
@ -536,7 +535,7 @@ pub fn cover_files(
|
||||||
in_npm_pkg_checker.as_ref(),
|
in_npm_pkg_checker.as_ref(),
|
||||||
);
|
);
|
||||||
if script_coverages.is_empty() {
|
if script_coverages.is_empty() {
|
||||||
return Err(generic_error("No covered files included in the report"));
|
return Err(anyhow!("No covered files included in the report"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let proc_coverages: Vec<_> = script_coverages
|
let proc_coverages: Vec<_> = script_coverages
|
||||||
|
|
101
cli/tools/doc.rs
101
cli/tools/doc.rs
|
@ -62,10 +62,11 @@ async fn generate_doc_nodes_for_builtin_types(
|
||||||
)],
|
)],
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
);
|
);
|
||||||
|
let roots = vec![source_file_specifier.clone()];
|
||||||
let mut graph = deno_graph::ModuleGraph::new(GraphKind::TypesOnly);
|
let mut graph = deno_graph::ModuleGraph::new(GraphKind::TypesOnly);
|
||||||
graph
|
graph
|
||||||
.build(
|
.build(
|
||||||
vec![source_file_specifier.clone()],
|
roots.clone(),
|
||||||
&loader,
|
&loader,
|
||||||
deno_graph::BuildOptions {
|
deno_graph::BuildOptions {
|
||||||
imports: Vec::new(),
|
imports: Vec::new(),
|
||||||
|
@ -85,14 +86,13 @@ async fn generate_doc_nodes_for_builtin_types(
|
||||||
let doc_parser = doc::DocParser::new(
|
let doc_parser = doc::DocParser::new(
|
||||||
&graph,
|
&graph,
|
||||||
parser,
|
parser,
|
||||||
|
&roots,
|
||||||
doc::DocParserOptions {
|
doc::DocParserOptions {
|
||||||
diagnostics: false,
|
diagnostics: false,
|
||||||
private: doc_flags.private,
|
private: doc_flags.private,
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
let nodes = doc_parser.parse_module(&source_file_specifier)?.definitions;
|
Ok(doc_parser.parse()?)
|
||||||
|
|
||||||
Ok(IndexMap::from([(source_file_specifier, nodes)]))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn doc(
|
pub async fn doc(
|
||||||
|
@ -158,19 +158,13 @@ pub async fn doc(
|
||||||
let doc_parser = doc::DocParser::new(
|
let doc_parser = doc::DocParser::new(
|
||||||
&graph,
|
&graph,
|
||||||
&capturing_parser,
|
&capturing_parser,
|
||||||
|
&module_specifiers,
|
||||||
doc::DocParserOptions {
|
doc::DocParserOptions {
|
||||||
private: doc_flags.private,
|
private: doc_flags.private,
|
||||||
diagnostics: doc_flags.lint,
|
diagnostics: doc_flags.lint,
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
let doc_nodes_by_url = doc_parser.parse()?;
|
||||||
let mut doc_nodes_by_url =
|
|
||||||
IndexMap::with_capacity(module_specifiers.len());
|
|
||||||
|
|
||||||
for module_specifier in module_specifiers {
|
|
||||||
let nodes = doc_parser.parse_with_reexports(&module_specifier)?;
|
|
||||||
doc_nodes_by_url.insert(module_specifier, nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
if doc_flags.lint {
|
if doc_flags.lint {
|
||||||
let diagnostics = doc_parser.take_diagnostics();
|
let diagnostics = doc_parser.take_diagnostics();
|
||||||
|
@ -191,29 +185,9 @@ pub async fn doc(
|
||||||
.await?;
|
.await?;
|
||||||
let (_, deno_ns) = deno_ns.into_iter().next().unwrap();
|
let (_, deno_ns) = deno_ns.into_iter().next().unwrap();
|
||||||
|
|
||||||
let short_path = Rc::new(ShortPath::new(
|
Some(deno_ns)
|
||||||
ModuleSpecifier::parse("file:///lib.deno.d.ts").unwrap(),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
));
|
|
||||||
|
|
||||||
deno_doc::html::compute_namespaced_symbols(
|
|
||||||
&deno_ns
|
|
||||||
.into_iter()
|
|
||||||
.map(|node| deno_doc::html::DocNodeWithContext {
|
|
||||||
origin: short_path.clone(),
|
|
||||||
ns_qualifiers: Rc::new([]),
|
|
||||||
kind_with_drilldown:
|
|
||||||
deno_doc::html::DocNodeKindWithDrilldown::Other(node.kind()),
|
|
||||||
inner: Rc::new(node),
|
|
||||||
drilldown_name: None,
|
|
||||||
parent: None,
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
Default::default()
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut main_entrypoint = None;
|
let mut main_entrypoint = None;
|
||||||
|
@ -393,7 +367,7 @@ impl UsageComposer for DocComposer {
|
||||||
fn generate_docs_directory(
|
fn generate_docs_directory(
|
||||||
doc_nodes_by_url: IndexMap<ModuleSpecifier, Vec<doc::DocNode>>,
|
doc_nodes_by_url: IndexMap<ModuleSpecifier, Vec<doc::DocNode>>,
|
||||||
html_options: &DocHtmlFlag,
|
html_options: &DocHtmlFlag,
|
||||||
deno_ns: std::collections::HashMap<Vec<String>, Option<Rc<ShortPath>>>,
|
built_in_types: Option<Vec<doc::DocNode>>,
|
||||||
rewrite_map: Option<IndexMap<ModuleSpecifier, String>>,
|
rewrite_map: Option<IndexMap<ModuleSpecifier, String>>,
|
||||||
main_entrypoint: Option<ModuleSpecifier>,
|
main_entrypoint: Option<ModuleSpecifier>,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
|
@ -426,12 +400,12 @@ fn generate_docs_directory(
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let options = deno_doc::html::GenerateOptions {
|
let mut options = deno_doc::html::GenerateOptions {
|
||||||
package_name: html_options.name.clone(),
|
package_name: html_options.name.clone(),
|
||||||
main_entrypoint,
|
main_entrypoint,
|
||||||
rewrite_map,
|
rewrite_map,
|
||||||
href_resolver: Rc::new(DocResolver {
|
href_resolver: Rc::new(DocResolver {
|
||||||
deno_ns,
|
deno_ns: Default::default(),
|
||||||
strip_trailing_html: html_options.strip_trailing_html,
|
strip_trailing_html: html_options.strip_trailing_html,
|
||||||
}),
|
}),
|
||||||
usage_composer: Rc::new(DocComposer),
|
usage_composer: Rc::new(DocComposer),
|
||||||
|
@ -451,7 +425,58 @@ fn generate_docs_directory(
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut files = deno_doc::html::generate(options, doc_nodes_by_url)
|
if let Some(built_in_types) = built_in_types {
|
||||||
|
let ctx = deno_doc::html::GenerateCtx::create_basic(
|
||||||
|
deno_doc::html::GenerateOptions {
|
||||||
|
package_name: None,
|
||||||
|
main_entrypoint: Some(
|
||||||
|
ModuleSpecifier::parse("file:///lib.deno.d.ts").unwrap(),
|
||||||
|
),
|
||||||
|
href_resolver: Rc::new(DocResolver {
|
||||||
|
deno_ns: Default::default(),
|
||||||
|
strip_trailing_html: false,
|
||||||
|
}),
|
||||||
|
usage_composer: Rc::new(DocComposer),
|
||||||
|
rewrite_map: Default::default(),
|
||||||
|
category_docs: Default::default(),
|
||||||
|
disable_search: Default::default(),
|
||||||
|
symbol_redirect_map: Default::default(),
|
||||||
|
default_symbol_map: Default::default(),
|
||||||
|
markdown_renderer: deno_doc::html::comrak::create_renderer(
|
||||||
|
None, None, None,
|
||||||
|
),
|
||||||
|
markdown_stripper: Rc::new(deno_doc::html::comrak::strip),
|
||||||
|
head_inject: None,
|
||||||
|
},
|
||||||
|
IndexMap::from([(
|
||||||
|
ModuleSpecifier::parse("file:///lib.deno.d.ts").unwrap(),
|
||||||
|
built_in_types,
|
||||||
|
)]),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let deno_ns = deno_doc::html::compute_namespaced_symbols(
|
||||||
|
&ctx,
|
||||||
|
Box::new(
|
||||||
|
ctx
|
||||||
|
.doc_nodes
|
||||||
|
.values()
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.iter()
|
||||||
|
.map(std::borrow::Cow::Borrowed),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
options.href_resolver = Rc::new(DocResolver {
|
||||||
|
deno_ns,
|
||||||
|
strip_trailing_html: html_options.strip_trailing_html,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let ctx =
|
||||||
|
deno_doc::html::GenerateCtx::create_basic(options, doc_nodes_by_url)?;
|
||||||
|
|
||||||
|
let mut files = deno_doc::html::generate(ctx)
|
||||||
.context("Failed to generate HTML documentation")?;
|
.context("Failed to generate HTML documentation")?;
|
||||||
|
|
||||||
files.insert("prism.js".to_string(), PRISM_JS.to_string());
|
files.insert("prism.js".to_string(), PRISM_JS.to_string());
|
||||||
|
|
|
@ -26,7 +26,6 @@ use deno_config::glob::FilePatterns;
|
||||||
use deno_core::anyhow::anyhow;
|
use deno_core::anyhow::anyhow;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::bail;
|
||||||
use deno_core::anyhow::Context;
|
use deno_core::anyhow::Context;
|
||||||
use deno_core::error::generic_error;
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::futures;
|
use deno_core::futures;
|
||||||
use deno_core::parking_lot::Mutex;
|
use deno_core::parking_lot::Mutex;
|
||||||
|
@ -167,7 +166,7 @@ fn resolve_paths_with_options_batches(
|
||||||
Vec::with_capacity(members_fmt_options.len());
|
Vec::with_capacity(members_fmt_options.len());
|
||||||
for (_ctx, member_fmt_options) in members_fmt_options {
|
for (_ctx, member_fmt_options) in members_fmt_options {
|
||||||
let files =
|
let files =
|
||||||
collect_fmt_files(cli_options, member_fmt_options.files.clone())?;
|
collect_fmt_files(cli_options, member_fmt_options.files.clone());
|
||||||
if !files.is_empty() {
|
if !files.is_empty() {
|
||||||
paths_with_options_batches.push(PathsWithOptions {
|
paths_with_options_batches.push(PathsWithOptions {
|
||||||
base: member_fmt_options.files.base.clone(),
|
base: member_fmt_options.files.base.clone(),
|
||||||
|
@ -177,7 +176,7 @@ fn resolve_paths_with_options_batches(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if paths_with_options_batches.is_empty() {
|
if paths_with_options_batches.is_empty() {
|
||||||
return Err(generic_error("No target files found."));
|
return Err(anyhow!("No target files found."));
|
||||||
}
|
}
|
||||||
Ok(paths_with_options_batches)
|
Ok(paths_with_options_batches)
|
||||||
}
|
}
|
||||||
|
@ -224,7 +223,7 @@ async fn format_files(
|
||||||
fn collect_fmt_files(
|
fn collect_fmt_files(
|
||||||
cli_options: &CliOptions,
|
cli_options: &CliOptions,
|
||||||
files: FilePatterns,
|
files: FilePatterns,
|
||||||
) -> Result<Vec<PathBuf>, AnyError> {
|
) -> Vec<PathBuf> {
|
||||||
FileCollector::new(|e| {
|
FileCollector::new(|e| {
|
||||||
is_supported_ext_fmt(e.path)
|
is_supported_ext_fmt(e.path)
|
||||||
|| (e.path.extension().is_none() && cli_options.ext_flag().is_some())
|
|| (e.path.extension().is_none() && cli_options.ext_flag().is_some())
|
||||||
|
@ -484,7 +483,7 @@ pub fn format_html(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(error_msg) = inner(&error, file_path) {
|
if let Some(error_msg) = inner(&error, file_path) {
|
||||||
AnyError::from(generic_error(error_msg))
|
AnyError::msg(error_msg)
|
||||||
} else {
|
} else {
|
||||||
AnyError::from(error)
|
AnyError::from(error)
|
||||||
}
|
}
|
||||||
|
@ -732,9 +731,9 @@ impl Formatter for CheckFormatter {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
let not_formatted_files_str = files_str(not_formatted_files_count);
|
let not_formatted_files_str = files_str(not_formatted_files_count);
|
||||||
Err(generic_error(format!(
|
Err(anyhow!(
|
||||||
"Found {not_formatted_files_count} not formatted {not_formatted_files_str} in {checked_files_str}",
|
"Found {not_formatted_files_count} not formatted {not_formatted_files_str} in {checked_files_str}",
|
||||||
)))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ use deno_core::error::AnyError;
|
||||||
use deno_core::resolve_url_or_path;
|
use deno_core::resolve_url_or_path;
|
||||||
use deno_core::serde_json;
|
use deno_core::serde_json;
|
||||||
use deno_core::url;
|
use deno_core::url;
|
||||||
|
use deno_error::JsErrorClass;
|
||||||
use deno_graph::Dependency;
|
use deno_graph::Dependency;
|
||||||
use deno_graph::GraphKind;
|
use deno_graph::GraphKind;
|
||||||
use deno_graph::Module;
|
use deno_graph::Module;
|
||||||
|
@ -664,9 +665,10 @@ impl<'a> GraphDisplayContext<'a> {
|
||||||
HttpsChecksumIntegrity(_) => "(checksum integrity error)",
|
HttpsChecksumIntegrity(_) => "(checksum integrity error)",
|
||||||
Decode(_) => "(loading decode error)",
|
Decode(_) => "(loading decode error)",
|
||||||
Loader(err) => {
|
Loader(err) => {
|
||||||
match deno_runtime::errors::get_error_class_name(err) {
|
if err.get_class() == "NotCapable" {
|
||||||
Some("NotCapable") => "(not capable, requires --allow-import)",
|
"(not capable, requires --allow-import)"
|
||||||
_ => "(loading error)",
|
} else {
|
||||||
|
"(loading error)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Jsr(_) => "(loading error)",
|
Jsr(_) => "(loading error)",
|
||||||
|
|
|
@ -12,9 +12,9 @@ use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use deno_cache_dir::file_fetcher::CacheSetting;
|
use deno_cache_dir::file_fetcher::CacheSetting;
|
||||||
|
use deno_core::anyhow::anyhow;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::bail;
|
||||||
use deno_core::anyhow::Context;
|
use deno_core::anyhow::Context;
|
||||||
use deno_core::error::generic_error;
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::resolve_url_or_path;
|
use deno_core::resolve_url_or_path;
|
||||||
use deno_core::url::Url;
|
use deno_core::url::Url;
|
||||||
|
@ -54,9 +54,7 @@ fn validate_name(exec_name: &str) -> Result<(), AnyError> {
|
||||||
if EXEC_NAME_RE.is_match(exec_name) {
|
if EXEC_NAME_RE.is_match(exec_name) {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(generic_error(format!(
|
Err(anyhow!("Invalid executable name: {exec_name}"))
|
||||||
"Invalid executable name: {exec_name}"
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +221,7 @@ pub async fn uninstall(
|
||||||
// ensure directory exists
|
// ensure directory exists
|
||||||
if let Ok(metadata) = fs::metadata(&installation_dir) {
|
if let Ok(metadata) = fs::metadata(&installation_dir) {
|
||||||
if !metadata.is_dir() {
|
if !metadata.is_dir() {
|
||||||
return Err(generic_error("Installation path is not a directory"));
|
return Err(anyhow!("Installation path is not a directory"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,10 +245,10 @@ pub async fn uninstall(
|
||||||
}
|
}
|
||||||
|
|
||||||
if !removed {
|
if !removed {
|
||||||
return Err(generic_error(format!(
|
return Err(anyhow!(
|
||||||
"No installation found for {}",
|
"No installation found for {}",
|
||||||
uninstall_flags.name
|
uninstall_flags.name
|
||||||
)));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// There might be some extra files to delete
|
// There might be some extra files to delete
|
||||||
|
@ -423,14 +421,14 @@ async fn create_install_shim(
|
||||||
// ensure directory exists
|
// ensure directory exists
|
||||||
if let Ok(metadata) = fs::metadata(&shim_data.installation_dir) {
|
if let Ok(metadata) = fs::metadata(&shim_data.installation_dir) {
|
||||||
if !metadata.is_dir() {
|
if !metadata.is_dir() {
|
||||||
return Err(generic_error("Installation path is not a directory"));
|
return Err(anyhow!("Installation path is not a directory"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fs::create_dir_all(&shim_data.installation_dir)?;
|
fs::create_dir_all(&shim_data.installation_dir)?;
|
||||||
};
|
};
|
||||||
|
|
||||||
if shim_data.file_path.exists() && !install_flags_global.force {
|
if shim_data.file_path.exists() && !install_flags_global.force {
|
||||||
return Err(generic_error(
|
return Err(anyhow!(
|
||||||
"Existing installation found. Aborting (Use -f to overwrite).",
|
"Existing installation found. Aborting (Use -f to overwrite).",
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
@ -492,7 +490,7 @@ async fn resolve_shim_data(
|
||||||
|
|
||||||
let name = match name {
|
let name = match name {
|
||||||
Some(name) => name,
|
Some(name) => name,
|
||||||
None => return Err(generic_error(
|
None => return Err(anyhow!(
|
||||||
"An executable name was not provided. One could not be inferred from the URL. Aborting.",
|
"An executable name was not provided. One could not be inferred from the URL. Aborting.",
|
||||||
)),
|
)),
|
||||||
};
|
};
|
||||||
|
@ -524,9 +522,7 @@ async fn resolve_shim_data(
|
||||||
let log_level = match log_level {
|
let log_level = match log_level {
|
||||||
Level::Debug => "debug",
|
Level::Debug => "debug",
|
||||||
Level::Info => "info",
|
Level::Info => "info",
|
||||||
_ => {
|
_ => return Err(anyhow!(format!("invalid log level {log_level}"))),
|
||||||
return Err(generic_error(format!("invalid log level {log_level}")))
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
executable_args.push(log_level.to_string());
|
executable_args.push(log_level.to_string());
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use deno_core::anyhow::anyhow;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::bail;
|
||||||
use deno_core::anyhow::Context;
|
use deno_core::anyhow::Context;
|
||||||
use deno_core::error::generic_error;
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::futures::FutureExt;
|
use deno_core::futures::FutureExt;
|
||||||
use deno_core::located_script_name;
|
use deno_core::located_script_name;
|
||||||
|
@ -137,10 +137,10 @@ pub async fn kernel(
|
||||||
}
|
}
|
||||||
let cwd_url =
|
let cwd_url =
|
||||||
Url::from_directory_path(cli_options.initial_cwd()).map_err(|_| {
|
Url::from_directory_path(cli_options.initial_cwd()).map_err(|_| {
|
||||||
generic_error(format!(
|
anyhow!(
|
||||||
"Unable to construct URL from the path of cwd: {}",
|
"Unable to construct URL from the path of cwd: {}",
|
||||||
cli_options.initial_cwd().to_string_lossy(),
|
cli_options.initial_cwd().to_string_lossy(),
|
||||||
))
|
)
|
||||||
})?;
|
})?;
|
||||||
repl_session.set_test_reporter_factory(Box::new(move || {
|
repl_session.set_test_reporter_factory(Box::new(move || {
|
||||||
Box::new(
|
Box::new(
|
||||||
|
|
|
@ -18,7 +18,6 @@ use deno_config::glob::FileCollector;
|
||||||
use deno_config::glob::FilePatterns;
|
use deno_config::glob::FilePatterns;
|
||||||
use deno_config::workspace::WorkspaceDirectory;
|
use deno_config::workspace::WorkspaceDirectory;
|
||||||
use deno_core::anyhow::anyhow;
|
use deno_core::anyhow::anyhow;
|
||||||
use deno_core::error::generic_error;
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::futures::future::LocalBoxFuture;
|
use deno_core::futures::future::LocalBoxFuture;
|
||||||
use deno_core::futures::FutureExt;
|
use deno_core::futures::FutureExt;
|
||||||
|
@ -77,9 +76,7 @@ pub async fn lint(
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
if lint_flags.watch.is_some() {
|
if lint_flags.watch.is_some() {
|
||||||
if lint_flags.is_stdin() {
|
if lint_flags.is_stdin() {
|
||||||
return Err(generic_error(
|
return Err(anyhow!("Lint watch on standard input is not supported.",));
|
||||||
"Lint watch on standard input is not supported.",
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return lint_with_watch(flags, lint_flags).await;
|
return lint_with_watch(flags, lint_flags).await;
|
||||||
|
@ -223,7 +220,7 @@ fn resolve_paths_with_options_batches(
|
||||||
let mut paths_with_options_batches =
|
let mut paths_with_options_batches =
|
||||||
Vec::with_capacity(members_lint_options.len());
|
Vec::with_capacity(members_lint_options.len());
|
||||||
for (dir, lint_options) in members_lint_options {
|
for (dir, lint_options) in members_lint_options {
|
||||||
let files = collect_lint_files(cli_options, lint_options.files.clone())?;
|
let files = collect_lint_files(cli_options, lint_options.files.clone());
|
||||||
if !files.is_empty() {
|
if !files.is_empty() {
|
||||||
paths_with_options_batches.push(PathsWithOptions {
|
paths_with_options_batches.push(PathsWithOptions {
|
||||||
dir,
|
dir,
|
||||||
|
@ -233,7 +230,7 @@ fn resolve_paths_with_options_batches(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if paths_with_options_batches.is_empty() {
|
if paths_with_options_batches.is_empty() {
|
||||||
return Err(generic_error("No target files found."));
|
return Err(anyhow!("No target files found."));
|
||||||
}
|
}
|
||||||
Ok(paths_with_options_batches)
|
Ok(paths_with_options_batches)
|
||||||
}
|
}
|
||||||
|
@ -446,7 +443,7 @@ impl WorkspaceLinter {
|
||||||
fn collect_lint_files(
|
fn collect_lint_files(
|
||||||
cli_options: &CliOptions,
|
cli_options: &CliOptions,
|
||||||
files: FilePatterns,
|
files: FilePatterns,
|
||||||
) -> Result<Vec<PathBuf>, AnyError> {
|
) -> Vec<PathBuf> {
|
||||||
FileCollector::new(|e| {
|
FileCollector::new(|e| {
|
||||||
is_script_ext(e.path)
|
is_script_ext(e.path)
|
||||||
|| (e.path.extension().is_none() && cli_options.ext_flag().is_some())
|
|| (e.path.extension().is_none() && cli_options.ext_flag().is_some())
|
||||||
|
@ -534,7 +531,7 @@ fn lint_stdin(
|
||||||
}
|
}
|
||||||
let mut source_code = String::new();
|
let mut source_code = String::new();
|
||||||
if stdin().read_to_string(&mut source_code).is_err() {
|
if stdin().read_to_string(&mut source_code).is_err() {
|
||||||
return Err(generic_error("Failed to read from stdin"));
|
return Err(anyhow!("Failed to read from stdin"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let linter = CliLinter::new(CliLinterOptions {
|
let linter = CliLinter::new(CliLinterOptions {
|
||||||
|
|
|
@ -7,7 +7,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use deno_ast::SourceRange;
|
use deno_ast::SourceRange;
|
||||||
use deno_config::workspace::WorkspaceResolver;
|
use deno_config::workspace::WorkspaceResolver;
|
||||||
use deno_core::anyhow::anyhow;
|
use deno_error::JsErrorBox;
|
||||||
use deno_graph::source::ResolutionKind;
|
use deno_graph::source::ResolutionKind;
|
||||||
use deno_graph::source::ResolveError;
|
use deno_graph::source::ResolveError;
|
||||||
use deno_graph::Range;
|
use deno_graph::Range;
|
||||||
|
@ -187,7 +187,7 @@ impl<'a> deno_graph::source::Resolver for SloppyImportCaptureResolver<'a> {
|
||||||
let resolution = self
|
let resolution = self
|
||||||
.workspace_resolver
|
.workspace_resolver
|
||||||
.resolve(specifier_text, &referrer_range.specifier)
|
.resolve(specifier_text, &referrer_range.specifier)
|
||||||
.map_err(|err| ResolveError::Other(err.into()))?;
|
.map_err(|err| ResolveError::Other(JsErrorBox::from_err(err)))?;
|
||||||
|
|
||||||
match resolution {
|
match resolution {
|
||||||
deno_config::workspace::MappedResolution::Normal {
|
deno_config::workspace::MappedResolution::Normal {
|
||||||
|
@ -220,7 +220,7 @@ impl<'a> deno_graph::source::Resolver for SloppyImportCaptureResolver<'a> {
|
||||||
}
|
}
|
||||||
| deno_config::workspace::MappedResolution::PackageJson { .. } => {
|
| deno_config::workspace::MappedResolution::PackageJson { .. } => {
|
||||||
// this error is ignored
|
// this error is ignored
|
||||||
Err(ResolveError::Other(anyhow!("")))
|
Err(ResolveError::Other(JsErrorBox::generic("")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,7 +233,7 @@ pub fn collect_publish_paths(
|
||||||
) -> Result<Vec<CollectedPublishPath>, AnyError> {
|
) -> Result<Vec<CollectedPublishPath>, AnyError> {
|
||||||
let diagnostics_collector = opts.diagnostics_collector;
|
let diagnostics_collector = opts.diagnostics_collector;
|
||||||
let publish_paths =
|
let publish_paths =
|
||||||
collect_paths(opts.cli_options, diagnostics_collector, opts.file_patterns)?;
|
collect_paths(opts.cli_options, diagnostics_collector, opts.file_patterns);
|
||||||
let publish_paths_set = publish_paths.iter().cloned().collect::<HashSet<_>>();
|
let publish_paths_set = publish_paths.iter().cloned().collect::<HashSet<_>>();
|
||||||
let capacity = publish_paths.len() + opts.force_include_paths.len();
|
let capacity = publish_paths.len() + opts.force_include_paths.len();
|
||||||
let mut paths = HashSet::with_capacity(capacity);
|
let mut paths = HashSet::with_capacity(capacity);
|
||||||
|
@ -321,7 +321,7 @@ fn collect_paths(
|
||||||
cli_options: &CliOptions,
|
cli_options: &CliOptions,
|
||||||
diagnostics_collector: &PublishDiagnosticsCollector,
|
diagnostics_collector: &PublishDiagnosticsCollector,
|
||||||
file_patterns: FilePatterns,
|
file_patterns: FilePatterns,
|
||||||
) -> Result<Vec<PathBuf>, AnyError> {
|
) -> Vec<PathBuf> {
|
||||||
FileCollector::new(|e| {
|
FileCollector::new(|e| {
|
||||||
if !e.metadata.file_type().is_file() {
|
if !e.metadata.file_type().is_file() {
|
||||||
if let Ok(specifier) = ModuleSpecifier::from_file_path(e.path) {
|
if let Ok(specifier) = ModuleSpecifier::from_file_path(e.path) {
|
||||||
|
|
|
@ -4,8 +4,10 @@ use std::cell::RefCell;
|
||||||
|
|
||||||
use deno_core::anyhow::anyhow;
|
use deno_core::anyhow::anyhow;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
use deno_core::error::CoreError;
|
||||||
use deno_core::serde_json;
|
use deno_core::serde_json;
|
||||||
use deno_core::serde_json::Value;
|
use deno_core::serde_json::Value;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use tokio::sync::mpsc::channel;
|
use tokio::sync::mpsc::channel;
|
||||||
use tokio::sync::mpsc::unbounded_channel;
|
use tokio::sync::mpsc::unbounded_channel;
|
||||||
use tokio::sync::mpsc::Receiver;
|
use tokio::sync::mpsc::Receiver;
|
||||||
|
@ -47,7 +49,7 @@ pub enum RustylineSyncMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum RustylineSyncResponse {
|
pub enum RustylineSyncResponse {
|
||||||
PostMessage(Result<Value, AnyError>),
|
PostMessage(Result<Value, CoreError>),
|
||||||
LspCompletions(Vec<ReplCompletionItem>),
|
LspCompletions(Vec<ReplCompletionItem>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +63,7 @@ impl RustylineSyncMessageSender {
|
||||||
&self,
|
&self,
|
||||||
method: &str,
|
method: &str,
|
||||||
params: Option<T>,
|
params: Option<T>,
|
||||||
) -> Result<Value, AnyError> {
|
) -> Result<Value, CoreError> {
|
||||||
if let Err(err) =
|
if let Err(err) =
|
||||||
self
|
self
|
||||||
.message_tx
|
.message_tx
|
||||||
|
@ -69,10 +71,11 @@ impl RustylineSyncMessageSender {
|
||||||
method: method.to_string(),
|
method: method.to_string(),
|
||||||
params: params
|
params: params
|
||||||
.map(|params| serde_json::to_value(params))
|
.map(|params| serde_json::to_value(params))
|
||||||
.transpose()?,
|
.transpose()
|
||||||
|
.map_err(JsErrorBox::from_err)?,
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
Err(anyhow!("{}", err))
|
Err(JsErrorBox::from_err(err).into())
|
||||||
} else {
|
} else {
|
||||||
match self.response_rx.borrow_mut().blocking_recv().unwrap() {
|
match self.response_rx.borrow_mut().blocking_recv().unwrap() {
|
||||||
RustylineSyncResponse::PostMessage(result) => result,
|
RustylineSyncResponse::PostMessage(result) => result,
|
||||||
|
|
|
@ -16,8 +16,9 @@ use deno_ast::ParsedSource;
|
||||||
use deno_ast::SourcePos;
|
use deno_ast::SourcePos;
|
||||||
use deno_ast::SourceRangedForSpanned;
|
use deno_ast::SourceRangedForSpanned;
|
||||||
use deno_ast::SourceTextInfo;
|
use deno_ast::SourceTextInfo;
|
||||||
use deno_core::error::generic_error;
|
use deno_core::anyhow::anyhow;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
use deno_core::error::CoreError;
|
||||||
use deno_core::futures::channel::mpsc::UnboundedReceiver;
|
use deno_core::futures::channel::mpsc::UnboundedReceiver;
|
||||||
use deno_core::futures::FutureExt;
|
use deno_core::futures::FutureExt;
|
||||||
use deno_core::futures::StreamExt;
|
use deno_core::futures::StreamExt;
|
||||||
|
@ -27,6 +28,7 @@ use deno_core::unsync::spawn;
|
||||||
use deno_core::url::Url;
|
use deno_core::url::Url;
|
||||||
use deno_core::LocalInspectorSession;
|
use deno_core::LocalInspectorSession;
|
||||||
use deno_core::PollEventLoopOptions;
|
use deno_core::PollEventLoopOptions;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_graph::Position;
|
use deno_graph::Position;
|
||||||
use deno_graph::PositionRange;
|
use deno_graph::PositionRange;
|
||||||
use deno_graph::SpecifierWithRange;
|
use deno_graph::SpecifierWithRange;
|
||||||
|
@ -250,10 +252,10 @@ impl ReplSession {
|
||||||
|
|
||||||
let cwd_url =
|
let cwd_url =
|
||||||
Url::from_directory_path(cli_options.initial_cwd()).map_err(|_| {
|
Url::from_directory_path(cli_options.initial_cwd()).map_err(|_| {
|
||||||
generic_error(format!(
|
anyhow!(
|
||||||
"Unable to construct URL from the path of cwd: {}",
|
"Unable to construct URL from the path of cwd: {}",
|
||||||
cli_options.initial_cwd().to_string_lossy(),
|
cli_options.initial_cwd().to_string_lossy(),
|
||||||
))
|
)
|
||||||
})?;
|
})?;
|
||||||
let ts_config_for_emit = cli_options
|
let ts_config_for_emit = cli_options
|
||||||
.resolve_ts_config_for_emit(deno_config::deno_json::TsConfigType::Emit)?;
|
.resolve_ts_config_for_emit(deno_config::deno_json::TsConfigType::Emit)?;
|
||||||
|
@ -322,7 +324,7 @@ impl ReplSession {
|
||||||
&mut self,
|
&mut self,
|
||||||
method: &str,
|
method: &str,
|
||||||
params: Option<T>,
|
params: Option<T>,
|
||||||
) -> Result<Value, AnyError> {
|
) -> Result<Value, CoreError> {
|
||||||
self
|
self
|
||||||
.worker
|
.worker
|
||||||
.js_runtime
|
.js_runtime
|
||||||
|
@ -339,7 +341,7 @@ impl ReplSession {
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run_event_loop(&mut self) -> Result<(), AnyError> {
|
pub async fn run_event_loop(&mut self) -> Result<(), CoreError> {
|
||||||
self.worker.run_event_loop(true).await
|
self.worker.run_event_loop(true).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,21 +402,29 @@ impl ReplSession {
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
// handle a parsing diagnostic
|
// handle a parsing diagnostic
|
||||||
match err.downcast_ref::<deno_ast::ParseDiagnostic>() {
|
match crate::util::result::any_and_jserrorbox_downcast_ref::<
|
||||||
|
deno_ast::ParseDiagnostic,
|
||||||
|
>(&err)
|
||||||
|
{
|
||||||
Some(diagnostic) => {
|
Some(diagnostic) => {
|
||||||
Ok(EvaluationOutput::Error(format_diagnostic(diagnostic)))
|
Ok(EvaluationOutput::Error(format_diagnostic(diagnostic)))
|
||||||
}
|
}
|
||||||
None => match err.downcast_ref::<ParseDiagnosticsError>() {
|
None => {
|
||||||
Some(diagnostics) => Ok(EvaluationOutput::Error(
|
match crate::util::result::any_and_jserrorbox_downcast_ref::<
|
||||||
diagnostics
|
ParseDiagnosticsError,
|
||||||
.0
|
>(&err)
|
||||||
.iter()
|
{
|
||||||
.map(format_diagnostic)
|
Some(diagnostics) => Ok(EvaluationOutput::Error(
|
||||||
.collect::<Vec<_>>()
|
diagnostics
|
||||||
.join("\n\n"),
|
.0
|
||||||
)),
|
.iter()
|
||||||
None => Err(err),
|
.map(format_diagnostic)
|
||||||
},
|
.collect::<Vec<_>>()
|
||||||
|
.join("\n\n"),
|
||||||
|
)),
|
||||||
|
None => Err(err),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -742,7 +752,7 @@ impl ReplSession {
|
||||||
async fn evaluate_expression(
|
async fn evaluate_expression(
|
||||||
&mut self,
|
&mut self,
|
||||||
expression: &str,
|
expression: &str,
|
||||||
) -> Result<cdp::EvaluateResponse, AnyError> {
|
) -> Result<cdp::EvaluateResponse, CoreError> {
|
||||||
self
|
self
|
||||||
.post_message_with_event_loop(
|
.post_message_with_event_loop(
|
||||||
"Runtime.evaluate",
|
"Runtime.evaluate",
|
||||||
|
@ -765,7 +775,9 @@ impl ReplSession {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.and_then(|res| serde_json::from_value(res).map_err(|e| e.into()))
|
.and_then(|res| {
|
||||||
|
serde_json::from_value(res).map_err(|e| JsErrorBox::from_err(e).into())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,13 @@ use std::collections::HashMap;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use deno_core::error::generic_error;
|
use deno_core::error::CoreError;
|
||||||
use deno_core::error::AnyError;
|
|
||||||
use deno_core::futures::StreamExt;
|
use deno_core::futures::StreamExt;
|
||||||
use deno_core::serde_json::json;
|
use deno_core::serde_json::json;
|
||||||
use deno_core::serde_json::{self};
|
use deno_core::serde_json::{self};
|
||||||
use deno_core::url::Url;
|
use deno_core::url::Url;
|
||||||
use deno_core::LocalInspectorSession;
|
use deno_core::LocalInspectorSession;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_terminal::colors;
|
use deno_terminal::colors;
|
||||||
use tokio::select;
|
use tokio::select;
|
||||||
|
|
||||||
|
@ -66,19 +66,19 @@ pub struct HmrRunner {
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl crate::worker::HmrRunner for HmrRunner {
|
impl crate::worker::HmrRunner for HmrRunner {
|
||||||
// TODO(bartlomieju): this code is duplicated in `cli/tools/coverage/mod.rs`
|
// TODO(bartlomieju): this code is duplicated in `cli/tools/coverage/mod.rs`
|
||||||
async fn start(&mut self) -> Result<(), AnyError> {
|
async fn start(&mut self) -> Result<(), CoreError> {
|
||||||
self.enable_debugger().await
|
self.enable_debugger().await
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(bartlomieju): this code is duplicated in `cli/tools/coverage/mod.rs`
|
// TODO(bartlomieju): this code is duplicated in `cli/tools/coverage/mod.rs`
|
||||||
async fn stop(&mut self) -> Result<(), AnyError> {
|
async fn stop(&mut self) -> Result<(), CoreError> {
|
||||||
self
|
self
|
||||||
.watcher_communicator
|
.watcher_communicator
|
||||||
.change_restart_mode(WatcherRestartMode::Automatic);
|
.change_restart_mode(WatcherRestartMode::Automatic);
|
||||||
self.disable_debugger().await
|
self.disable_debugger().await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(&mut self) -> Result<(), AnyError> {
|
async fn run(&mut self) -> Result<(), CoreError> {
|
||||||
self
|
self
|
||||||
.watcher_communicator
|
.watcher_communicator
|
||||||
.change_restart_mode(WatcherRestartMode::Manual);
|
.change_restart_mode(WatcherRestartMode::Manual);
|
||||||
|
@ -87,13 +87,13 @@ impl crate::worker::HmrRunner for HmrRunner {
|
||||||
select! {
|
select! {
|
||||||
biased;
|
biased;
|
||||||
Some(notification) = session_rx.next() => {
|
Some(notification) = session_rx.next() => {
|
||||||
let notification = serde_json::from_value::<cdp::Notification>(notification)?;
|
let notification = serde_json::from_value::<cdp::Notification>(notification).map_err(JsErrorBox::from_err)?;
|
||||||
if notification.method == "Runtime.exceptionThrown" {
|
if notification.method == "Runtime.exceptionThrown" {
|
||||||
let exception_thrown = serde_json::from_value::<cdp::ExceptionThrown>(notification.params)?;
|
let exception_thrown = serde_json::from_value::<cdp::ExceptionThrown>(notification.params).map_err(JsErrorBox::from_err)?;
|
||||||
let (message, description) = exception_thrown.exception_details.get_message_and_description();
|
let (message, description) = exception_thrown.exception_details.get_message_and_description();
|
||||||
break Err(generic_error(format!("{} {}", message, description)));
|
break Err(JsErrorBox::generic(format!("{} {}", message, description)).into());
|
||||||
} else if notification.method == "Debugger.scriptParsed" {
|
} else if notification.method == "Debugger.scriptParsed" {
|
||||||
let params = serde_json::from_value::<cdp::ScriptParsed>(notification.params)?;
|
let params = serde_json::from_value::<cdp::ScriptParsed>(notification.params).map_err(JsErrorBox::from_err)?;
|
||||||
if params.url.starts_with("file://") {
|
if params.url.starts_with("file://") {
|
||||||
let file_url = Url::parse(¶ms.url).unwrap();
|
let file_url = Url::parse(¶ms.url).unwrap();
|
||||||
let file_path = file_url.to_file_path().unwrap();
|
let file_path = file_url.to_file_path().unwrap();
|
||||||
|
@ -105,7 +105,7 @@ impl crate::worker::HmrRunner for HmrRunner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
changed_paths = self.watcher_communicator.watch_for_changed_paths() => {
|
changed_paths = self.watcher_communicator.watch_for_changed_paths() => {
|
||||||
let changed_paths = changed_paths?;
|
let changed_paths = changed_paths.map_err(JsErrorBox::from_err)?;
|
||||||
|
|
||||||
let Some(changed_paths) = changed_paths else {
|
let Some(changed_paths) = changed_paths else {
|
||||||
let _ = self.watcher_communicator.force_restart();
|
let _ = self.watcher_communicator.force_restart();
|
||||||
|
@ -187,7 +187,7 @@ impl HmrRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(bartlomieju): this code is duplicated in `cli/tools/coverage/mod.rs`
|
// TODO(bartlomieju): this code is duplicated in `cli/tools/coverage/mod.rs`
|
||||||
async fn enable_debugger(&mut self) -> Result<(), AnyError> {
|
async fn enable_debugger(&mut self) -> Result<(), CoreError> {
|
||||||
self
|
self
|
||||||
.session
|
.session
|
||||||
.post_message::<()>("Debugger.enable", None)
|
.post_message::<()>("Debugger.enable", None)
|
||||||
|
@ -200,7 +200,7 @@ impl HmrRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(bartlomieju): this code is duplicated in `cli/tools/coverage/mod.rs`
|
// TODO(bartlomieju): this code is duplicated in `cli/tools/coverage/mod.rs`
|
||||||
async fn disable_debugger(&mut self) -> Result<(), AnyError> {
|
async fn disable_debugger(&mut self) -> Result<(), CoreError> {
|
||||||
self
|
self
|
||||||
.session
|
.session
|
||||||
.post_message::<()>("Debugger.disable", None)
|
.post_message::<()>("Debugger.disable", None)
|
||||||
|
@ -216,7 +216,7 @@ impl HmrRunner {
|
||||||
&mut self,
|
&mut self,
|
||||||
script_id: &str,
|
script_id: &str,
|
||||||
source: &str,
|
source: &str,
|
||||||
) -> Result<cdp::SetScriptSourceResponse, AnyError> {
|
) -> Result<cdp::SetScriptSourceResponse, CoreError> {
|
||||||
let result = self
|
let result = self
|
||||||
.session
|
.session
|
||||||
.post_message(
|
.post_message(
|
||||||
|
@ -229,15 +229,16 @@ impl HmrRunner {
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(serde_json::from_value::<cdp::SetScriptSourceResponse>(
|
Ok(
|
||||||
result,
|
serde_json::from_value::<cdp::SetScriptSourceResponse>(result)
|
||||||
)?)
|
.map_err(JsErrorBox::from_err)?,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn dispatch_hmr_event(
|
async fn dispatch_hmr_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
script_id: &str,
|
script_id: &str,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), CoreError> {
|
||||||
let expr = format!(
|
let expr = format!(
|
||||||
"dispatchEvent(new CustomEvent(\"hmr\", {{ detail: {{ path: \"{}\" }} }}));",
|
"dispatchEvent(new CustomEvent(\"hmr\", {{ detail: {{ path: \"{}\" }} }}));",
|
||||||
script_id
|
script_id
|
||||||
|
|
|
@ -73,7 +73,7 @@ async fn do_serve(
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let worker_count = match worker_count {
|
let worker_count = match worker_count {
|
||||||
None | Some(1) => return worker.run().await,
|
None | Some(1) => return worker.run().await.map_err(Into::into),
|
||||||
Some(c) => c,
|
Some(c) => c,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ async fn run_worker(
|
||||||
worker.run_for_watcher().await?;
|
worker.run_for_watcher().await?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
} else {
|
} else {
|
||||||
worker.run().await
|
worker.run().await.map_err(Into::into)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,8 @@ const HALF_SYNC_MARKER: &[u8; 4] = &[226, 128, 139, 0];
|
||||||
const BUFFER_SIZE: usize = 4096;
|
const BUFFER_SIZE: usize = 4096;
|
||||||
|
|
||||||
/// The test channel has been closed and cannot be used to send further messages.
|
/// The test channel has been closed and cannot be used to send further messages.
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, deno_error::JsError)]
|
||||||
|
#[class(generic)]
|
||||||
pub struct ChannelClosedError;
|
pub struct ChannelClosedError;
|
||||||
|
|
||||||
impl std::error::Error for ChannelClosedError {}
|
impl std::error::Error for ChannelClosedError {}
|
||||||
|
|
|
@ -25,10 +25,9 @@ use deno_cache_dir::file_fetcher::File;
|
||||||
use deno_config::glob::FilePatterns;
|
use deno_config::glob::FilePatterns;
|
||||||
use deno_config::glob::WalkEntry;
|
use deno_config::glob::WalkEntry;
|
||||||
use deno_core::anyhow;
|
use deno_core::anyhow;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::anyhow;
|
||||||
use deno_core::anyhow::Context as _;
|
|
||||||
use deno_core::error::generic_error;
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
use deno_core::error::CoreError;
|
||||||
use deno_core::error::JsError;
|
use deno_core::error::JsError;
|
||||||
use deno_core::futures::future;
|
use deno_core::futures::future;
|
||||||
use deno_core::futures::stream;
|
use deno_core::futures::stream;
|
||||||
|
@ -49,6 +48,7 @@ use deno_core::v8;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
use deno_core::PollEventLoopOptions;
|
use deno_core::PollEventLoopOptions;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_runtime::deno_io::Stdio;
|
use deno_runtime::deno_io::Stdio;
|
||||||
use deno_runtime::deno_io::StdioPipe;
|
use deno_runtime::deno_io::StdioPipe;
|
||||||
use deno_runtime::deno_permissions::Permissions;
|
use deno_runtime::deno_permissions::Permissions;
|
||||||
|
@ -106,6 +106,8 @@ use reporters::PrettyTestReporter;
|
||||||
use reporters::TapTestReporter;
|
use reporters::TapTestReporter;
|
||||||
use reporters::TestReporter;
|
use reporters::TestReporter;
|
||||||
|
|
||||||
|
use crate::tools::test::channel::ChannelClosedError;
|
||||||
|
|
||||||
/// How many times we're allowed to spin the event loop before considering something a leak.
|
/// How many times we're allowed to spin the event loop before considering something a leak.
|
||||||
const MAX_SANITIZER_LOOP_SPINS: usize = 16;
|
const MAX_SANITIZER_LOOP_SPINS: usize = 16;
|
||||||
|
|
||||||
|
@ -612,7 +614,7 @@ async fn configure_main_worker(
|
||||||
permissions_container: PermissionsContainer,
|
permissions_container: PermissionsContainer,
|
||||||
worker_sender: TestEventWorkerSender,
|
worker_sender: TestEventWorkerSender,
|
||||||
options: &TestSpecifierOptions,
|
options: &TestSpecifierOptions,
|
||||||
) -> Result<(Option<Box<dyn CoverageCollector>>, MainWorker), anyhow::Error> {
|
) -> Result<(Option<Box<dyn CoverageCollector>>, MainWorker), CoreError> {
|
||||||
let mut worker = worker_factory
|
let mut worker = worker_factory
|
||||||
.create_custom_worker(
|
.create_custom_worker(
|
||||||
WorkerExecutionMode::Test,
|
WorkerExecutionMode::Test,
|
||||||
|
@ -640,21 +642,15 @@ async fn configure_main_worker(
|
||||||
let mut worker = worker.into_main_worker();
|
let mut worker = worker.into_main_worker();
|
||||||
match res {
|
match res {
|
||||||
Ok(()) => Ok(()),
|
Ok(()) => Ok(()),
|
||||||
Err(error) => {
|
Err(CoreError::Js(err)) => {
|
||||||
// TODO(mmastrac): It would be nice to avoid having this error pattern repeated
|
send_test_event(
|
||||||
if error.is::<JsError>() {
|
&worker.js_runtime.op_state(),
|
||||||
send_test_event(
|
TestEvent::UncaughtError(specifier.to_string(), Box::new(err)),
|
||||||
&worker.js_runtime.op_state(),
|
)
|
||||||
TestEvent::UncaughtError(
|
.map_err(JsErrorBox::from_err)?;
|
||||||
specifier.to_string(),
|
Ok(())
|
||||||
Box::new(error.downcast::<JsError>().unwrap()),
|
|
||||||
),
|
|
||||||
)?;
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Err(err) => Err(err),
|
||||||
}?;
|
}?;
|
||||||
Ok((coverage_collector, worker))
|
Ok((coverage_collector, worker))
|
||||||
}
|
}
|
||||||
|
@ -691,21 +687,14 @@ pub async fn test_specifier(
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(()) => Ok(()),
|
Ok(()) => Ok(()),
|
||||||
Err(error) => {
|
Err(CoreError::Js(err)) => {
|
||||||
// TODO(mmastrac): It would be nice to avoid having this error pattern repeated
|
send_test_event(
|
||||||
if error.is::<JsError>() {
|
&worker.js_runtime.op_state(),
|
||||||
send_test_event(
|
TestEvent::UncaughtError(specifier.to_string(), Box::new(err)),
|
||||||
&worker.js_runtime.op_state(),
|
)?;
|
||||||
TestEvent::UncaughtError(
|
Ok(())
|
||||||
specifier.to_string(),
|
|
||||||
Box::new(error.downcast::<JsError>().unwrap()),
|
|
||||||
),
|
|
||||||
)?;
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Err(e) => Err(e.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -718,7 +707,7 @@ async fn test_specifier_inner(
|
||||||
specifier: ModuleSpecifier,
|
specifier: ModuleSpecifier,
|
||||||
fail_fast_tracker: FailFastTracker,
|
fail_fast_tracker: FailFastTracker,
|
||||||
options: TestSpecifierOptions,
|
options: TestSpecifierOptions,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), CoreError> {
|
||||||
// Ensure that there are no pending exceptions before we start running tests
|
// Ensure that there are no pending exceptions before we start running tests
|
||||||
worker.run_up_to_duration(Duration::from_millis(0)).await?;
|
worker.run_up_to_duration(Duration::from_millis(0)).await?;
|
||||||
|
|
||||||
|
@ -765,7 +754,7 @@ pub fn worker_has_tests(worker: &mut MainWorker) -> bool {
|
||||||
/// Yields to tokio to allow async work to process, and then polls
|
/// Yields to tokio to allow async work to process, and then polls
|
||||||
/// the event loop once.
|
/// the event loop once.
|
||||||
#[must_use = "The event loop result should be checked"]
|
#[must_use = "The event loop result should be checked"]
|
||||||
pub async fn poll_event_loop(worker: &mut MainWorker) -> Result<(), AnyError> {
|
pub async fn poll_event_loop(worker: &mut MainWorker) -> Result<(), CoreError> {
|
||||||
// Allow any ops that to do work in the tokio event loop to do so
|
// Allow any ops that to do work in the tokio event loop to do so
|
||||||
tokio::task::yield_now().await;
|
tokio::task::yield_now().await;
|
||||||
// Spin the event loop once
|
// Spin the event loop once
|
||||||
|
@ -784,13 +773,11 @@ pub async fn poll_event_loop(worker: &mut MainWorker) -> Result<(), AnyError> {
|
||||||
pub fn send_test_event(
|
pub fn send_test_event(
|
||||||
op_state: &RefCell<OpState>,
|
op_state: &RefCell<OpState>,
|
||||||
event: TestEvent,
|
event: TestEvent,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), ChannelClosedError> {
|
||||||
Ok(
|
op_state
|
||||||
op_state
|
.borrow_mut()
|
||||||
.borrow_mut()
|
.borrow_mut::<TestEventSender>()
|
||||||
.borrow_mut::<TestEventSender>()
|
.send(event)
|
||||||
.send(event)?,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run_tests_for_worker(
|
pub async fn run_tests_for_worker(
|
||||||
|
@ -986,13 +973,10 @@ async fn run_tests_for_worker_inner(
|
||||||
let result = match result {
|
let result = match result {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
if error.is::<JsError>() {
|
if let CoreError::Js(js_error) = error {
|
||||||
send_test_event(
|
send_test_event(
|
||||||
&state_rc,
|
&state_rc,
|
||||||
TestEvent::UncaughtError(
|
TestEvent::UncaughtError(specifier.to_string(), Box::new(js_error)),
|
||||||
specifier.to_string(),
|
|
||||||
Box::new(error.downcast::<JsError>().unwrap()),
|
|
||||||
),
|
|
||||||
)?;
|
)?;
|
||||||
fail_fast_tracker.add_failure();
|
fail_fast_tracker.add_failure();
|
||||||
send_test_event(
|
send_test_event(
|
||||||
|
@ -1002,7 +986,7 @@ async fn run_tests_for_worker_inner(
|
||||||
had_uncaught_error = true;
|
had_uncaught_error = true;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
return Err(error);
|
return Err(error.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1374,25 +1358,20 @@ pub async fn report_tests(
|
||||||
reporter.report_summary(&elapsed, &tests, &test_steps);
|
reporter.report_summary(&elapsed, &tests, &test_steps);
|
||||||
if let Err(err) = reporter.flush_report(&elapsed, &tests, &test_steps) {
|
if let Err(err) = reporter.flush_report(&elapsed, &tests, &test_steps) {
|
||||||
return (
|
return (
|
||||||
Err(generic_error(format!(
|
Err(anyhow!("Test reporter failed to flush: {}", err)),
|
||||||
"Test reporter failed to flush: {}",
|
|
||||||
err
|
|
||||||
))),
|
|
||||||
receiver,
|
receiver,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if used_only {
|
if used_only {
|
||||||
return (
|
return (
|
||||||
Err(generic_error(
|
Err(anyhow!("Test failed because the \"only\" option was used",)),
|
||||||
"Test failed because the \"only\" option was used",
|
|
||||||
)),
|
|
||||||
receiver,
|
receiver,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if failed {
|
if failed {
|
||||||
return (Err(generic_error("Test failed")), receiver);
|
return (Err(anyhow!("Test failed")), receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
(Ok(()), receiver)
|
(Ok(()), receiver)
|
||||||
|
@ -1575,7 +1554,7 @@ pub async fn run_tests(
|
||||||
|
|
||||||
if !workspace_test_options.permit_no_files && specifiers_with_mode.is_empty()
|
if !workspace_test_options.permit_no_files && specifiers_with_mode.is_empty()
|
||||||
{
|
{
|
||||||
return Err(generic_error("No test modules found"));
|
return Err(anyhow!("No test modules found"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let doc_tests = get_doc_tests(&specifiers_with_mode, file_fetcher).await?;
|
let doc_tests = get_doc_tests(&specifiers_with_mode, file_fetcher).await?;
|
||||||
|
@ -1611,10 +1590,10 @@ pub async fn run_tests(
|
||||||
TestSpecifiersOptions {
|
TestSpecifiersOptions {
|
||||||
cwd: Url::from_directory_path(cli_options.initial_cwd()).map_err(
|
cwd: Url::from_directory_path(cli_options.initial_cwd()).map_err(
|
||||||
|_| {
|
|_| {
|
||||||
generic_error(format!(
|
anyhow!(
|
||||||
"Unable to construct URL from the path of cwd: {}",
|
"Unable to construct URL from the path of cwd: {}",
|
||||||
cli_options.initial_cwd().to_string_lossy(),
|
cli_options.initial_cwd().to_string_lossy(),
|
||||||
))
|
)
|
||||||
},
|
},
|
||||||
)?,
|
)?,
|
||||||
concurrent_jobs: workspace_test_options.concurrent_jobs,
|
concurrent_jobs: workspace_test_options.concurrent_jobs,
|
||||||
|
@ -1793,10 +1772,10 @@ pub async fn run_tests_with_watch(
|
||||||
TestSpecifiersOptions {
|
TestSpecifiersOptions {
|
||||||
cwd: Url::from_directory_path(cli_options.initial_cwd()).map_err(
|
cwd: Url::from_directory_path(cli_options.initial_cwd()).map_err(
|
||||||
|_| {
|
|_| {
|
||||||
generic_error(format!(
|
anyhow!(
|
||||||
"Unable to construct URL from the path of cwd: {}",
|
"Unable to construct URL from the path of cwd: {}",
|
||||||
cli_options.initial_cwd().to_string_lossy(),
|
cli_options.initial_cwd().to_string_lossy(),
|
||||||
))
|
)
|
||||||
},
|
},
|
||||||
)?,
|
)?,
|
||||||
concurrent_jobs: workspace_test_options.concurrent_jobs,
|
concurrent_jobs: workspace_test_options.concurrent_jobs,
|
||||||
|
|
|
@ -129,7 +129,7 @@ impl TestReporter for CompoundTestReporter {
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
bail!(
|
anyhow::bail!(
|
||||||
"error in one or more wrapped reporters:\n{}",
|
"error in one or more wrapped reporters:\n{}",
|
||||||
errors
|
errors
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use deno_core::anyhow::Context;
|
||||||
|
|
||||||
use super::fmt::to_relative_path_or_remote_url;
|
use super::fmt::to_relative_path_or_remote_url;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
|
|
@ -320,7 +320,8 @@ impl fmt::Display for Diagnostic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
#[derive(Clone, Debug, Default, Eq, PartialEq, deno_error::JsError)]
|
||||||
|
#[class(generic)]
|
||||||
pub struct Diagnostics(Vec<Diagnostic>);
|
pub struct Diagnostics(Vec<Diagnostic>);
|
||||||
|
|
||||||
impl Diagnostics {
|
impl Diagnostics {
|
||||||
|
|
119
cli/tsc/mod.rs
119
cli/tsc/mod.rs
|
@ -3,12 +3,10 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::path::Path;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
use deno_core::anyhow::anyhow;
|
|
||||||
use deno_core::anyhow::Context;
|
use deno_core::anyhow::Context;
|
||||||
use deno_core::ascii_str;
|
use deno_core::ascii_str;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
@ -454,13 +452,6 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn normalize_specifier(
|
|
||||||
specifier: &str,
|
|
||||||
current_dir: &Path,
|
|
||||||
) -> Result<ModuleSpecifier, AnyError> {
|
|
||||||
resolve_url_or_path(specifier, current_dir).map_err(|err| err.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[op2]
|
#[op2]
|
||||||
#[string]
|
#[string]
|
||||||
fn op_create_hash(s: &mut OpState, #[string] text: &str) -> String {
|
fn op_create_hash(s: &mut OpState, #[string] text: &str) -> String {
|
||||||
|
@ -531,6 +522,21 @@ pub fn as_ts_script_kind(media_type: MediaType) -> i32 {
|
||||||
pub const MISSING_DEPENDENCY_SPECIFIER: &str =
|
pub const MISSING_DEPENDENCY_SPECIFIER: &str =
|
||||||
"internal:///missing_dependency.d.ts";
|
"internal:///missing_dependency.d.ts";
|
||||||
|
|
||||||
|
#[derive(Debug, Error, deno_error::JsError)]
|
||||||
|
pub enum LoadError {
|
||||||
|
#[class(generic)]
|
||||||
|
#[error("Unable to load {path}: {error}")]
|
||||||
|
LoadFromNodeModule { path: String, error: std::io::Error },
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(
|
||||||
|
"Error converting a string module specifier for \"op_resolve\": {0}"
|
||||||
|
)]
|
||||||
|
ModuleResolution(#[from] deno_core::ModuleResolutionError),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("{0}")]
|
||||||
|
ClosestPkgJson(#[from] node_resolver::errors::ClosestPkgJsonError),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
struct LoadResponse {
|
struct LoadResponse {
|
||||||
|
@ -545,24 +551,28 @@ struct LoadResponse {
|
||||||
fn op_load(
|
fn op_load(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] load_specifier: &str,
|
#[string] load_specifier: &str,
|
||||||
) -> Result<Option<LoadResponse>, AnyError> {
|
) -> Result<Option<LoadResponse>, LoadError> {
|
||||||
op_load_inner(state, load_specifier)
|
op_load_inner(state, load_specifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_load_inner(
|
fn op_load_inner(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
load_specifier: &str,
|
load_specifier: &str,
|
||||||
) -> Result<Option<LoadResponse>, AnyError> {
|
) -> Result<Option<LoadResponse>, LoadError> {
|
||||||
fn load_from_node_modules(
|
fn load_from_node_modules(
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
npm_state: Option<&RequestNpmState>,
|
npm_state: Option<&RequestNpmState>,
|
||||||
media_type: &mut MediaType,
|
media_type: &mut MediaType,
|
||||||
is_cjs: &mut bool,
|
is_cjs: &mut bool,
|
||||||
) -> Result<String, AnyError> {
|
) -> Result<String, LoadError> {
|
||||||
*media_type = MediaType::from_specifier(specifier);
|
*media_type = MediaType::from_specifier(specifier);
|
||||||
let file_path = specifier.to_file_path().unwrap();
|
let file_path = specifier.to_file_path().unwrap();
|
||||||
let code = std::fs::read_to_string(&file_path)
|
let code = std::fs::read_to_string(&file_path).map_err(|err| {
|
||||||
.with_context(|| format!("Unable to load {}", file_path.display()))?;
|
LoadError::LoadFromNodeModule {
|
||||||
|
path: file_path.display().to_string(),
|
||||||
|
error: err,
|
||||||
|
}
|
||||||
|
})?;
|
||||||
let code: Arc<str> = code.into();
|
let code: Arc<str> = code.into();
|
||||||
*is_cjs = npm_state
|
*is_cjs = npm_state
|
||||||
.map(|npm_state| {
|
.map(|npm_state| {
|
||||||
|
@ -575,8 +585,7 @@ fn op_load_inner(
|
||||||
|
|
||||||
let state = state.borrow_mut::<State>();
|
let state = state.borrow_mut::<State>();
|
||||||
|
|
||||||
let specifier = normalize_specifier(load_specifier, &state.current_dir)
|
let specifier = resolve_url_or_path(load_specifier, &state.current_dir)?;
|
||||||
.context("Error converting a string module specifier for \"op_load\".")?;
|
|
||||||
|
|
||||||
let mut hash: Option<String> = None;
|
let mut hash: Option<String> = None;
|
||||||
let mut media_type = MediaType::Unknown;
|
let mut media_type = MediaType::Unknown;
|
||||||
|
@ -688,6 +697,26 @@ fn op_load_inner(
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error, deno_error::JsError)]
|
||||||
|
pub enum ResolveError {
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(
|
||||||
|
"Error converting a string module specifier for \"op_resolve\": {0}"
|
||||||
|
)]
|
||||||
|
ModuleResolution(#[from] deno_core::ModuleResolutionError),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("{0}")]
|
||||||
|
PackageSubpathResolve(PackageSubpathResolveError),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("{0}")]
|
||||||
|
ResolvePkgFolderFromDenoModule(
|
||||||
|
#[from] crate::npm::ResolvePkgFolderFromDenoModuleError,
|
||||||
|
),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("{0}")]
|
||||||
|
ResolveNonGraphSpecifierTypes(#[from] ResolveNonGraphSpecifierTypesError),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ResolveArgs {
|
pub struct ResolveArgs {
|
||||||
|
@ -717,7 +746,7 @@ fn op_resolve(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] base: String,
|
#[string] base: String,
|
||||||
#[serde] specifiers: Vec<(bool, String)>,
|
#[serde] specifiers: Vec<(bool, String)>,
|
||||||
) -> Result<Vec<(String, &'static str)>, AnyError> {
|
) -> Result<Vec<(String, &'static str)>, ResolveError> {
|
||||||
op_resolve_inner(state, ResolveArgs { base, specifiers })
|
op_resolve_inner(state, ResolveArgs { base, specifiers })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -725,7 +754,7 @@ fn op_resolve(
|
||||||
fn op_resolve_inner(
|
fn op_resolve_inner(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
args: ResolveArgs,
|
args: ResolveArgs,
|
||||||
) -> Result<Vec<(String, &'static str)>, AnyError> {
|
) -> Result<Vec<(String, &'static str)>, ResolveError> {
|
||||||
let state = state.borrow_mut::<State>();
|
let state = state.borrow_mut::<State>();
|
||||||
let mut resolved: Vec<(String, &'static str)> =
|
let mut resolved: Vec<(String, &'static str)> =
|
||||||
Vec::with_capacity(args.specifiers.len());
|
Vec::with_capacity(args.specifiers.len());
|
||||||
|
@ -734,9 +763,7 @@ fn op_resolve_inner(
|
||||||
{
|
{
|
||||||
remapped_specifier.clone()
|
remapped_specifier.clone()
|
||||||
} else {
|
} else {
|
||||||
normalize_specifier(&args.base, &state.current_dir).context(
|
resolve_url_or_path(&args.base, &state.current_dir)?
|
||||||
"Error converting a string module specifier for \"op_resolve\".",
|
|
||||||
)?
|
|
||||||
};
|
};
|
||||||
let referrer_module = state.graph.get(&referrer);
|
let referrer_module = state.graph.get(&referrer);
|
||||||
for (is_cjs, specifier) in args.specifiers {
|
for (is_cjs, specifier) in args.specifiers {
|
||||||
|
@ -852,7 +879,7 @@ fn resolve_graph_specifier_types(
|
||||||
referrer: &ModuleSpecifier,
|
referrer: &ModuleSpecifier,
|
||||||
resolution_mode: ResolutionMode,
|
resolution_mode: ResolutionMode,
|
||||||
state: &State,
|
state: &State,
|
||||||
) -> Result<Option<(ModuleSpecifier, MediaType)>, AnyError> {
|
) -> Result<Option<(ModuleSpecifier, MediaType)>, ResolveError> {
|
||||||
let graph = &state.graph;
|
let graph = &state.graph;
|
||||||
let maybe_module = match graph.try_get(specifier) {
|
let maybe_module = match graph.try_get(specifier) {
|
||||||
Ok(Some(module)) => Some(module),
|
Ok(Some(module)) => Some(module),
|
||||||
|
@ -914,7 +941,7 @@ fn resolve_graph_specifier_types(
|
||||||
Err(err) => match err.code() {
|
Err(err) => match err.code() {
|
||||||
NodeJsErrorCode::ERR_TYPES_NOT_FOUND
|
NodeJsErrorCode::ERR_TYPES_NOT_FOUND
|
||||||
| NodeJsErrorCode::ERR_MODULE_NOT_FOUND => None,
|
| NodeJsErrorCode::ERR_MODULE_NOT_FOUND => None,
|
||||||
_ => return Err(err.into()),
|
_ => return Err(ResolveError::PackageSubpathResolve(err)),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
Ok(Some(into_specifier_and_media_type(maybe_url)))
|
Ok(Some(into_specifier_and_media_type(maybe_url)))
|
||||||
|
@ -936,10 +963,12 @@ fn resolve_graph_specifier_types(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error, deno_error::JsError)]
|
||||||
enum ResolveNonGraphSpecifierTypesError {
|
pub enum ResolveNonGraphSpecifierTypesError {
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
ResolvePkgFolderFromDenoReq(#[from] ResolvePkgFolderFromDenoReqError),
|
ResolvePkgFolderFromDenoReq(#[from] ResolvePkgFolderFromDenoReqError),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
PackageSubpathResolve(#[from] PackageSubpathResolveError),
|
PackageSubpathResolve(#[from] PackageSubpathResolveError),
|
||||||
}
|
}
|
||||||
|
@ -1036,10 +1065,20 @@ fn op_respond_inner(state: &mut OpState, args: RespondArgs) {
|
||||||
state.maybe_response = Some(args);
|
state.maybe_response = Some(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error, deno_error::JsError)]
|
||||||
|
pub enum ExecError {
|
||||||
|
#[class(generic)]
|
||||||
|
#[error("The response for the exec request was not set.")]
|
||||||
|
ResponseNotSet,
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
Core(deno_core::error::CoreError),
|
||||||
|
}
|
||||||
|
|
||||||
/// Execute a request on the supplied snapshot, returning a response which
|
/// Execute a request on the supplied snapshot, returning a response which
|
||||||
/// contains information, like any emitted files, diagnostics, statistics and
|
/// contains information, like any emitted files, diagnostics, statistics and
|
||||||
/// optionally an updated TypeScript build info.
|
/// optionally an updated TypeScript build info.
|
||||||
pub fn exec(request: Request) -> Result<Response, AnyError> {
|
pub fn exec(request: Request) -> Result<Response, ExecError> {
|
||||||
// tsc cannot handle root specifiers that don't have one of the "acceptable"
|
// tsc cannot handle root specifiers that don't have one of the "acceptable"
|
||||||
// extensions. Therefore, we have to check the root modules against their
|
// extensions. Therefore, we have to check the root modules against their
|
||||||
// extensions and remap any that are unacceptable to tsc and add them to the
|
// extensions and remap any that are unacceptable to tsc and add them to the
|
||||||
|
@ -1115,7 +1154,9 @@ pub fn exec(request: Request) -> Result<Response, AnyError> {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
runtime.execute_script(located_script_name!(), exec_source)?;
|
runtime
|
||||||
|
.execute_script(located_script_name!(), exec_source)
|
||||||
|
.map_err(ExecError::Core)?;
|
||||||
|
|
||||||
let op_state = runtime.op_state();
|
let op_state = runtime.op_state();
|
||||||
let mut op_state = op_state.borrow_mut();
|
let mut op_state = op_state.borrow_mut();
|
||||||
|
@ -1132,7 +1173,7 @@ pub fn exec(request: Request) -> Result<Response, AnyError> {
|
||||||
stats,
|
stats,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(anyhow!("The response for the exec request was not set."))
|
Err(ExecError::ResponseNotSet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1141,6 +1182,7 @@ mod tests {
|
||||||
use deno_core::futures::future;
|
use deno_core::futures::future;
|
||||||
use deno_core::serde_json;
|
use deno_core::serde_json;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_graph::GraphKind;
|
use deno_graph::GraphKind;
|
||||||
use deno_graph::ModuleGraph;
|
use deno_graph::ModuleGraph;
|
||||||
use test_util::PathRef;
|
use test_util::PathRef;
|
||||||
|
@ -1167,13 +1209,20 @@ mod tests {
|
||||||
.replace("://", "_")
|
.replace("://", "_")
|
||||||
.replace('/', "-");
|
.replace('/', "-");
|
||||||
let source_path = self.fixtures.join(specifier_text);
|
let source_path = self.fixtures.join(specifier_text);
|
||||||
let response = source_path.read_to_bytes_if_exists().map(|c| {
|
let response = source_path
|
||||||
Some(deno_graph::source::LoadResponse::Module {
|
.read_to_bytes_if_exists()
|
||||||
specifier: specifier.clone(),
|
.map(|c| {
|
||||||
maybe_headers: None,
|
Some(deno_graph::source::LoadResponse::Module {
|
||||||
content: c.into(),
|
specifier: specifier.clone(),
|
||||||
|
maybe_headers: None,
|
||||||
|
content: c.into(),
|
||||||
|
})
|
||||||
})
|
})
|
||||||
});
|
.map_err(|e| {
|
||||||
|
deno_graph::source::LoadError::Other(Arc::new(JsErrorBox::generic(
|
||||||
|
e.to_string(),
|
||||||
|
)))
|
||||||
|
});
|
||||||
Box::pin(future::ready(response))
|
Box::pin(future::ready(response))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1210,7 +1259,7 @@ mod tests {
|
||||||
|
|
||||||
async fn test_exec(
|
async fn test_exec(
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
) -> Result<Response, AnyError> {
|
) -> Result<Response, ExecError> {
|
||||||
let hash_data = 123; // something random
|
let hash_data = 123; // something random
|
||||||
let fixtures = test_util::testdata_path().join("tsc2");
|
let fixtures = test_util::testdata_path().join("tsc2");
|
||||||
let loader = MockLoader { fixtures };
|
let loader = MockLoader { fixtures };
|
||||||
|
|
|
@ -10,7 +10,7 @@ use std::time::Duration;
|
||||||
|
|
||||||
use deno_config::glob::PathOrPatternSet;
|
use deno_config::glob::PathOrPatternSet;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::error::JsError;
|
use deno_core::error::CoreError;
|
||||||
use deno_core::futures::Future;
|
use deno_core::futures::Future;
|
||||||
use deno_core::futures::FutureExt;
|
use deno_core::futures::FutureExt;
|
||||||
use deno_core::parking_lot::Mutex;
|
use deno_core::parking_lot::Mutex;
|
||||||
|
@ -23,6 +23,7 @@ use notify::RecommendedWatcher;
|
||||||
use notify::RecursiveMode;
|
use notify::RecursiveMode;
|
||||||
use notify::Watcher;
|
use notify::Watcher;
|
||||||
use tokio::select;
|
use tokio::select;
|
||||||
|
use tokio::sync::broadcast::error::RecvError;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use tokio::sync::mpsc::UnboundedReceiver;
|
use tokio::sync::mpsc::UnboundedReceiver;
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
|
@ -80,10 +81,13 @@ where
|
||||||
{
|
{
|
||||||
let result = watch_future.await;
|
let result = watch_future.await;
|
||||||
if let Err(err) = result {
|
if let Err(err) = result {
|
||||||
let error_string = match err.downcast_ref::<JsError>() {
|
let error_string =
|
||||||
Some(e) => format_js_error(e),
|
match crate::util::result::any_and_jserrorbox_downcast_ref::<CoreError>(
|
||||||
None => format!("{err:?}"),
|
&err,
|
||||||
};
|
) {
|
||||||
|
Some(CoreError::Js(e)) => format_js_error(e),
|
||||||
|
_ => format!("{err:?}"),
|
||||||
|
};
|
||||||
log::error!(
|
log::error!(
|
||||||
"{}: {}",
|
"{}: {}",
|
||||||
colors::red_bold("error"),
|
colors::red_bold("error"),
|
||||||
|
@ -171,9 +175,9 @@ impl WatcherCommunicator {
|
||||||
|
|
||||||
pub async fn watch_for_changed_paths(
|
pub async fn watch_for_changed_paths(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<Option<Vec<PathBuf>>, AnyError> {
|
) -> Result<Option<Vec<PathBuf>>, RecvError> {
|
||||||
let mut rx = self.changed_paths_rx.resubscribe();
|
let mut rx = self.changed_paths_rx.resubscribe();
|
||||||
rx.recv().await.map_err(AnyError::from)
|
rx.recv().await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn change_restart_mode(&self, restart_mode: WatcherRestartMode) {
|
pub fn change_restart_mode(&self, restart_mode: WatcherRestartMode) {
|
||||||
|
|
|
@ -13,7 +13,6 @@ use deno_config::glob::PathOrPattern;
|
||||||
use deno_config::glob::PathOrPatternSet;
|
use deno_config::glob::PathOrPatternSet;
|
||||||
use deno_config::glob::WalkEntry;
|
use deno_config::glob::WalkEntry;
|
||||||
use deno_core::anyhow::anyhow;
|
use deno_core::anyhow::anyhow;
|
||||||
use deno_core::anyhow::Context;
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::unsync::spawn_blocking;
|
use deno_core::unsync::spawn_blocking;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
|
@ -129,7 +128,7 @@ pub fn collect_specifiers(
|
||||||
.ignore_git_folder()
|
.ignore_git_folder()
|
||||||
.ignore_node_modules()
|
.ignore_node_modules()
|
||||||
.set_vendor_folder(vendor_folder)
|
.set_vendor_folder(vendor_folder)
|
||||||
.collect_file_patterns(&CliSys::default(), files)?;
|
.collect_file_patterns(&CliSys::default(), files);
|
||||||
let mut collected_files_as_urls = collected_files
|
let mut collected_files_as_urls = collected_files
|
||||||
.iter()
|
.iter()
|
||||||
.map(|f| specifier_from_file_path(f).unwrap())
|
.map(|f| specifier_from_file_path(f).unwrap())
|
||||||
|
@ -169,7 +168,7 @@ pub fn clone_dir_recursive<
|
||||||
sys: &TSys,
|
sys: &TSys,
|
||||||
from: &Path,
|
from: &Path,
|
||||||
to: &Path,
|
to: &Path,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), CopyDirRecursiveError> {
|
||||||
if cfg!(target_vendor = "apple") {
|
if cfg!(target_vendor = "apple") {
|
||||||
if let Some(parent) = to.parent() {
|
if let Some(parent) = to.parent() {
|
||||||
sys.fs_create_dir_all(parent)?;
|
sys.fs_create_dir_all(parent)?;
|
||||||
|
@ -200,6 +199,47 @@ pub fn clone_dir_recursive<
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
pub enum CopyDirRecursiveError {
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("Creating {path}")]
|
||||||
|
Creating {
|
||||||
|
path: PathBuf,
|
||||||
|
#[source]
|
||||||
|
#[inherit]
|
||||||
|
source: Error,
|
||||||
|
},
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("Creating {path}")]
|
||||||
|
Reading {
|
||||||
|
path: PathBuf,
|
||||||
|
#[source]
|
||||||
|
#[inherit]
|
||||||
|
source: Error,
|
||||||
|
},
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("Dir {from} to {to}")]
|
||||||
|
Dir {
|
||||||
|
from: PathBuf,
|
||||||
|
to: PathBuf,
|
||||||
|
#[source]
|
||||||
|
#[inherit]
|
||||||
|
source: Box<Self>,
|
||||||
|
},
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("Copying {from} to {to}")]
|
||||||
|
Copying {
|
||||||
|
from: PathBuf,
|
||||||
|
to: PathBuf,
|
||||||
|
#[source]
|
||||||
|
#[inherit]
|
||||||
|
source: Error,
|
||||||
|
},
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error(transparent)]
|
||||||
|
Other(#[from] Error),
|
||||||
|
}
|
||||||
|
|
||||||
/// Copies a directory to another directory.
|
/// Copies a directory to another directory.
|
||||||
///
|
///
|
||||||
/// Note: Does not handle symlinks.
|
/// Note: Does not handle symlinks.
|
||||||
|
@ -213,13 +253,20 @@ pub fn copy_dir_recursive<
|
||||||
sys: &TSys,
|
sys: &TSys,
|
||||||
from: &Path,
|
from: &Path,
|
||||||
to: &Path,
|
to: &Path,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), CopyDirRecursiveError> {
|
||||||
sys
|
sys.fs_create_dir_all(to).map_err(|source| {
|
||||||
.fs_create_dir_all(to)
|
CopyDirRecursiveError::Creating {
|
||||||
.with_context(|| format!("Creating {}", to.display()))?;
|
path: to.to_path_buf(),
|
||||||
let read_dir = sys
|
source,
|
||||||
.fs_read_dir(from)
|
}
|
||||||
.with_context(|| format!("Reading {}", from.display()))?;
|
})?;
|
||||||
|
let read_dir =
|
||||||
|
sys
|
||||||
|
.fs_read_dir(from)
|
||||||
|
.map_err(|source| CopyDirRecursiveError::Reading {
|
||||||
|
path: from.to_path_buf(),
|
||||||
|
source,
|
||||||
|
})?;
|
||||||
|
|
||||||
for entry in read_dir {
|
for entry in read_dir {
|
||||||
let entry = entry?;
|
let entry = entry?;
|
||||||
|
@ -228,12 +275,20 @@ pub fn copy_dir_recursive<
|
||||||
let new_to = to.join(entry.file_name());
|
let new_to = to.join(entry.file_name());
|
||||||
|
|
||||||
if file_type.is_dir() {
|
if file_type.is_dir() {
|
||||||
copy_dir_recursive(sys, &new_from, &new_to).with_context(|| {
|
copy_dir_recursive(sys, &new_from, &new_to).map_err(|source| {
|
||||||
format!("Dir {} to {}", new_from.display(), new_to.display())
|
CopyDirRecursiveError::Dir {
|
||||||
|
from: new_from.to_path_buf(),
|
||||||
|
to: new_to.to_path_buf(),
|
||||||
|
source: Box::new(source),
|
||||||
|
}
|
||||||
})?;
|
})?;
|
||||||
} else if file_type.is_file() {
|
} else if file_type.is_file() {
|
||||||
sys.fs_copy(&new_from, &new_to).with_context(|| {
|
sys.fs_copy(&new_from, &new_to).map_err(|source| {
|
||||||
format!("Copying {} to {}", new_from.display(), new_to.display())
|
CopyDirRecursiveError::Copying {
|
||||||
|
from: new_from.to_path_buf(),
|
||||||
|
to: new_to.to_path_buf(),
|
||||||
|
source,
|
||||||
|
}
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||||
|
|
||||||
use std::convert::Infallible;
|
use std::convert::Infallible;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
|
use deno_core::error::AnyError;
|
||||||
|
use deno_core::error::CoreError;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
|
use deno_error::JsErrorClass;
|
||||||
|
|
||||||
pub trait InfallibleResultExt<T> {
|
pub trait InfallibleResultExt<T> {
|
||||||
fn unwrap_infallible(self) -> T;
|
fn unwrap_infallible(self) -> T;
|
||||||
|
@ -14,3 +21,23 @@ impl<T> InfallibleResultExt<T> for Result<T, Infallible> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn any_and_jserrorbox_downcast_ref<
|
||||||
|
E: Display + Debug + Send + Sync + 'static,
|
||||||
|
>(
|
||||||
|
err: &AnyError,
|
||||||
|
) -> Option<&E> {
|
||||||
|
err
|
||||||
|
.downcast_ref::<E>()
|
||||||
|
.or_else(|| {
|
||||||
|
err
|
||||||
|
.downcast_ref::<JsErrorBox>()
|
||||||
|
.and_then(|e| e.as_any().downcast_ref::<E>())
|
||||||
|
})
|
||||||
|
.or_else(|| {
|
||||||
|
err.downcast_ref::<CoreError>().and_then(|e| match e {
|
||||||
|
CoreError::JsNative(e) => e.as_any().downcast_ref::<E>(),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ use std::sync::Arc;
|
||||||
use deno_ast::ModuleSpecifier;
|
use deno_ast::ModuleSpecifier;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::bail;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
use deno_core::error::CoreError;
|
||||||
use deno_core::futures::FutureExt;
|
use deno_core::futures::FutureExt;
|
||||||
use deno_core::url::Url;
|
use deno_core::url::Url;
|
||||||
use deno_core::v8;
|
use deno_core::v8;
|
||||||
|
@ -17,6 +18,7 @@ use deno_core::FeatureChecker;
|
||||||
use deno_core::ModuleLoader;
|
use deno_core::ModuleLoader;
|
||||||
use deno_core::PollEventLoopOptions;
|
use deno_core::PollEventLoopOptions;
|
||||||
use deno_core::SharedArrayBufferStore;
|
use deno_core::SharedArrayBufferStore;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_runtime::code_cache;
|
use deno_runtime::code_cache;
|
||||||
use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel;
|
use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel;
|
||||||
use deno_runtime::deno_fs;
|
use deno_runtime::deno_fs;
|
||||||
|
@ -50,7 +52,6 @@ use crate::args::CliLockfile;
|
||||||
use crate::args::DenoSubcommand;
|
use crate::args::DenoSubcommand;
|
||||||
use crate::args::NpmCachingStrategy;
|
use crate::args::NpmCachingStrategy;
|
||||||
use crate::args::StorageKeyResolver;
|
use crate::args::StorageKeyResolver;
|
||||||
use crate::errors;
|
|
||||||
use crate::node::CliNodeResolver;
|
use crate::node::CliNodeResolver;
|
||||||
use crate::node::CliPackageJsonResolver;
|
use crate::node::CliPackageJsonResolver;
|
||||||
use crate::npm::CliNpmResolver;
|
use crate::npm::CliNpmResolver;
|
||||||
|
@ -80,9 +81,9 @@ pub trait ModuleLoaderFactory: Send + Sync {
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
pub trait HmrRunner: Send + Sync {
|
pub trait HmrRunner: Send + Sync {
|
||||||
async fn start(&mut self) -> Result<(), AnyError>;
|
async fn start(&mut self) -> Result<(), CoreError>;
|
||||||
async fn stop(&mut self) -> Result<(), AnyError>;
|
async fn stop(&mut self) -> Result<(), CoreError>;
|
||||||
async fn run(&mut self) -> Result<(), AnyError>;
|
async fn run(&mut self) -> Result<(), CoreError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CliCodeCache: code_cache::CodeCache {
|
pub trait CliCodeCache: code_cache::CodeCache {
|
||||||
|
@ -195,7 +196,7 @@ impl CliMainWorker {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run(&mut self) -> Result<i32, AnyError> {
|
pub async fn run(&mut self) -> Result<i32, CoreError> {
|
||||||
let mut maybe_coverage_collector =
|
let mut maybe_coverage_collector =
|
||||||
self.maybe_setup_coverage_collector().await?;
|
self.maybe_setup_coverage_collector().await?;
|
||||||
let mut maybe_hmr_runner = self.maybe_setup_hmr_runner().await?;
|
let mut maybe_hmr_runner = self.maybe_setup_hmr_runner().await?;
|
||||||
|
@ -216,7 +217,7 @@ impl CliMainWorker {
|
||||||
let result;
|
let result;
|
||||||
select! {
|
select! {
|
||||||
hmr_result = hmr_future => {
|
hmr_result = hmr_future => {
|
||||||
result = hmr_result;
|
result = hmr_result.map_err(Into::into);
|
||||||
},
|
},
|
||||||
event_loop_result = event_loop_future => {
|
event_loop_result = event_loop_future => {
|
||||||
result = event_loop_result;
|
result = event_loop_result;
|
||||||
|
@ -331,12 +332,12 @@ impl CliMainWorker {
|
||||||
executor.execute().await
|
executor.execute().await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn execute_main_module(&mut self) -> Result<(), AnyError> {
|
pub async fn execute_main_module(&mut self) -> Result<(), CoreError> {
|
||||||
let id = self.worker.preload_main_module(&self.main_module).await?;
|
let id = self.worker.preload_main_module(&self.main_module).await?;
|
||||||
self.worker.evaluate_module(id).await
|
self.worker.evaluate_module(id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn execute_side_module(&mut self) -> Result<(), AnyError> {
|
pub async fn execute_side_module(&mut self) -> Result<(), CoreError> {
|
||||||
let id = self.worker.preload_side_module(&self.main_module).await?;
|
let id = self.worker.preload_side_module(&self.main_module).await?;
|
||||||
self.worker.evaluate_module(id).await
|
self.worker.evaluate_module(id).await
|
||||||
}
|
}
|
||||||
|
@ -393,7 +394,7 @@ impl CliMainWorker {
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
source_code: &'static str,
|
source_code: &'static str,
|
||||||
) -> Result<v8::Global<v8::Value>, AnyError> {
|
) -> Result<v8::Global<v8::Value>, CoreError> {
|
||||||
self.worker.js_runtime.execute_script(name, source_code)
|
self.worker.js_runtime.execute_script(name, source_code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -465,7 +466,7 @@ impl CliMainWorkerFactory {
|
||||||
&self,
|
&self,
|
||||||
mode: WorkerExecutionMode,
|
mode: WorkerExecutionMode,
|
||||||
main_module: ModuleSpecifier,
|
main_module: ModuleSpecifier,
|
||||||
) -> Result<CliMainWorker, AnyError> {
|
) -> Result<CliMainWorker, CoreError> {
|
||||||
self
|
self
|
||||||
.create_custom_worker(
|
.create_custom_worker(
|
||||||
mode,
|
mode,
|
||||||
|
@ -484,7 +485,7 @@ impl CliMainWorkerFactory {
|
||||||
permissions: PermissionsContainer,
|
permissions: PermissionsContainer,
|
||||||
custom_extensions: Vec<Extension>,
|
custom_extensions: Vec<Extension>,
|
||||||
stdio: deno_runtime::deno_io::Stdio,
|
stdio: deno_runtime::deno_io::Stdio,
|
||||||
) -> Result<CliMainWorker, AnyError> {
|
) -> Result<CliMainWorker, CoreError> {
|
||||||
let shared = &self.shared;
|
let shared = &self.shared;
|
||||||
let CreateModuleLoaderResult {
|
let CreateModuleLoaderResult {
|
||||||
module_loader,
|
module_loader,
|
||||||
|
@ -513,16 +514,15 @@ impl CliMainWorkerFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
// use a fake referrer that can be used to discover the package.json if necessary
|
// use a fake referrer that can be used to discover the package.json if necessary
|
||||||
let referrer =
|
let referrer = ModuleSpecifier::from_directory_path(
|
||||||
ModuleSpecifier::from_directory_path(self.shared.fs.cwd()?)
|
self.shared.fs.cwd().map_err(JsErrorBox::from_err)?,
|
||||||
.unwrap()
|
)
|
||||||
.join("package.json")?;
|
.unwrap()
|
||||||
|
.join("package.json")?;
|
||||||
let package_folder = shared
|
let package_folder = shared
|
||||||
.npm_resolver
|
.npm_resolver
|
||||||
.resolve_pkg_folder_from_deno_module_req(
|
.resolve_pkg_folder_from_deno_module_req(package_ref.req(), &referrer)
|
||||||
package_ref.req(),
|
.map_err(JsErrorBox::from_err)?;
|
||||||
&referrer,
|
|
||||||
)?;
|
|
||||||
let main_module = self
|
let main_module = self
|
||||||
.resolve_binary_entrypoint(&package_folder, package_ref.sub_path())?;
|
.resolve_binary_entrypoint(&package_folder, package_ref.sub_path())?;
|
||||||
|
|
||||||
|
@ -633,7 +633,6 @@ impl CliMainWorkerFactory {
|
||||||
should_break_on_first_statement: shared.options.inspect_brk,
|
should_break_on_first_statement: shared.options.inspect_brk,
|
||||||
should_wait_for_inspector_session: shared.options.inspect_wait,
|
should_wait_for_inspector_session: shared.options.inspect_wait,
|
||||||
strace_ops: shared.options.strace_ops.clone(),
|
strace_ops: shared.options.strace_ops.clone(),
|
||||||
get_error_class_fn: Some(&errors::get_error_class_name),
|
|
||||||
cache_storage_dir,
|
cache_storage_dir,
|
||||||
origin_storage_dir,
|
origin_storage_dir,
|
||||||
stdio,
|
stdio,
|
||||||
|
@ -834,7 +833,6 @@ fn create_web_worker_callback(
|
||||||
create_web_worker_cb,
|
create_web_worker_cb,
|
||||||
format_js_error_fn: Some(Arc::new(format_js_error)),
|
format_js_error_fn: Some(Arc::new(format_js_error)),
|
||||||
worker_type: args.worker_type,
|
worker_type: args.worker_type,
|
||||||
get_error_class_fn: Some(&errors::get_error_class_name),
|
|
||||||
stdio: stdio.clone(),
|
stdio: stdio.clone(),
|
||||||
cache_storage_dir,
|
cache_storage_dir,
|
||||||
strace_ops: shared.options.strace_ops.clone(),
|
strace_ops: shared.options.strace_ops.clone(),
|
||||||
|
|
|
@ -16,6 +16,7 @@ path = "lib.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait.workspace = true
|
async-trait.workspace = true
|
||||||
deno_core.workspace = true
|
deno_core.workspace = true
|
||||||
|
deno_error.workspace = true
|
||||||
thiserror.workspace = true
|
thiserror.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
uuid.workspace = true
|
uuid.workspace = true
|
||||||
|
|
|
@ -12,6 +12,7 @@ use deno_core::JsBuffer;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
use deno_core::Resource;
|
use deno_core::Resource;
|
||||||
use deno_core::ResourceId;
|
use deno_core::ResourceId;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
pub use in_memory_broadcast_channel::InMemoryBroadcastChannel;
|
pub use in_memory_broadcast_channel::InMemoryBroadcastChannel;
|
||||||
pub use in_memory_broadcast_channel::InMemoryBroadcastChannelResource;
|
pub use in_memory_broadcast_channel::InMemoryBroadcastChannelResource;
|
||||||
use tokio::sync::broadcast::error::SendError as BroadcastSendError;
|
use tokio::sync::broadcast::error::SendError as BroadcastSendError;
|
||||||
|
@ -19,18 +20,26 @@ use tokio::sync::mpsc::error::SendError as MpscSendError;
|
||||||
|
|
||||||
pub const UNSTABLE_FEATURE_NAME: &str = "broadcast-channel";
|
pub const UNSTABLE_FEATURE_NAME: &str = "broadcast-channel";
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum BroadcastChannelError {
|
pub enum BroadcastChannelError {
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Resource(deno_core::error::AnyError),
|
Resource(
|
||||||
|
#[from]
|
||||||
|
#[inherit]
|
||||||
|
deno_core::error::ResourceError,
|
||||||
|
),
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
MPSCSendError(MpscSendError<Box<dyn std::fmt::Debug + Send + Sync>>),
|
MPSCSendError(MpscSendError<Box<dyn std::fmt::Debug + Send + Sync>>),
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
BroadcastSendError(
|
BroadcastSendError(
|
||||||
BroadcastSendError<Box<dyn std::fmt::Debug + Send + Sync>>,
|
BroadcastSendError<Box<dyn std::fmt::Debug + Send + Sync>>,
|
||||||
),
|
),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Other(deno_core::error::AnyError),
|
Other(#[inherit] JsErrorBox),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: std::fmt::Debug + Send + Sync + 'static> From<MpscSendError<T>>
|
impl<T: std::fmt::Debug + Send + Sync + 'static> From<MpscSendError<T>>
|
||||||
|
@ -100,10 +109,7 @@ pub fn op_broadcast_unsubscribe<BC>(
|
||||||
where
|
where
|
||||||
BC: BroadcastChannel + 'static,
|
BC: BroadcastChannel + 'static,
|
||||||
{
|
{
|
||||||
let resource = state
|
let resource = state.resource_table.get::<BC::Resource>(rid)?;
|
||||||
.resource_table
|
|
||||||
.get::<BC::Resource>(rid)
|
|
||||||
.map_err(BroadcastChannelError::Resource)?;
|
|
||||||
let bc = state.borrow::<BC>();
|
let bc = state.borrow::<BC>();
|
||||||
bc.unsubscribe(&resource)
|
bc.unsubscribe(&resource)
|
||||||
}
|
}
|
||||||
|
@ -118,11 +124,7 @@ pub async fn op_broadcast_send<BC>(
|
||||||
where
|
where
|
||||||
BC: BroadcastChannel + 'static,
|
BC: BroadcastChannel + 'static,
|
||||||
{
|
{
|
||||||
let resource = state
|
let resource = state.borrow().resource_table.get::<BC::Resource>(rid)?;
|
||||||
.borrow()
|
|
||||||
.resource_table
|
|
||||||
.get::<BC::Resource>(rid)
|
|
||||||
.map_err(BroadcastChannelError::Resource)?;
|
|
||||||
let bc = state.borrow().borrow::<BC>().clone();
|
let bc = state.borrow().borrow::<BC>().clone();
|
||||||
bc.send(&resource, name, buf.to_vec()).await
|
bc.send(&resource, name, buf.to_vec()).await
|
||||||
}
|
}
|
||||||
|
@ -136,11 +138,7 @@ pub async fn op_broadcast_recv<BC>(
|
||||||
where
|
where
|
||||||
BC: BroadcastChannel + 'static,
|
BC: BroadcastChannel + 'static,
|
||||||
{
|
{
|
||||||
let resource = state
|
let resource = state.borrow().resource_table.get::<BC::Resource>(rid)?;
|
||||||
.borrow()
|
|
||||||
.resource_table
|
|
||||||
.get::<BC::Resource>(rid)
|
|
||||||
.map_err(BroadcastChannelError::Resource)?;
|
|
||||||
let bc = state.borrow().borrow::<BC>().clone();
|
let bc = state.borrow().borrow::<BC>().clone();
|
||||||
bc.recv(&resource).await
|
bc.recv(&resource).await
|
||||||
}
|
}
|
||||||
|
|
1
ext/cache/Cargo.toml
vendored
1
ext/cache/Cargo.toml
vendored
|
@ -16,6 +16,7 @@ path = "lib.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait.workspace = true
|
async-trait.workspace = true
|
||||||
deno_core.workspace = true
|
deno_core.workspace = true
|
||||||
|
deno_error.workspace = true
|
||||||
rusqlite.workspace = true
|
rusqlite.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
sha2.workspace = true
|
sha2.workspace = true
|
||||||
|
|
27
ext/cache/lib.rs
vendored
27
ext/cache/lib.rs
vendored
|
@ -6,7 +6,6 @@ use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use deno_core::error::type_error;
|
|
||||||
use deno_core::op2;
|
use deno_core::op2;
|
||||||
use deno_core::serde::Deserialize;
|
use deno_core::serde::Deserialize;
|
||||||
use deno_core::serde::Serialize;
|
use deno_core::serde::Serialize;
|
||||||
|
@ -14,22 +13,38 @@ use deno_core::ByteString;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
use deno_core::Resource;
|
use deno_core::Resource;
|
||||||
use deno_core::ResourceId;
|
use deno_core::ResourceId;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
|
|
||||||
mod sqlite;
|
mod sqlite;
|
||||||
pub use sqlite::SqliteBackedCache;
|
pub use sqlite::SqliteBackedCache;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum CacheError {
|
pub enum CacheError {
|
||||||
|
#[class(type)]
|
||||||
|
#[error("CacheStorage is not available in this context")]
|
||||||
|
ContextUnsupported,
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Sqlite(#[from] rusqlite::Error),
|
Sqlite(#[from] rusqlite::Error),
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
JoinError(#[from] tokio::task::JoinError),
|
JoinError(#[from] tokio::task::JoinError),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Resource(deno_core::error::AnyError),
|
Resource(#[from] deno_core::error::ResourceError),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Other(deno_core::error::AnyError),
|
Other(JsErrorBox),
|
||||||
|
#[class(inherit)]
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
Io(#[from] std::io::Error),
|
Io(#[from] std::io::Error),
|
||||||
|
#[class(generic)]
|
||||||
|
#[error("Failed to create cache storage directory {}", .dir.display())]
|
||||||
|
CacheStorageDirectory {
|
||||||
|
dir: PathBuf,
|
||||||
|
#[source]
|
||||||
|
source: std::io::Error,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -237,9 +252,7 @@ where
|
||||||
state.put(cache);
|
state.put(cache);
|
||||||
Ok(state.borrow::<CA>().clone())
|
Ok(state.borrow::<CA>().clone())
|
||||||
} else {
|
} else {
|
||||||
Err(CacheError::Other(type_error(
|
Err(CacheError::ContextUnsupported)
|
||||||
"CacheStorage is not available in this context",
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
21
ext/cache/sqlite.rs
vendored
21
ext/cache/sqlite.rs
vendored
|
@ -8,8 +8,6 @@ use std::time::SystemTime;
|
||||||
use std::time::UNIX_EPOCH;
|
use std::time::UNIX_EPOCH;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use deno_core::anyhow::Context;
|
|
||||||
use deno_core::error::AnyError;
|
|
||||||
use deno_core::futures::future::poll_fn;
|
use deno_core::futures::future::poll_fn;
|
||||||
use deno_core::parking_lot::Mutex;
|
use deno_core::parking_lot::Mutex;
|
||||||
use deno_core::unsync::spawn_blocking;
|
use deno_core::unsync::spawn_blocking;
|
||||||
|
@ -45,14 +43,12 @@ pub struct SqliteBackedCache {
|
||||||
impl SqliteBackedCache {
|
impl SqliteBackedCache {
|
||||||
pub fn new(cache_storage_dir: PathBuf) -> Result<Self, CacheError> {
|
pub fn new(cache_storage_dir: PathBuf) -> Result<Self, CacheError> {
|
||||||
{
|
{
|
||||||
std::fs::create_dir_all(&cache_storage_dir)
|
std::fs::create_dir_all(&cache_storage_dir).map_err(|source| {
|
||||||
.with_context(|| {
|
CacheError::CacheStorageDirectory {
|
||||||
format!(
|
dir: cache_storage_dir.clone(),
|
||||||
"Failed to create cache storage directory {}",
|
source,
|
||||||
cache_storage_dir.display()
|
}
|
||||||
)
|
})?;
|
||||||
})
|
|
||||||
.map_err(CacheError::Other)?;
|
|
||||||
let path = cache_storage_dir.join("cache_metadata.db");
|
let path = cache_storage_dir.join("cache_metadata.db");
|
||||||
let connection = rusqlite::Connection::open(&path).unwrap_or_else(|_| {
|
let connection = rusqlite::Connection::open(&path).unwrap_or_else(|_| {
|
||||||
panic!("failed to open cache db at {}", path.display())
|
panic!("failed to open cache db at {}", path.display())
|
||||||
|
@ -385,7 +381,10 @@ impl CacheResponseResource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn read(self: Rc<Self>, data: &mut [u8]) -> Result<usize, AnyError> {
|
async fn read(
|
||||||
|
self: Rc<Self>,
|
||||||
|
data: &mut [u8],
|
||||||
|
) -> Result<usize, std::io::Error> {
|
||||||
let resource = deno_core::RcRef::map(&self, |r| &r.file);
|
let resource = deno_core::RcRef::map(&self, |r| &r.file);
|
||||||
let mut file = resource.borrow_mut().await;
|
let mut file = resource.borrow_mut().await;
|
||||||
let nread = file.read(data).await?;
|
let nread = file.read(data).await?;
|
||||||
|
|
|
@ -15,6 +15,7 @@ path = "lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
deno_core.workspace = true
|
deno_core.workspace = true
|
||||||
|
deno_error.workspace = true
|
||||||
deno_webgpu.workspace = true
|
deno_webgpu.workspace = true
|
||||||
image = { version = "0.24.7", default-features = false, features = ["png"] }
|
image = { version = "0.24.7", default-features = false, features = ["png"] }
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
|
|
|
@ -12,10 +12,12 @@ use image::RgbaImage;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum CanvasError {
|
pub enum CanvasError {
|
||||||
|
#[class(type)]
|
||||||
#[error("Color type '{0:?}' not supported")]
|
#[error("Color type '{0:?}' not supported")]
|
||||||
UnsupportedColorType(ColorType),
|
UnsupportedColorType(ColorType),
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Image(#[from] image::ImageError),
|
Image(#[from] image::ImageError),
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ anyhow.workspace = true
|
||||||
async-trait.workspace = true
|
async-trait.workspace = true
|
||||||
chrono = { workspace = true, features = ["now"] }
|
chrono = { workspace = true, features = ["now"] }
|
||||||
deno_core.workspace = true
|
deno_core.workspace = true
|
||||||
|
deno_error.workspace = true
|
||||||
saffron.workspace = true
|
saffron.workspace = true
|
||||||
thiserror.workspace = true
|
thiserror.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
|
|
|
@ -7,11 +7,12 @@ use std::borrow::Cow;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use deno_core::error::get_custom_error_class;
|
|
||||||
use deno_core::op2;
|
use deno_core::op2;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
use deno_core::Resource;
|
use deno_core::Resource;
|
||||||
use deno_core::ResourceId;
|
use deno_core::ResourceId;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
|
use deno_error::JsErrorClass;
|
||||||
|
|
||||||
pub use crate::interface::*;
|
pub use crate::interface::*;
|
||||||
|
|
||||||
|
@ -47,26 +48,35 @@ impl<EH: CronHandle + 'static> Resource for CronResource<EH> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum CronError {
|
pub enum CronError {
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Resource(deno_core::error::AnyError),
|
Resource(#[from] deno_core::error::ResourceError),
|
||||||
|
#[class(type)]
|
||||||
#[error("Cron name cannot exceed 64 characters: current length {0}")]
|
#[error("Cron name cannot exceed 64 characters: current length {0}")]
|
||||||
NameExceeded(usize),
|
NameExceeded(usize),
|
||||||
|
#[class(type)]
|
||||||
#[error("Invalid cron name: only alphanumeric characters, whitespace, hyphens, and underscores are allowed")]
|
#[error("Invalid cron name: only alphanumeric characters, whitespace, hyphens, and underscores are allowed")]
|
||||||
NameInvalid,
|
NameInvalid,
|
||||||
|
#[class(type)]
|
||||||
#[error("Cron with this name already exists")]
|
#[error("Cron with this name already exists")]
|
||||||
AlreadyExists,
|
AlreadyExists,
|
||||||
|
#[class(type)]
|
||||||
#[error("Too many crons")]
|
#[error("Too many crons")]
|
||||||
TooManyCrons,
|
TooManyCrons,
|
||||||
|
#[class(type)]
|
||||||
#[error("Invalid cron schedule")]
|
#[error("Invalid cron schedule")]
|
||||||
InvalidCron,
|
InvalidCron,
|
||||||
|
#[class(type)]
|
||||||
#[error("Invalid backoff schedule")]
|
#[error("Invalid backoff schedule")]
|
||||||
InvalidBackoff,
|
InvalidBackoff,
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
AcquireError(#[from] tokio::sync::AcquireError),
|
AcquireError(#[from] tokio::sync::AcquireError),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Other(deno_core::error::AnyError),
|
Other(JsErrorBox),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2]
|
||||||
|
@ -119,7 +129,7 @@ where
|
||||||
let resource = match state.resource_table.get::<CronResource<C::EH>>(rid) {
|
let resource = match state.resource_table.get::<CronResource<C::EH>>(rid) {
|
||||||
Ok(resource) => resource,
|
Ok(resource) => resource,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if get_custom_error_class(&err) == Some("BadResource") {
|
if err.get_class() == "BadResource" {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
} else {
|
} else {
|
||||||
return Err(CronError::Resource(err));
|
return Err(CronError::Resource(err));
|
||||||
|
|
|
@ -23,6 +23,7 @@ const-oid = "0.9.0"
|
||||||
ctr = "0.9.1"
|
ctr = "0.9.1"
|
||||||
curve25519-dalek = "4.1.3"
|
curve25519-dalek = "4.1.3"
|
||||||
deno_core.workspace = true
|
deno_core.workspace = true
|
||||||
|
deno_error.workspace = true
|
||||||
deno_web.workspace = true
|
deno_web.workspace = true
|
||||||
ed448-goldilocks = { version = "0.8.3", features = ["zeroize"] }
|
ed448-goldilocks = { version = "0.8.3", features = ["zeroize"] }
|
||||||
elliptic-curve = { version = "0.13.1", features = ["std", "pem"] }
|
elliptic-curve = { version = "0.13.1", features = ["std", "pem"] }
|
||||||
|
|
|
@ -70,26 +70,40 @@ pub enum DecryptAlgorithm {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum DecryptError {
|
pub enum DecryptError {
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
General(#[from] SharedError),
|
General(
|
||||||
|
#[from]
|
||||||
|
#[inherit]
|
||||||
|
SharedError,
|
||||||
|
),
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Pkcs1(#[from] rsa::pkcs1::Error),
|
Pkcs1(#[from] rsa::pkcs1::Error),
|
||||||
|
#[class("DOMExceptionOperationError")]
|
||||||
#[error("Decryption failed")]
|
#[error("Decryption failed")]
|
||||||
Failed,
|
Failed,
|
||||||
|
#[class(type)]
|
||||||
#[error("invalid length")]
|
#[error("invalid length")]
|
||||||
InvalidLength,
|
InvalidLength,
|
||||||
|
#[class(type)]
|
||||||
#[error("invalid counter length. Currently supported 32/64/128 bits")]
|
#[error("invalid counter length. Currently supported 32/64/128 bits")]
|
||||||
InvalidCounterLength,
|
InvalidCounterLength,
|
||||||
|
#[class(type)]
|
||||||
#[error("tag length not equal to 128")]
|
#[error("tag length not equal to 128")]
|
||||||
InvalidTagLength,
|
InvalidTagLength,
|
||||||
|
#[class("DOMExceptionOperationError")]
|
||||||
#[error("invalid key or iv")]
|
#[error("invalid key or iv")]
|
||||||
InvalidKeyOrIv,
|
InvalidKeyOrIv,
|
||||||
|
#[class("DOMExceptionOperationError")]
|
||||||
#[error("tried to decrypt too much data")]
|
#[error("tried to decrypt too much data")]
|
||||||
TooMuchData,
|
TooMuchData,
|
||||||
|
#[class(type)]
|
||||||
#[error("iv length not equal to 12 or 16")]
|
#[error("iv length not equal to 12 or 16")]
|
||||||
InvalidIvLength,
|
InvalidIvLength,
|
||||||
|
#[class("DOMExceptionOperationError")]
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
Rsa(rsa::Error),
|
Rsa(rsa::Error),
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,12 +13,15 @@ use spki::der::asn1::BitString;
|
||||||
use spki::der::Decode;
|
use spki::der::Decode;
|
||||||
use spki::der::Encode;
|
use spki::der::Encode;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum Ed25519Error {
|
pub enum Ed25519Error {
|
||||||
|
#[class("DOMExceptionOperationError")]
|
||||||
#[error("Failed to export key")]
|
#[error("Failed to export key")]
|
||||||
FailedExport,
|
FailedExport,
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Der(#[from] rsa::pkcs1::der::Error),
|
Der(#[from] rsa::pkcs1::der::Error),
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
KeyRejected(#[from] ring::error::KeyRejected),
|
KeyRejected(#[from] ring::error::KeyRejected),
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,20 +71,31 @@ pub enum EncryptAlgorithm {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum EncryptError {
|
pub enum EncryptError {
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
General(#[from] SharedError),
|
General(
|
||||||
|
#[from]
|
||||||
|
#[inherit]
|
||||||
|
SharedError,
|
||||||
|
),
|
||||||
|
#[class(type)]
|
||||||
#[error("invalid length")]
|
#[error("invalid length")]
|
||||||
InvalidLength,
|
InvalidLength,
|
||||||
|
#[class("DOMExceptionOperationError")]
|
||||||
#[error("invalid key or iv")]
|
#[error("invalid key or iv")]
|
||||||
InvalidKeyOrIv,
|
InvalidKeyOrIv,
|
||||||
|
#[class(type)]
|
||||||
#[error("iv length not equal to 12 or 16")]
|
#[error("iv length not equal to 12 or 16")]
|
||||||
InvalidIvLength,
|
InvalidIvLength,
|
||||||
|
#[class(type)]
|
||||||
#[error("invalid counter length. Currently supported 32/64/128 bits")]
|
#[error("invalid counter length. Currently supported 32/64/128 bits")]
|
||||||
InvalidCounterLength,
|
InvalidCounterLength,
|
||||||
|
#[class("DOMExceptionOperationError")]
|
||||||
#[error("tried to encrypt too much data")]
|
#[error("tried to encrypt too much data")]
|
||||||
TooMuchData,
|
TooMuchData,
|
||||||
|
#[class("DOMExceptionOperationError")]
|
||||||
#[error("Encryption failed")]
|
#[error("Encryption failed")]
|
||||||
Failed,
|
Failed,
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,19 @@ use spki::AlgorithmIdentifierOwned;
|
||||||
|
|
||||||
use crate::shared::*;
|
use crate::shared::*;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum ExportKeyError {
|
pub enum ExportKeyError {
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
General(#[from] SharedError),
|
General(
|
||||||
|
#[from]
|
||||||
|
#[inherit]
|
||||||
|
SharedError,
|
||||||
|
),
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Der(#[from] spki::der::Error),
|
Der(#[from] spki::der::Error),
|
||||||
|
#[class("DOMExceptionNotSupportedError")]
|
||||||
#[error("Unsupported named curve")]
|
#[error("Unsupported named curve")]
|
||||||
UnsupportedNamedCurve,
|
UnsupportedNamedCurve,
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,16 @@ use serde::Deserialize;
|
||||||
|
|
||||||
use crate::shared::*;
|
use crate::shared::*;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
#[class("DOMExceptionOperationError")]
|
||||||
pub enum GenerateKeyError {
|
pub enum GenerateKeyError {
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
General(#[from] SharedError),
|
General(
|
||||||
|
#[from]
|
||||||
|
#[inherit]
|
||||||
|
SharedError,
|
||||||
|
),
|
||||||
#[error("Bad public exponent")]
|
#[error("Bad public exponent")]
|
||||||
BadPublicExponent,
|
BadPublicExponent,
|
||||||
#[error("Invalid HMAC key length")]
|
#[error("Invalid HMAC key length")]
|
||||||
|
|
|
@ -14,10 +14,16 @@ use spki::der::Decode;
|
||||||
|
|
||||||
use crate::shared::*;
|
use crate::shared::*;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
#[class("DOMExceptionDataError")]
|
||||||
pub enum ImportKeyError {
|
pub enum ImportKeyError {
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
General(#[from] SharedError),
|
General(
|
||||||
|
#[from]
|
||||||
|
#[inherit]
|
||||||
|
SharedError,
|
||||||
|
),
|
||||||
#[error("invalid modulus")]
|
#[error("invalid modulus")]
|
||||||
InvalidModulus,
|
InvalidModulus,
|
||||||
#[error("invalid public exponent")]
|
#[error("invalid public exponent")]
|
||||||
|
|
|
@ -8,12 +8,12 @@ use aes_kw::KekAes192;
|
||||||
use aes_kw::KekAes256;
|
use aes_kw::KekAes256;
|
||||||
use base64::prelude::BASE64_URL_SAFE_NO_PAD;
|
use base64::prelude::BASE64_URL_SAFE_NO_PAD;
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use deno_core::error::not_supported;
|
|
||||||
use deno_core::op2;
|
use deno_core::op2;
|
||||||
use deno_core::unsync::spawn_blocking;
|
use deno_core::unsync::spawn_blocking;
|
||||||
use deno_core::JsBuffer;
|
use deno_core::JsBuffer;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
use deno_core::ToJsBuffer;
|
use deno_core::ToJsBuffer;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use p256::elliptic_curve::sec1::FromEncodedPoint;
|
use p256::elliptic_curve::sec1::FromEncodedPoint;
|
||||||
use p256::pkcs8::DecodePrivateKey;
|
use p256::pkcs8::DecodePrivateKey;
|
||||||
pub use rand;
|
pub use rand;
|
||||||
|
@ -129,63 +129,99 @@ deno_core::extension!(deno_crypto,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum Error {
|
pub enum CryptoError {
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
General(#[from] SharedError),
|
General(
|
||||||
|
#[from]
|
||||||
|
#[inherit]
|
||||||
|
SharedError,
|
||||||
|
),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
JoinError(#[from] tokio::task::JoinError),
|
JoinError(
|
||||||
|
#[from]
|
||||||
|
#[inherit]
|
||||||
|
tokio::task::JoinError,
|
||||||
|
),
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Der(#[from] rsa::pkcs1::der::Error),
|
Der(#[from] rsa::pkcs1::der::Error),
|
||||||
|
#[class(type)]
|
||||||
#[error("Missing argument hash")]
|
#[error("Missing argument hash")]
|
||||||
MissingArgumentHash,
|
MissingArgumentHash,
|
||||||
|
#[class(type)]
|
||||||
#[error("Missing argument saltLength")]
|
#[error("Missing argument saltLength")]
|
||||||
MissingArgumentSaltLength,
|
MissingArgumentSaltLength,
|
||||||
|
#[class(type)]
|
||||||
#[error("unsupported algorithm")]
|
#[error("unsupported algorithm")]
|
||||||
UnsupportedAlgorithm,
|
UnsupportedAlgorithm,
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
KeyRejected(#[from] ring::error::KeyRejected),
|
KeyRejected(#[from] ring::error::KeyRejected),
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
RSA(#[from] rsa::Error),
|
RSA(#[from] rsa::Error),
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Pkcs1(#[from] rsa::pkcs1::Error),
|
Pkcs1(#[from] rsa::pkcs1::Error),
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Unspecified(#[from] ring::error::Unspecified),
|
Unspecified(#[from] ring::error::Unspecified),
|
||||||
|
#[class(type)]
|
||||||
#[error("Invalid key format")]
|
#[error("Invalid key format")]
|
||||||
InvalidKeyFormat,
|
InvalidKeyFormat,
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
P256Ecdsa(#[from] p256::ecdsa::Error),
|
P256Ecdsa(#[from] p256::ecdsa::Error),
|
||||||
|
#[class(type)]
|
||||||
#[error("Unexpected error decoding private key")]
|
#[error("Unexpected error decoding private key")]
|
||||||
DecodePrivateKey,
|
DecodePrivateKey,
|
||||||
|
#[class(type)]
|
||||||
#[error("Missing argument publicKey")]
|
#[error("Missing argument publicKey")]
|
||||||
MissingArgumentPublicKey,
|
MissingArgumentPublicKey,
|
||||||
|
#[class(type)]
|
||||||
#[error("Missing argument namedCurve")]
|
#[error("Missing argument namedCurve")]
|
||||||
MissingArgumentNamedCurve,
|
MissingArgumentNamedCurve,
|
||||||
|
#[class(type)]
|
||||||
#[error("Missing argument info")]
|
#[error("Missing argument info")]
|
||||||
MissingArgumentInfo,
|
MissingArgumentInfo,
|
||||||
|
#[class("DOMExceptionOperationError")]
|
||||||
#[error("The length provided for HKDF is too large")]
|
#[error("The length provided for HKDF is too large")]
|
||||||
HKDFLengthTooLarge,
|
HKDFLengthTooLarge,
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Base64Decode(#[from] base64::DecodeError),
|
Base64Decode(#[from] base64::DecodeError),
|
||||||
|
#[class(type)]
|
||||||
#[error("Data must be multiple of 8 bytes")]
|
#[error("Data must be multiple of 8 bytes")]
|
||||||
DataInvalidSize,
|
DataInvalidSize,
|
||||||
|
#[class(type)]
|
||||||
#[error("Invalid key length")]
|
#[error("Invalid key length")]
|
||||||
InvalidKeyLength,
|
InvalidKeyLength,
|
||||||
|
#[class("DOMExceptionOperationError")]
|
||||||
#[error("encryption error")]
|
#[error("encryption error")]
|
||||||
EncryptionError,
|
EncryptionError,
|
||||||
|
#[class("DOMExceptionOperationError")]
|
||||||
#[error("decryption error - integrity check failed")]
|
#[error("decryption error - integrity check failed")]
|
||||||
DecryptionError,
|
DecryptionError,
|
||||||
|
#[class("DOMExceptionQuotaExceededError")]
|
||||||
#[error("The ArrayBufferView's byte length ({0}) exceeds the number of bytes of entropy available via this API (65536)")]
|
#[error("The ArrayBufferView's byte length ({0}) exceeds the number of bytes of entropy available via this API (65536)")]
|
||||||
ArrayBufferViewLengthExceeded(usize),
|
ArrayBufferViewLengthExceeded(usize),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Other(deno_core::error::AnyError),
|
Other(
|
||||||
|
#[from]
|
||||||
|
#[inherit]
|
||||||
|
JsErrorBox,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2]
|
||||||
#[serde]
|
#[serde]
|
||||||
pub fn op_crypto_base64url_decode(
|
pub fn op_crypto_base64url_decode(
|
||||||
#[string] data: String,
|
#[string] data: String,
|
||||||
) -> Result<ToJsBuffer, Error> {
|
) -> Result<ToJsBuffer, CryptoError> {
|
||||||
let data: Vec<u8> = BASE64_URL_SAFE_NO_PAD.decode(data)?;
|
let data: Vec<u8> = BASE64_URL_SAFE_NO_PAD.decode(data)?;
|
||||||
Ok(data.into())
|
Ok(data.into())
|
||||||
}
|
}
|
||||||
|
@ -201,9 +237,9 @@ pub fn op_crypto_base64url_encode(#[buffer] data: JsBuffer) -> String {
|
||||||
pub fn op_crypto_get_random_values(
|
pub fn op_crypto_get_random_values(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[buffer] out: &mut [u8],
|
#[buffer] out: &mut [u8],
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), CryptoError> {
|
||||||
if out.len() > 65536 {
|
if out.len() > 65536 {
|
||||||
return Err(Error::ArrayBufferViewLengthExceeded(out.len()));
|
return Err(CryptoError::ArrayBufferViewLengthExceeded(out.len()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let maybe_seeded_rng = state.try_borrow_mut::<StdRng>();
|
let maybe_seeded_rng = state.try_borrow_mut::<StdRng>();
|
||||||
|
@ -255,7 +291,7 @@ pub struct SignArg {
|
||||||
pub async fn op_crypto_sign_key(
|
pub async fn op_crypto_sign_key(
|
||||||
#[serde] args: SignArg,
|
#[serde] args: SignArg,
|
||||||
#[buffer] zero_copy: JsBuffer,
|
#[buffer] zero_copy: JsBuffer,
|
||||||
) -> Result<ToJsBuffer, Error> {
|
) -> Result<ToJsBuffer, CryptoError> {
|
||||||
deno_core::unsync::spawn_blocking(move || {
|
deno_core::unsync::spawn_blocking(move || {
|
||||||
let data = &*zero_copy;
|
let data = &*zero_copy;
|
||||||
let algorithm = args.algorithm;
|
let algorithm = args.algorithm;
|
||||||
|
@ -264,7 +300,7 @@ pub async fn op_crypto_sign_key(
|
||||||
Algorithm::RsassaPkcs1v15 => {
|
Algorithm::RsassaPkcs1v15 => {
|
||||||
use rsa::pkcs1v15::SigningKey;
|
use rsa::pkcs1v15::SigningKey;
|
||||||
let private_key = RsaPrivateKey::from_pkcs1_der(&args.key.data)?;
|
let private_key = RsaPrivateKey::from_pkcs1_der(&args.key.data)?;
|
||||||
match args.hash.ok_or_else(|| Error::MissingArgumentHash)? {
|
match args.hash.ok_or_else(|| CryptoError::MissingArgumentHash)? {
|
||||||
CryptoHash::Sha1 => {
|
CryptoHash::Sha1 => {
|
||||||
let signing_key = SigningKey::<Sha1>::new(private_key);
|
let signing_key = SigningKey::<Sha1>::new(private_key);
|
||||||
signing_key.sign(data)
|
signing_key.sign(data)
|
||||||
|
@ -289,11 +325,11 @@ pub async fn op_crypto_sign_key(
|
||||||
|
|
||||||
let salt_len = args
|
let salt_len = args
|
||||||
.salt_length
|
.salt_length
|
||||||
.ok_or_else(|| Error::MissingArgumentSaltLength)?
|
.ok_or_else(|| CryptoError::MissingArgumentSaltLength)?
|
||||||
as usize;
|
as usize;
|
||||||
|
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
match args.hash.ok_or_else(|| Error::MissingArgumentHash)? {
|
match args.hash.ok_or_else(|| CryptoError::MissingArgumentHash)? {
|
||||||
CryptoHash::Sha1 => {
|
CryptoHash::Sha1 => {
|
||||||
let signing_key = Pss::new_with_salt::<Sha1>(salt_len);
|
let signing_key = Pss::new_with_salt::<Sha1>(salt_len);
|
||||||
let hashed = Sha1::digest(data);
|
let hashed = Sha1::digest(data);
|
||||||
|
@ -320,7 +356,7 @@ pub async fn op_crypto_sign_key(
|
||||||
Algorithm::Ecdsa => {
|
Algorithm::Ecdsa => {
|
||||||
let curve: &EcdsaSigningAlgorithm = args
|
let curve: &EcdsaSigningAlgorithm = args
|
||||||
.named_curve
|
.named_curve
|
||||||
.ok_or_else(|| Error::Other(not_supported()))?
|
.ok_or_else(JsErrorBox::not_supported)?
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
let rng = RingRand::SystemRandom::new();
|
let rng = RingRand::SystemRandom::new();
|
||||||
|
@ -330,7 +366,7 @@ pub async fn op_crypto_sign_key(
|
||||||
if let Some(hash) = args.hash {
|
if let Some(hash) = args.hash {
|
||||||
match hash {
|
match hash {
|
||||||
CryptoHash::Sha256 | CryptoHash::Sha384 => (),
|
CryptoHash::Sha256 | CryptoHash::Sha384 => (),
|
||||||
_ => return Err(Error::UnsupportedAlgorithm),
|
_ => return Err(CryptoError::UnsupportedAlgorithm),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -340,17 +376,15 @@ pub async fn op_crypto_sign_key(
|
||||||
signature.as_ref().to_vec()
|
signature.as_ref().to_vec()
|
||||||
}
|
}
|
||||||
Algorithm::Hmac => {
|
Algorithm::Hmac => {
|
||||||
let hash: HmacAlgorithm = args
|
let hash: HmacAlgorithm =
|
||||||
.hash
|
args.hash.ok_or_else(JsErrorBox::not_supported)?.into();
|
||||||
.ok_or_else(|| Error::Other(not_supported()))?
|
|
||||||
.into();
|
|
||||||
|
|
||||||
let key = HmacKey::new(hash, &args.key.data);
|
let key = HmacKey::new(hash, &args.key.data);
|
||||||
|
|
||||||
let signature = ring::hmac::sign(&key, data);
|
let signature = ring::hmac::sign(&key, data);
|
||||||
signature.as_ref().to_vec()
|
signature.as_ref().to_vec()
|
||||||
}
|
}
|
||||||
_ => return Err(Error::UnsupportedAlgorithm),
|
_ => return Err(CryptoError::UnsupportedAlgorithm),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(signature.into())
|
Ok(signature.into())
|
||||||
|
@ -373,7 +407,7 @@ pub struct VerifyArg {
|
||||||
pub async fn op_crypto_verify_key(
|
pub async fn op_crypto_verify_key(
|
||||||
#[serde] args: VerifyArg,
|
#[serde] args: VerifyArg,
|
||||||
#[buffer] zero_copy: JsBuffer,
|
#[buffer] zero_copy: JsBuffer,
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, CryptoError> {
|
||||||
deno_core::unsync::spawn_blocking(move || {
|
deno_core::unsync::spawn_blocking(move || {
|
||||||
let data = &*zero_copy;
|
let data = &*zero_copy;
|
||||||
let algorithm = args.algorithm;
|
let algorithm = args.algorithm;
|
||||||
|
@ -384,7 +418,7 @@ pub async fn op_crypto_verify_key(
|
||||||
use rsa::pkcs1v15::VerifyingKey;
|
use rsa::pkcs1v15::VerifyingKey;
|
||||||
let public_key = read_rsa_public_key(args.key)?;
|
let public_key = read_rsa_public_key(args.key)?;
|
||||||
let signature: Signature = args.signature.as_ref().try_into()?;
|
let signature: Signature = args.signature.as_ref().try_into()?;
|
||||||
match args.hash.ok_or_else(|| Error::MissingArgumentHash)? {
|
match args.hash.ok_or_else(|| CryptoError::MissingArgumentHash)? {
|
||||||
CryptoHash::Sha1 => {
|
CryptoHash::Sha1 => {
|
||||||
let verifying_key = VerifyingKey::<Sha1>::new(public_key);
|
let verifying_key = VerifyingKey::<Sha1>::new(public_key);
|
||||||
verifying_key.verify(data, &signature).is_ok()
|
verifying_key.verify(data, &signature).is_ok()
|
||||||
|
@ -409,10 +443,10 @@ pub async fn op_crypto_verify_key(
|
||||||
|
|
||||||
let salt_len = args
|
let salt_len = args
|
||||||
.salt_length
|
.salt_length
|
||||||
.ok_or_else(|| Error::MissingArgumentSaltLength)?
|
.ok_or_else(|| CryptoError::MissingArgumentSaltLength)?
|
||||||
as usize;
|
as usize;
|
||||||
|
|
||||||
match args.hash.ok_or_else(|| Error::MissingArgumentHash)? {
|
match args.hash.ok_or_else(|| CryptoError::MissingArgumentHash)? {
|
||||||
CryptoHash::Sha1 => {
|
CryptoHash::Sha1 => {
|
||||||
let pss = Pss::new_with_salt::<Sha1>(salt_len);
|
let pss = Pss::new_with_salt::<Sha1>(salt_len);
|
||||||
let hashed = Sha1::digest(data);
|
let hashed = Sha1::digest(data);
|
||||||
|
@ -436,21 +470,19 @@ pub async fn op_crypto_verify_key(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Algorithm::Hmac => {
|
Algorithm::Hmac => {
|
||||||
let hash: HmacAlgorithm = args
|
let hash: HmacAlgorithm =
|
||||||
.hash
|
args.hash.ok_or_else(JsErrorBox::not_supported)?.into();
|
||||||
.ok_or_else(|| Error::Other(not_supported()))?
|
|
||||||
.into();
|
|
||||||
let key = HmacKey::new(hash, &args.key.data);
|
let key = HmacKey::new(hash, &args.key.data);
|
||||||
ring::hmac::verify(&key, data, &args.signature).is_ok()
|
ring::hmac::verify(&key, data, &args.signature).is_ok()
|
||||||
}
|
}
|
||||||
Algorithm::Ecdsa => {
|
Algorithm::Ecdsa => {
|
||||||
let signing_alg: &EcdsaSigningAlgorithm = args
|
let signing_alg: &EcdsaSigningAlgorithm = args
|
||||||
.named_curve
|
.named_curve
|
||||||
.ok_or_else(|| Error::Other(not_supported()))?
|
.ok_or_else(JsErrorBox::not_supported)?
|
||||||
.into();
|
.into();
|
||||||
let verify_alg: &EcdsaVerificationAlgorithm = args
|
let verify_alg: &EcdsaVerificationAlgorithm = args
|
||||||
.named_curve
|
.named_curve
|
||||||
.ok_or_else(|| Error::Other(not_supported()))?
|
.ok_or_else(JsErrorBox::not_supported)?
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
let private_key;
|
let private_key;
|
||||||
|
@ -464,7 +496,7 @@ pub async fn op_crypto_verify_key(
|
||||||
private_key.public_key().as_ref()
|
private_key.public_key().as_ref()
|
||||||
}
|
}
|
||||||
KeyType::Public => &*args.key.data,
|
KeyType::Public => &*args.key.data,
|
||||||
_ => return Err(Error::InvalidKeyFormat),
|
_ => return Err(CryptoError::InvalidKeyFormat),
|
||||||
};
|
};
|
||||||
|
|
||||||
let public_key =
|
let public_key =
|
||||||
|
@ -472,7 +504,7 @@ pub async fn op_crypto_verify_key(
|
||||||
|
|
||||||
public_key.verify(data, &args.signature).is_ok()
|
public_key.verify(data, &args.signature).is_ok()
|
||||||
}
|
}
|
||||||
_ => return Err(Error::UnsupportedAlgorithm),
|
_ => return Err(CryptoError::UnsupportedAlgorithm),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(verification)
|
Ok(verification)
|
||||||
|
@ -500,31 +532,27 @@ pub struct DeriveKeyArg {
|
||||||
pub async fn op_crypto_derive_bits(
|
pub async fn op_crypto_derive_bits(
|
||||||
#[serde] args: DeriveKeyArg,
|
#[serde] args: DeriveKeyArg,
|
||||||
#[buffer] zero_copy: Option<JsBuffer>,
|
#[buffer] zero_copy: Option<JsBuffer>,
|
||||||
) -> Result<ToJsBuffer, Error> {
|
) -> Result<ToJsBuffer, CryptoError> {
|
||||||
deno_core::unsync::spawn_blocking(move || {
|
deno_core::unsync::spawn_blocking(move || {
|
||||||
let algorithm = args.algorithm;
|
let algorithm = args.algorithm;
|
||||||
match algorithm {
|
match algorithm {
|
||||||
Algorithm::Pbkdf2 => {
|
Algorithm::Pbkdf2 => {
|
||||||
let zero_copy =
|
let zero_copy = zero_copy.ok_or_else(JsErrorBox::not_supported)?;
|
||||||
zero_copy.ok_or_else(|| Error::Other(not_supported()))?;
|
|
||||||
let salt = &*zero_copy;
|
let salt = &*zero_copy;
|
||||||
// The caller must validate these cases.
|
// The caller must validate these cases.
|
||||||
assert!(args.length > 0);
|
assert!(args.length > 0);
|
||||||
assert!(args.length % 8 == 0);
|
assert!(args.length % 8 == 0);
|
||||||
|
|
||||||
let algorithm =
|
let algorithm = match args.hash.ok_or_else(JsErrorBox::not_supported)? {
|
||||||
match args.hash.ok_or_else(|| Error::Other(not_supported()))? {
|
CryptoHash::Sha1 => pbkdf2::PBKDF2_HMAC_SHA1,
|
||||||
CryptoHash::Sha1 => pbkdf2::PBKDF2_HMAC_SHA1,
|
CryptoHash::Sha256 => pbkdf2::PBKDF2_HMAC_SHA256,
|
||||||
CryptoHash::Sha256 => pbkdf2::PBKDF2_HMAC_SHA256,
|
CryptoHash::Sha384 => pbkdf2::PBKDF2_HMAC_SHA384,
|
||||||
CryptoHash::Sha384 => pbkdf2::PBKDF2_HMAC_SHA384,
|
CryptoHash::Sha512 => pbkdf2::PBKDF2_HMAC_SHA512,
|
||||||
CryptoHash::Sha512 => pbkdf2::PBKDF2_HMAC_SHA512,
|
};
|
||||||
};
|
|
||||||
|
|
||||||
// This will never panic. We have already checked length earlier.
|
// This will never panic. We have already checked length earlier.
|
||||||
let iterations = NonZeroU32::new(
|
let iterations = NonZeroU32::new(
|
||||||
args
|
args.iterations.ok_or_else(JsErrorBox::not_supported)?,
|
||||||
.iterations
|
|
||||||
.ok_or_else(|| Error::Other(not_supported()))?,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let secret = args.key.data;
|
let secret = args.key.data;
|
||||||
|
@ -535,33 +563,33 @@ pub async fn op_crypto_derive_bits(
|
||||||
Algorithm::Ecdh => {
|
Algorithm::Ecdh => {
|
||||||
let named_curve = args
|
let named_curve = args
|
||||||
.named_curve
|
.named_curve
|
||||||
.ok_or_else(|| Error::MissingArgumentNamedCurve)?;
|
.ok_or_else(|| CryptoError::MissingArgumentNamedCurve)?;
|
||||||
|
|
||||||
let public_key = args
|
let public_key = args
|
||||||
.public_key
|
.public_key
|
||||||
.ok_or_else(|| Error::MissingArgumentPublicKey)?;
|
.ok_or_else(|| CryptoError::MissingArgumentPublicKey)?;
|
||||||
|
|
||||||
match named_curve {
|
match named_curve {
|
||||||
CryptoNamedCurve::P256 => {
|
CryptoNamedCurve::P256 => {
|
||||||
let secret_key = p256::SecretKey::from_pkcs8_der(&args.key.data)
|
let secret_key = p256::SecretKey::from_pkcs8_der(&args.key.data)
|
||||||
.map_err(|_| Error::DecodePrivateKey)?;
|
.map_err(|_| CryptoError::DecodePrivateKey)?;
|
||||||
|
|
||||||
let public_key = match public_key.r#type {
|
let public_key = match public_key.r#type {
|
||||||
KeyType::Private => {
|
KeyType::Private => {
|
||||||
p256::SecretKey::from_pkcs8_der(&public_key.data)
|
p256::SecretKey::from_pkcs8_der(&public_key.data)
|
||||||
.map_err(|_| Error::DecodePrivateKey)?
|
.map_err(|_| CryptoError::DecodePrivateKey)?
|
||||||
.public_key()
|
.public_key()
|
||||||
}
|
}
|
||||||
KeyType::Public => {
|
KeyType::Public => {
|
||||||
let point = p256::EncodedPoint::from_bytes(public_key.data)
|
let point = p256::EncodedPoint::from_bytes(public_key.data)
|
||||||
.map_err(|_| Error::DecodePrivateKey)?;
|
.map_err(|_| CryptoError::DecodePrivateKey)?;
|
||||||
|
|
||||||
let pk = p256::PublicKey::from_encoded_point(&point);
|
let pk = p256::PublicKey::from_encoded_point(&point);
|
||||||
// pk is a constant time Option.
|
// pk is a constant time Option.
|
||||||
if pk.is_some().into() {
|
if pk.is_some().into() {
|
||||||
pk.unwrap()
|
pk.unwrap()
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::DecodePrivateKey);
|
return Err(CryptoError::DecodePrivateKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
@ -577,24 +605,24 @@ pub async fn op_crypto_derive_bits(
|
||||||
}
|
}
|
||||||
CryptoNamedCurve::P384 => {
|
CryptoNamedCurve::P384 => {
|
||||||
let secret_key = p384::SecretKey::from_pkcs8_der(&args.key.data)
|
let secret_key = p384::SecretKey::from_pkcs8_der(&args.key.data)
|
||||||
.map_err(|_| Error::DecodePrivateKey)?;
|
.map_err(|_| CryptoError::DecodePrivateKey)?;
|
||||||
|
|
||||||
let public_key = match public_key.r#type {
|
let public_key = match public_key.r#type {
|
||||||
KeyType::Private => {
|
KeyType::Private => {
|
||||||
p384::SecretKey::from_pkcs8_der(&public_key.data)
|
p384::SecretKey::from_pkcs8_der(&public_key.data)
|
||||||
.map_err(|_| Error::DecodePrivateKey)?
|
.map_err(|_| CryptoError::DecodePrivateKey)?
|
||||||
.public_key()
|
.public_key()
|
||||||
}
|
}
|
||||||
KeyType::Public => {
|
KeyType::Public => {
|
||||||
let point = p384::EncodedPoint::from_bytes(public_key.data)
|
let point = p384::EncodedPoint::from_bytes(public_key.data)
|
||||||
.map_err(|_| Error::DecodePrivateKey)?;
|
.map_err(|_| CryptoError::DecodePrivateKey)?;
|
||||||
|
|
||||||
let pk = p384::PublicKey::from_encoded_point(&point);
|
let pk = p384::PublicKey::from_encoded_point(&point);
|
||||||
// pk is a constant time Option.
|
// pk is a constant time Option.
|
||||||
if pk.is_some().into() {
|
if pk.is_some().into() {
|
||||||
pk.unwrap()
|
pk.unwrap()
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::DecodePrivateKey);
|
return Err(CryptoError::DecodePrivateKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
@ -611,18 +639,16 @@ pub async fn op_crypto_derive_bits(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Algorithm::Hkdf => {
|
Algorithm::Hkdf => {
|
||||||
let zero_copy =
|
let zero_copy = zero_copy.ok_or_else(JsErrorBox::not_supported)?;
|
||||||
zero_copy.ok_or_else(|| Error::Other(not_supported()))?;
|
|
||||||
let salt = &*zero_copy;
|
let salt = &*zero_copy;
|
||||||
let algorithm =
|
let algorithm = match args.hash.ok_or_else(JsErrorBox::not_supported)? {
|
||||||
match args.hash.ok_or_else(|| Error::Other(not_supported()))? {
|
CryptoHash::Sha1 => hkdf::HKDF_SHA1_FOR_LEGACY_USE_ONLY,
|
||||||
CryptoHash::Sha1 => hkdf::HKDF_SHA1_FOR_LEGACY_USE_ONLY,
|
CryptoHash::Sha256 => hkdf::HKDF_SHA256,
|
||||||
CryptoHash::Sha256 => hkdf::HKDF_SHA256,
|
CryptoHash::Sha384 => hkdf::HKDF_SHA384,
|
||||||
CryptoHash::Sha384 => hkdf::HKDF_SHA384,
|
CryptoHash::Sha512 => hkdf::HKDF_SHA512,
|
||||||
CryptoHash::Sha512 => hkdf::HKDF_SHA512,
|
};
|
||||||
};
|
|
||||||
|
|
||||||
let info = args.info.ok_or_else(|| Error::MissingArgumentInfo)?;
|
let info = args.info.ok_or(CryptoError::MissingArgumentInfo)?;
|
||||||
// IKM
|
// IKM
|
||||||
let secret = args.key.data;
|
let secret = args.key.data;
|
||||||
// L
|
// L
|
||||||
|
@ -633,18 +659,18 @@ pub async fn op_crypto_derive_bits(
|
||||||
let info = &[&*info];
|
let info = &[&*info];
|
||||||
let okm = prk
|
let okm = prk
|
||||||
.expand(info, HkdfOutput(length))
|
.expand(info, HkdfOutput(length))
|
||||||
.map_err(|_e| Error::HKDFLengthTooLarge)?;
|
.map_err(|_e| CryptoError::HKDFLengthTooLarge)?;
|
||||||
let mut r = vec![0u8; length];
|
let mut r = vec![0u8; length];
|
||||||
okm.fill(&mut r)?;
|
okm.fill(&mut r)?;
|
||||||
Ok(r.into())
|
Ok(r.into())
|
||||||
}
|
}
|
||||||
_ => Err(Error::UnsupportedAlgorithm),
|
_ => Err(CryptoError::UnsupportedAlgorithm),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_rsa_public_key(key_data: KeyData) -> Result<RsaPublicKey, Error> {
|
fn read_rsa_public_key(key_data: KeyData) -> Result<RsaPublicKey, CryptoError> {
|
||||||
let public_key = match key_data.r#type {
|
let public_key = match key_data.r#type {
|
||||||
KeyType::Private => {
|
KeyType::Private => {
|
||||||
RsaPrivateKey::from_pkcs1_der(&key_data.data)?.to_public_key()
|
RsaPrivateKey::from_pkcs1_der(&key_data.data)?.to_public_key()
|
||||||
|
@ -657,7 +683,9 @@ fn read_rsa_public_key(key_data: KeyData) -> Result<RsaPublicKey, Error> {
|
||||||
|
|
||||||
#[op2]
|
#[op2]
|
||||||
#[string]
|
#[string]
|
||||||
pub fn op_crypto_random_uuid(state: &mut OpState) -> Result<String, Error> {
|
pub fn op_crypto_random_uuid(
|
||||||
|
state: &mut OpState,
|
||||||
|
) -> Result<String, CryptoError> {
|
||||||
let maybe_seeded_rng = state.try_borrow_mut::<StdRng>();
|
let maybe_seeded_rng = state.try_borrow_mut::<StdRng>();
|
||||||
let uuid = if let Some(seeded_rng) = maybe_seeded_rng {
|
let uuid = if let Some(seeded_rng) = maybe_seeded_rng {
|
||||||
let mut bytes = [0u8; 16];
|
let mut bytes = [0u8; 16];
|
||||||
|
@ -678,7 +706,7 @@ pub fn op_crypto_random_uuid(state: &mut OpState) -> Result<String, Error> {
|
||||||
pub async fn op_crypto_subtle_digest(
|
pub async fn op_crypto_subtle_digest(
|
||||||
#[serde] algorithm: CryptoHash,
|
#[serde] algorithm: CryptoHash,
|
||||||
#[buffer] data: JsBuffer,
|
#[buffer] data: JsBuffer,
|
||||||
) -> Result<ToJsBuffer, Error> {
|
) -> Result<ToJsBuffer, CryptoError> {
|
||||||
let output = spawn_blocking(move || {
|
let output = spawn_blocking(move || {
|
||||||
digest::digest(algorithm.into(), &data)
|
digest::digest(algorithm.into(), &data)
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -702,7 +730,7 @@ pub struct WrapUnwrapKeyArg {
|
||||||
pub fn op_crypto_wrap_key(
|
pub fn op_crypto_wrap_key(
|
||||||
#[serde] args: WrapUnwrapKeyArg,
|
#[serde] args: WrapUnwrapKeyArg,
|
||||||
#[buffer] data: JsBuffer,
|
#[buffer] data: JsBuffer,
|
||||||
) -> Result<ToJsBuffer, Error> {
|
) -> Result<ToJsBuffer, CryptoError> {
|
||||||
let algorithm = args.algorithm;
|
let algorithm = args.algorithm;
|
||||||
|
|
||||||
match algorithm {
|
match algorithm {
|
||||||
|
@ -710,20 +738,20 @@ pub fn op_crypto_wrap_key(
|
||||||
let key = args.key.as_secret_key()?;
|
let key = args.key.as_secret_key()?;
|
||||||
|
|
||||||
if data.len() % 8 != 0 {
|
if data.len() % 8 != 0 {
|
||||||
return Err(Error::DataInvalidSize);
|
return Err(CryptoError::DataInvalidSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
let wrapped_key = match key.len() {
|
let wrapped_key = match key.len() {
|
||||||
16 => KekAes128::new(key.into()).wrap_vec(&data),
|
16 => KekAes128::new(key.into()).wrap_vec(&data),
|
||||||
24 => KekAes192::new(key.into()).wrap_vec(&data),
|
24 => KekAes192::new(key.into()).wrap_vec(&data),
|
||||||
32 => KekAes256::new(key.into()).wrap_vec(&data),
|
32 => KekAes256::new(key.into()).wrap_vec(&data),
|
||||||
_ => return Err(Error::InvalidKeyLength),
|
_ => return Err(CryptoError::InvalidKeyLength),
|
||||||
}
|
}
|
||||||
.map_err(|_| Error::EncryptionError)?;
|
.map_err(|_| CryptoError::EncryptionError)?;
|
||||||
|
|
||||||
Ok(wrapped_key.into())
|
Ok(wrapped_key.into())
|
||||||
}
|
}
|
||||||
_ => Err(Error::UnsupportedAlgorithm),
|
_ => Err(CryptoError::UnsupportedAlgorithm),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -732,27 +760,27 @@ pub fn op_crypto_wrap_key(
|
||||||
pub fn op_crypto_unwrap_key(
|
pub fn op_crypto_unwrap_key(
|
||||||
#[serde] args: WrapUnwrapKeyArg,
|
#[serde] args: WrapUnwrapKeyArg,
|
||||||
#[buffer] data: JsBuffer,
|
#[buffer] data: JsBuffer,
|
||||||
) -> Result<ToJsBuffer, Error> {
|
) -> Result<ToJsBuffer, CryptoError> {
|
||||||
let algorithm = args.algorithm;
|
let algorithm = args.algorithm;
|
||||||
match algorithm {
|
match algorithm {
|
||||||
Algorithm::AesKw => {
|
Algorithm::AesKw => {
|
||||||
let key = args.key.as_secret_key()?;
|
let key = args.key.as_secret_key()?;
|
||||||
|
|
||||||
if data.len() % 8 != 0 {
|
if data.len() % 8 != 0 {
|
||||||
return Err(Error::DataInvalidSize);
|
return Err(CryptoError::DataInvalidSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
let unwrapped_key = match key.len() {
|
let unwrapped_key = match key.len() {
|
||||||
16 => KekAes128::new(key.into()).unwrap_vec(&data),
|
16 => KekAes128::new(key.into()).unwrap_vec(&data),
|
||||||
24 => KekAes192::new(key.into()).unwrap_vec(&data),
|
24 => KekAes192::new(key.into()).unwrap_vec(&data),
|
||||||
32 => KekAes256::new(key.into()).unwrap_vec(&data),
|
32 => KekAes256::new(key.into()).unwrap_vec(&data),
|
||||||
_ => return Err(Error::InvalidKeyLength),
|
_ => return Err(CryptoError::InvalidKeyLength),
|
||||||
}
|
}
|
||||||
.map_err(|_| Error::DecryptionError)?;
|
.map_err(|_| CryptoError::DecryptionError)?;
|
||||||
|
|
||||||
Ok(unwrapped_key.into())
|
Ok(unwrapped_key.into())
|
||||||
}
|
}
|
||||||
_ => Err(Error::UnsupportedAlgorithm),
|
_ => Err(CryptoError::UnsupportedAlgorithm),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,26 +60,36 @@ pub enum RustRawKeyData {
|
||||||
Public(ToJsBuffer),
|
Public(ToJsBuffer),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum SharedError {
|
pub enum SharedError {
|
||||||
|
#[class(type)]
|
||||||
#[error("expected valid private key")]
|
#[error("expected valid private key")]
|
||||||
ExpectedValidPrivateKey,
|
ExpectedValidPrivateKey,
|
||||||
|
#[class(type)]
|
||||||
#[error("expected valid public key")]
|
#[error("expected valid public key")]
|
||||||
ExpectedValidPublicKey,
|
ExpectedValidPublicKey,
|
||||||
|
#[class(type)]
|
||||||
#[error("expected valid private EC key")]
|
#[error("expected valid private EC key")]
|
||||||
ExpectedValidPrivateECKey,
|
ExpectedValidPrivateECKey,
|
||||||
|
#[class(type)]
|
||||||
#[error("expected valid public EC key")]
|
#[error("expected valid public EC key")]
|
||||||
ExpectedValidPublicECKey,
|
ExpectedValidPublicECKey,
|
||||||
|
#[class(type)]
|
||||||
#[error("expected private key")]
|
#[error("expected private key")]
|
||||||
ExpectedPrivateKey,
|
ExpectedPrivateKey,
|
||||||
|
#[class(type)]
|
||||||
#[error("expected public key")]
|
#[error("expected public key")]
|
||||||
ExpectedPublicKey,
|
ExpectedPublicKey,
|
||||||
|
#[class(type)]
|
||||||
#[error("expected secret key")]
|
#[error("expected secret key")]
|
||||||
ExpectedSecretKey,
|
ExpectedSecretKey,
|
||||||
|
#[class("DOMExceptionOperationError")]
|
||||||
#[error("failed to decode private key")]
|
#[error("failed to decode private key")]
|
||||||
FailedDecodePrivateKey,
|
FailedDecodePrivateKey,
|
||||||
|
#[class("DOMExceptionOperationError")]
|
||||||
#[error("failed to decode public key")]
|
#[error("failed to decode public key")]
|
||||||
FailedDecodePublicKey,
|
FailedDecodePublicKey,
|
||||||
|
#[class("DOMExceptionNotSupportedError")]
|
||||||
#[error("unsupported format")]
|
#[error("unsupported format")]
|
||||||
UnsupportedFormat,
|
UnsupportedFormat,
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,12 @@ use spki::der::asn1::BitString;
|
||||||
use spki::der::Decode;
|
use spki::der::Decode;
|
||||||
use spki::der::Encode;
|
use spki::der::Encode;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum X25519Error {
|
pub enum X25519Error {
|
||||||
|
#[class("DOMExceptionOperationError")]
|
||||||
#[error("Failed to export key")]
|
#[error("Failed to export key")]
|
||||||
FailedExport,
|
FailedExport,
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Der(#[from] spki::der::Error),
|
Der(#[from] spki::der::Error),
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,12 @@ use spki::der::asn1::BitString;
|
||||||
use spki::der::Decode;
|
use spki::der::Decode;
|
||||||
use spki::der::Encode;
|
use spki::der::Encode;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum X448Error {
|
pub enum X448Error {
|
||||||
|
#[class("DOMExceptionOperationError")]
|
||||||
#[error("Failed to export key")]
|
#[error("Failed to export key")]
|
||||||
FailedExport,
|
FailedExport,
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Der(#[from] spki::der::Error),
|
Der(#[from] spki::der::Error),
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ base64.workspace = true
|
||||||
bytes.workspace = true
|
bytes.workspace = true
|
||||||
data-url.workspace = true
|
data-url.workspace = true
|
||||||
deno_core.workspace = true
|
deno_core.workspace = true
|
||||||
|
deno_error.workspace = true
|
||||||
deno_path_util.workspace = true
|
deno_path_util.workspace = true
|
||||||
deno_permissions.workspace = true
|
deno_permissions.workspace = true
|
||||||
deno_tls.workspace = true
|
deno_tls.workspace = true
|
||||||
|
|
|
@ -8,6 +8,7 @@ use deno_core::futures::TryStreamExt;
|
||||||
use deno_core::url::Url;
|
use deno_core::url::Url;
|
||||||
use deno_core::CancelFuture;
|
use deno_core::CancelFuture;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use http::StatusCode;
|
use http::StatusCode;
|
||||||
use http_body_util::BodyExt;
|
use http_body_util::BodyExt;
|
||||||
use tokio_util::io::ReaderStream;
|
use tokio_util::io::ReaderStream;
|
||||||
|
@ -34,7 +35,7 @@ impl FetchHandler for FsFetchHandler {
|
||||||
let file = tokio::fs::File::open(path).map_err(|_| ()).await?;
|
let file = tokio::fs::File::open(path).map_err(|_| ()).await?;
|
||||||
let stream = ReaderStream::new(file)
|
let stream = ReaderStream::new(file)
|
||||||
.map_ok(hyper::body::Frame::data)
|
.map_ok(hyper::body::Frame::data)
|
||||||
.map_err(Into::into);
|
.map_err(JsErrorBox::from_err);
|
||||||
let body = http_body_util::StreamBody::new(stream).boxed();
|
let body = http_body_util::StreamBody::new(stream).boxed();
|
||||||
let response = http::Response::builder()
|
let response = http::Response::builder()
|
||||||
.status(StatusCode::OK)
|
.status(StatusCode::OK)
|
||||||
|
|
|
@ -46,6 +46,7 @@ use deno_core::OpState;
|
||||||
use deno_core::RcRef;
|
use deno_core::RcRef;
|
||||||
use deno_core::Resource;
|
use deno_core::Resource;
|
||||||
use deno_core::ResourceId;
|
use deno_core::ResourceId;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_path_util::url_from_file_path;
|
use deno_path_util::url_from_file_path;
|
||||||
use deno_path_util::PathToUrlError;
|
use deno_path_util::PathToUrlError;
|
||||||
use deno_permissions::PermissionCheckError;
|
use deno_permissions::PermissionCheckError;
|
||||||
|
@ -100,9 +101,8 @@ pub struct Options {
|
||||||
/// For more info on what can be configured, see [`hyper_util::client::legacy::Builder`].
|
/// For more info on what can be configured, see [`hyper_util::client::legacy::Builder`].
|
||||||
pub client_builder_hook: Option<fn(HyperClientBuilder) -> HyperClientBuilder>,
|
pub client_builder_hook: Option<fn(HyperClientBuilder) -> HyperClientBuilder>,
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub request_builder_hook: Option<
|
pub request_builder_hook:
|
||||||
fn(&mut http::Request<ReqBody>) -> Result<(), deno_core::error::AnyError>,
|
Option<fn(&mut http::Request<ReqBody>) -> Result<(), JsErrorBox>>,
|
||||||
>,
|
|
||||||
pub unsafely_ignore_certificate_errors: Option<Vec<String>>,
|
pub unsafely_ignore_certificate_errors: Option<Vec<String>>,
|
||||||
pub client_cert_chain_and_key: TlsKeys,
|
pub client_cert_chain_and_key: TlsKeys,
|
||||||
pub file_fetch_handler: Rc<dyn FetchHandler>,
|
pub file_fetch_handler: Rc<dyn FetchHandler>,
|
||||||
|
@ -110,9 +110,7 @@ pub struct Options {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Options {
|
impl Options {
|
||||||
pub fn root_cert_store(
|
pub fn root_cert_store(&self) -> Result<Option<RootCertStore>, JsErrorBox> {
|
||||||
&self,
|
|
||||||
) -> Result<Option<RootCertStore>, deno_core::error::AnyError> {
|
|
||||||
Ok(match &self.root_cert_store_provider {
|
Ok(match &self.root_cert_store_provider {
|
||||||
Some(provider) => Some(provider.get_or_try_init()?.clone()),
|
Some(provider) => Some(provider.get_or_try_init()?.clone()),
|
||||||
None => None,
|
None => None,
|
||||||
|
@ -164,48 +162,71 @@ deno_core::extension!(deno_fetch,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum FetchError {
|
pub enum FetchError {
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Resource(deno_core::error::AnyError),
|
Resource(#[from] deno_core::error::ResourceError),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Permission(#[from] PermissionCheckError),
|
Permission(#[from] PermissionCheckError),
|
||||||
|
#[class(type)]
|
||||||
#[error("NetworkError when attempting to fetch resource")]
|
#[error("NetworkError when attempting to fetch resource")]
|
||||||
NetworkError,
|
NetworkError,
|
||||||
|
#[class(type)]
|
||||||
#[error("Fetching files only supports the GET method: received {0}")]
|
#[error("Fetching files only supports the GET method: received {0}")]
|
||||||
FsNotGet(Method),
|
FsNotGet(Method),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
PathToUrl(#[from] PathToUrlError),
|
PathToUrl(#[from] PathToUrlError),
|
||||||
|
#[class(type)]
|
||||||
#[error("Invalid URL {0}")]
|
#[error("Invalid URL {0}")]
|
||||||
InvalidUrl(Url),
|
InvalidUrl(Url),
|
||||||
|
#[class(type)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
InvalidHeaderName(#[from] http::header::InvalidHeaderName),
|
InvalidHeaderName(#[from] http::header::InvalidHeaderName),
|
||||||
|
#[class(type)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
InvalidHeaderValue(#[from] http::header::InvalidHeaderValue),
|
InvalidHeaderValue(#[from] http::header::InvalidHeaderValue),
|
||||||
|
#[class(type)]
|
||||||
#[error("{0:?}")]
|
#[error("{0:?}")]
|
||||||
DataUrl(data_url::DataUrlError),
|
DataUrl(data_url::DataUrlError),
|
||||||
|
#[class(type)]
|
||||||
#[error("{0:?}")]
|
#[error("{0:?}")]
|
||||||
Base64(data_url::forgiving_base64::InvalidBase64),
|
Base64(data_url::forgiving_base64::InvalidBase64),
|
||||||
|
#[class(type)]
|
||||||
#[error("Blob for the given URL not found.")]
|
#[error("Blob for the given URL not found.")]
|
||||||
BlobNotFound,
|
BlobNotFound,
|
||||||
|
#[class(type)]
|
||||||
#[error("Url scheme '{0}' not supported")]
|
#[error("Url scheme '{0}' not supported")]
|
||||||
SchemeNotSupported(String),
|
SchemeNotSupported(String),
|
||||||
|
#[class(type)]
|
||||||
#[error("Request was cancelled")]
|
#[error("Request was cancelled")]
|
||||||
RequestCanceled,
|
RequestCanceled,
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Http(#[from] http::Error),
|
Http(#[from] http::Error),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
ClientCreate(#[from] HttpClientCreateError),
|
ClientCreate(#[from] HttpClientCreateError),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Url(#[from] url::ParseError),
|
Url(#[from] url::ParseError),
|
||||||
|
#[class(type)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Method(#[from] http::method::InvalidMethod),
|
Method(#[from] http::method::InvalidMethod),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
ClientSend(#[from] ClientSendError),
|
ClientSend(#[from] ClientSendError),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
RequestBuilderHook(deno_core::error::AnyError),
|
RequestBuilderHook(JsErrorBox),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Io(#[from] std::io::Error),
|
Io(#[from] std::io::Error),
|
||||||
|
#[class(generic)]
|
||||||
|
#[error(transparent)]
|
||||||
|
Dns(hickory_resolver::ResolveError),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type CancelableResponseFuture =
|
pub type CancelableResponseFuture =
|
||||||
|
@ -294,9 +315,7 @@ pub fn create_client_from_options(
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub struct ResourceToBodyAdapter(
|
pub struct ResourceToBodyAdapter(
|
||||||
Rc<dyn Resource>,
|
Rc<dyn Resource>,
|
||||||
Option<
|
Option<Pin<Box<dyn Future<Output = Result<BufView, JsErrorBox>>>>>,
|
||||||
Pin<Box<dyn Future<Output = Result<BufView, deno_core::error::AnyError>>>>,
|
|
||||||
>,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
impl ResourceToBodyAdapter {
|
impl ResourceToBodyAdapter {
|
||||||
|
@ -312,7 +331,7 @@ unsafe impl Send for ResourceToBodyAdapter {}
|
||||||
unsafe impl Sync for ResourceToBodyAdapter {}
|
unsafe impl Sync for ResourceToBodyAdapter {}
|
||||||
|
|
||||||
impl Stream for ResourceToBodyAdapter {
|
impl Stream for ResourceToBodyAdapter {
|
||||||
type Item = Result<Bytes, deno_core::error::AnyError>;
|
type Item = Result<Bytes, JsErrorBox>;
|
||||||
|
|
||||||
fn poll_next(
|
fn poll_next(
|
||||||
self: Pin<&mut Self>,
|
self: Pin<&mut Self>,
|
||||||
|
@ -342,7 +361,7 @@ impl Stream for ResourceToBodyAdapter {
|
||||||
|
|
||||||
impl hyper::body::Body for ResourceToBodyAdapter {
|
impl hyper::body::Body for ResourceToBodyAdapter {
|
||||||
type Data = Bytes;
|
type Data = Bytes;
|
||||||
type Error = deno_core::error::AnyError;
|
type Error = JsErrorBox;
|
||||||
|
|
||||||
fn poll_frame(
|
fn poll_frame(
|
||||||
self: Pin<&mut Self>,
|
self: Pin<&mut Self>,
|
||||||
|
@ -417,10 +436,7 @@ where
|
||||||
FP: FetchPermissions + 'static,
|
FP: FetchPermissions + 'static,
|
||||||
{
|
{
|
||||||
let (client, allow_host) = if let Some(rid) = client_rid {
|
let (client, allow_host) = if let Some(rid) = client_rid {
|
||||||
let r = state
|
let r = state.resource_table.get::<HttpClientResource>(rid)?;
|
||||||
.resource_table
|
|
||||||
.get::<HttpClientResource>(rid)
|
|
||||||
.map_err(FetchError::Resource)?;
|
|
||||||
(r.client.clone(), r.allow_host)
|
(r.client.clone(), r.allow_host)
|
||||||
} else {
|
} else {
|
||||||
(get_or_create_client_from_state(state)?, false)
|
(get_or_create_client_from_state(state)?, false)
|
||||||
|
@ -479,10 +495,7 @@ where
|
||||||
ReqBody::full(data.to_vec().into())
|
ReqBody::full(data.to_vec().into())
|
||||||
}
|
}
|
||||||
(_, Some(resource)) => {
|
(_, Some(resource)) => {
|
||||||
let resource = state
|
let resource = state.resource_table.take_any(resource)?;
|
||||||
.resource_table
|
|
||||||
.take_any(resource)
|
|
||||||
.map_err(FetchError::Resource)?;
|
|
||||||
match resource.size_hint() {
|
match resource.size_hint() {
|
||||||
(body_size, Some(n)) if body_size == n && body_size > 0 => {
|
(body_size, Some(n)) if body_size == n && body_size > 0 => {
|
||||||
con_len = Some(body_size);
|
con_len = Some(body_size);
|
||||||
|
@ -624,8 +637,7 @@ pub async fn op_fetch_send(
|
||||||
let request = state
|
let request = state
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.resource_table
|
.resource_table
|
||||||
.take::<FetchRequestResource>(rid)
|
.take::<FetchRequestResource>(rid)?;
|
||||||
.map_err(FetchError::Resource)?;
|
|
||||||
|
|
||||||
let request = Rc::try_unwrap(request)
|
let request = Rc::try_unwrap(request)
|
||||||
.ok()
|
.ok()
|
||||||
|
@ -804,9 +816,7 @@ impl Resource for FetchResponseResource {
|
||||||
// safely call `await` on it without creating a race condition.
|
// safely call `await` on it without creating a race condition.
|
||||||
Some(_) => match reader.as_mut().next().await.unwrap() {
|
Some(_) => match reader.as_mut().next().await.unwrap() {
|
||||||
Ok(chunk) => assert!(chunk.is_empty()),
|
Ok(chunk) => assert!(chunk.is_empty()),
|
||||||
Err(err) => {
|
Err(err) => break Err(JsErrorBox::type_error(err.to_string())),
|
||||||
break Err(deno_core::error::type_error(err.to_string()))
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
None => break Ok(BufView::empty()),
|
None => break Ok(BufView::empty()),
|
||||||
}
|
}
|
||||||
|
@ -814,7 +824,10 @@ impl Resource for FetchResponseResource {
|
||||||
};
|
};
|
||||||
|
|
||||||
let cancel_handle = RcRef::map(self, |r| &r.cancel);
|
let cancel_handle = RcRef::map(self, |r| &r.cancel);
|
||||||
fut.try_or_cancel(cancel_handle).await
|
fut
|
||||||
|
.try_or_cancel(cancel_handle)
|
||||||
|
.await
|
||||||
|
.map_err(JsErrorBox::from_err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -897,9 +910,7 @@ where
|
||||||
ca_certs,
|
ca_certs,
|
||||||
proxy: args.proxy,
|
proxy: args.proxy,
|
||||||
dns_resolver: if args.use_hickory_resolver {
|
dns_resolver: if args.use_hickory_resolver {
|
||||||
dns::Resolver::hickory()
|
dns::Resolver::hickory().map_err(FetchError::Dns)?
|
||||||
.map_err(deno_core::error::AnyError::new)
|
|
||||||
.map_err(FetchError::Resource)?
|
|
||||||
} else {
|
} else {
|
||||||
dns::Resolver::default()
|
dns::Resolver::default()
|
||||||
},
|
},
|
||||||
|
@ -963,7 +974,8 @@ impl Default for CreateHttpClientOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
#[class(type)]
|
||||||
pub enum HttpClientCreateError {
|
pub enum HttpClientCreateError {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Tls(deno_tls::TlsError),
|
Tls(deno_tls::TlsError),
|
||||||
|
@ -973,8 +985,9 @@ pub enum HttpClientCreateError {
|
||||||
InvalidProxyUrl,
|
InvalidProxyUrl,
|
||||||
#[error("Cannot create Http Client: either `http1` or `http2` needs to be set to true")]
|
#[error("Cannot create Http Client: either `http1` or `http2` needs to be set to true")]
|
||||||
HttpVersionSelectionInvalid,
|
HttpVersionSelectionInvalid,
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
RootCertStore(deno_core::error::AnyError),
|
RootCertStore(JsErrorBox),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create new instance of async Client. This client supports
|
/// Create new instance of async Client. This client supports
|
||||||
|
@ -1097,7 +1110,8 @@ type Connector = proxy::ProxyConnector<HttpConnector<dns::Resolver>>;
|
||||||
#[allow(clippy::declare_interior_mutable_const)]
|
#[allow(clippy::declare_interior_mutable_const)]
|
||||||
const STAR_STAR: HeaderValue = HeaderValue::from_static("*/*");
|
const STAR_STAR: HeaderValue = HeaderValue::from_static("*/*");
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, deno_error::JsError)]
|
||||||
|
#[class(type)]
|
||||||
pub struct ClientSendError {
|
pub struct ClientSendError {
|
||||||
uri: Uri,
|
uri: Uri,
|
||||||
pub source: hyper_util::client::legacy::Error,
|
pub source: hyper_util::client::legacy::Error,
|
||||||
|
@ -1172,7 +1186,7 @@ impl Client {
|
||||||
.oneshot(req)
|
.oneshot(req)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| ClientSendError { uri, source: e })?;
|
.map_err(|e| ClientSendError { uri, source: e })?;
|
||||||
Ok(resp.map(|b| b.map_err(|e| deno_core::anyhow::anyhow!(e)).boxed()))
|
Ok(resp.map(|b| b.map_err(|e| JsErrorBox::generic(e.to_string())).boxed()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1180,10 +1194,10 @@ impl Client {
|
||||||
pub enum ReqBody {
|
pub enum ReqBody {
|
||||||
Full(http_body_util::Full<Bytes>),
|
Full(http_body_util::Full<Bytes>),
|
||||||
Empty(http_body_util::Empty<Bytes>),
|
Empty(http_body_util::Empty<Bytes>),
|
||||||
Streaming(BoxBody<Bytes, deno_core::error::AnyError>),
|
Streaming(BoxBody<Bytes, JsErrorBox>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ResBody = BoxBody<Bytes, deno_core::error::AnyError>;
|
pub type ResBody = BoxBody<Bytes, JsErrorBox>;
|
||||||
|
|
||||||
impl ReqBody {
|
impl ReqBody {
|
||||||
pub fn full(bytes: Bytes) -> Self {
|
pub fn full(bytes: Bytes) -> Self {
|
||||||
|
@ -1196,7 +1210,7 @@ impl ReqBody {
|
||||||
|
|
||||||
pub fn streaming<B>(body: B) -> Self
|
pub fn streaming<B>(body: B) -> Self
|
||||||
where
|
where
|
||||||
B: hyper::body::Body<Data = Bytes, Error = deno_core::error::AnyError>
|
B: hyper::body::Body<Data = Bytes, Error = JsErrorBox>
|
||||||
+ Send
|
+ Send
|
||||||
+ Sync
|
+ Sync
|
||||||
+ 'static,
|
+ 'static,
|
||||||
|
@ -1207,7 +1221,7 @@ impl ReqBody {
|
||||||
|
|
||||||
impl hyper::body::Body for ReqBody {
|
impl hyper::body::Body for ReqBody {
|
||||||
type Data = Bytes;
|
type Data = Bytes;
|
||||||
type Error = deno_core::error::AnyError;
|
type Error = JsErrorBox;
|
||||||
|
|
||||||
fn poll_frame(
|
fn poll_frame(
|
||||||
mut self: Pin<&mut Self>,
|
mut self: Pin<&mut Self>,
|
||||||
|
|
|
@ -15,6 +15,7 @@ path = "lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
deno_core.workspace = true
|
deno_core.workspace = true
|
||||||
|
deno_error.workspace = true
|
||||||
deno_permissions.workspace = true
|
deno_permissions.workspace = true
|
||||||
dlopen2.workspace = true
|
dlopen2.workspace = true
|
||||||
dynasmrt = "1.2.3"
|
dynasmrt = "1.2.3"
|
||||||
|
|
|
@ -25,18 +25,24 @@ use crate::symbol::Symbol;
|
||||||
use crate::FfiPermissions;
|
use crate::FfiPermissions;
|
||||||
use crate::ForeignFunction;
|
use crate::ForeignFunction;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum CallError {
|
pub enum CallError {
|
||||||
|
#[class(type)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
IR(#[from] IRError),
|
IR(#[from] IRError),
|
||||||
|
#[class(generic)]
|
||||||
#[error("Nonblocking FFI call failed: {0}")]
|
#[error("Nonblocking FFI call failed: {0}")]
|
||||||
NonblockingCallFailure(#[source] tokio::task::JoinError),
|
NonblockingCallFailure(#[source] tokio::task::JoinError),
|
||||||
|
#[class(type)]
|
||||||
#[error("Invalid FFI symbol name: '{0}'")]
|
#[error("Invalid FFI symbol name: '{0}'")]
|
||||||
InvalidSymbol(String),
|
InvalidSymbol(String),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Permission(#[from] deno_permissions::PermissionCheckError),
|
Permission(#[from] deno_permissions::PermissionCheckError),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Resource(deno_core::error::AnyError),
|
Resource(#[from] deno_core::error::ResourceError),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Callback(#[from] super::CallbackError),
|
Callback(#[from] super::CallbackError),
|
||||||
}
|
}
|
||||||
|
@ -346,10 +352,7 @@ pub fn op_ffi_call_nonblocking(
|
||||||
) -> Result<impl Future<Output = Result<FfiValue, CallError>>, CallError> {
|
) -> Result<impl Future<Output = Result<FfiValue, CallError>>, CallError> {
|
||||||
let symbol = {
|
let symbol = {
|
||||||
let state = state.borrow();
|
let state = state.borrow();
|
||||||
let resource = state
|
let resource = state.resource_table.get::<DynamicLibraryResource>(rid)?;
|
||||||
.resource_table
|
|
||||||
.get::<DynamicLibraryResource>(rid)
|
|
||||||
.map_err(CallError::Resource)?;
|
|
||||||
let symbols = &resource.symbols;
|
let symbols = &resource.symbols;
|
||||||
*symbols
|
*symbols
|
||||||
.get(&symbol)
|
.get(&symbol)
|
||||||
|
|
|
@ -35,14 +35,17 @@ thread_local! {
|
||||||
static LOCAL_THREAD_ID: RefCell<u32> = const { RefCell::new(0) };
|
static LOCAL_THREAD_ID: RefCell<u32> = const { RefCell::new(0) };
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum CallbackError {
|
pub enum CallbackError {
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Resource(deno_core::error::AnyError),
|
Resource(#[from] deno_core::error::ResourceError),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Permission(#[from] deno_permissions::PermissionCheckError),
|
Permission(#[from] deno_permissions::PermissionCheckError),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Other(deno_core::error::AnyError),
|
Other(#[from] deno_error::JsErrorBox),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -63,13 +66,8 @@ impl PtrSymbol {
|
||||||
.clone()
|
.clone()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(libffi::middle::Type::try_from)
|
.map(libffi::middle::Type::try_from)
|
||||||
.collect::<Result<Vec<_>, _>>()
|
.collect::<Result<Vec<_>, _>>()?,
|
||||||
.map_err(CallbackError::Other)?,
|
def.result.clone().try_into()?,
|
||||||
def
|
|
||||||
.result
|
|
||||||
.clone()
|
|
||||||
.try_into()
|
|
||||||
.map_err(CallbackError::Other)?,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(Self { cif, ptr })
|
Ok(Self { cif, ptr })
|
||||||
|
@ -540,10 +538,8 @@ pub fn op_ffi_unsafe_callback_ref(
|
||||||
#[smi] rid: ResourceId,
|
#[smi] rid: ResourceId,
|
||||||
) -> Result<impl Future<Output = ()>, CallbackError> {
|
) -> Result<impl Future<Output = ()>, CallbackError> {
|
||||||
let state = state.borrow();
|
let state = state.borrow();
|
||||||
let callback_resource = state
|
let callback_resource =
|
||||||
.resource_table
|
state.resource_table.get::<UnsafeCallbackResource>(rid)?;
|
||||||
.get::<UnsafeCallbackResource>(rid)
|
|
||||||
.map_err(CallbackError::Resource)?;
|
|
||||||
|
|
||||||
Ok(async move {
|
Ok(async move {
|
||||||
let info: &mut CallbackInfo =
|
let info: &mut CallbackInfo =
|
||||||
|
@ -610,10 +606,8 @@ where
|
||||||
.parameters
|
.parameters
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(libffi::middle::Type::try_from)
|
.map(libffi::middle::Type::try_from)
|
||||||
.collect::<Result<Vec<_>, _>>()
|
.collect::<Result<Vec<_>, _>>()?,
|
||||||
.map_err(CallbackError::Other)?,
|
libffi::middle::Type::try_from(args.result)?,
|
||||||
libffi::middle::Type::try_from(args.result)
|
|
||||||
.map_err(CallbackError::Other)?,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// SAFETY: CallbackInfo is leaked, is not null and stays valid as long as the callback exists.
|
// SAFETY: CallbackInfo is leaked, is not null and stays valid as long as the callback exists.
|
||||||
|
@ -649,10 +643,8 @@ pub fn op_ffi_unsafe_callback_close(
|
||||||
// It is up to the user to know that it is safe to call the `close()` on the
|
// It is up to the user to know that it is safe to call the `close()` on the
|
||||||
// UnsafeCallback instance.
|
// UnsafeCallback instance.
|
||||||
unsafe {
|
unsafe {
|
||||||
let callback_resource = state
|
let callback_resource =
|
||||||
.resource_table
|
state.resource_table.take::<UnsafeCallbackResource>(rid)?;
|
||||||
.take::<UnsafeCallbackResource>(rid)
|
|
||||||
.map_err(CallbackError::Resource)?;
|
|
||||||
let info = Box::from_raw(callback_resource.info);
|
let info = Box::from_raw(callback_resource.info);
|
||||||
let _ = v8::Global::from_raw(scope, info.callback);
|
let _ = v8::Global::from_raw(scope, info.callback);
|
||||||
let _ = v8::Global::from_raw(scope, info.context);
|
let _ = v8::Global::from_raw(scope, info.context);
|
||||||
|
|
|
@ -11,6 +11,8 @@ use deno_core::v8;
|
||||||
use deno_core::GarbageCollected;
|
use deno_core::GarbageCollected;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
use deno_core::Resource;
|
use deno_core::Resource;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
|
use deno_error::JsErrorClass;
|
||||||
use dlopen2::raw::Library;
|
use dlopen2::raw::Library;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde_value::ValueDeserializer;
|
use serde_value::ValueDeserializer;
|
||||||
|
@ -22,20 +24,34 @@ use crate::turbocall;
|
||||||
use crate::turbocall::Turbocall;
|
use crate::turbocall::Turbocall;
|
||||||
use crate::FfiPermissions;
|
use crate::FfiPermissions;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
deno_error::js_error_wrapper!(dlopen2::Error, JsDlopen2Error, |err| {
|
||||||
|
match err {
|
||||||
|
dlopen2::Error::NullCharacter(_) => "InvalidData".into(),
|
||||||
|
dlopen2::Error::OpeningLibraryError(e) => e.get_class(),
|
||||||
|
dlopen2::Error::SymbolGettingError(e) => e.get_class(),
|
||||||
|
dlopen2::Error::AddrNotMatchingDll(e) => e.get_class(),
|
||||||
|
dlopen2::Error::NullSymbol => "NotFound".into(),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum DlfcnError {
|
pub enum DlfcnError {
|
||||||
|
#[class(generic)]
|
||||||
#[error("Failed to register symbol {symbol}: {error}")]
|
#[error("Failed to register symbol {symbol}: {error}")]
|
||||||
RegisterSymbol {
|
RegisterSymbol {
|
||||||
symbol: String,
|
symbol: String,
|
||||||
#[source]
|
#[source]
|
||||||
error: dlopen2::Error,
|
error: dlopen2::Error,
|
||||||
},
|
},
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Dlopen(#[from] dlopen2::Error),
|
Dlopen(#[from] dlopen2::Error),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Permission(#[from] deno_permissions::PermissionCheckError),
|
Permission(#[from] deno_permissions::PermissionCheckError),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Other(deno_core::error::AnyError),
|
Other(#[from] JsErrorBox),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DynamicLibraryResource {
|
pub struct DynamicLibraryResource {
|
||||||
|
@ -190,13 +206,8 @@ where
|
||||||
.clone()
|
.clone()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(libffi::middle::Type::try_from)
|
.map(libffi::middle::Type::try_from)
|
||||||
.collect::<Result<Vec<_>, _>>()
|
.collect::<Result<Vec<_>, _>>()?,
|
||||||
.map_err(DlfcnError::Other)?,
|
foreign_fn.result.clone().try_into()?,
|
||||||
foreign_fn
|
|
||||||
.result
|
|
||||||
.clone()
|
|
||||||
.try_into()
|
|
||||||
.map_err(DlfcnError::Other)?,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let func_key = v8::String::new(scope, &symbol_key).unwrap();
|
let func_key = v8::String::new(scope, &symbol_key).unwrap();
|
||||||
|
@ -304,9 +315,7 @@ fn sync_fn_impl<'s>(
|
||||||
unsafe { result.to_v8(scope, data.symbol.result_type.clone()) };
|
unsafe { result.to_v8(scope, data.symbol.result_type.clone()) };
|
||||||
rv.set(result);
|
rv.set(result);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => deno_core::error::throw_js_error_class(scope, &err),
|
||||||
deno_core::_ops::throw_type_error(scope, err.to_string());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,8 @@ use libffi::middle::Arg;
|
||||||
|
|
||||||
use crate::symbol::NativeType;
|
use crate::symbol::NativeType;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
#[class(type)]
|
||||||
pub enum IRError {
|
pub enum IRError {
|
||||||
#[error("Invalid FFI u8 type, expected boolean")]
|
#[error("Invalid FFI u8 type, expected boolean")]
|
||||||
InvalidU8ExpectedBoolean,
|
InvalidU8ExpectedBoolean,
|
||||||
|
|
|
@ -11,7 +11,8 @@ use deno_core::OpState;
|
||||||
|
|
||||||
use crate::FfiPermissions;
|
use crate::FfiPermissions;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
|
#[class(type)]
|
||||||
pub enum ReprError {
|
pub enum ReprError {
|
||||||
#[error("Invalid pointer to offset, pointer is null")]
|
#[error("Invalid pointer to offset, pointer is null")]
|
||||||
InvalidOffset,
|
InvalidOffset,
|
||||||
|
@ -47,6 +48,7 @@ pub enum ReprError {
|
||||||
InvalidF64,
|
InvalidF64,
|
||||||
#[error("Invalid pointer pointer, pointer is null")]
|
#[error("Invalid pointer pointer, pointer is null")]
|
||||||
InvalidPointer,
|
InvalidPointer,
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Permission(#[from] deno_permissions::PermissionCheckError),
|
Permission(#[from] deno_permissions::PermissionCheckError),
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,16 +10,20 @@ use deno_core::ResourceId;
|
||||||
use crate::dlfcn::DynamicLibraryResource;
|
use crate::dlfcn::DynamicLibraryResource;
|
||||||
use crate::symbol::NativeType;
|
use crate::symbol::NativeType;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum StaticError {
|
pub enum StaticError {
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Dlfcn(super::DlfcnError),
|
Dlfcn(super::DlfcnError),
|
||||||
|
#[class(type)]
|
||||||
#[error("Invalid FFI static type 'void'")]
|
#[error("Invalid FFI static type 'void'")]
|
||||||
InvalidTypeVoid,
|
InvalidTypeVoid,
|
||||||
|
#[class(type)]
|
||||||
#[error("Invalid FFI static type 'struct'")]
|
#[error("Invalid FFI static type 'struct'")]
|
||||||
InvalidTypeStruct,
|
InvalidTypeStruct,
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Resource(deno_core::error::AnyError),
|
Resource(#[from] deno_core::error::ResourceError),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2]
|
||||||
|
@ -31,10 +35,7 @@ pub fn op_ffi_get_static<'scope>(
|
||||||
#[serde] static_type: NativeType,
|
#[serde] static_type: NativeType,
|
||||||
optional: bool,
|
optional: bool,
|
||||||
) -> Result<v8::Local<'scope, v8::Value>, StaticError> {
|
) -> Result<v8::Local<'scope, v8::Value>, StaticError> {
|
||||||
let resource = state
|
let resource = state.resource_table.get::<DynamicLibraryResource>(rid)?;
|
||||||
.resource_table
|
|
||||||
.get::<DynamicLibraryResource>(rid)
|
|
||||||
.map_err(StaticError::Resource)?;
|
|
||||||
|
|
||||||
let data_ptr = match resource.get_static(name) {
|
let data_ptr = match resource.get_static(name) {
|
||||||
Ok(data_ptr) => data_ptr,
|
Ok(data_ptr) => data_ptr,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||||
|
|
||||||
use deno_core::error::type_error;
|
use deno_error::JsErrorBox;
|
||||||
use deno_core::error::AnyError;
|
|
||||||
|
|
||||||
/// Defines the accepted types that can be used as
|
/// Defines the accepted types that can be used as
|
||||||
/// parameters and return values in FFI.
|
/// parameters and return values in FFI.
|
||||||
|
@ -29,7 +28,7 @@ pub enum NativeType {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<NativeType> for libffi::middle::Type {
|
impl TryFrom<NativeType> for libffi::middle::Type {
|
||||||
type Error = AnyError;
|
type Error = JsErrorBox;
|
||||||
|
|
||||||
fn try_from(native_type: NativeType) -> Result<Self, Self::Error> {
|
fn try_from(native_type: NativeType) -> Result<Self, Self::Error> {
|
||||||
Ok(match native_type {
|
Ok(match native_type {
|
||||||
|
@ -56,7 +55,9 @@ impl TryFrom<NativeType> for libffi::middle::Type {
|
||||||
.map(|field| field.clone().try_into())
|
.map(|field| field.clone().try_into())
|
||||||
.collect::<Result<Vec<_>, _>>()?,
|
.collect::<Result<Vec<_>, _>>()?,
|
||||||
false => {
|
false => {
|
||||||
return Err(type_error("Struct must have at least one field"))
|
return Err(JsErrorBox::type_error(
|
||||||
|
"Struct must have at least one field",
|
||||||
|
))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ async-trait.workspace = true
|
||||||
base32.workspace = true
|
base32.workspace = true
|
||||||
boxed_error.workspace = true
|
boxed_error.workspace = true
|
||||||
deno_core.workspace = true
|
deno_core.workspace = true
|
||||||
|
deno_error.workspace = true
|
||||||
deno_io.workspace = true
|
deno_io.workspace = true
|
||||||
deno_path_util.workspace = true
|
deno_path_util.workspace = true
|
||||||
deno_permissions.workspace = true
|
deno_permissions.workspace = true
|
||||||
|
|
|
@ -12,6 +12,7 @@ use std::path::StripPrefixError;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use boxed_error::Boxed;
|
use boxed_error::Boxed;
|
||||||
|
use deno_core::error::ResourceError;
|
||||||
use deno_core::op2;
|
use deno_core::op2;
|
||||||
use deno_core::CancelFuture;
|
use deno_core::CancelFuture;
|
||||||
use deno_core::CancelHandle;
|
use deno_core::CancelHandle;
|
||||||
|
@ -20,6 +21,7 @@ use deno_core::JsBuffer;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
use deno_core::ResourceId;
|
use deno_core::ResourceId;
|
||||||
use deno_core::ToJsBuffer;
|
use deno_core::ToJsBuffer;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_io::fs::FileResource;
|
use deno_io::fs::FileResource;
|
||||||
use deno_io::fs::FsError;
|
use deno_io::fs::FsError;
|
||||||
use deno_io::fs::FsStat;
|
use deno_io::fs::FsStat;
|
||||||
|
@ -36,34 +38,46 @@ use crate::interface::FsFileType;
|
||||||
use crate::FsPermissions;
|
use crate::FsPermissions;
|
||||||
use crate::OpenOptions;
|
use crate::OpenOptions;
|
||||||
|
|
||||||
#[derive(Debug, Boxed)]
|
#[derive(Debug, Boxed, deno_error::JsError)]
|
||||||
pub struct FsOpsError(pub Box<FsOpsErrorKind>);
|
pub struct FsOpsError(pub Box<FsOpsErrorKind>);
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum FsOpsErrorKind {
|
pub enum FsOpsErrorKind {
|
||||||
|
#[class(inherit)]
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
Io(#[source] std::io::Error),
|
Io(#[source] std::io::Error),
|
||||||
|
#[class(inherit)]
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
OperationError(#[source] OperationError),
|
OperationError(#[source] OperationError),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Permission(#[from] PermissionCheckError),
|
Permission(#[from] PermissionCheckError),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Resource(deno_core::error::AnyError),
|
Resource(#[from] ResourceError),
|
||||||
|
#[class("InvalidData")]
|
||||||
#[error("File name or path {0:?} is not valid UTF-8")]
|
#[error("File name or path {0:?} is not valid UTF-8")]
|
||||||
InvalidUtf8(std::ffi::OsString),
|
InvalidUtf8(std::ffi::OsString),
|
||||||
|
#[class(generic)]
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
StripPrefix(#[from] StripPrefixError),
|
StripPrefix(#[from] StripPrefixError),
|
||||||
|
#[class(inherit)]
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
Canceled(#[from] deno_core::Canceled),
|
Canceled(#[from] deno_core::Canceled),
|
||||||
|
#[class(type)]
|
||||||
#[error("Invalid seek mode: {0}")]
|
#[error("Invalid seek mode: {0}")]
|
||||||
InvalidSeekMode(i32),
|
InvalidSeekMode(i32),
|
||||||
|
#[class(generic)]
|
||||||
#[error("Invalid control character in prefix or suffix: {0:?}")]
|
#[error("Invalid control character in prefix or suffix: {0:?}")]
|
||||||
InvalidControlCharacter(String),
|
InvalidControlCharacter(String),
|
||||||
|
#[class(generic)]
|
||||||
#[error("Invalid character in prefix or suffix: {0:?}")]
|
#[error("Invalid character in prefix or suffix: {0:?}")]
|
||||||
InvalidCharacter(String),
|
InvalidCharacter(String),
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
|
#[class(generic)]
|
||||||
#[error("Invalid trailing character in suffix")]
|
#[error("Invalid trailing character in suffix")]
|
||||||
InvalidTrailingCharacter,
|
InvalidTrailingCharacter,
|
||||||
|
#[class("NotCapable")]
|
||||||
#[error("Requires {err} access to {path}, {}", print_not_capable_info(*.standalone, .err))]
|
#[error("Requires {err} access to {path}, {}", print_not_capable_info(*.standalone, .err))]
|
||||||
NotCapableAccess {
|
NotCapableAccess {
|
||||||
// NotCapable
|
// NotCapable
|
||||||
|
@ -71,21 +85,21 @@ pub enum FsOpsErrorKind {
|
||||||
err: &'static str,
|
err: &'static str,
|
||||||
path: String,
|
path: String,
|
||||||
},
|
},
|
||||||
|
#[class("NotCapable")]
|
||||||
#[error("permission denied: {0}")]
|
#[error("permission denied: {0}")]
|
||||||
NotCapable(&'static str), // NotCapable
|
NotCapable(&'static str),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Other(deno_core::error::AnyError),
|
Other(JsErrorBox),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<FsError> for FsOpsError {
|
impl From<FsError> for FsOpsError {
|
||||||
fn from(err: FsError) -> Self {
|
fn from(err: FsError) -> Self {
|
||||||
match err {
|
match err {
|
||||||
FsError::Io(err) => FsOpsErrorKind::Io(err),
|
FsError::Io(err) => FsOpsErrorKind::Io(err),
|
||||||
FsError::FileBusy => {
|
FsError::FileBusy => FsOpsErrorKind::Resource(ResourceError::Unavailable),
|
||||||
FsOpsErrorKind::Other(deno_core::error::resource_unavailable())
|
|
||||||
}
|
|
||||||
FsError::NotSupported => {
|
FsError::NotSupported => {
|
||||||
FsOpsErrorKind::Other(deno_core::error::not_supported())
|
FsOpsErrorKind::Other(JsErrorBox::not_supported())
|
||||||
}
|
}
|
||||||
FsError::NotCapable(err) => FsOpsErrorKind::NotCapable(err),
|
FsError::NotCapable(err) => FsOpsErrorKind::NotCapable(err),
|
||||||
}
|
}
|
||||||
|
@ -1666,10 +1680,12 @@ pub async fn op_fs_futime_async(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, deno_error::JsError)]
|
||||||
|
#[class(inherit)]
|
||||||
pub struct OperationError {
|
pub struct OperationError {
|
||||||
operation: &'static str,
|
operation: &'static str,
|
||||||
kind: OperationErrorKind,
|
kind: OperationErrorKind,
|
||||||
|
#[inherit]
|
||||||
pub err: FsError,
|
pub err: FsError,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ brotli.workspace = true
|
||||||
bytes.workspace = true
|
bytes.workspace = true
|
||||||
cache_control.workspace = true
|
cache_control.workspace = true
|
||||||
deno_core.workspace = true
|
deno_core.workspace = true
|
||||||
|
deno_error.workspace = true
|
||||||
deno_net.workspace = true
|
deno_net.workspace = true
|
||||||
deno_websocket.workspace = true
|
deno_websocket.workspace = true
|
||||||
flate2.workspace = true
|
flate2.workspace = true
|
||||||
|
|
|
@ -146,24 +146,44 @@ macro_rules! clone_external {
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum HttpNextError {
|
pub enum HttpNextError {
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Resource(deno_core::error::AnyError),
|
Resource(#[from] deno_core::error::ResourceError),
|
||||||
|
#[class(inherit)]
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
Io(#[from] io::Error),
|
Io(#[from] io::Error),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
WebSocketUpgrade(crate::websocket_upgrade::WebSocketUpgradeError),
|
WebSocketUpgrade(crate::websocket_upgrade::WebSocketUpgradeError),
|
||||||
|
#[class("Http")]
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
Hyper(#[from] hyper::Error),
|
Hyper(#[from] hyper::Error),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
JoinError(#[from] tokio::task::JoinError),
|
JoinError(
|
||||||
|
#[from]
|
||||||
|
#[inherit]
|
||||||
|
tokio::task::JoinError,
|
||||||
|
),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Canceled(#[from] deno_core::Canceled),
|
Canceled(
|
||||||
#[error(transparent)]
|
#[from]
|
||||||
HttpPropertyExtractor(deno_core::error::AnyError),
|
#[inherit]
|
||||||
|
deno_core::Canceled,
|
||||||
|
),
|
||||||
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
UpgradeUnavailable(#[from] crate::service::UpgradeUnavailableError),
|
UpgradeUnavailable(#[from] crate::service::UpgradeUnavailableError),
|
||||||
|
#[class(inherit)]
|
||||||
|
#[error("{0}")]
|
||||||
|
Other(
|
||||||
|
#[from]
|
||||||
|
#[inherit]
|
||||||
|
deno_error::JsErrorBox,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast)]
|
||||||
|
@ -747,15 +767,9 @@ pub async fn op_http_set_response_body_resource(
|
||||||
let resource = {
|
let resource = {
|
||||||
let mut state = state.borrow_mut();
|
let mut state = state.borrow_mut();
|
||||||
if auto_close {
|
if auto_close {
|
||||||
state
|
state.resource_table.take_any(stream_rid)?
|
||||||
.resource_table
|
|
||||||
.take_any(stream_rid)
|
|
||||||
.map_err(HttpNextError::Resource)?
|
|
||||||
} else {
|
} else {
|
||||||
state
|
state.resource_table.get_any(stream_rid)?
|
||||||
.resource_table
|
|
||||||
.get_any(stream_rid)
|
|
||||||
.map_err(HttpNextError::Resource)?
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1063,8 +1077,7 @@ where
|
||||||
HTTP: HttpPropertyExtractor,
|
HTTP: HttpPropertyExtractor,
|
||||||
{
|
{
|
||||||
let listener =
|
let listener =
|
||||||
HTTP::get_listener_for_rid(&mut state.borrow_mut(), listener_rid)
|
HTTP::get_listener_for_rid(&mut state.borrow_mut(), listener_rid)?;
|
||||||
.map_err(HttpNextError::Resource)?;
|
|
||||||
|
|
||||||
let listen_properties = HTTP::listen_properties_from_listener(&listener)?;
|
let listen_properties = HTTP::listen_properties_from_listener(&listener)?;
|
||||||
|
|
||||||
|
@ -1084,8 +1097,7 @@ where
|
||||||
loop {
|
loop {
|
||||||
let conn = HTTP::accept_connection_from_listener(&listener)
|
let conn = HTTP::accept_connection_from_listener(&listener)
|
||||||
.try_or_cancel(listen_cancel_clone.clone())
|
.try_or_cancel(listen_cancel_clone.clone())
|
||||||
.await
|
.await?;
|
||||||
.map_err(HttpNextError::HttpPropertyExtractor)?;
|
|
||||||
serve_http_on::<HTTP>(
|
serve_http_on::<HTTP>(
|
||||||
conn,
|
conn,
|
||||||
&listen_properties_clone,
|
&listen_properties_clone,
|
||||||
|
@ -1120,8 +1132,7 @@ where
|
||||||
HTTP: HttpPropertyExtractor,
|
HTTP: HttpPropertyExtractor,
|
||||||
{
|
{
|
||||||
let connection =
|
let connection =
|
||||||
HTTP::get_connection_for_rid(&mut state.borrow_mut(), connection_rid)
|
HTTP::get_connection_for_rid(&mut state.borrow_mut(), connection_rid)?;
|
||||||
.map_err(HttpNextError::Resource)?;
|
|
||||||
|
|
||||||
let listen_properties = HTTP::listen_properties_from_connection(&connection)?;
|
let listen_properties = HTTP::listen_properties_from_connection(&connection)?;
|
||||||
|
|
||||||
|
@ -1190,8 +1201,7 @@ pub async fn op_http_wait(
|
||||||
let join_handle = state
|
let join_handle = state
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<HttpJoinHandle>(rid)
|
.get::<HttpJoinHandle>(rid)?;
|
||||||
.map_err(HttpNextError::Resource)?;
|
|
||||||
|
|
||||||
let cancel = join_handle.listen_cancel_handle();
|
let cancel = join_handle.listen_cancel_handle();
|
||||||
let next = async {
|
let next = async {
|
||||||
|
@ -1236,7 +1246,7 @@ pub fn op_http_cancel(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[smi] rid: ResourceId,
|
#[smi] rid: ResourceId,
|
||||||
graceful: bool,
|
graceful: bool,
|
||||||
) -> Result<(), deno_core::error::AnyError> {
|
) -> Result<(), deno_core::error::ResourceError> {
|
||||||
let join_handle = state.resource_table.get::<HttpJoinHandle>(rid)?;
|
let join_handle = state.resource_table.get::<HttpJoinHandle>(rid)?;
|
||||||
|
|
||||||
if graceful {
|
if graceful {
|
||||||
|
@ -1260,8 +1270,7 @@ pub async fn op_http_close(
|
||||||
let join_handle = state
|
let join_handle = state
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.resource_table
|
.resource_table
|
||||||
.take::<HttpJoinHandle>(rid)
|
.take::<HttpJoinHandle>(rid)?;
|
||||||
.map_err(HttpNextError::Resource)?;
|
|
||||||
|
|
||||||
if graceful {
|
if graceful {
|
||||||
http_general_trace!("graceful shutdown");
|
http_general_trace!("graceful shutdown");
|
||||||
|
@ -1390,11 +1399,8 @@ pub async fn op_raw_write_vectored(
|
||||||
#[buffer] buf1: JsBuffer,
|
#[buffer] buf1: JsBuffer,
|
||||||
#[buffer] buf2: JsBuffer,
|
#[buffer] buf2: JsBuffer,
|
||||||
) -> Result<usize, HttpNextError> {
|
) -> Result<usize, HttpNextError> {
|
||||||
let resource: Rc<UpgradeStream> = state
|
let resource: Rc<UpgradeStream> =
|
||||||
.borrow()
|
state.borrow().resource_table.get::<UpgradeStream>(rid)?;
|
||||||
.resource_table
|
|
||||||
.get::<UpgradeStream>(rid)
|
|
||||||
.map_err(HttpNextError::Resource)?;
|
|
||||||
let nwritten = resource.write_vectored(&buf1, &buf2).await?;
|
let nwritten = resource.write_vectored(&buf1, &buf2).await?;
|
||||||
Ok(nwritten)
|
Ok(nwritten)
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ use deno_core::RcRef;
|
||||||
use deno_core::Resource;
|
use deno_core::Resource;
|
||||||
use deno_core::ResourceId;
|
use deno_core::ResourceId;
|
||||||
use deno_core::StringOrBuffer;
|
use deno_core::StringOrBuffer;
|
||||||
|
use deno_error::JsErrorBox;
|
||||||
use deno_net::raw::NetworkStream;
|
use deno_net::raw::NetworkStream;
|
||||||
use deno_websocket::ws_create_server_stream;
|
use deno_websocket::ws_create_server_stream;
|
||||||
use flate2::write::GzEncoder;
|
use flate2::write::GzEncoder;
|
||||||
|
@ -165,36 +166,50 @@ deno_core::extension!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||||
pub enum HttpError {
|
pub enum HttpError {
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Resource(deno_core::error::AnyError),
|
Resource(#[from] deno_core::error::ResourceError),
|
||||||
|
#[class(inherit)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Canceled(#[from] deno_core::Canceled),
|
Canceled(#[from] deno_core::Canceled),
|
||||||
|
#[class("Http")]
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
HyperV014(#[source] Arc<hyper_v014::Error>),
|
HyperV014(#[source] Arc<hyper_v014::Error>),
|
||||||
|
#[class(generic)]
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
InvalidHeaderName(#[from] hyper_v014::header::InvalidHeaderName),
|
InvalidHeaderName(#[from] hyper_v014::header::InvalidHeaderName),
|
||||||
|
#[class(generic)]
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
InvalidHeaderValue(#[from] hyper_v014::header::InvalidHeaderValue),
|
InvalidHeaderValue(#[from] hyper_v014::header::InvalidHeaderValue),
|
||||||
|
#[class(generic)]
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
Http(#[from] hyper_v014::http::Error),
|
Http(#[from] hyper_v014::http::Error),
|
||||||
|
#[class("Http")]
|
||||||
#[error("response headers already sent")]
|
#[error("response headers already sent")]
|
||||||
ResponseHeadersAlreadySent,
|
ResponseHeadersAlreadySent,
|
||||||
|
#[class("Http")]
|
||||||
#[error("connection closed while sending response")]
|
#[error("connection closed while sending response")]
|
||||||
ConnectionClosedWhileSendingResponse,
|
ConnectionClosedWhileSendingResponse,
|
||||||
|
#[class("Http")]
|
||||||
#[error("already in use")]
|
#[error("already in use")]
|
||||||
AlreadyInUse,
|
AlreadyInUse,
|
||||||
|
#[class(inherit)]
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
Io(#[from] std::io::Error),
|
Io(#[from] std::io::Error),
|
||||||
|
#[class("Http")]
|
||||||
#[error("no response headers")]
|
#[error("no response headers")]
|
||||||
NoResponseHeaders,
|
NoResponseHeaders,
|
||||||
|
#[class("Http")]
|
||||||
#[error("response already completed")]
|
#[error("response already completed")]
|
||||||
ResponseAlreadyCompleted,
|
ResponseAlreadyCompleted,
|
||||||
|
#[class("Http")]
|
||||||
#[error("cannot upgrade because request body was used")]
|
#[error("cannot upgrade because request body was used")]
|
||||||
UpgradeBodyUsed,
|
UpgradeBodyUsed,
|
||||||
|
#[class("Http")]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Other(deno_core::error::AnyError),
|
Other(#[from] JsErrorBox),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum HttpSocketAddr {
|
pub enum HttpSocketAddr {
|
||||||
|
@ -486,7 +501,9 @@ impl Resource for HttpStreamReadResource {
|
||||||
Some(_) => match body.as_mut().next().await.unwrap() {
|
Some(_) => match body.as_mut().next().await.unwrap() {
|
||||||
Ok(chunk) => assert!(chunk.is_empty()),
|
Ok(chunk) => assert!(chunk.is_empty()),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
break Err(HttpError::HyperV014(Arc::new(err)).into())
|
break Err(JsErrorBox::from_err(HttpError::HyperV014(
|
||||||
|
Arc::new(err),
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => break Ok(BufView::empty()),
|
None => break Ok(BufView::empty()),
|
||||||
|
@ -610,11 +627,7 @@ async fn op_http_accept(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[smi] rid: ResourceId,
|
#[smi] rid: ResourceId,
|
||||||
) -> Result<Option<NextRequestResponse>, HttpError> {
|
) -> Result<Option<NextRequestResponse>, HttpError> {
|
||||||
let conn = state
|
let conn = state.borrow().resource_table.get::<HttpConnResource>(rid)?;
|
||||||
.borrow()
|
|
||||||
.resource_table
|
|
||||||
.get::<HttpConnResource>(rid)
|
|
||||||
.map_err(HttpError::Resource)?;
|
|
||||||
|
|
||||||
match conn.accept().await {
|
match conn.accept().await {
|
||||||
Ok(Some((read_stream, write_stream, method, url))) => {
|
Ok(Some((read_stream, write_stream, method, url))) => {
|
||||||
|
@ -729,8 +742,7 @@ async fn op_http_write_headers(
|
||||||
let stream = state
|
let stream = state
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<HttpStreamWriteResource>(rid)
|
.get::<HttpStreamWriteResource>(rid)?;
|
||||||
.map_err(HttpError::Resource)?;
|
|
||||||
|
|
||||||
// Track supported encoding
|
// Track supported encoding
|
||||||
let encoding = stream.accept_encoding;
|
let encoding = stream.accept_encoding;
|
||||||
|
@ -795,10 +807,7 @@ fn op_http_headers(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[smi] rid: u32,
|
#[smi] rid: u32,
|
||||||
) -> Result<Vec<(ByteString, ByteString)>, HttpError> {
|
) -> Result<Vec<(ByteString, ByteString)>, HttpError> {
|
||||||
let stream = state
|
let stream = state.resource_table.get::<HttpStreamReadResource>(rid)?;
|
||||||
.resource_table
|
|
||||||
.get::<HttpStreamReadResource>(rid)
|
|
||||||
.map_err(HttpError::Resource)?;
|
|
||||||
let rd = RcRef::map(&stream, |r| &r.rd)
|
let rd = RcRef::map(&stream, |r| &r.rd)
|
||||||
.try_borrow()
|
.try_borrow()
|
||||||
.ok_or(HttpError::AlreadyInUse)?;
|
.ok_or(HttpError::AlreadyInUse)?;
|
||||||
|
@ -954,14 +963,9 @@ async fn op_http_write_resource(
|
||||||
let http_stream = state
|
let http_stream = state
|
||||||
.borrow()
|
.borrow()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<HttpStreamWriteResource>(rid)
|
.get::<HttpStreamWriteResource>(rid)?;
|
||||||
.map_err(HttpError::Resource)?;
|
|
||||||
let mut wr = RcRef::map(&http_stream, |r| &r.wr).borrow_mut().await;
|
let mut wr = RcRef::map(&http_stream, |r| &r.wr).borrow_mut().await;
|
||||||
let resource = state
|
let resource = state.borrow().resource_table.get_any(stream)?;
|
||||||
.borrow()
|
|
||||||
.resource_table
|
|
||||||
.get_any(stream)
|
|
||||||
.map_err(HttpError::Resource)?;
|
|
||||||
loop {
|
loop {
|
||||||
match *wr {
|
match *wr {
|
||||||
HttpResponseWriter::Headers(_) => {
|
HttpResponseWriter::Headers(_) => {
|
||||||
|
@ -973,11 +977,7 @@ async fn op_http_write_resource(
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
let view = resource
|
let view = resource.clone().read(64 * 1024).await?; // 64KB
|
||||||
.clone()
|
|
||||||
.read(64 * 1024)
|
|
||||||
.await
|
|
||||||
.map_err(HttpError::Other)?; // 64KB
|
|
||||||
if view.is_empty() {
|
if view.is_empty() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1022,8 +1022,7 @@ async fn op_http_write(
|
||||||
let stream = state
|
let stream = state
|
||||||
.borrow()
|
.borrow()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<HttpStreamWriteResource>(rid)
|
.get::<HttpStreamWriteResource>(rid)?;
|
||||||
.map_err(HttpError::Resource)?;
|
|
||||||
let mut wr = RcRef::map(&stream, |r| &r.wr).borrow_mut().await;
|
let mut wr = RcRef::map(&stream, |r| &r.wr).borrow_mut().await;
|
||||||
|
|
||||||
match &mut *wr {
|
match &mut *wr {
|
||||||
|
@ -1075,8 +1074,7 @@ async fn op_http_shutdown(
|
||||||
let stream = state
|
let stream = state
|
||||||
.borrow()
|
.borrow()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<HttpStreamWriteResource>(rid)
|
.get::<HttpStreamWriteResource>(rid)?;
|
||||||
.map_err(HttpError::Resource)?;
|
|
||||||
let mut wr = RcRef::map(&stream, |r| &r.wr).borrow_mut().await;
|
let mut wr = RcRef::map(&stream, |r| &r.wr).borrow_mut().await;
|
||||||
let wr = take(&mut *wr);
|
let wr = take(&mut *wr);
|
||||||
match wr {
|
match wr {
|
||||||
|
@ -1122,8 +1120,7 @@ async fn op_http_upgrade_websocket(
|
||||||
let stream = state
|
let stream = state
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<HttpStreamReadResource>(rid)
|
.get::<HttpStreamReadResource>(rid)?;
|
||||||
.map_err(HttpError::Resource)?;
|
|
||||||
let mut rd = RcRef::map(&stream, |r| &r.rd).borrow_mut().await;
|
let mut rd = RcRef::map(&stream, |r| &r.rd).borrow_mut().await;
|
||||||
|
|
||||||
let request = match &mut *rd {
|
let request = match &mut *rd {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue