mirror of
https://github.com/denoland/deno.git
synced 2025-03-08 04:07:41 -05:00
Merge remote-tracking branch 'upstream/main' into lsp-jupyter-cell-continuity
This commit is contained in:
commit
3f3fb886f3
490 changed files with 5263 additions and 6203 deletions
.github/workflows
Cargo.lockCargo.tomlcli
Cargo.toml
args
bench
cache
factory.rslsp
main.rsmodule_loader.rsnpm/managed/resolvers
resolver.rsschemas
standalone
tools
tsc
worker.rsext
console
fetch
ffi
fs
http
io
net
node
Cargo.toml
benchmarks
lib.rsops
polyfills
01_require.js_brotli.js
_fs
_process
_stream.mjs_util
console.tsconstants.tsinternal
internal_binding
path
string_decoder.tstimers.tsutil.tsv8.tsvm.jsworker_threads.tsweb
webgpu
webidl
websocket
webstorage
17
.github/workflows/ci.generate.ts
vendored
17
.github/workflows/ci.generate.ts
vendored
|
@ -649,7 +649,7 @@ const ci = {
|
|||
name: "test_format.js",
|
||||
if: "matrix.job == 'lint' && matrix.os == 'linux'",
|
||||
run:
|
||||
"deno run --unstable --allow-write --allow-read --allow-run --allow-net ./tools/format.js --check",
|
||||
"deno run --allow-write --allow-read --allow-run --allow-net ./tools/format.js --check",
|
||||
},
|
||||
{
|
||||
name: "Lint PR title",
|
||||
|
@ -664,7 +664,7 @@ const ci = {
|
|||
name: "lint.js",
|
||||
if: "matrix.job == 'lint'",
|
||||
run:
|
||||
"deno run --unstable --allow-write --allow-read --allow-run --allow-net ./tools/lint.js",
|
||||
"deno run --allow-write --allow-read --allow-run --allow-net ./tools/lint.js",
|
||||
},
|
||||
{
|
||||
name: "jsdoc_checker.js",
|
||||
|
@ -826,7 +826,7 @@ const ci = {
|
|||
"!startsWith(github.ref, 'refs/tags/')",
|
||||
].join("\n"),
|
||||
run:
|
||||
"target/release/deno run -A --unstable --config tests/config/deno.json ext/websocket/autobahn/fuzzingclient.js",
|
||||
"target/release/deno run -A --config tests/config/deno.json ext/websocket/autobahn/fuzzingclient.js",
|
||||
},
|
||||
{
|
||||
name: "Test (full, debug)",
|
||||
|
@ -879,9 +879,9 @@ const ci = {
|
|||
DENO_BIN: "./target/debug/deno",
|
||||
},
|
||||
run: [
|
||||
"deno run -A --unstable --lock=tools/deno.lock.json --config tests/config/deno.json\\",
|
||||
"deno run -A --lock=tools/deno.lock.json --config tests/config/deno.json\\",
|
||||
" ./tests/wpt/wpt.ts setup",
|
||||
"deno run -A --unstable --lock=tools/deno.lock.json --config tests/config/deno.json\\",
|
||||
"deno run -A --lock=tools/deno.lock.json --config tests/config/deno.json\\",
|
||||
' ./tests/wpt/wpt.ts run --quiet --binary="$DENO_BIN"',
|
||||
].join("\n"),
|
||||
},
|
||||
|
@ -892,9 +892,9 @@ const ci = {
|
|||
DENO_BIN: "./target/release/deno",
|
||||
},
|
||||
run: [
|
||||
"deno run -A --unstable --lock=tools/deno.lock.json --config tests/config/deno.json\\",
|
||||
"deno run -A --lock=tools/deno.lock.json --config tests/config/deno.json\\",
|
||||
" ./tests/wpt/wpt.ts setup",
|
||||
"deno run -A --unstable --lock=tools/deno.lock.json --config tests/config/deno.json\\",
|
||||
"deno run -A --lock=tools/deno.lock.json --config tests/config/deno.json\\",
|
||||
" ./tests/wpt/wpt.ts run --quiet --release \\",
|
||||
' --binary="$DENO_BIN" \\',
|
||||
" --json=wpt.json \\",
|
||||
|
@ -958,8 +958,7 @@ const ci = {
|
|||
"git clone --depth 1 --branch gh-pages \\",
|
||||
" https://${DENOBOT_PAT}@github.com/denoland/benchmark_data.git \\",
|
||||
" gh-pages",
|
||||
"./target/release/deno run --allow-all --unstable \\",
|
||||
" ./tools/build_benchmark_jsons.js --release",
|
||||
"./target/release/deno run --allow-all ./tools/build_benchmark_jsons.js --release",
|
||||
"cd gh-pages",
|
||||
'git config user.email "propelml@gmail.com"',
|
||||
'git config user.name "denobot"',
|
||||
|
|
17
.github/workflows/ci.yml
vendored
17
.github/workflows/ci.yml
vendored
|
@ -389,7 +389,7 @@ jobs:
|
|||
cache-path: ./target
|
||||
- name: test_format.js
|
||||
if: '!(matrix.skip) && (matrix.job == ''lint'' && matrix.os == ''linux'')'
|
||||
run: deno run --unstable --allow-write --allow-read --allow-run --allow-net ./tools/format.js --check
|
||||
run: deno run --allow-write --allow-read --allow-run --allow-net ./tools/format.js --check
|
||||
- name: Lint PR title
|
||||
if: '!(matrix.skip) && (matrix.job == ''lint'' && github.event_name == ''pull_request'' && matrix.os == ''linux'')'
|
||||
env:
|
||||
|
@ -397,7 +397,7 @@ jobs:
|
|||
run: deno run ./tools/verify_pr_title.js "$PR_TITLE"
|
||||
- name: lint.js
|
||||
if: '!(matrix.skip) && (matrix.job == ''lint'')'
|
||||
run: deno run --unstable --allow-write --allow-read --allow-run --allow-net ./tools/lint.js
|
||||
run: deno run --allow-write --allow-read --allow-run --allow-net ./tools/lint.js
|
||||
- name: jsdoc_checker.js
|
||||
if: '!(matrix.skip) && (matrix.job == ''lint'')'
|
||||
run: deno run --allow-read --allow-env --allow-sys ./tools/jsdoc_checker.js
|
||||
|
@ -494,7 +494,7 @@ jobs:
|
|||
matrix.job == 'test' &&
|
||||
matrix.profile == 'release' &&
|
||||
!startsWith(github.ref, 'refs/tags/'))
|
||||
run: target/release/deno run -A --unstable --config tests/config/deno.json ext/websocket/autobahn/fuzzingclient.js
|
||||
run: target/release/deno run -A --config tests/config/deno.json ext/websocket/autobahn/fuzzingclient.js
|
||||
- name: 'Test (full, debug)'
|
||||
if: |-
|
||||
!(matrix.skip) && (matrix.job == 'test' &&
|
||||
|
@ -531,18 +531,18 @@ jobs:
|
|||
env:
|
||||
DENO_BIN: ./target/debug/deno
|
||||
run: |-
|
||||
deno run -A --unstable --lock=tools/deno.lock.json --config tests/config/deno.json\
|
||||
deno run -A --lock=tools/deno.lock.json --config tests/config/deno.json\
|
||||
./tests/wpt/wpt.ts setup
|
||||
deno run -A --unstable --lock=tools/deno.lock.json --config tests/config/deno.json\
|
||||
deno run -A --lock=tools/deno.lock.json --config tests/config/deno.json\
|
||||
./tests/wpt/wpt.ts run --quiet --binary="$DENO_BIN"
|
||||
- name: Run web platform tests (release)
|
||||
if: '!(matrix.skip) && (matrix.wpt && matrix.profile == ''release'')'
|
||||
env:
|
||||
DENO_BIN: ./target/release/deno
|
||||
run: |-
|
||||
deno run -A --unstable --lock=tools/deno.lock.json --config tests/config/deno.json\
|
||||
deno run -A --lock=tools/deno.lock.json --config tests/config/deno.json\
|
||||
./tests/wpt/wpt.ts setup
|
||||
deno run -A --unstable --lock=tools/deno.lock.json --config tests/config/deno.json\
|
||||
deno run -A --lock=tools/deno.lock.json --config tests/config/deno.json\
|
||||
./tests/wpt/wpt.ts run --quiet --release \
|
||||
--binary="$DENO_BIN" \
|
||||
--json=wpt.json \
|
||||
|
@ -590,8 +590,7 @@ jobs:
|
|||
git clone --depth 1 --branch gh-pages \
|
||||
https://${DENOBOT_PAT}@github.com/denoland/benchmark_data.git \
|
||||
gh-pages
|
||||
./target/release/deno run --allow-all --unstable \
|
||||
./tools/build_benchmark_jsons.js --release
|
||||
./target/release/deno run --allow-all ./tools/build_benchmark_jsons.js --release
|
||||
cd gh-pages
|
||||
git config user.email "propelml@gmail.com"
|
||||
git config user.name "denobot"
|
||||
|
|
4
.github/workflows/wpt_epoch.yml
vendored
4
.github/workflows/wpt_epoch.yml
vendored
|
@ -66,9 +66,9 @@ jobs:
|
|||
- name: Run web platform tests
|
||||
shell: bash
|
||||
run: |
|
||||
deno run --unstable -A --lock=tools/deno.lock.json --config=tests/config/deno.json \
|
||||
deno run -A --lock=tools/deno.lock.json --config=tests/config/deno.json \
|
||||
./tests/wpt/wpt.ts setup
|
||||
deno run --unstable -A --lock=tools/deno.lock.json --config=tests/config/deno.json \
|
||||
deno run -A --lock=tools/deno.lock.json --config=tests/config/deno.json \
|
||||
./tests/wpt/wpt.ts run \ \
|
||||
--binary=$(which deno) --quiet --release --no-ignore --json=wpt.json --wptreport=wptreport.json --exit-zero
|
||||
|
||||
|
|
33
Cargo.lock
generated
33
Cargo.lock
generated
|
@ -1253,6 +1253,7 @@ dependencies = [
|
|||
"which 4.4.2",
|
||||
"winapi",
|
||||
"winres",
|
||||
"yoke",
|
||||
"zeromq",
|
||||
"zip",
|
||||
"zstd",
|
||||
|
@ -1374,9 +1375,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_config"
|
||||
version = "0.33.2"
|
||||
version = "0.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84d90b5eacfd6ee4ec978a11739c71eaeb19a575889f8c2b473430df84078fe2"
|
||||
checksum = "353595ebd9d19602f4cc0bb5613ae8bf036fb23ce1e6638eec594a63b1f8d48a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"deno_package_json",
|
||||
|
@ -1404,9 +1405,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_core"
|
||||
version = "0.307.0"
|
||||
version = "0.308.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "154b0902402807a043579102f949e6dd6f3a09d2d5049929fd710fc3192bf109"
|
||||
checksum = "62fc8250fa9da059cc05b18328319a9048c73e4889ca929cc60877a8a1bfc4d4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
|
@ -1700,9 +1701,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_lint"
|
||||
version = "0.64.0"
|
||||
version = "0.65.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b47f5f65369a3f188b5fa7c1263d9f96cdaa688e417b8852a3c8de0389e1c985"
|
||||
checksum = "90a58ed695d2a04c43ff6f5fb03d1597f86e3748861c872ea5a9443da7512fc7"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"deno_ast",
|
||||
|
@ -1886,9 +1887,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_ops"
|
||||
version = "0.183.0"
|
||||
version = "0.184.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9114f9eb6419839f1ab9668f91c463238945bb974e1998629a703f72b4608daf"
|
||||
checksum = "24a465b7d691ad7cae41e8f51bd954b1e3ffd201b84dc30de2c16cf91034946e"
|
||||
dependencies = [
|
||||
"proc-macro-rules",
|
||||
"proc-macro2",
|
||||
|
@ -4305,9 +4306,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "malva"
|
||||
version = "0.9.0"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e6e9f16e424a6672f6726daf965333952dece79ef3d17aac712b92b3b72d0a8"
|
||||
checksum = "484beda6e5d775ed06a8ec0fce79e51d39f49d834ed2a29da3f437079321804f"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"itertools 0.13.0",
|
||||
|
@ -5241,9 +5242,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pretty_yaml"
|
||||
version = "0.4.0"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22ba50511591c8e1d84125f7e2e6d17ccb06865c484b812f5ee3af61f42a66be"
|
||||
checksum = "dda9a64ee7296e82d1e0f4389383e6a7d8e6e2487d8391f7d028c131395fd376"
|
||||
dependencies = [
|
||||
"rowan",
|
||||
"tiny_pretty",
|
||||
|
@ -6256,9 +6257,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_v8"
|
||||
version = "0.216.0"
|
||||
version = "0.217.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1733b8192f123beedd2fc7998efeaf2a0b8bfa35c01537f50b690e786db8024c"
|
||||
checksum = "467c0a7bfc67cd918f1f7ab7a5ab70a9e744e466ff428cd728ff2c03bc77874c"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"serde",
|
||||
|
@ -7911,9 +7912,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "v8"
|
||||
version = "0.105.0"
|
||||
version = "0.106.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "692624c4fd58ff50aa6d690c159df18e7881c13970005b9b2bff77dc425fd370"
|
||||
checksum = "a381badc47c6f15acb5fe0b5b40234162349ed9d4e4fd7c83a7f5547c0fc69c5"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"bitflags 2.6.0",
|
||||
|
|
|
@ -45,7 +45,7 @@ repository = "https://github.com/denoland/deno"
|
|||
|
||||
[workspace.dependencies]
|
||||
deno_ast = { version = "=0.42.0", features = ["transpiling"] }
|
||||
deno_core = { version = "0.307.0" }
|
||||
deno_core = { version = "0.308.0" }
|
||||
|
||||
deno_bench_util = { version = "0.162.0", path = "./bench_util" }
|
||||
deno_lockfile = "=0.23.0"
|
||||
|
@ -193,6 +193,7 @@ url = { version = "< 2.5.0", features = ["serde", "expose_internals"] }
|
|||
uuid = { version = "1.3.0", features = ["v4"] }
|
||||
webpki-roots = "0.26"
|
||||
which = "4.2.5"
|
||||
yoke = { version = "0.7.4", features = ["derive"] }
|
||||
zeromq = { version = "=0.4.0", default-features = false, features = ["tcp-transport", "tokio-runtime"] }
|
||||
zstd = "=0.12.4"
|
||||
|
||||
|
|
|
@ -65,11 +65,11 @@ winres.workspace = true
|
|||
[dependencies]
|
||||
deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "proposal", "react", "sourcemap", "transforms", "typescript", "view", "visit"] }
|
||||
deno_cache_dir = { workspace = true }
|
||||
deno_config = { version = "=0.33.2", features = ["workspace", "sync"] }
|
||||
deno_config = { version = "=0.34.0", features = ["workspace", "sync"] }
|
||||
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
||||
deno_doc = { version = "0.148.0", features = ["html", "syntect"] }
|
||||
deno_graph = { version = "=0.82.1" }
|
||||
deno_lint = { version = "=0.64.0", features = ["docs"] }
|
||||
deno_lint = { version = "=0.65.0", features = ["docs"] }
|
||||
deno_lockfile.workspace = true
|
||||
deno_npm = "=0.25.0"
|
||||
deno_package_json.workspace = true
|
||||
|
@ -123,7 +123,7 @@ libc.workspace = true
|
|||
libz-sys.workspace = true
|
||||
log = { workspace = true, features = ["serde"] }
|
||||
lsp-types.workspace = true
|
||||
malva = "=0.9.0"
|
||||
malva = "=0.10.1"
|
||||
markup_fmt = "=0.12.0"
|
||||
memmem.workspace = true
|
||||
monch.workspace = true
|
||||
|
@ -134,7 +134,7 @@ p256.workspace = true
|
|||
pathdiff = "0.2.1"
|
||||
percent-encoding.workspace = true
|
||||
phf.workspace = true
|
||||
pretty_yaml = "=0.4.0"
|
||||
pretty_yaml = "=0.5.0"
|
||||
quick-junit = "^0.3.5"
|
||||
rand = { workspace = true, features = ["small_rng"] }
|
||||
regex.workspace = true
|
||||
|
@ -161,6 +161,7 @@ typed-arena = "=2.0.2"
|
|||
uuid = { workspace = true, features = ["serde"] }
|
||||
walkdir = "=2.3.2"
|
||||
which.workspace = true
|
||||
yoke.workspace = true
|
||||
zeromq.workspace = true
|
||||
zip = { version = "2.1.6", default-features = false, features = ["deflate-flate2"] }
|
||||
zstd.workspace = true
|
||||
|
|
|
@ -85,6 +85,7 @@ impl FileFlags {
|
|||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||
pub struct AddFlags {
|
||||
pub packages: Vec<String>,
|
||||
pub dev: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||
|
@ -569,6 +570,7 @@ fn parse_packages_allowed_scripts(s: &str) -> Result<String, AnyError> {
|
|||
Clone, Default, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize,
|
||||
)]
|
||||
pub struct UnstableConfig {
|
||||
// TODO(bartlomieju): remove in Deno 2.5
|
||||
pub legacy_flag_enabled: bool, // --unstable
|
||||
pub bare_node_builtins: bool, // --unstable-bare-node-builts
|
||||
pub sloppy_imports: bool,
|
||||
|
@ -1120,6 +1122,8 @@ impl Flags {
|
|||
|
||||
static ENV_VARIABLES_HELP: &str = cstr!(
|
||||
r#"<y>Environment variables:</>
|
||||
<y>Docs:</> <c>https://docs.deno.com/go/env-vars</>
|
||||
|
||||
<g>DENO_AUTH_TOKENS</> A semi-colon separated list of bearer tokens and hostnames
|
||||
to use when fetching remote modules from private repositories
|
||||
<p(245)>(e.g. "abcde12345@deno.land;54321edcba@github.com")</>
|
||||
|
@ -1585,6 +1589,15 @@ fn help_subcommand(app: &Command) -> Command {
|
|||
}))
|
||||
}
|
||||
|
||||
fn add_dev_arg() -> Arg {
|
||||
Arg::new("dev")
|
||||
.long("dev")
|
||||
.short('D')
|
||||
.help("Add as a dev dependency")
|
||||
.long_help("Add the package as a dev dependency. Note: This only applies when adding to a `package.json` file.")
|
||||
.action(ArgAction::SetTrue)
|
||||
}
|
||||
|
||||
fn add_subcommand() -> Command {
|
||||
command(
|
||||
"add",
|
||||
|
@ -1598,13 +1611,15 @@ You can add multiple dependencies at once:
|
|||
UnstableArgsConfig::None,
|
||||
)
|
||||
.defer(|cmd| {
|
||||
cmd.arg(
|
||||
Arg::new("packages")
|
||||
.help("List of packages to add")
|
||||
.required_unless_present("help")
|
||||
.num_args(1..)
|
||||
.action(ArgAction::Append),
|
||||
)
|
||||
cmd
|
||||
.arg(
|
||||
Arg::new("packages")
|
||||
.help("List of packages to add")
|
||||
.required_unless_present("help")
|
||||
.num_args(1..)
|
||||
.action(ArgAction::Append),
|
||||
)
|
||||
.arg(add_dev_arg())
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2453,6 +2468,7 @@ These must be added to the path manually if required."), UnstableArgsConfig::Res
|
|||
.help("Install dependents of the specified entrypoint(s)"),
|
||||
)
|
||||
.arg(env_file_arg())
|
||||
.arg(add_dev_arg().conflicts_with("entrypoint").conflicts_with("global"))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2461,7 +2477,7 @@ fn json_reference_subcommand() -> Command {
|
|||
}
|
||||
|
||||
fn jupyter_subcommand() -> Command {
|
||||
Command::new("jupyter")
|
||||
command("jupyter", "Deno kernel for Jupyter notebooks", UnstableArgsConfig::ResolutionAndRuntime)
|
||||
.arg(
|
||||
Arg::new("install")
|
||||
.long("install")
|
||||
|
@ -2484,7 +2500,6 @@ fn jupyter_subcommand() -> Command {
|
|||
.value_parser(value_parser!(String))
|
||||
.value_hint(ValueHint::FilePath)
|
||||
.conflicts_with("install"))
|
||||
.about("Deno kernel for Jupyter notebooks")
|
||||
}
|
||||
|
||||
fn uninstall_subcommand() -> Command {
|
||||
|
@ -2971,12 +2986,8 @@ The declaration file could be saved and used for typing information.",
|
|||
)
|
||||
}
|
||||
|
||||
fn upgrade_subcommand() -> Command {
|
||||
command(
|
||||
"upgrade",
|
||||
cstr!("Upgrade deno executable to the given version.
|
||||
|
||||
<g>Latest</>
|
||||
pub static UPGRADE_USAGE: &str = cstr!(
|
||||
"<g>Latest</>
|
||||
<bold>deno upgrade</>
|
||||
|
||||
<g>Specific version</>
|
||||
|
@ -2987,7 +2998,15 @@ fn upgrade_subcommand() -> Command {
|
|||
<g>Channel</>
|
||||
<bold>deno upgrade</> <p(245)>stable</>
|
||||
<bold>deno upgrade</> <p(245)>rc</>
|
||||
<bold>deno upgrade</> <p(245)>canary</>
|
||||
<bold>deno upgrade</> <p(245)>canary</>"
|
||||
);
|
||||
|
||||
fn upgrade_subcommand() -> Command {
|
||||
command(
|
||||
"upgrade",
|
||||
color_print::cformat!("Upgrade deno executable to the given version.
|
||||
|
||||
{}
|
||||
|
||||
The version is downloaded from <p(245)>https://dl.deno.land</> and is used to replace the current executable.
|
||||
|
||||
|
@ -2995,7 +3014,7 @@ If you want to not replace the current Deno executable but instead download an u
|
|||
different location, use the <c>--output</> flag:
|
||||
<p(245)>deno upgrade --output $HOME/my_deno</>
|
||||
|
||||
<y>Read more:</> <c>https://docs.deno.com/go/cmd/upgrade</>"),
|
||||
<y>Read more:</> <c>https://docs.deno.com/go/cmd/upgrade</>", UPGRADE_USAGE),
|
||||
UnstableArgsConfig::None,
|
||||
)
|
||||
.hide(cfg!(not(feature = "upgrade")))
|
||||
|
@ -3139,7 +3158,7 @@ fn compile_args_without_check_args(app: Command) -> Command {
|
|||
fn permission_args(app: Command, requires: Option<&'static str>) -> Command {
|
||||
app
|
||||
.after_help(cstr!(r#"<y>Permission options:</>
|
||||
Docs: <c>https://docs.deno.com/go/permissions</>
|
||||
<y>Docs</>: <c>https://docs.deno.com/go/permissions</>
|
||||
|
||||
<g>-A, --allow-all</> Allow all permissions.
|
||||
<g>--no-prompt</> Always throw if required permission wasn't passed.
|
||||
|
@ -4092,7 +4111,8 @@ fn add_parse_inner(
|
|||
let packages = packages
|
||||
.unwrap_or_else(|| matches.remove_many::<String>("packages").unwrap())
|
||||
.collect();
|
||||
AddFlags { packages }
|
||||
let dev = matches.get_flag("dev");
|
||||
AddFlags { packages, dev }
|
||||
}
|
||||
|
||||
fn remove_parse(flags: &mut Flags, matches: &mut ArgMatches) {
|
||||
|
@ -4584,6 +4604,8 @@ fn json_reference_parse(
|
|||
}
|
||||
|
||||
fn jupyter_parse(flags: &mut Flags, matches: &mut ArgMatches) {
|
||||
unstable_args_parse(flags, matches, UnstableArgsConfig::ResolutionAndRuntime);
|
||||
|
||||
let conn_file = matches.remove_one::<String>("conn");
|
||||
let kernel = matches.get_flag("kernel");
|
||||
let install = matches.get_flag("install");
|
||||
|
@ -5461,6 +5483,7 @@ fn unstable_args_parse(
|
|||
matches: &mut ArgMatches,
|
||||
cfg: UnstableArgsConfig,
|
||||
) {
|
||||
// TODO(bartlomieju): remove in Deno 2.5
|
||||
if matches.get_flag("unstable") {
|
||||
flags.unstable_config.legacy_flag_enabled = true;
|
||||
}
|
||||
|
@ -8750,7 +8773,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_with_flags() {
|
||||
#[rustfmt::skip]
|
||||
let r = flags_from_vec(svec!["deno", "test", "--unstable", "--no-npm", "--no-remote", "--trace-leaks", "--no-run", "--filter", "- foo", "--coverage=cov", "--clean", "--location", "https:foo", "--allow-net", "--permit-no-files", "dir1/", "dir2/", "--", "arg1", "arg2"]);
|
||||
let r = flags_from_vec(svec!["deno", "test", "--no-npm", "--no-remote", "--trace-leaks", "--no-run", "--filter", "- foo", "--coverage=cov", "--clean", "--location", "https:foo", "--allow-net", "--permit-no-files", "dir1/", "dir2/", "--", "arg1", "arg2"]);
|
||||
assert_eq!(
|
||||
r.unwrap(),
|
||||
Flags {
|
||||
|
@ -8774,10 +8797,6 @@ mod tests {
|
|||
junit_path: None,
|
||||
hide_stacktraces: false,
|
||||
}),
|
||||
unstable_config: UnstableConfig {
|
||||
legacy_flag_enabled: true,
|
||||
..Default::default()
|
||||
},
|
||||
no_npm: true,
|
||||
no_remote: true,
|
||||
location: Some(Url::parse("https://foo/").unwrap()),
|
||||
|
@ -10185,7 +10204,6 @@ mod tests {
|
|||
"deno",
|
||||
"bench",
|
||||
"--json",
|
||||
"--unstable",
|
||||
"--no-npm",
|
||||
"--no-remote",
|
||||
"--no-run",
|
||||
|
@ -10213,10 +10231,6 @@ mod tests {
|
|||
},
|
||||
watch: Default::default(),
|
||||
}),
|
||||
unstable_config: UnstableConfig {
|
||||
legacy_flag_enabled: true,
|
||||
..Default::default()
|
||||
},
|
||||
no_npm: true,
|
||||
no_remote: true,
|
||||
type_check_mode: TypeCheckMode::Local,
|
||||
|
@ -10508,31 +10522,53 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn add_subcommand() {
|
||||
fn add_or_install_subcommand() {
|
||||
let r = flags_from_vec(svec!["deno", "add"]);
|
||||
r.unwrap_err();
|
||||
for cmd in ["add", "install"] {
|
||||
let mk_flags = |flags: AddFlags| -> Flags {
|
||||
match cmd {
|
||||
"add" => Flags {
|
||||
subcommand: DenoSubcommand::Add(flags),
|
||||
..Flags::default()
|
||||
},
|
||||
"install" => Flags {
|
||||
subcommand: DenoSubcommand::Install(InstallFlags {
|
||||
kind: InstallKind::Local(InstallFlagsLocal::Add(flags)),
|
||||
}),
|
||||
..Flags::default()
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
};
|
||||
|
||||
let r = flags_from_vec(svec!["deno", "add", "@david/which"]);
|
||||
assert_eq!(
|
||||
r.unwrap(),
|
||||
Flags {
|
||||
subcommand: DenoSubcommand::Add(AddFlags {
|
||||
let r = flags_from_vec(svec!["deno", cmd, "@david/which"]);
|
||||
assert_eq!(
|
||||
r.unwrap(),
|
||||
mk_flags(AddFlags {
|
||||
packages: svec!["@david/which"],
|
||||
}),
|
||||
..Flags::default()
|
||||
}
|
||||
);
|
||||
dev: false,
|
||||
}) // default is false
|
||||
);
|
||||
|
||||
let r = flags_from_vec(svec!["deno", "add", "@david/which", "@luca/hello"]);
|
||||
assert_eq!(
|
||||
r.unwrap(),
|
||||
Flags {
|
||||
subcommand: DenoSubcommand::Add(AddFlags {
|
||||
let r = flags_from_vec(svec!["deno", cmd, "@david/which", "@luca/hello"]);
|
||||
assert_eq!(
|
||||
r.unwrap(),
|
||||
mk_flags(AddFlags {
|
||||
packages: svec!["@david/which", "@luca/hello"],
|
||||
dev: false,
|
||||
})
|
||||
);
|
||||
|
||||
let r = flags_from_vec(svec!["deno", cmd, "--dev", "npm:chalk"]);
|
||||
assert_eq!(
|
||||
r.unwrap(),
|
||||
mk_flags(AddFlags {
|
||||
packages: svec!["npm:chalk"],
|
||||
dev: true,
|
||||
}),
|
||||
..Flags::default()
|
||||
}
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -10746,6 +10782,35 @@ mod tests {
|
|||
.contains("Note: Permission flags can only be used in a global setting"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn jupyter_unstable_flags() {
|
||||
let r = flags_from_vec(svec![
|
||||
"deno",
|
||||
"jupyter",
|
||||
"--unstable-ffi",
|
||||
"--unstable-bare-node-builtins",
|
||||
"--unstable-worker-options"
|
||||
]);
|
||||
|
||||
assert_eq!(
|
||||
r.unwrap(),
|
||||
Flags {
|
||||
subcommand: DenoSubcommand::Jupyter(JupyterFlags {
|
||||
install: false,
|
||||
kernel: false,
|
||||
conn_file: None,
|
||||
}),
|
||||
unstable_config: UnstableConfig {
|
||||
bare_node_builtins: true,
|
||||
sloppy_imports: false,
|
||||
features: svec!["ffi", "worker-options"],
|
||||
..Default::default()
|
||||
},
|
||||
..Flags::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn escape_and_split_commas_test() {
|
||||
assert_eq!(escape_and_split_commas("foo".to_string()).unwrap(), ["foo"]);
|
||||
|
|
|
@ -50,7 +50,7 @@ pub fn parse(paths: Vec<String>) -> clap::error::Result<Vec<String>> {
|
|||
out.push(format!("{}:{}", host, port.0));
|
||||
}
|
||||
} else {
|
||||
host_and_port.parse::<NetDescriptor>().map_err(|e| {
|
||||
NetDescriptor::parse(&host_and_port).map_err(|e| {
|
||||
clap::Error::raw(clap::error::ErrorKind::InvalidValue, format!("{e:?}"))
|
||||
})?;
|
||||
out.push(host_and_port)
|
||||
|
|
|
@ -1548,10 +1548,6 @@ impl CliOptions {
|
|||
&self.flags.unsafely_ignore_certificate_errors
|
||||
}
|
||||
|
||||
pub fn legacy_unstable_flag(&self) -> bool {
|
||||
self.flags.unstable_config.legacy_flag_enabled
|
||||
}
|
||||
|
||||
pub fn unstable_bare_node_builtins(&self) -> bool {
|
||||
self.flags.unstable_config.bare_node_builtins
|
||||
|| self.workspace().has_unstable("bare-node-builtins")
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -10,18 +9,16 @@ use deno_package_json::PackageJsonDepValue;
|
|||
use deno_semver::npm::NpmPackageReqReference;
|
||||
use deno_semver::package::PackageReq;
|
||||
|
||||
use crate::util::path::is_banned_path_char;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InstallNpmRemotePkg {
|
||||
pub alias: String,
|
||||
pub alias: Option<String>,
|
||||
pub base_dir: PathBuf,
|
||||
pub req: PackageReq,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InstallNpmWorkspacePkg {
|
||||
pub alias: String,
|
||||
pub alias: Option<String>,
|
||||
pub target_dir: PathBuf,
|
||||
}
|
||||
|
||||
|
@ -43,16 +40,13 @@ impl NpmInstallDepsProvider {
|
|||
let workspace_npm_pkgs = workspace.npm_packages();
|
||||
|
||||
for (_, folder) in workspace.config_folders() {
|
||||
let mut deno_json_aliases = HashSet::new();
|
||||
|
||||
// deal with the deno.json first because it takes precedence during resolution
|
||||
if let Some(deno_json) = &folder.deno_json {
|
||||
// don't bother with externally referenced import maps as users
|
||||
// should inline their import map to get this behaviour
|
||||
if let Some(serde_json::Value::Object(obj)) = &deno_json.json.imports {
|
||||
deno_json_aliases.reserve(obj.len());
|
||||
let mut pkg_pkgs = Vec::with_capacity(obj.len());
|
||||
for (alias, value) in obj {
|
||||
for (_alias, value) in obj {
|
||||
let serde_json::Value::String(specifier) = value else {
|
||||
continue;
|
||||
};
|
||||
|
@ -60,11 +54,6 @@ impl NpmInstallDepsProvider {
|
|||
else {
|
||||
continue;
|
||||
};
|
||||
// skip any aliases with banned characters
|
||||
if alias.chars().any(|c| c == '\\' || is_banned_path_char(c)) {
|
||||
continue;
|
||||
}
|
||||
deno_json_aliases.insert(alias.to_lowercase());
|
||||
let pkg_req = npm_req_ref.into_inner().req;
|
||||
let workspace_pkg = workspace_npm_pkgs
|
||||
.iter()
|
||||
|
@ -72,12 +61,12 @@ impl NpmInstallDepsProvider {
|
|||
|
||||
if let Some(pkg) = workspace_pkg {
|
||||
workspace_pkgs.push(InstallNpmWorkspacePkg {
|
||||
alias: alias.to_string(),
|
||||
alias: None,
|
||||
target_dir: pkg.pkg_json.dir_path().to_path_buf(),
|
||||
});
|
||||
} else {
|
||||
pkg_pkgs.push(InstallNpmRemotePkg {
|
||||
alias: alias.to_string(),
|
||||
alias: None,
|
||||
base_dir: deno_json.dir_path(),
|
||||
req: pkg_req,
|
||||
});
|
||||
|
@ -85,7 +74,7 @@ impl NpmInstallDepsProvider {
|
|||
}
|
||||
|
||||
// sort within each package (more like npm resolution)
|
||||
pkg_pkgs.sort_by(|a, b| a.alias.cmp(&b.alias));
|
||||
pkg_pkgs.sort_by(|a, b| a.req.cmp(&b.req));
|
||||
remote_pkgs.extend(pkg_pkgs);
|
||||
}
|
||||
}
|
||||
|
@ -97,11 +86,6 @@ impl NpmInstallDepsProvider {
|
|||
let Ok(dep) = dep else {
|
||||
continue;
|
||||
};
|
||||
if deno_json_aliases.contains(&alias.to_lowercase()) {
|
||||
// aliases in deno.json take precedence over package.json, so
|
||||
// since this can't be resolved don't bother installing it
|
||||
continue;
|
||||
}
|
||||
match dep {
|
||||
PackageJsonDepValue::Req(pkg_req) => {
|
||||
let workspace_pkg = workspace_npm_pkgs.iter().find(|pkg| {
|
||||
|
@ -112,12 +96,12 @@ impl NpmInstallDepsProvider {
|
|||
|
||||
if let Some(pkg) = workspace_pkg {
|
||||
workspace_pkgs.push(InstallNpmWorkspacePkg {
|
||||
alias,
|
||||
alias: Some(alias),
|
||||
target_dir: pkg.pkg_json.dir_path().to_path_buf(),
|
||||
});
|
||||
} else {
|
||||
pkg_pkgs.push(InstallNpmRemotePkg {
|
||||
alias,
|
||||
alias: Some(alias),
|
||||
base_dir: pkg_json.dir_path().to_path_buf(),
|
||||
req: pkg_req,
|
||||
});
|
||||
|
@ -128,7 +112,7 @@ impl NpmInstallDepsProvider {
|
|||
pkg.matches_name_and_version_req(&alias, &version_req)
|
||||
}) {
|
||||
workspace_pkgs.push(InstallNpmWorkspacePkg {
|
||||
alias,
|
||||
alias: Some(alias),
|
||||
target_dir: pkg.pkg_json.dir_path().to_path_buf(),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ pub fn benchmark(
|
|||
}
|
||||
|
||||
let port = get_port();
|
||||
// deno run -A --unstable <path> <addr>
|
||||
// deno run -A --unstable-net <path> <addr>
|
||||
res.insert(
|
||||
file_stem.to_string(),
|
||||
run(
|
||||
|
@ -57,7 +57,7 @@ pub fn benchmark(
|
|||
deno_exe.as_str(),
|
||||
"run",
|
||||
"--allow-all",
|
||||
"--unstable",
|
||||
"--unstable-net",
|
||||
"--enable-testing-features-do-not-use",
|
||||
path,
|
||||
&server_addr(port),
|
||||
|
|
13
cli/cache/code_cache.rs
vendored
13
cli/cache/code_cache.rs
vendored
|
@ -80,10 +80,6 @@ impl CodeCache {
|
|||
data,
|
||||
));
|
||||
}
|
||||
|
||||
pub fn remove_code_cache(&self, specifier: &str) {
|
||||
Self::ensure_ok(self.inner.remove_code_cache(specifier))
|
||||
}
|
||||
}
|
||||
|
||||
impl code_cache::CodeCache for CodeCache {
|
||||
|
@ -162,15 +158,6 @@ impl CodeCacheInner {
|
|||
self.conn.execute(sql, params)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn remove_code_cache(&self, specifier: &str) -> Result<(), AnyError> {
|
||||
let sql = "
|
||||
DELETE FROM codecache
|
||||
WHERE specifier=$1;";
|
||||
let params = params![specifier];
|
||||
self.conn.execute(sql, params)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn serialize_code_cache_type(
|
||||
|
|
|
@ -714,10 +714,6 @@ impl CliFactory {
|
|||
let mut checker = FeatureChecker::default();
|
||||
checker.set_exit_cb(Box::new(crate::unstable_exit_cb));
|
||||
checker.set_warn_cb(Box::new(crate::unstable_warn_cb));
|
||||
if cli_options.legacy_unstable_flag() {
|
||||
checker.enable_legacy_unstable();
|
||||
checker.warn_on_legacy_unstable();
|
||||
}
|
||||
let unstable_features = cli_options.unstable_features();
|
||||
for granular_flag in crate::UNSTABLE_GRANULAR_FLAGS {
|
||||
if unstable_features.contains(&granular_flag.name.to_string()) {
|
||||
|
@ -856,7 +852,6 @@ impl CliFactory {
|
|||
unsafely_ignore_certificate_errors: cli_options
|
||||
.unsafely_ignore_certificate_errors()
|
||||
.clone(),
|
||||
unstable: cli_options.legacy_unstable_flag(),
|
||||
create_hmr_runner,
|
||||
create_coverage_collector,
|
||||
node_ipc: cli_options.node_ipc_fd(),
|
||||
|
|
|
@ -43,6 +43,8 @@ use indexmap::IndexSet;
|
|||
use lsp_types::ClientCapabilities;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Deref;
|
||||
use std::ops::DerefMut;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
@ -70,6 +72,54 @@ fn is_true() -> bool {
|
|||
true
|
||||
}
|
||||
|
||||
/// Wrapper that defaults if it fails to deserialize. Good for individual
|
||||
/// settings.
|
||||
#[derive(Debug, Default, Clone, Eq, PartialEq)]
|
||||
pub struct SafeValue<T> {
|
||||
inner: T,
|
||||
}
|
||||
|
||||
impl<'de, T: Default + for<'de2> Deserialize<'de2>> Deserialize<'de>
|
||||
for SafeValue<T>
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
Ok(Self {
|
||||
inner: Deserialize::deserialize(deserializer).unwrap_or_default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Serialize> Serialize for SafeValue<T> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
self.inner.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for SafeValue<T> {
|
||||
type Target = T;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DerefMut for SafeValue<T> {
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
&mut self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> SafeValue<T> {
|
||||
pub fn as_deref(&self) -> &T {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CodeLensSettings {
|
||||
|
@ -538,7 +588,7 @@ pub struct WorkspaceSettings {
|
|||
pub unsafely_ignore_certificate_errors: Option<Vec<String>>,
|
||||
|
||||
#[serde(default)]
|
||||
pub unstable: bool,
|
||||
pub unstable: SafeValue<Vec<String>>,
|
||||
|
||||
#[serde(default)]
|
||||
pub javascript: LanguageWorkspaceSettings,
|
||||
|
@ -568,7 +618,7 @@ impl Default for WorkspaceSettings {
|
|||
testing: Default::default(),
|
||||
tls_certificate: None,
|
||||
unsafely_ignore_certificate_errors: None,
|
||||
unstable: false,
|
||||
unstable: Default::default(),
|
||||
javascript: Default::default(),
|
||||
typescript: Default::default(),
|
||||
}
|
||||
|
@ -1084,7 +1134,6 @@ impl Default for LspTsConfig {
|
|||
"strict": true,
|
||||
"target": "esnext",
|
||||
"useDefineForClassFields": true,
|
||||
"useUnknownInCatchVariables": false,
|
||||
"jsx": "react",
|
||||
"jsxFactory": "React.createElement",
|
||||
"jsxFragmentFactory": "React.Fragment",
|
||||
|
@ -2142,7 +2191,7 @@ mod tests {
|
|||
},
|
||||
tls_certificate: None,
|
||||
unsafely_ignore_certificate_errors: None,
|
||||
unstable: false,
|
||||
unstable: Default::default(),
|
||||
javascript: LanguageWorkspaceSettings {
|
||||
inlay_hints: InlayHintsSettings {
|
||||
parameter_names: InlayHintsParamNamesOptions {
|
||||
|
|
|
@ -12,6 +12,7 @@ use super::language_server::StateSnapshot;
|
|||
use super::performance::Performance;
|
||||
use super::tsc;
|
||||
use super::tsc::TsServer;
|
||||
use super::urls::uri_parse_unencoded;
|
||||
use super::urls::url_to_uri;
|
||||
use super::urls::LspUrlMap;
|
||||
|
||||
|
@ -53,11 +54,9 @@ use deno_semver::package::PackageReq;
|
|||
use import_map::ImportMap;
|
||||
use import_map::ImportMapError;
|
||||
use log::error;
|
||||
use lsp_types::Uri;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
|
@ -738,7 +737,7 @@ fn to_lsp_related_information(
|
|||
if let (Some(file_name), Some(start), Some(end)) =
|
||||
(&ri.file_name, &ri.start, &ri.end)
|
||||
{
|
||||
let uri = Uri::from_str(file_name).unwrap();
|
||||
let uri = uri_parse_unencoded(file_name).unwrap();
|
||||
Some(lsp::DiagnosticRelatedInformation {
|
||||
location: lsp::Location {
|
||||
uri,
|
||||
|
|
|
@ -4042,7 +4042,11 @@ impl Inner {
|
|||
|
||||
</details>
|
||||
"#,
|
||||
serde_json::to_string_pretty(&workspace_settings).unwrap(),
|
||||
serde_json::to_string_pretty(&workspace_settings)
|
||||
.inspect_err(|e| {
|
||||
dbg!(e);
|
||||
})
|
||||
.unwrap(),
|
||||
documents_specifiers.len(),
|
||||
documents_specifiers
|
||||
.into_iter()
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::str::FromStr;
|
||||
|
||||
use deno_ast::LineAndColumnIndex;
|
||||
use deno_ast::ModuleSpecifier;
|
||||
|
@ -42,6 +41,7 @@ use super::config::LanguageWorkspaceSettings;
|
|||
use super::config::ObjectLiteralMethodSnippets;
|
||||
use super::config::TestingSettings;
|
||||
use super::config::WorkspaceSettings;
|
||||
use super::urls::uri_parse_unencoded;
|
||||
use super::urls::url_to_uri;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -263,7 +263,8 @@ impl ReplLanguageServer {
|
|||
}
|
||||
|
||||
fn get_document_uri(&self) -> Uri {
|
||||
Uri::from_str(self.cwd_uri.join("$deno$repl.ts").unwrap().as_str()).unwrap()
|
||||
uri_parse_unencoded(self.cwd_uri.join("$deno$repl.ts").unwrap().as_str())
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,7 +312,7 @@ pub fn get_repl_workspace_settings() -> WorkspaceSettings {
|
|||
document_preload_limit: 0, // don't pre-load any modules as it's expensive and not useful for the repl
|
||||
tls_certificate: None,
|
||||
unsafely_ignore_certificate_errors: None,
|
||||
unstable: false,
|
||||
unstable: Default::default(),
|
||||
suggest: DenoCompletionSettings {
|
||||
imports: ImportCompletionSettings {
|
||||
auto_discover: false,
|
||||
|
|
|
@ -12,6 +12,7 @@ use crate::lsp::client::Client;
|
|||
use crate::lsp::client::TestingNotification;
|
||||
use crate::lsp::config;
|
||||
use crate::lsp::logging::lsp_log;
|
||||
use crate::lsp::urls::uri_parse_unencoded;
|
||||
use crate::lsp::urls::uri_to_url;
|
||||
use crate::lsp::urls::url_to_uri;
|
||||
use crate::tools::test;
|
||||
|
@ -32,11 +33,10 @@ use deno_core::ModuleSpecifier;
|
|||
use deno_runtime::deno_permissions::Permissions;
|
||||
use deno_runtime::tokio_util::create_and_run_current_thread;
|
||||
use indexmap::IndexMap;
|
||||
use lsp_types::Uri;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::num::NonZeroUsize;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use std::time::Instant;
|
||||
|
@ -219,8 +219,9 @@ impl TestRun {
|
|||
) -> Result<(), AnyError> {
|
||||
let args = self.get_args();
|
||||
lsp_log!("Executing test run with arguments: {}", args.join(" "));
|
||||
let flags =
|
||||
Arc::new(flags_from_vec(args.into_iter().map(From::from).collect())?);
|
||||
let flags = Arc::new(flags_from_vec(
|
||||
args.into_iter().map(|s| From::from(s.as_ref())).collect(),
|
||||
)?);
|
||||
let factory = CliFactory::from_flags(flags);
|
||||
let cli_options = factory.cli_options()?;
|
||||
// Various test files should not share the same permissions in terms of
|
||||
|
@ -452,37 +453,42 @@ impl TestRun {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn get_args(&self) -> Vec<&str> {
|
||||
let mut args = vec!["deno", "test"];
|
||||
fn get_args(&self) -> Vec<Cow<str>> {
|
||||
let mut args = vec![Cow::Borrowed("deno"), Cow::Borrowed("test")];
|
||||
args.extend(
|
||||
self
|
||||
.workspace_settings
|
||||
.testing
|
||||
.args
|
||||
.iter()
|
||||
.map(|s| s.as_str()),
|
||||
.map(|s| Cow::Borrowed(s.as_str())),
|
||||
);
|
||||
args.push("--trace-leaks");
|
||||
if self.workspace_settings.unstable && !args.contains(&"--unstable") {
|
||||
args.push("--unstable");
|
||||
args.push(Cow::Borrowed("--trace-leaks"));
|
||||
for unstable_feature in self.workspace_settings.unstable.as_deref() {
|
||||
let flag = format!("--unstable-{unstable_feature}");
|
||||
if !args.contains(&Cow::Borrowed(&flag)) {
|
||||
args.push(Cow::Owned(flag));
|
||||
}
|
||||
}
|
||||
if let Some(config) = &self.workspace_settings.config {
|
||||
if !args.contains(&"--config") && !args.contains(&"-c") {
|
||||
args.push("--config");
|
||||
args.push(config.as_str());
|
||||
if !args.contains(&Cow::Borrowed("--config"))
|
||||
&& !args.contains(&Cow::Borrowed("-c"))
|
||||
{
|
||||
args.push(Cow::Borrowed("--config"));
|
||||
args.push(Cow::Borrowed(config.as_str()));
|
||||
}
|
||||
}
|
||||
if let Some(import_map) = &self.workspace_settings.import_map {
|
||||
if !args.contains(&"--import-map") {
|
||||
args.push("--import-map");
|
||||
args.push(import_map.as_str());
|
||||
if !args.contains(&Cow::Borrowed("--import-map")) {
|
||||
args.push(Cow::Borrowed("--import-map"));
|
||||
args.push(Cow::Borrowed(import_map.as_str()));
|
||||
}
|
||||
}
|
||||
if self.kind == lsp_custom::TestRunKind::Debug
|
||||
&& !args.contains(&"--inspect")
|
||||
&& !args.contains(&"--inspect-brk")
|
||||
&& !args.contains(&Cow::Borrowed("--inspect"))
|
||||
&& !args.contains(&Cow::Borrowed("--inspect-brk"))
|
||||
{
|
||||
args.push("--inspect");
|
||||
args.push(Cow::Borrowed("--inspect"));
|
||||
}
|
||||
args
|
||||
}
|
||||
|
@ -529,7 +535,7 @@ impl LspTestDescription {
|
|||
&self,
|
||||
tests: &IndexMap<usize, LspTestDescription>,
|
||||
) -> lsp_custom::TestIdentifier {
|
||||
let uri = Uri::from_str(&self.location().file_name).unwrap();
|
||||
let uri = uri_parse_unencoded(&self.location().file_name).unwrap();
|
||||
let static_id = self.static_id();
|
||||
let mut root_desc = self;
|
||||
while let Some(parent_id) = root_desc.parent_id() {
|
||||
|
|
|
@ -61,6 +61,25 @@ const COMPONENT: &percent_encoding::AsciiSet = &percent_encoding::CONTROLS
|
|||
.add(b'+')
|
||||
.add(b',');
|
||||
|
||||
/// Characters that may be left unencoded in a `Url` path but not valid in a
|
||||
/// `Uri` path.
|
||||
const URL_TO_URI_PATH: &percent_encoding::AsciiSet =
|
||||
&percent_encoding::CONTROLS
|
||||
.add(b'[')
|
||||
.add(b']')
|
||||
.add(b'^')
|
||||
.add(b'|');
|
||||
|
||||
/// Characters that may be left unencoded in a `Url` query but not valid in a
|
||||
/// `Uri` query.
|
||||
const URL_TO_URI_QUERY: &percent_encoding::AsciiSet =
|
||||
&URL_TO_URI_PATH.add(b'\\').add(b'`').add(b'{').add(b'}');
|
||||
|
||||
/// Characters that may be left unencoded in a `Url` fragment but not valid in
|
||||
/// a `Uri` fragment.
|
||||
const URL_TO_URI_FRAGMENT: &percent_encoding::AsciiSet =
|
||||
&URL_TO_URI_PATH.add(b'#').add(b'\\').add(b'{').add(b'}');
|
||||
|
||||
fn hash_data_specifier(specifier: &ModuleSpecifier) -> String {
|
||||
let mut file_name_str = specifier.path().to_string();
|
||||
if let Some(query) = specifier.query() {
|
||||
|
@ -259,8 +278,33 @@ impl LspUrlMapInner {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn uri_parse_unencoded(s: &str) -> Result<Uri, AnyError> {
|
||||
url_to_uri(&Url::parse(s)?)
|
||||
}
|
||||
|
||||
pub fn url_to_uri(url: &Url) -> Result<Uri, AnyError> {
|
||||
Ok(Uri::from_str(url.as_str()).inspect_err(|err| {
|
||||
let components = deno_core::url::quirks::internal_components(url);
|
||||
let mut input = String::with_capacity(url.as_str().len());
|
||||
input.push_str(&url.as_str()[..components.path_start as usize]);
|
||||
input.push_str(
|
||||
&percent_encoding::utf8_percent_encode(url.path(), URL_TO_URI_PATH)
|
||||
.to_string(),
|
||||
);
|
||||
if let Some(query) = url.query() {
|
||||
input.push('?');
|
||||
input.push_str(
|
||||
&percent_encoding::utf8_percent_encode(query, URL_TO_URI_QUERY)
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
if let Some(fragment) = url.fragment() {
|
||||
input.push('#');
|
||||
input.push_str(
|
||||
&percent_encoding::utf8_percent_encode(fragment, URL_TO_URI_FRAGMENT)
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
Ok(Uri::from_str(&input).inspect_err(|err| {
|
||||
lsp_warn!("Could not convert URL \"{url}\" to URI: {err}")
|
||||
})?)
|
||||
}
|
||||
|
@ -373,7 +417,7 @@ impl LspUrlMap {
|
|||
} else {
|
||||
to_deno_uri(specifier)
|
||||
};
|
||||
let uri = Uri::from_str(&uri_str)?;
|
||||
let uri = uri_parse_unencoded(&uri_str)?;
|
||||
inner.put(specifier.clone(), uri.clone());
|
||||
uri
|
||||
};
|
||||
|
|
93
cli/main.rs
93
cli/main.rs
|
@ -337,17 +337,61 @@ fn exit_with_message(message: &str, code: i32) -> ! {
|
|||
std::process::exit(code);
|
||||
}
|
||||
|
||||
fn get_suggestions_for_commonjs_error(e: &JsError) -> Vec<FixSuggestion> {
|
||||
if e.name.as_deref() == Some("ReferenceError") {
|
||||
if let Some(msg) = &e.message {
|
||||
if msg.contains("module is not defined")
|
||||
|| msg.contains("exports is not defined")
|
||||
{
|
||||
return vec![
|
||||
FixSuggestion::info("Deno does not support CommonJS modules without `.cjs` extension."),
|
||||
FixSuggestion::hint("Rewrite this module to ESM or change the file extension to `.cjs`."),
|
||||
];
|
||||
}
|
||||
fn get_suggestions_for_terminal_errors(e: &JsError) -> Vec<FixSuggestion> {
|
||||
if let Some(msg) = &e.message {
|
||||
if msg.contains("module is not defined")
|
||||
|| msg.contains("exports is not defined")
|
||||
{
|
||||
return vec![
|
||||
FixSuggestion::info(
|
||||
"Deno does not support CommonJS modules without `.cjs` extension.",
|
||||
),
|
||||
FixSuggestion::hint(
|
||||
"Rewrite this module to ESM or change the file extension to `.cjs`.",
|
||||
),
|
||||
];
|
||||
} else if msg.contains("openKv is not a function") {
|
||||
return vec![
|
||||
FixSuggestion::info("Deno.openKv() is an unstable API."),
|
||||
FixSuggestion::hint(
|
||||
"Run again with `--unstable-kv` flag to enable this API.",
|
||||
),
|
||||
];
|
||||
} else if msg.contains("cron is not a function") {
|
||||
return vec![
|
||||
FixSuggestion::info("Deno.cron() is an unstable API."),
|
||||
FixSuggestion::hint(
|
||||
"Run again with `--unstable-cron` flag to enable this API.",
|
||||
),
|
||||
];
|
||||
} else if msg.contains("createHttpClient is not a function") {
|
||||
return vec![
|
||||
FixSuggestion::info("Deno.createHttpClient() is an unstable API."),
|
||||
FixSuggestion::hint(
|
||||
"Run again with `--unstable-http` flag to enable this API.",
|
||||
),
|
||||
];
|
||||
} else if msg.contains("WebSocketStream is not defined") {
|
||||
return vec![
|
||||
FixSuggestion::info("new WebSocketStream() is an unstable API."),
|
||||
FixSuggestion::hint(
|
||||
"Run again with `--unstable-net` flag to enable this API.",
|
||||
),
|
||||
];
|
||||
} else if msg.contains("Temporal is not defined") {
|
||||
return vec![
|
||||
FixSuggestion::info("Temporal is an unstable API."),
|
||||
FixSuggestion::hint(
|
||||
"Run again with `--unstable-temporal` flag to enable this API.",
|
||||
),
|
||||
];
|
||||
} else if msg.contains("BroadcastChannel is not defined") {
|
||||
return vec![
|
||||
FixSuggestion::info("BroadcastChannel is an unstable API."),
|
||||
FixSuggestion::hint(
|
||||
"Run again with `--unstable-broadcast-channel` flag to enable this API.",
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -359,7 +403,7 @@ fn exit_for_error(error: AnyError) -> ! {
|
|||
let mut error_code = 1;
|
||||
|
||||
if let Some(e) = error.downcast_ref::<JsError>() {
|
||||
let suggestions = get_suggestions_for_commonjs_error(e);
|
||||
let suggestions = get_suggestions_for_terminal_errors(e);
|
||||
error_string = format_js_error_with_suggestions(e, suggestions);
|
||||
} else if let Some(SnapshotFromLockfileError::IntegrityCheckFailed(e)) =
|
||||
error.downcast_ref::<SnapshotFromLockfileError>()
|
||||
|
@ -434,25 +478,14 @@ fn resolve_flags_and_init(
|
|||
Err(err) => exit_for_error(AnyError::from(err)),
|
||||
};
|
||||
|
||||
// TODO(bartlomieju): remove when `--unstable` flag is removed.
|
||||
// TODO(bartlomieju): remove in Deno v2.5 and hard error then.
|
||||
if flags.unstable_config.legacy_flag_enabled {
|
||||
#[allow(clippy::print_stderr)]
|
||||
if matches!(flags.subcommand, DenoSubcommand::Check(_)) {
|
||||
// can't use log crate because that's not setup yet
|
||||
eprintln!(
|
||||
"⚠️ {}",
|
||||
colors::yellow(
|
||||
"The `--unstable` flag is not needed for `deno check` anymore."
|
||||
)
|
||||
);
|
||||
} else {
|
||||
eprintln!(
|
||||
"⚠️ {}",
|
||||
colors::yellow(
|
||||
"The `--unstable` flag is deprecated and will be removed in Deno 2.0. Use granular `--unstable-*` flags instead.\nLearn more at: https://docs.deno.com/runtime/manual/tools/unstable_flags"
|
||||
)
|
||||
);
|
||||
}
|
||||
log::warn!(
|
||||
"⚠️ {}",
|
||||
colors::yellow(
|
||||
"The `--unstable` flag has been removed in Deno 2.0. Use granular `--unstable-*` flags instead.\nLearn more at: https://docs.deno.com/runtime/manual/tools/unstable_flags"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
let default_v8_flags = match flags.subcommand {
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
use std::borrow::Cow;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashSet;
|
||||
use std::path::PathBuf;
|
||||
use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
|
@ -44,7 +43,6 @@ use deno_core::error::generic_error;
|
|||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::future::FutureExt;
|
||||
use deno_core::futures::Future;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::resolve_url;
|
||||
use deno_core::ModuleCodeString;
|
||||
use deno_core::ModuleLoader;
|
||||
|
@ -244,7 +242,6 @@ impl CliModuleLoaderFactory {
|
|||
emitter: self.shared.emitter.clone(),
|
||||
parsed_source_cache: self.shared.parsed_source_cache.clone(),
|
||||
shared: self.shared.clone(),
|
||||
prevent_v8_code_cache: Default::default(),
|
||||
})));
|
||||
ModuleLoaderAndSourceMapGetter {
|
||||
module_loader: loader,
|
||||
|
@ -296,10 +293,6 @@ struct CliModuleLoaderInner<TGraphContainer: ModuleGraphContainer> {
|
|||
emitter: Arc<Emitter>,
|
||||
parsed_source_cache: Arc<ParsedSourceCache>,
|
||||
graph_container: TGraphContainer,
|
||||
// NOTE(bartlomieju): this is temporary, for deprecated import assertions.
|
||||
// Should be removed in Deno 2.
|
||||
// Modules stored here should not be V8 code-cached.
|
||||
prevent_v8_code_cache: Arc<Mutex<HashSet<String>>>,
|
||||
}
|
||||
|
||||
impl<TGraphContainer: ModuleGraphContainer>
|
||||
|
@ -785,14 +778,6 @@ impl<TGraphContainer: ModuleGraphContainer> ModuleLoader
|
|||
code_cache: &[u8],
|
||||
) -> Pin<Box<dyn Future<Output = ()>>> {
|
||||
if let Some(cache) = self.0.shared.code_cache.as_ref() {
|
||||
if self
|
||||
.0
|
||||
.prevent_v8_code_cache
|
||||
.lock()
|
||||
.contains(specifier.as_str())
|
||||
{
|
||||
return std::future::ready(()).boxed_local();
|
||||
}
|
||||
// This log line is also used by tests.
|
||||
log::debug!(
|
||||
"Updating V8 code cache for ES module: {specifier}, [{source_hash:?}]"
|
||||
|
@ -807,19 +792,6 @@ impl<TGraphContainer: ModuleGraphContainer> ModuleLoader
|
|||
std::future::ready(()).boxed_local()
|
||||
}
|
||||
|
||||
fn purge_and_prevent_code_cache(&self, specifier: &str) {
|
||||
if let Some(cache) = self.0.shared.code_cache.as_ref() {
|
||||
// This log line is also used by tests.
|
||||
log::debug!("Remove V8 code cache for ES module: {specifier}");
|
||||
cache.remove_code_cache(specifier);
|
||||
self
|
||||
.0
|
||||
.prevent_v8_code_cache
|
||||
.lock()
|
||||
.insert(specifier.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
fn get_source_map(&self, file_name: &str) -> Option<Vec<u8>> {
|
||||
let specifier = resolve_url(file_name).ok()?;
|
||||
match specifier.scheme() {
|
||||
|
|
|
@ -10,6 +10,7 @@ use std::cmp::Ordering;
|
|||
use std::collections::hash_map::Entry;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
@ -620,6 +621,9 @@ async fn sync_resolution_with_fs(
|
|||
|
||||
let mut found_names: HashMap<&String, &PackageNv> = HashMap::new();
|
||||
|
||||
// set of node_modules in workspace packages that we've already ensured exist
|
||||
let mut existing_child_node_modules_dirs: HashSet<PathBuf> = HashSet::new();
|
||||
|
||||
// 4. Create symlinks for package json dependencies
|
||||
{
|
||||
for remote in npm_install_deps_provider.remote_pkgs() {
|
||||
|
@ -638,13 +642,16 @@ async fn sync_resolution_with_fs(
|
|||
} else {
|
||||
continue; // skip, package not found
|
||||
};
|
||||
let alias_clashes = remote.req.name != remote.alias
|
||||
&& newest_packages_by_name.contains_key(&remote.alias);
|
||||
let Some(remote_alias) = &remote.alias else {
|
||||
continue;
|
||||
};
|
||||
let alias_clashes = remote.req.name != *remote_alias
|
||||
&& newest_packages_by_name.contains_key(remote_alias);
|
||||
let install_in_child = {
|
||||
// we'll install in the child if the alias is taken by another package, or
|
||||
// if there's already a package with the same name but different version
|
||||
// linked into the root
|
||||
match found_names.entry(&remote.alias) {
|
||||
match found_names.entry(remote_alias) {
|
||||
Entry::Occupied(nv) => {
|
||||
alias_clashes
|
||||
|| remote.req.name != nv.get().name // alias to a different package (in case of duplicate aliases)
|
||||
|
@ -667,8 +674,15 @@ async fn sync_resolution_with_fs(
|
|||
);
|
||||
if install_in_child {
|
||||
// symlink the dep into the package's child node_modules folder
|
||||
let dest_path =
|
||||
remote.base_dir.join("node_modules").join(&remote.alias);
|
||||
let dest_node_modules = remote.base_dir.join("node_modules");
|
||||
if !existing_child_node_modules_dirs.contains(&dest_node_modules) {
|
||||
fs::create_dir_all(&dest_node_modules).with_context(|| {
|
||||
format!("Creating '{}'", dest_node_modules.display())
|
||||
})?;
|
||||
existing_child_node_modules_dirs.insert(dest_node_modules.clone());
|
||||
}
|
||||
let mut dest_path = dest_node_modules;
|
||||
dest_path.push(remote_alias);
|
||||
|
||||
symlink_package_dir(&local_registry_package_path, &dest_path)?;
|
||||
} else {
|
||||
|
@ -678,7 +692,7 @@ async fn sync_resolution_with_fs(
|
|||
{
|
||||
symlink_package_dir(
|
||||
&local_registry_package_path,
|
||||
&join_package_name(root_node_modules_dir_path, &remote.alias),
|
||||
&join_package_name(root_node_modules_dir_path, remote_alias),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
@ -763,9 +777,12 @@ async fn sync_resolution_with_fs(
|
|||
// install correctly for a workspace (potentially in sub directories),
|
||||
// but this is good enough for a first pass
|
||||
for workspace in npm_install_deps_provider.workspace_pkgs() {
|
||||
let Some(workspace_alias) = &workspace.alias else {
|
||||
continue;
|
||||
};
|
||||
symlink_package_dir(
|
||||
&workspace.target_dir,
|
||||
&root_node_modules_dir_path.join(&workspace.alias),
|
||||
&root_node_modules_dir_path.join(workspace_alias),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -707,7 +707,14 @@ impl Resolver for CliGraphResolver {
|
|||
.resolve_if_for_npm_pkg(raw_specifier, referrer, to_node_mode(mode))
|
||||
.map_err(ResolveError::Other)?;
|
||||
if let Some(res) = maybe_resolution {
|
||||
return Ok(res.into_url());
|
||||
match res {
|
||||
NodeResolution::Esm(url) | NodeResolution::CommonJs(url) => {
|
||||
return Ok(url)
|
||||
}
|
||||
NodeResolution::BuiltIn(_) => {
|
||||
// don't resolve bare specifiers for built-in modules via node resolution
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@
|
|||
"useUnknownInCatchVariables": {
|
||||
"description": "Default catch clause variables as `unknown` instead of `any`.",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"default": true,
|
||||
"markdownDescription": "Default catch clause variables as `unknown` instead of `any`.\n\nSee more: https://www.typescriptlang.org/tsconfig#useUnknownInCatchVariables"
|
||||
}
|
||||
}
|
||||
|
@ -279,25 +279,6 @@
|
|||
"type": "string"
|
||||
}
|
||||
},
|
||||
"files": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"include": {
|
||||
"type": "array",
|
||||
"description": "List of files, directories or globs that will be linted.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"exclude": {
|
||||
"type": "array",
|
||||
"description": "List of files, directories or globs that will not be linted.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -355,25 +336,6 @@
|
|||
"type": "string"
|
||||
}
|
||||
},
|
||||
"files": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"include": {
|
||||
"type": "array",
|
||||
"description": "List of files, directories or globs that will be formatted.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"exclude": {
|
||||
"type": "array",
|
||||
"description": "List of files, directories or globs that will not be formatted.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"useTabs": {
|
||||
"description": "Whether to use tabs (true) or spaces (false) for indentation.",
|
||||
"type": "boolean",
|
||||
|
@ -477,25 +439,6 @@
|
|||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"files": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"include": {
|
||||
"type": "array",
|
||||
"description": "List of files, directories or globs that will be searched for tests.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"exclude": {
|
||||
"type": "array",
|
||||
"description": "List of files, directories or globs that will not be searched for tests.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -536,25 +479,6 @@
|
|||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"files": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"include": {
|
||||
"type": "array",
|
||||
"description": "List of files, directories or globs that will be searched for benchmarks.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"exclude": {
|
||||
"type": "array",
|
||||
"description": "List of files, directories or globs that will not be searched for benchmarks.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -624,7 +624,7 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
|||
},
|
||||
node_modules,
|
||||
unstable_config: UnstableConfig {
|
||||
legacy_flag_enabled: cli_options.legacy_unstable_flag(),
|
||||
legacy_flag_enabled: false,
|
||||
bare_node_builtins: cli_options.unstable_bare_node_builtins(),
|
||||
sloppy_imports: cli_options.unstable_sloppy_imports(),
|
||||
features: cli_options.unstable_features(),
|
||||
|
|
|
@ -682,12 +682,6 @@ pub async fn run(
|
|||
let feature_checker = Arc::new({
|
||||
let mut checker = FeatureChecker::default();
|
||||
checker.set_exit_cb(Box::new(crate::unstable_exit_cb));
|
||||
// TODO(bartlomieju): enable, once we deprecate `--unstable` in favor
|
||||
// of granular --unstable-* flags.
|
||||
// feature_checker.set_warn_cb(Box::new(crate::unstable_warn_cb));
|
||||
if metadata.unstable_config.legacy_flag_enabled {
|
||||
checker.enable_legacy_unstable();
|
||||
}
|
||||
for feature in metadata.unstable_config.features {
|
||||
// `metadata` is valid for the whole lifetime of the program, so we
|
||||
// can leak the string here.
|
||||
|
@ -733,7 +727,6 @@ pub async fn run(
|
|||
seed: metadata.seed,
|
||||
unsafely_ignore_certificate_errors: metadata
|
||||
.unsafely_ignore_certificate_errors,
|
||||
unstable: metadata.unstable_config.legacy_flag_enabled,
|
||||
create_hmr_runner: None,
|
||||
create_coverage_collector: None,
|
||||
node_ipc: None,
|
||||
|
|
|
@ -907,6 +907,7 @@ fn get_resolved_malva_config(
|
|||
};
|
||||
|
||||
let language_options = LanguageOptions {
|
||||
align_comments: true,
|
||||
hex_case: HexCase::Lower,
|
||||
hex_color_length: None,
|
||||
quotes: if let Some(true) = options.single_quote {
|
||||
|
@ -1011,7 +1012,6 @@ fn get_resolved_yaml_config(
|
|||
|
||||
let layout_options = LayoutOptions {
|
||||
print_width: options.line_width.unwrap_or(80) as usize,
|
||||
use_tabs: options.use_tabs.unwrap_or_default(),
|
||||
indent_width: options.indent_width.unwrap_or(2) as usize,
|
||||
line_break: LineBreak::Lf,
|
||||
};
|
||||
|
@ -1028,6 +1028,9 @@ fn get_resolved_yaml_config(
|
|||
brace_spacing: true,
|
||||
bracket_spacing: false,
|
||||
dash_spacing: DashSpacing::OneSpace,
|
||||
prefer_single_line: false,
|
||||
flow_sequence_prefer_single_line: None,
|
||||
flow_map_prefer_single_line: None,
|
||||
trim_trailing_whitespaces: true,
|
||||
trim_trailing_zero: false,
|
||||
ignore_comment_directive: "deno-fmt-ignore".into(),
|
||||
|
|
|
@ -490,10 +490,6 @@ async fn resolve_shim_data(
|
|||
TypeCheckMode::Local => executable_args.push("--check".to_string()),
|
||||
}
|
||||
|
||||
if flags.unstable_config.legacy_flag_enabled {
|
||||
executable_args.push("--unstable".to_string());
|
||||
}
|
||||
|
||||
for feature in &flags.unstable_config.features {
|
||||
executable_args.push(format!("--unstable-{}", feature));
|
||||
}
|
||||
|
@ -822,13 +818,7 @@ mod tests {
|
|||
|
||||
create_install_shim(
|
||||
&HttpClientProvider::new(None, None),
|
||||
&Flags {
|
||||
unstable_config: UnstableConfig {
|
||||
legacy_flag_enabled: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Flags::default()
|
||||
},
|
||||
&Flags::default(),
|
||||
InstallFlagsGlobal {
|
||||
module_url: "http://localhost:4545/echo_server.ts".to_string(),
|
||||
args: vec![],
|
||||
|
@ -850,12 +840,11 @@ mod tests {
|
|||
let content = fs::read_to_string(file_path).unwrap();
|
||||
if cfg!(windows) {
|
||||
assert!(content.contains(
|
||||
r#""run" "--unstable" "--no-config" "http://localhost:4545/echo_server.ts""#
|
||||
r#""run" "--no-config" "http://localhost:4545/echo_server.ts""#
|
||||
));
|
||||
} else {
|
||||
assert!(content.contains(
|
||||
r#"run --unstable --no-config 'http://localhost:4545/echo_server.ts'"#
|
||||
));
|
||||
assert!(content
|
||||
.contains(r#"run --no-config 'http://localhost:4545/echo_server.ts'"#));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -886,13 +875,7 @@ mod tests {
|
|||
async fn install_unstable_legacy() {
|
||||
let shim_data = resolve_shim_data(
|
||||
&HttpClientProvider::new(None, None),
|
||||
&Flags {
|
||||
unstable_config: UnstableConfig {
|
||||
legacy_flag_enabled: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
&Default::default(),
|
||||
&InstallFlagsGlobal {
|
||||
module_url: "http://localhost:4545/echo_server.ts".to_string(),
|
||||
args: vec![],
|
||||
|
@ -907,12 +890,7 @@ mod tests {
|
|||
assert_eq!(shim_data.name, "echo_server");
|
||||
assert_eq!(
|
||||
shim_data.args,
|
||||
vec![
|
||||
"run",
|
||||
"--unstable",
|
||||
"--no-config",
|
||||
"http://localhost:4545/echo_server.ts",
|
||||
]
|
||||
vec!["run", "--no-config", "http://localhost:4545/echo_server.ts",]
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ use deno_semver::jsr::JsrPackageReqReference;
|
|||
use deno_semver::npm::NpmPackageReqReference;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -26,9 +25,11 @@ use deno_semver::package::PackageReq;
|
|||
use indexmap::IndexMap;
|
||||
use jsonc_parser::ast::ObjectProp;
|
||||
use jsonc_parser::ast::Value;
|
||||
use yoke::Yoke;
|
||||
|
||||
use crate::args::AddFlags;
|
||||
use crate::args::CacheSetting;
|
||||
use crate::args::CliOptions;
|
||||
use crate::args::Flags;
|
||||
use crate::args::RemoveFlags;
|
||||
use crate::factory::CliFactory;
|
||||
|
@ -56,115 +57,303 @@ impl DenoConfigFormat {
|
|||
}
|
||||
}
|
||||
|
||||
struct DenoConfig {
|
||||
config: Arc<deno_config::deno_json::ConfigFile>,
|
||||
format: DenoConfigFormat,
|
||||
imports: IndexMap<String, String>,
|
||||
}
|
||||
|
||||
fn deno_json_imports(
|
||||
config: &deno_config::deno_json::ConfigFile,
|
||||
) -> Result<IndexMap<String, String>, AnyError> {
|
||||
Ok(
|
||||
config
|
||||
.json
|
||||
.imports
|
||||
.clone()
|
||||
.map(|imports| {
|
||||
serde_json::from_value(imports)
|
||||
.map_err(|err| anyhow!("Malformed \"imports\" configuration: {err}"))
|
||||
})
|
||||
.transpose()?
|
||||
.unwrap_or_default(),
|
||||
)
|
||||
}
|
||||
impl DenoConfig {
|
||||
fn from_options(options: &CliOptions) -> Result<Option<Self>, AnyError> {
|
||||
let start_dir = &options.start_dir;
|
||||
if let Some(config) = start_dir.maybe_deno_json() {
|
||||
Ok(Some(Self {
|
||||
imports: deno_json_imports(config)?,
|
||||
config: config.clone(),
|
||||
format: DenoConfigFormat::from_specifier(&config.specifier)?,
|
||||
}))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn add(&mut self, selected: SelectedPackage) {
|
||||
self.imports.insert(
|
||||
selected.import_name,
|
||||
format!("{}@{}", selected.package_name, selected.version_req),
|
||||
);
|
||||
}
|
||||
|
||||
fn remove(&mut self, package: &str) -> bool {
|
||||
self.imports.shift_remove(package).is_some()
|
||||
}
|
||||
|
||||
fn take_import_fields(
|
||||
&mut self,
|
||||
) -> Vec<(&'static str, IndexMap<String, String>)> {
|
||||
vec![("imports", std::mem::take(&mut self.imports))]
|
||||
}
|
||||
}
|
||||
|
||||
impl NpmConfig {
|
||||
fn from_options(options: &CliOptions) -> Result<Option<Self>, AnyError> {
|
||||
let start_dir = &options.start_dir;
|
||||
if let Some(pkg_json) = start_dir.maybe_pkg_json() {
|
||||
Ok(Some(Self {
|
||||
dependencies: pkg_json.dependencies.clone().unwrap_or_default(),
|
||||
dev_dependencies: pkg_json.dev_dependencies.clone().unwrap_or_default(),
|
||||
config: pkg_json.clone(),
|
||||
fmt_options: None,
|
||||
}))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn add(&mut self, selected: SelectedPackage, dev: bool) {
|
||||
let (name, version) = package_json_dependency_entry(selected);
|
||||
if dev {
|
||||
self.dev_dependencies.insert(name, version);
|
||||
} else {
|
||||
self.dependencies.insert(name, version);
|
||||
}
|
||||
}
|
||||
|
||||
fn remove(&mut self, package: &str) -> bool {
|
||||
let in_deps = self.dependencies.shift_remove(package).is_some();
|
||||
let in_dev_deps = self.dev_dependencies.shift_remove(package).is_some();
|
||||
in_deps || in_dev_deps
|
||||
}
|
||||
|
||||
fn take_import_fields(
|
||||
&mut self,
|
||||
) -> Vec<(&'static str, IndexMap<String, String>)> {
|
||||
vec![
|
||||
("dependencies", std::mem::take(&mut self.dependencies)),
|
||||
(
|
||||
"devDependencies",
|
||||
std::mem::take(&mut self.dev_dependencies),
|
||||
),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
struct NpmConfig {
|
||||
config: Arc<deno_node::PackageJson>,
|
||||
fmt_options: Option<FmtOptionsConfig>,
|
||||
dependencies: IndexMap<String, String>,
|
||||
dev_dependencies: IndexMap<String, String>,
|
||||
}
|
||||
|
||||
enum DenoOrPackageJson {
|
||||
Deno(Arc<deno_config::deno_json::ConfigFile>, DenoConfigFormat),
|
||||
Npm(Arc<deno_node::PackageJson>, Option<FmtOptionsConfig>),
|
||||
Deno(DenoConfig),
|
||||
Npm(NpmConfig),
|
||||
}
|
||||
|
||||
impl From<DenoConfig> for DenoOrPackageJson {
|
||||
fn from(config: DenoConfig) -> Self {
|
||||
Self::Deno(config)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NpmConfig> for DenoOrPackageJson {
|
||||
fn from(config: NpmConfig) -> Self {
|
||||
Self::Npm(config)
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper around `jsonc_parser::ast::Object` that can be stored in a `Yoke`
|
||||
#[derive(yoke::Yokeable)]
|
||||
struct JsoncObjectView<'a>(jsonc_parser::ast::Object<'a>);
|
||||
|
||||
struct ConfigUpdater {
|
||||
config: DenoOrPackageJson,
|
||||
// the `Yoke` is so we can carry the parsed object (which borrows from
|
||||
// the source) along with the source itself
|
||||
ast: Yoke<JsoncObjectView<'static>, String>,
|
||||
path: PathBuf,
|
||||
modified: bool,
|
||||
}
|
||||
|
||||
impl ConfigUpdater {
|
||||
fn obj(&self) -> &jsonc_parser::ast::Object<'_> {
|
||||
&self.ast.get().0
|
||||
}
|
||||
fn contents(&self) -> &str {
|
||||
self.ast.backing_cart()
|
||||
}
|
||||
async fn maybe_new(
|
||||
config: Option<impl Into<DenoOrPackageJson>>,
|
||||
) -> Result<Option<Self>, AnyError> {
|
||||
if let Some(config) = config {
|
||||
Ok(Some(Self::new(config.into()).await?))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
async fn new(config: DenoOrPackageJson) -> Result<Self, AnyError> {
|
||||
let specifier = config.specifier();
|
||||
if specifier.scheme() != "file" {
|
||||
bail!("Can't update a remote configuration file");
|
||||
}
|
||||
let config_file_path = specifier.to_file_path().map_err(|_| {
|
||||
anyhow!("Specifier {specifier:?} is an invalid file path")
|
||||
})?;
|
||||
let config_file_contents = {
|
||||
let contents = tokio::fs::read_to_string(&config_file_path)
|
||||
.await
|
||||
.with_context(|| {
|
||||
format!("Reading config file at: {}", config_file_path.display())
|
||||
})?;
|
||||
if contents.trim().is_empty() {
|
||||
"{}\n".into()
|
||||
} else {
|
||||
contents
|
||||
}
|
||||
};
|
||||
let ast = Yoke::try_attach_to_cart(config_file_contents, |contents| {
|
||||
let ast = jsonc_parser::parse_to_ast(
|
||||
contents,
|
||||
&Default::default(),
|
||||
&Default::default(),
|
||||
)
|
||||
.with_context(|| {
|
||||
format!("Failed to parse config file at {}", specifier)
|
||||
})?;
|
||||
let obj = match ast.value {
|
||||
Some(Value::Object(obj)) => obj,
|
||||
_ => bail!(
|
||||
"Failed to update config file at {}, expected an object",
|
||||
specifier
|
||||
),
|
||||
};
|
||||
Ok(JsoncObjectView(obj))
|
||||
})?;
|
||||
Ok(Self {
|
||||
config,
|
||||
ast,
|
||||
path: config_file_path,
|
||||
modified: false,
|
||||
})
|
||||
}
|
||||
|
||||
fn add(&mut self, selected: SelectedPackage, dev: bool) {
|
||||
match &mut self.config {
|
||||
DenoOrPackageJson::Deno(deno) => deno.add(selected),
|
||||
DenoOrPackageJson::Npm(npm) => npm.add(selected, dev),
|
||||
}
|
||||
self.modified = true;
|
||||
}
|
||||
|
||||
fn remove(&mut self, package: &str) -> bool {
|
||||
let removed = match &mut self.config {
|
||||
DenoOrPackageJson::Deno(deno) => deno.remove(package),
|
||||
DenoOrPackageJson::Npm(npm) => npm.remove(package),
|
||||
};
|
||||
if removed {
|
||||
self.modified = true;
|
||||
}
|
||||
removed
|
||||
}
|
||||
|
||||
async fn commit(mut self) -> Result<(), AnyError> {
|
||||
if !self.modified {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let import_fields = self.config.take_import_fields();
|
||||
|
||||
let fmt_config_options = self.config.fmt_options();
|
||||
|
||||
let new_text = update_config_file_content(
|
||||
self.obj(),
|
||||
self.contents(),
|
||||
fmt_config_options,
|
||||
import_fields.into_iter().map(|(k, v)| {
|
||||
(
|
||||
k,
|
||||
if v.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(generate_imports(v.into_iter().collect()))
|
||||
},
|
||||
)
|
||||
}),
|
||||
self.config.file_name(),
|
||||
);
|
||||
|
||||
tokio::fs::write(&self.path, new_text).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl DenoOrPackageJson {
|
||||
fn specifier(&self) -> Cow<ModuleSpecifier> {
|
||||
match self {
|
||||
Self::Deno(d, ..) => Cow::Borrowed(&d.specifier),
|
||||
Self::Npm(n, ..) => Cow::Owned(n.specifier()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the existing imports/dependencies from the config.
|
||||
fn existing_imports(&self) -> Result<IndexMap<String, String>, AnyError> {
|
||||
match self {
|
||||
DenoOrPackageJson::Deno(deno, ..) => {
|
||||
if let Some(imports) = deno.json.imports.clone() {
|
||||
match serde_json::from_value(imports) {
|
||||
Ok(map) => Ok(map),
|
||||
Err(err) => {
|
||||
bail!("Malformed \"imports\" configuration: {err}")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Ok(Default::default())
|
||||
}
|
||||
}
|
||||
DenoOrPackageJson::Npm(npm, ..) => {
|
||||
Ok(npm.dependencies.clone().unwrap_or_default())
|
||||
}
|
||||
Self::Deno(d, ..) => Cow::Borrowed(&d.config.specifier),
|
||||
Self::Npm(n, ..) => Cow::Owned(n.config.specifier()),
|
||||
}
|
||||
}
|
||||
|
||||
fn fmt_options(&self) -> FmtOptionsConfig {
|
||||
match self {
|
||||
DenoOrPackageJson::Deno(deno, ..) => deno
|
||||
.config
|
||||
.to_fmt_config()
|
||||
.ok()
|
||||
.map(|f| f.options)
|
||||
.unwrap_or_default(),
|
||||
DenoOrPackageJson::Npm(_, config) => config.clone().unwrap_or_default(),
|
||||
DenoOrPackageJson::Npm(config) => {
|
||||
config.fmt_options.clone().unwrap_or_default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn imports_key(&self) -> &'static str {
|
||||
fn take_import_fields(
|
||||
&mut self,
|
||||
) -> Vec<(&'static str, IndexMap<String, String>)> {
|
||||
match self {
|
||||
DenoOrPackageJson::Deno(..) => "imports",
|
||||
DenoOrPackageJson::Npm(..) => "dependencies",
|
||||
Self::Deno(d) => d.take_import_fields(),
|
||||
Self::Npm(n) => n.take_import_fields(),
|
||||
}
|
||||
}
|
||||
|
||||
fn file_name(&self) -> &'static str {
|
||||
match self {
|
||||
DenoOrPackageJson::Deno(_, format) => match format {
|
||||
DenoOrPackageJson::Deno(config) => match config.format {
|
||||
DenoConfigFormat::Json => "deno.json",
|
||||
DenoConfigFormat::Jsonc => "deno.jsonc",
|
||||
},
|
||||
DenoOrPackageJson::Npm(..) => "package.json",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_npm(&self) -> bool {
|
||||
matches!(self, Self::Npm(..))
|
||||
}
|
||||
|
||||
/// Get the preferred config file to operate on
|
||||
/// given the flags. If no config file is present,
|
||||
/// creates a `deno.json` file - in this case
|
||||
/// we also return a new `CliFactory` that knows about
|
||||
/// the new config
|
||||
fn from_flags(flags: Arc<Flags>) -> Result<(Self, CliFactory), AnyError> {
|
||||
let factory = CliFactory::from_flags(flags.clone());
|
||||
let options = factory.cli_options()?;
|
||||
let start_dir = &options.start_dir;
|
||||
|
||||
match (start_dir.maybe_deno_json(), start_dir.maybe_pkg_json()) {
|
||||
// when both are present, for now,
|
||||
// default to deno.json
|
||||
(Some(deno), Some(_) | None) => Ok((
|
||||
DenoOrPackageJson::Deno(
|
||||
deno.clone(),
|
||||
DenoConfigFormat::from_specifier(&deno.specifier)?,
|
||||
),
|
||||
factory,
|
||||
)),
|
||||
(None, Some(package_json)) => {
|
||||
Ok((DenoOrPackageJson::Npm(package_json.clone(), None), factory))
|
||||
}
|
||||
(None, None) => {
|
||||
std::fs::write(options.initial_cwd().join("deno.json"), "{}\n")
|
||||
.context("Failed to create deno.json file")?;
|
||||
drop(factory); // drop to prevent use
|
||||
log::info!("Created deno.json configuration file.");
|
||||
let factory = CliFactory::from_flags(flags.clone());
|
||||
let options = factory.cli_options()?.clone();
|
||||
let start_dir = &options.start_dir;
|
||||
Ok((
|
||||
DenoOrPackageJson::Deno(
|
||||
start_dir.maybe_deno_json().cloned().ok_or_else(|| {
|
||||
anyhow!("config not found, but it was just created")
|
||||
})?,
|
||||
DenoConfigFormat::Json,
|
||||
),
|
||||
factory,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
fn create_deno_json(
|
||||
flags: &Arc<Flags>,
|
||||
options: &CliOptions,
|
||||
) -> Result<CliFactory, AnyError> {
|
||||
std::fs::write(options.initial_cwd().join("deno.json"), "{}\n")
|
||||
.context("Failed to create deno.json file")?;
|
||||
log::info!("Created deno.json configuration file.");
|
||||
let factory = CliFactory::from_flags(flags.clone());
|
||||
Ok(factory)
|
||||
}
|
||||
|
||||
fn package_json_dependency_entry(
|
||||
|
@ -199,19 +388,53 @@ impl std::fmt::Display for AddCommandName {
|
|||
}
|
||||
}
|
||||
|
||||
fn load_configs(
|
||||
flags: &Arc<Flags>,
|
||||
) -> Result<(CliFactory, Option<NpmConfig>, Option<DenoConfig>), AnyError> {
|
||||
let cli_factory = CliFactory::from_flags(flags.clone());
|
||||
let options = cli_factory.cli_options()?;
|
||||
let npm_config = NpmConfig::from_options(options)?;
|
||||
let (cli_factory, deno_config) = match DenoConfig::from_options(options)? {
|
||||
Some(config) => (cli_factory, Some(config)),
|
||||
None if npm_config.is_some() => (cli_factory, None),
|
||||
None => {
|
||||
let factory = create_deno_json(flags, options)?;
|
||||
let options = factory.cli_options()?.clone();
|
||||
(
|
||||
factory,
|
||||
Some(
|
||||
DenoConfig::from_options(&options)?.expect("Just created deno.json"),
|
||||
),
|
||||
)
|
||||
}
|
||||
};
|
||||
assert!(deno_config.is_some() || npm_config.is_some());
|
||||
Ok((cli_factory, npm_config, deno_config))
|
||||
}
|
||||
|
||||
pub async fn add(
|
||||
flags: Arc<Flags>,
|
||||
add_flags: AddFlags,
|
||||
cmd_name: AddCommandName,
|
||||
) -> Result<(), AnyError> {
|
||||
let (config_file, cli_factory) =
|
||||
DenoOrPackageJson::from_flags(flags.clone())?;
|
||||
let (cli_factory, npm_config, deno_config) = load_configs(&flags)?;
|
||||
let mut npm_config = ConfigUpdater::maybe_new(npm_config).await?;
|
||||
let mut deno_config = ConfigUpdater::maybe_new(deno_config).await?;
|
||||
|
||||
let config_specifier = config_file.specifier();
|
||||
if config_specifier.scheme() != "file" {
|
||||
bail!("Can't add dependencies to a remote configuration file");
|
||||
if let Some(deno) = &deno_config {
|
||||
let specifier = deno.config.specifier();
|
||||
if deno.obj().get_string("importMap").is_some() {
|
||||
bail!(
|
||||
concat!(
|
||||
"`deno {}` is not supported when configuration file contains an \"importMap\" field. ",
|
||||
"Inline the import map into the Deno configuration file.\n",
|
||||
" at {}",
|
||||
),
|
||||
cmd_name,
|
||||
specifier
|
||||
);
|
||||
}
|
||||
}
|
||||
let config_file_path = config_specifier.to_file_path().unwrap();
|
||||
|
||||
let http_client = cli_factory.http_client_provider();
|
||||
|
||||
|
@ -279,39 +502,7 @@ pub async fn add(
|
|||
}
|
||||
}
|
||||
|
||||
let config_file_contents = {
|
||||
let contents = tokio::fs::read_to_string(&config_file_path).await.unwrap();
|
||||
if contents.trim().is_empty() {
|
||||
"{}\n".into()
|
||||
} else {
|
||||
contents
|
||||
}
|
||||
};
|
||||
let ast = jsonc_parser::parse_to_ast(
|
||||
&config_file_contents,
|
||||
&Default::default(),
|
||||
&Default::default(),
|
||||
)?;
|
||||
|
||||
let obj = match ast.value {
|
||||
Some(Value::Object(obj)) => obj,
|
||||
_ => bail!("Failed updating config file due to no object."),
|
||||
};
|
||||
|
||||
if obj.get_string("importMap").is_some() {
|
||||
bail!(
|
||||
concat!(
|
||||
"`deno add` is not supported when configuration file contains an \"importMap\" field. ",
|
||||
"Inline the import map into the Deno configuration file.\n",
|
||||
" at {}",
|
||||
),
|
||||
config_specifier
|
||||
);
|
||||
}
|
||||
|
||||
let mut existing_imports = config_file.existing_imports()?;
|
||||
|
||||
let is_npm = config_file.is_npm();
|
||||
let dev = add_flags.dev;
|
||||
for selected_package in selected_packages {
|
||||
log::info!(
|
||||
"Add {}{}{}",
|
||||
|
@ -320,39 +511,32 @@ pub async fn add(
|
|||
selected_package.selected_version
|
||||
);
|
||||
|
||||
if is_npm {
|
||||
let (name, version) = package_json_dependency_entry(selected_package);
|
||||
existing_imports.insert(name, version)
|
||||
if selected_package.package_name.starts_with("npm:") {
|
||||
if let Some(npm) = &mut npm_config {
|
||||
npm.add(selected_package, dev);
|
||||
} else {
|
||||
deno_config.as_mut().unwrap().add(selected_package, dev);
|
||||
}
|
||||
} else if let Some(deno) = &mut deno_config {
|
||||
deno.add(selected_package, dev);
|
||||
} else {
|
||||
existing_imports.insert(
|
||||
selected_package.import_name,
|
||||
format!(
|
||||
"{}@{}",
|
||||
selected_package.package_name, selected_package.version_req
|
||||
),
|
||||
)
|
||||
};
|
||||
npm_config.as_mut().unwrap().add(selected_package, dev);
|
||||
}
|
||||
}
|
||||
let mut import_list: Vec<(String, String)> =
|
||||
existing_imports.into_iter().collect();
|
||||
|
||||
import_list.sort_by(|(k1, _), (k2, _)| k1.cmp(k2));
|
||||
let generated_imports = generate_imports(import_list);
|
||||
let mut commit_futures = vec![];
|
||||
if let Some(npm) = npm_config {
|
||||
commit_futures.push(npm.commit());
|
||||
}
|
||||
if let Some(deno) = deno_config {
|
||||
commit_futures.push(deno.commit());
|
||||
}
|
||||
let commit_futures =
|
||||
deno_core::futures::future::join_all(commit_futures).await;
|
||||
|
||||
let fmt_config_options = config_file.fmt_options();
|
||||
|
||||
let new_text = update_config_file_content(
|
||||
obj,
|
||||
&config_file_contents,
|
||||
generated_imports,
|
||||
fmt_config_options,
|
||||
config_file.imports_key(),
|
||||
config_file.file_name(),
|
||||
);
|
||||
|
||||
tokio::fs::write(&config_file_path, new_text)
|
||||
.await
|
||||
.context("Failed to update configuration file")?;
|
||||
for result in commit_futures {
|
||||
result.context("Failed to update configuration file")?;
|
||||
}
|
||||
|
||||
// clear the previously cached package.json from memory before reloading it
|
||||
node_resolver::PackageJsonThreadLocalCache::clear();
|
||||
|
@ -524,7 +708,8 @@ impl AddPackageReq {
|
|||
}
|
||||
}
|
||||
|
||||
fn generate_imports(packages_to_version: Vec<(String, String)>) -> String {
|
||||
fn generate_imports(mut packages_to_version: Vec<(String, String)>) -> String {
|
||||
packages_to_version.sort_by(|(k1, _), (k2, _)| k1.cmp(k2));
|
||||
let mut contents = vec![];
|
||||
let len = packages_to_version.len();
|
||||
for (index, (package, version)) in packages_to_version.iter().enumerate() {
|
||||
|
@ -537,68 +722,27 @@ fn generate_imports(packages_to_version: Vec<(String, String)>) -> String {
|
|||
contents.join("\n")
|
||||
}
|
||||
|
||||
fn remove_from_config(
|
||||
config_path: &Path,
|
||||
keys: &[&'static str],
|
||||
packages_to_remove: &[String],
|
||||
removed_packages: &mut Vec<String>,
|
||||
fmt_options: &FmtOptionsConfig,
|
||||
) -> Result<(), AnyError> {
|
||||
let mut json: serde_json::Value =
|
||||
serde_json::from_slice(&std::fs::read(config_path)?)?;
|
||||
for key in keys {
|
||||
let Some(obj) = json.get_mut(*key).and_then(|v| v.as_object_mut()) else {
|
||||
continue;
|
||||
};
|
||||
for package in packages_to_remove {
|
||||
if obj.shift_remove(package).is_some() {
|
||||
removed_packages.push(package.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let config = serde_json::to_string_pretty(&json)?;
|
||||
let config =
|
||||
crate::tools::fmt::format_json(config_path, &config, fmt_options)
|
||||
.ok()
|
||||
.flatten()
|
||||
.unwrap_or(config);
|
||||
|
||||
std::fs::write(config_path, config)
|
||||
.context("Failed to update configuration file")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn remove(
|
||||
flags: Arc<Flags>,
|
||||
remove_flags: RemoveFlags,
|
||||
) -> Result<(), AnyError> {
|
||||
let (config_file, factory) = DenoOrPackageJson::from_flags(flags.clone())?;
|
||||
let options = factory.cli_options()?;
|
||||
let start_dir = &options.start_dir;
|
||||
let fmt_config_options = config_file.fmt_options();
|
||||
let (_, npm_config, deno_config) = load_configs(&flags)?;
|
||||
|
||||
let mut removed_packages = Vec::new();
|
||||
let mut configs = [
|
||||
ConfigUpdater::maybe_new(npm_config).await?,
|
||||
ConfigUpdater::maybe_new(deno_config).await?,
|
||||
];
|
||||
|
||||
if let Some(deno_json) = start_dir.maybe_deno_json() {
|
||||
remove_from_config(
|
||||
&deno_json.specifier.to_file_path().unwrap(),
|
||||
&["imports"],
|
||||
&remove_flags.packages,
|
||||
&mut removed_packages,
|
||||
&fmt_config_options,
|
||||
)?;
|
||||
}
|
||||
let mut removed_packages = vec![];
|
||||
|
||||
if let Some(pkg_json) = start_dir.maybe_pkg_json() {
|
||||
remove_from_config(
|
||||
&pkg_json.path,
|
||||
&["dependencies", "devDependencies"],
|
||||
&remove_flags.packages,
|
||||
&mut removed_packages,
|
||||
&fmt_config_options,
|
||||
)?;
|
||||
for package in &remove_flags.packages {
|
||||
let mut removed = false;
|
||||
for config in configs.iter_mut().flatten() {
|
||||
removed |= config.remove(package);
|
||||
}
|
||||
if removed {
|
||||
removed_packages.push(package.clone());
|
||||
}
|
||||
}
|
||||
|
||||
if removed_packages.is_empty() {
|
||||
|
@ -607,6 +751,10 @@ pub async fn remove(
|
|||
for package in &removed_packages {
|
||||
log::info!("Removed {}", crate::colors::green(package));
|
||||
}
|
||||
for config in configs.into_iter().flatten() {
|
||||
config.commit().await?;
|
||||
}
|
||||
|
||||
// Update deno.lock
|
||||
node_resolver::PackageJsonThreadLocalCache::clear();
|
||||
let cli_factory = CliFactory::from_flags(flags);
|
||||
|
@ -616,41 +764,72 @@ pub async fn remove(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn update_config_file_content(
|
||||
obj: jsonc_parser::ast::Object,
|
||||
fn update_config_file_content<
|
||||
I: IntoIterator<Item = (&'static str, Option<String>)>,
|
||||
>(
|
||||
obj: &jsonc_parser::ast::Object,
|
||||
config_file_contents: &str,
|
||||
generated_imports: String,
|
||||
fmt_options: FmtOptionsConfig,
|
||||
imports_key: &str,
|
||||
entries: I,
|
||||
file_name: &str,
|
||||
) -> String {
|
||||
let mut text_changes = vec![];
|
||||
for (key, value) in entries {
|
||||
match obj.properties.iter().enumerate().find_map(|(idx, k)| {
|
||||
if k.name.as_str() == key {
|
||||
Some((idx, k))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}) {
|
||||
Some((
|
||||
idx,
|
||||
ObjectProp {
|
||||
value: Value::Object(lit),
|
||||
range,
|
||||
..
|
||||
},
|
||||
)) => {
|
||||
if let Some(value) = value {
|
||||
text_changes.push(TextChange {
|
||||
range: (lit.range.start + 1)..(lit.range.end - 1),
|
||||
new_text: value,
|
||||
})
|
||||
} else {
|
||||
text_changes.push(TextChange {
|
||||
// remove field entirely, making sure to
|
||||
// remove the comma if it's not the last field
|
||||
range: range.start..(if idx == obj.properties.len() - 1 {
|
||||
range.end
|
||||
} else {
|
||||
obj.properties[idx + 1].range.start
|
||||
}),
|
||||
new_text: "".to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
match obj.get(imports_key) {
|
||||
Some(ObjectProp {
|
||||
value: Value::Object(lit),
|
||||
..
|
||||
}) => text_changes.push(TextChange {
|
||||
range: (lit.range.start + 1)..(lit.range.end - 1),
|
||||
new_text: generated_imports,
|
||||
}),
|
||||
None => {
|
||||
let insert_position = obj.range.end - 1;
|
||||
text_changes.push(TextChange {
|
||||
range: insert_position..insert_position,
|
||||
// NOTE(bartlomieju): adding `\n` here to force the formatter to always
|
||||
// produce a config file that is multiline, like so:
|
||||
// ```
|
||||
// {
|
||||
// "imports": {
|
||||
// "<package_name>": "<registry>:<package_name>@<semver>"
|
||||
// }
|
||||
// }
|
||||
new_text: format!("\"{imports_key}\": {{\n {generated_imports} }}"),
|
||||
})
|
||||
// need to add field
|
||||
None => {
|
||||
if let Some(value) = value {
|
||||
let insert_position = obj.range.end - 1;
|
||||
text_changes.push(TextChange {
|
||||
range: insert_position..insert_position,
|
||||
// NOTE(bartlomieju): adding `\n` here to force the formatter to always
|
||||
// produce a config file that is multiline, like so:
|
||||
// ```
|
||||
// {
|
||||
// "imports": {
|
||||
// "<package_name>": "<registry>:<package_name>@<semver>"
|
||||
// }
|
||||
// }
|
||||
new_text: format!("\"{key}\": {{\n {value} }}"),
|
||||
})
|
||||
}
|
||||
}
|
||||
// we verified the shape of `imports`/`dependencies` above
|
||||
Some(_) => unreachable!(),
|
||||
}
|
||||
// we verified the shape of `imports`/`dependencies` above
|
||||
Some(_) => unreachable!(),
|
||||
}
|
||||
|
||||
let new_text =
|
||||
|
|
|
@ -318,10 +318,10 @@ pub const OP_DETAILS: phf::Map<&'static str, [&'static str; 2]> = phf_map! {
|
|||
"op_fs_chown_async" => ["change the owner of a file", "awaiting the result of a `Deno.chown` call"],
|
||||
"op_fs_copy_file_async" => ["copy a file", "awaiting the result of a `Deno.copyFile` call"],
|
||||
"op_fs_events_poll" => ["get the next file system event", "breaking out of a for await loop looping over `Deno.FsEvents`"],
|
||||
"op_fs_fdatasync_async" => ["flush pending data operations for a file to disk", "awaiting the result of a `Deno.fdatasync` or `Deno.FsFile.syncData` call"],
|
||||
"op_fs_file_sync_data_async" => ["flush pending data operations for a file to disk", "awaiting the result of a `Deno.FsFile.prototype.syncData` call"],
|
||||
"op_fs_file_stat_async" => ["get file metadata", "awaiting the result of a `Deno.FsFile.prototype.stat` call"],
|
||||
"op_fs_flock_async" => ["lock a file", "awaiting the result of a `Deno.FsFile.lock` call"],
|
||||
"op_fs_fsync_async" => ["flush pending data operations for a file to disk", "awaiting the result of a `Deno.fsync` or `Deno.FsFile.sync` call"],
|
||||
"op_fs_file_sync_async" => ["flush pending data operations for a file to disk", "awaiting the result of a `Deno.FsFile.sync` call"],
|
||||
"op_fs_file_truncate_async" => ["truncate a file", "awaiting the result of a `Deno.FsFile.prototype.truncate` call"],
|
||||
"op_fs_funlock_async" => ["unlock a file", "awaiting the result of a `Deno.FsFile.unlock` call"],
|
||||
"op_fs_link_async" => ["create a hard link", "awaiting the result of a `Deno.link` call"],
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
use crate::args::Flags;
|
||||
use crate::args::UpgradeFlags;
|
||||
use crate::args::UPGRADE_USAGE;
|
||||
use crate::colors;
|
||||
use crate::factory::CliFactory;
|
||||
use crate::http_util::HttpClient;
|
||||
|
@ -15,7 +16,6 @@ use crate::util::progress_bar::ProgressBarStyle;
|
|||
use crate::version;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use color_print::cstr;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
|
@ -38,8 +38,6 @@ const RELEASE_URL: &str = "https://github.com/denoland/deno/releases";
|
|||
const CANARY_URL: &str = "https://dl.deno.land/canary";
|
||||
const RC_URL: &str = "https://dl.deno.land/release";
|
||||
|
||||
static EXAMPLE_USAGE: &str = cstr!("Example usage:\n <p(245)>deno upgrade | deno upgrade 1.46 | deno upgrade canary</>");
|
||||
|
||||
pub static ARCHIVE_NAME: Lazy<String> =
|
||||
Lazy::new(|| format!("deno-{}.zip", env!("TARGET")));
|
||||
|
||||
|
@ -625,6 +623,7 @@ impl RequestedVersion {
|
|||
};
|
||||
let mut maybe_passed_version = upgrade_flags.version.clone();
|
||||
|
||||
// TODO(bartlomieju): prefer flags first? This whole logic could be cleaned up...
|
||||
if let Some(val) = &upgrade_flags.version_or_hash_or_channel {
|
||||
if let Ok(channel) = ReleaseChannel::deserialize(&val.to_lowercase()) {
|
||||
// TODO(bartlomieju): print error if any other flags passed?
|
||||
|
@ -651,18 +650,19 @@ impl RequestedVersion {
|
|||
let (channel, passed_version) = if is_canary {
|
||||
if !re_hash.is_match(&passed_version) {
|
||||
bail!(
|
||||
"Invalid commit hash passed ({})\n\n{}",
|
||||
"Invalid commit hash passed ({})\n\nPass a semver, or a full 40 character git commit hash, or a release channel name.\n\nUsage:\n{}",
|
||||
colors::gray(passed_version),
|
||||
EXAMPLE_USAGE
|
||||
UPGRADE_USAGE
|
||||
);
|
||||
}
|
||||
|
||||
(ReleaseChannel::Canary, passed_version)
|
||||
} else {
|
||||
let Ok(semver) = Version::parse_standard(&passed_version) else {
|
||||
bail!(
|
||||
"Invalid version passed ({})\n\n{}",
|
||||
"Invalid version passed ({})\n\nPass a semver, or a full 40 character git commit hash, or a release channel name.\n\nUsage:\n{}",
|
||||
colors::gray(passed_version),
|
||||
EXAMPLE_USAGE
|
||||
UPGRADE_USAGE
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1123,6 +1123,8 @@ mod test {
|
|||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use test_util::assert_contains;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
|
@ -1221,6 +1223,27 @@ mod test {
|
|||
"5c69b4861b52ab406e73b9cd85c254f0505cb20f".to_string()
|
||||
)
|
||||
);
|
||||
|
||||
upgrade_flags.version_or_hash_or_channel =
|
||||
Some("5c69b4861b52a".to_string());
|
||||
let err = RequestedVersion::from_upgrade_flags(upgrade_flags.clone())
|
||||
.unwrap_err()
|
||||
.to_string();
|
||||
assert_contains!(err, "Invalid version passed");
|
||||
assert_contains!(
|
||||
err,
|
||||
"Pass a semver, or a full 40 character git commit hash, or a release channel name."
|
||||
);
|
||||
|
||||
upgrade_flags.version_or_hash_or_channel = Some("11.asd.1324".to_string());
|
||||
let err = RequestedVersion::from_upgrade_flags(upgrade_flags.clone())
|
||||
.unwrap_err()
|
||||
.to_string();
|
||||
assert_contains!(err, "Invalid version passed");
|
||||
assert_contains!(
|
||||
err,
|
||||
"Pass a semver, or a full 40 character git commit hash, or a release channel name."
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1152,7 +1152,6 @@ delete Object.prototype.__proto__;
|
|||
"strict": true,
|
||||
"target": "esnext",
|
||||
"useDefineForClassFields": true,
|
||||
"useUnknownInCatchVariables": false,
|
||||
"jsx": "react",
|
||||
"jsxFactory": "React.createElement",
|
||||
"jsxFragmentFactory": "React.Fragment",
|
||||
|
|
1217
cli/tsc/dts/lib.deno.ns.d.ts
vendored
1217
cli/tsc/dts/lib.deno.ns.d.ts
vendored
File diff suppressed because it is too large
Load diff
1320
cli/tsc/dts/lib.deno.unstable.d.ts
vendored
1320
cli/tsc/dts/lib.deno.unstable.d.ts
vendored
File diff suppressed because it is too large
Load diff
691
cli/tsc/dts/lib.deno_webgpu.d.ts
vendored
691
cli/tsc/dts/lib.deno_webgpu.d.ts
vendored
File diff suppressed because it is too large
Load diff
|
@ -112,7 +112,6 @@ pub struct CliMainWorkerOptions {
|
|||
pub origin_data_folder_path: Option<PathBuf>,
|
||||
pub seed: Option<u64>,
|
||||
pub unsafely_ignore_certificate_errors: Option<Vec<String>>,
|
||||
pub unstable: bool,
|
||||
pub skip_op_registration: bool,
|
||||
pub create_hmr_runner: Option<CreateHmrRunnerCb>,
|
||||
pub create_coverage_collector: Option<CreateCoverageCollectorCb>,
|
||||
|
@ -580,7 +579,6 @@ impl CliMainWorkerFactory {
|
|||
is_stdout_tty: deno_terminal::is_stdout_tty(),
|
||||
is_stderr_tty: deno_terminal::is_stderr_tty(),
|
||||
color_level: colors::get_color_level(),
|
||||
unstable: shared.options.unstable,
|
||||
unstable_features,
|
||||
user_agent: version::DENO_VERSION_INFO.user_agent.to_string(),
|
||||
inspect: shared.options.is_inspecting,
|
||||
|
@ -775,7 +773,6 @@ fn create_web_worker_callback(
|
|||
color_level: colors::get_color_level(),
|
||||
is_stdout_tty: deno_terminal::is_stdout_tty(),
|
||||
is_stderr_tty: deno_terminal::is_stderr_tty(),
|
||||
unstable: shared.options.unstable,
|
||||
unstable_features,
|
||||
user_agent: version::DENO_VERSION_INFO.user_agent.to_string(),
|
||||
inspect: shared.options.is_inspecting,
|
||||
|
|
|
@ -260,6 +260,7 @@ const colors = {
|
|||
|
||||
function defineColorAlias(target, alias) {
|
||||
ObjectDefineProperty(colors, alias, {
|
||||
__proto__: null,
|
||||
get() {
|
||||
return this[target];
|
||||
},
|
||||
|
@ -843,14 +844,6 @@ function formatRaw(ctx, value, recurseTimes, typedArray, proxyDetails) {
|
|||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.Duration.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.TimeZone.prototype,
|
||||
value,
|
||||
) ||
|
||||
ObjectPrototypeIsPrototypeOf(
|
||||
globalThis.Temporal.Calendar.prototype,
|
||||
value,
|
||||
)
|
||||
)
|
||||
) {
|
||||
|
@ -3447,7 +3440,10 @@ function inspect(
|
|||
function createFilteredInspectProxy({ object, keys, evaluate }) {
|
||||
const obj = class {};
|
||||
if (object.constructor?.name) {
|
||||
ObjectDefineProperty(obj, "name", { value: object.constructor.name });
|
||||
ObjectDefineProperty(obj, "name", {
|
||||
__proto__: null,
|
||||
value: object.constructor.name,
|
||||
});
|
||||
}
|
||||
|
||||
return new Proxy(new obj(), {
|
||||
|
|
|
@ -263,6 +263,7 @@ function mixinBody(prototype, bodySymbol, mimeTypeSymbol) {
|
|||
/** @type {PropertyDescriptorMap} */
|
||||
const mixin = {
|
||||
body: {
|
||||
__proto__: null,
|
||||
/**
|
||||
* @returns {ReadableStream<Uint8Array> | null}
|
||||
*/
|
||||
|
@ -278,6 +279,7 @@ function mixinBody(prototype, bodySymbol, mimeTypeSymbol) {
|
|||
enumerable: true,
|
||||
},
|
||||
bodyUsed: {
|
||||
__proto__: null,
|
||||
/**
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
@ -292,6 +294,7 @@ function mixinBody(prototype, bodySymbol, mimeTypeSymbol) {
|
|||
enumerable: true,
|
||||
},
|
||||
arrayBuffer: {
|
||||
__proto__: null,
|
||||
/** @returns {Promise<ArrayBuffer>} */
|
||||
value: function arrayBuffer() {
|
||||
return consumeBody(this, "ArrayBuffer");
|
||||
|
@ -301,6 +304,7 @@ function mixinBody(prototype, bodySymbol, mimeTypeSymbol) {
|
|||
enumerable: true,
|
||||
},
|
||||
blob: {
|
||||
__proto__: null,
|
||||
/** @returns {Promise<Blob>} */
|
||||
value: function blob() {
|
||||
return consumeBody(this, "Blob");
|
||||
|
@ -310,6 +314,7 @@ function mixinBody(prototype, bodySymbol, mimeTypeSymbol) {
|
|||
enumerable: true,
|
||||
},
|
||||
bytes: {
|
||||
__proto__: null,
|
||||
/** @returns {Promise<Uint8Array>} */
|
||||
value: function bytes() {
|
||||
return consumeBody(this, "bytes");
|
||||
|
@ -319,6 +324,7 @@ function mixinBody(prototype, bodySymbol, mimeTypeSymbol) {
|
|||
enumerable: true,
|
||||
},
|
||||
formData: {
|
||||
__proto__: null,
|
||||
/** @returns {Promise<FormData>} */
|
||||
value: function formData() {
|
||||
return consumeBody(this, "FormData");
|
||||
|
@ -328,6 +334,7 @@ function mixinBody(prototype, bodySymbol, mimeTypeSymbol) {
|
|||
enumerable: true,
|
||||
},
|
||||
json: {
|
||||
__proto__: null,
|
||||
/** @returns {Promise<any>} */
|
||||
value: function json() {
|
||||
return consumeBody(this, "JSON");
|
||||
|
@ -337,6 +344,7 @@ function mixinBody(prototype, bodySymbol, mimeTypeSymbol) {
|
|||
enumerable: true,
|
||||
},
|
||||
text: {
|
||||
__proto__: null,
|
||||
/** @returns {Promise<string>} */
|
||||
value: function text() {
|
||||
return consumeBody(this, "text");
|
||||
|
|
|
@ -42,6 +42,7 @@ class HttpClient {
|
|||
*/
|
||||
constructor(rid) {
|
||||
ObjectDefineProperty(this, internalRidSymbol, {
|
||||
__proto__: null,
|
||||
enumerable: false,
|
||||
value: rid,
|
||||
});
|
||||
|
|
|
@ -432,9 +432,9 @@ class Response {
|
|||
|
||||
webidl.configureInterface(Response);
|
||||
ObjectDefineProperties(Response, {
|
||||
json: { enumerable: true },
|
||||
redirect: { enumerable: true },
|
||||
error: { enumerable: true },
|
||||
json: { __proto__: null, enumerable: true },
|
||||
redirect: { __proto__: null, enumerable: true },
|
||||
error: { __proto__: null, enumerable: true },
|
||||
});
|
||||
const ResponsePrototype = Response.prototype;
|
||||
mixinBody(ResponsePrototype, _body, _mimeType);
|
||||
|
|
|
@ -355,12 +355,15 @@ const EventSourcePrototype = EventSource.prototype;
|
|||
|
||||
ObjectDefineProperties(EventSource, {
|
||||
CONNECTING: {
|
||||
__proto__: null,
|
||||
value: 0,
|
||||
},
|
||||
OPEN: {
|
||||
__proto__: null,
|
||||
value: 1,
|
||||
},
|
||||
CLOSED: {
|
||||
__proto__: null,
|
||||
value: 2,
|
||||
},
|
||||
});
|
||||
|
|
|
@ -484,10 +484,11 @@ class DynamicLibrary {
|
|||
this.symbols,
|
||||
symbol,
|
||||
{
|
||||
__proto__: null,
|
||||
configurable: false,
|
||||
enumerable: true,
|
||||
value,
|
||||
writable: false,
|
||||
value,
|
||||
},
|
||||
);
|
||||
continue;
|
||||
|
@ -504,8 +505,10 @@ class DynamicLibrary {
|
|||
this.symbols,
|
||||
symbol,
|
||||
{
|
||||
__proto__: null,
|
||||
configurable: false,
|
||||
enumerable: true,
|
||||
writable: false,
|
||||
value: (...parameters) => {
|
||||
if (isStructResult) {
|
||||
const buffer = new Uint8Array(structSize);
|
||||
|
@ -527,7 +530,6 @@ class DynamicLibrary {
|
|||
);
|
||||
}
|
||||
},
|
||||
writable: false,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
import { core, internals, primordials } from "ext:core/mod.js";
|
||||
import { core, primordials } from "ext:core/mod.js";
|
||||
const {
|
||||
isDate,
|
||||
internalRidSymbol,
|
||||
|
@ -15,15 +15,15 @@ import {
|
|||
op_fs_copy_file_async,
|
||||
op_fs_copy_file_sync,
|
||||
op_fs_cwd,
|
||||
op_fs_fdatasync_async,
|
||||
op_fs_fdatasync_sync,
|
||||
op_fs_file_stat_async,
|
||||
op_fs_file_stat_sync,
|
||||
op_fs_file_sync_async,
|
||||
op_fs_file_sync_data_async,
|
||||
op_fs_file_sync_data_sync,
|
||||
op_fs_file_sync_sync,
|
||||
op_fs_file_truncate_async,
|
||||
op_fs_flock_async,
|
||||
op_fs_flock_sync,
|
||||
op_fs_fsync_async,
|
||||
op_fs_fsync_sync,
|
||||
op_fs_ftruncate_sync,
|
||||
op_fs_funlock_async,
|
||||
op_fs_funlock_sync,
|
||||
|
@ -517,22 +517,6 @@ async function symlink(
|
|||
);
|
||||
}
|
||||
|
||||
function fdatasyncSync(rid) {
|
||||
op_fs_fdatasync_sync(rid);
|
||||
}
|
||||
|
||||
async function fdatasync(rid) {
|
||||
await op_fs_fdatasync_async(rid);
|
||||
}
|
||||
|
||||
function fsyncSync(rid) {
|
||||
op_fs_fsync_sync(rid);
|
||||
}
|
||||
|
||||
async function fsync(rid) {
|
||||
await op_fs_fsync_async(rid);
|
||||
}
|
||||
|
||||
function openSync(
|
||||
path,
|
||||
options,
|
||||
|
@ -585,33 +569,18 @@ class FsFile {
|
|||
|
||||
constructor(rid, symbol) {
|
||||
ObjectDefineProperty(this, internalRidSymbol, {
|
||||
__proto__: null,
|
||||
enumerable: false,
|
||||
value: rid,
|
||||
});
|
||||
this.#rid = rid;
|
||||
if (!symbol || symbol !== SymbolFor("Deno.internal.FsFile")) {
|
||||
internals.warnOnDeprecatedApi(
|
||||
"new Deno.FsFile()",
|
||||
new Error().stack,
|
||||
"Use `Deno.open` or `Deno.openSync` instead.",
|
||||
throw new TypeError(
|
||||
"`Deno.FsFile` cannot be constructed, use `Deno.open()` or `Deno.openSync()` instead.",
|
||||
);
|
||||
if (internals.future) {
|
||||
throw new TypeError(
|
||||
"`Deno.FsFile` cannot be constructed, use `Deno.open()` or `Deno.openSync()` instead.",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get rid() {
|
||||
internals.warnOnDeprecatedApi(
|
||||
"Deno.FsFile.rid",
|
||||
new Error().stack,
|
||||
"Use `Deno.FsFile` methods directly instead.",
|
||||
);
|
||||
return this.#rid;
|
||||
}
|
||||
|
||||
write(p) {
|
||||
return write(this.#rid, p);
|
||||
}
|
||||
|
@ -654,11 +623,11 @@ class FsFile {
|
|||
}
|
||||
|
||||
async syncData() {
|
||||
await op_fs_fdatasync_async(this.#rid);
|
||||
await op_fs_file_sync_data_async(this.#rid);
|
||||
}
|
||||
|
||||
syncDataSync() {
|
||||
op_fs_fdatasync_sync(this.#rid);
|
||||
op_fs_file_sync_data_sync(this.#rid);
|
||||
}
|
||||
|
||||
close() {
|
||||
|
@ -680,11 +649,11 @@ class FsFile {
|
|||
}
|
||||
|
||||
async sync() {
|
||||
await op_fs_fsync_async(this.#rid);
|
||||
await op_fs_file_sync_async(this.#rid);
|
||||
}
|
||||
|
||||
syncSync() {
|
||||
op_fs_fsync_sync(this.#rid);
|
||||
op_fs_file_sync_sync(this.#rid);
|
||||
}
|
||||
|
||||
async utime(atime, mtime) {
|
||||
|
@ -920,11 +889,7 @@ export {
|
|||
create,
|
||||
createSync,
|
||||
cwd,
|
||||
fdatasync,
|
||||
fdatasyncSync,
|
||||
FsFile,
|
||||
fsync,
|
||||
fsyncSync,
|
||||
link,
|
||||
linkSync,
|
||||
lstat,
|
||||
|
|
|
@ -91,7 +91,7 @@ impl FsPermissions for deno_permissions::PermissionsContainer {
|
|||
if resolved {
|
||||
self
|
||||
.check_special_file(path, api_name)
|
||||
.map_err(FsError::PermissionDenied)?;
|
||||
.map_err(FsError::NotCapable)?;
|
||||
return Ok(Cow::Borrowed(path));
|
||||
}
|
||||
|
||||
|
@ -99,11 +99,11 @@ impl FsPermissions for deno_permissions::PermissionsContainer {
|
|||
let read = read || !write;
|
||||
if read {
|
||||
FsPermissions::check_read(self, path, api_name)
|
||||
.map_err(|_| FsError::PermissionDenied("read"))?;
|
||||
.map_err(|_| FsError::NotCapable("read"))?;
|
||||
}
|
||||
if write {
|
||||
FsPermissions::check_write(self, path, api_name)
|
||||
.map_err(|_| FsError::PermissionDenied("write"))?;
|
||||
.map_err(|_| FsError::NotCapable("write"))?;
|
||||
}
|
||||
Ok(Cow::Borrowed(path))
|
||||
}
|
||||
|
@ -229,10 +229,10 @@ deno_core::extension!(deno_fs,
|
|||
|
||||
op_fs_seek_sync,
|
||||
op_fs_seek_async,
|
||||
op_fs_fdatasync_sync,
|
||||
op_fs_fdatasync_async,
|
||||
op_fs_fsync_sync,
|
||||
op_fs_fsync_async,
|
||||
op_fs_file_sync_data_sync,
|
||||
op_fs_file_sync_data_async,
|
||||
op_fs_file_sync_sync,
|
||||
op_fs_file_sync_async,
|
||||
op_fs_file_stat_sync,
|
||||
op_fs_file_stat_async,
|
||||
op_fs_flock_async,
|
||||
|
|
|
@ -60,7 +60,7 @@ fn map_permission_error(
|
|||
path: &Path,
|
||||
) -> AnyError {
|
||||
match error {
|
||||
FsError::PermissionDenied(err) => {
|
||||
FsError::NotCapable(err) => {
|
||||
let path = format!("{path:?}");
|
||||
let (path, truncated) = if path.len() > 1024 {
|
||||
(&path[0..1024], "...(truncated)")
|
||||
|
@ -74,7 +74,7 @@ fn map_permission_error(
|
|||
format!(
|
||||
"Requires {err} access to {path}{truncated}, run again with the --allow-{err} flag")
|
||||
};
|
||||
custom_error("PermissionDenied", msg)
|
||||
custom_error("NotCapable", msg)
|
||||
}
|
||||
err => Err::<(), _>(err)
|
||||
.context_path(operation, path)
|
||||
|
@ -1430,7 +1430,7 @@ pub async fn op_fs_seek_async(
|
|||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_fs_fdatasync_sync(
|
||||
pub fn op_fs_file_sync_data_sync(
|
||||
state: &mut OpState,
|
||||
#[smi] rid: ResourceId,
|
||||
) -> Result<(), AnyError> {
|
||||
|
@ -1440,7 +1440,7 @@ pub fn op_fs_fdatasync_sync(
|
|||
}
|
||||
|
||||
#[op2(async)]
|
||||
pub async fn op_fs_fdatasync_async(
|
||||
pub async fn op_fs_file_sync_data_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
#[smi] rid: ResourceId,
|
||||
) -> Result<(), AnyError> {
|
||||
|
@ -1450,7 +1450,7 @@ pub async fn op_fs_fdatasync_async(
|
|||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_fs_fsync_sync(
|
||||
pub fn op_fs_file_sync_sync(
|
||||
state: &mut OpState,
|
||||
#[smi] rid: ResourceId,
|
||||
) -> Result<(), AnyError> {
|
||||
|
@ -1460,7 +1460,7 @@ pub fn op_fs_fsync_sync(
|
|||
}
|
||||
|
||||
#[op2(async)]
|
||||
pub async fn op_fs_fsync_async(
|
||||
pub async fn op_fs_file_sync_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
#[smi] rid: ResourceId,
|
||||
) -> Result<(), AnyError> {
|
||||
|
|
|
@ -1069,8 +1069,10 @@ fn open_with_access_check(
|
|||
};
|
||||
(*access_check)(false, &path, &options)?;
|
||||
// On Linux, /proc may contain magic links that we don't want to resolve
|
||||
let needs_canonicalization = !is_windows_device_path
|
||||
&& (!cfg!(target_os = "linux") || path.starts_with("/proc"));
|
||||
let is_linux_special_path = cfg!(target_os = "linux")
|
||||
&& (path.starts_with("/proc") || path.starts_with("/dev"));
|
||||
let needs_canonicalization =
|
||||
!is_windows_device_path && !is_linux_special_path;
|
||||
let path = if needs_canonicalization {
|
||||
match path.canonicalize() {
|
||||
Ok(path) => path,
|
||||
|
|
|
@ -583,7 +583,7 @@ type RawServeOptions = {
|
|||
|
||||
const kLoadBalanced = Symbol("kLoadBalanced");
|
||||
|
||||
function mapAnyAddrToLocalhostForWindows(hostname: string) {
|
||||
function formatHostName(hostname: string): string {
|
||||
// If the hostname is "0.0.0.0", we display "localhost" in console
|
||||
// because browsers in Windows don't resolve "0.0.0.0".
|
||||
// See the discussion in https://github.com/denoland/deno_std/issues/1165
|
||||
|
@ -593,7 +593,9 @@ function mapAnyAddrToLocalhostForWindows(hostname: string) {
|
|||
) {
|
||||
return "localhost";
|
||||
}
|
||||
return hostname;
|
||||
|
||||
// Add brackets around ipv6 hostname
|
||||
return StringPrototypeIncludes(hostname, ":") ? `[${hostname}]` : hostname;
|
||||
}
|
||||
|
||||
function serve(arg1, arg2) {
|
||||
|
@ -690,10 +692,8 @@ function serve(arg1, arg2) {
|
|||
if (options.onListen) {
|
||||
options.onListen(addr);
|
||||
} else {
|
||||
const hostname = mapAnyAddrToLocalhostForWindows(addr.hostname);
|
||||
const host = StringPrototypeIncludes(hostname, ":")
|
||||
? `[${hostname}]`
|
||||
: hostname;
|
||||
const host = formatHostName(addr.hostname);
|
||||
|
||||
// deno-lint-ignore no-console
|
||||
console.log(`Listening on ${scheme}${host}:${addr.port}/`);
|
||||
}
|
||||
|
@ -868,10 +868,11 @@ function registerDeclarativeServer(exports) {
|
|||
const nThreads = serveWorkerCount > 1
|
||||
? ` with ${serveWorkerCount} threads`
|
||||
: "";
|
||||
const hostname_ = mapAnyAddrToLocalhostForWindows(hostname);
|
||||
const host = formatHostName(hostname);
|
||||
|
||||
// deno-lint-ignore no-console
|
||||
console.debug(
|
||||
`%cdeno serve%c: Listening on %chttp://${hostname_}:${port}/%c${nThreads}`,
|
||||
`%cdeno serve%c: Listening on %chttp://${host}:${port}/%c${nThreads}`,
|
||||
"color: green",
|
||||
"color: inherit",
|
||||
"color: yellow",
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// Documentation liberally lifted from them too.
|
||||
// Thank you! We love Go! <3
|
||||
|
||||
import { core, internals, primordials } from "ext:core/mod.js";
|
||||
import { core, primordials } from "ext:core/mod.js";
|
||||
import { op_set_raw } from "ext:core/ops";
|
||||
const {
|
||||
Uint8Array,
|
||||
|
@ -121,11 +121,6 @@ class Stdin {
|
|||
}
|
||||
|
||||
get rid() {
|
||||
internals.warnOnDeprecatedApi(
|
||||
"Deno.stdin.rid",
|
||||
new Error().stack,
|
||||
"Use `Deno.stdin` instance methods instead.",
|
||||
);
|
||||
return this.#rid;
|
||||
}
|
||||
|
||||
|
@ -186,11 +181,6 @@ class Stdout {
|
|||
}
|
||||
|
||||
get rid() {
|
||||
internals.warnOnDeprecatedApi(
|
||||
"Deno.stdout.rid",
|
||||
new Error().stack,
|
||||
"Use `Deno.stdout` instance methods instead.",
|
||||
);
|
||||
return this.#rid;
|
||||
}
|
||||
|
||||
|
@ -226,11 +216,6 @@ class Stderr {
|
|||
}
|
||||
|
||||
get rid() {
|
||||
internals.warnOnDeprecatedApi(
|
||||
"Deno.stderr.rid",
|
||||
new Error().stack,
|
||||
"Use `Deno.stderr` instance methods instead.",
|
||||
);
|
||||
return this.#rid;
|
||||
}
|
||||
|
||||
|
|
10
ext/io/fs.rs
10
ext/io/fs.rs
|
@ -22,7 +22,7 @@ pub enum FsError {
|
|||
Io(io::Error),
|
||||
FileBusy,
|
||||
NotSupported,
|
||||
PermissionDenied(&'static str),
|
||||
NotCapable(&'static str),
|
||||
}
|
||||
|
||||
impl FsError {
|
||||
|
@ -31,7 +31,7 @@ impl FsError {
|
|||
Self::Io(err) => err.kind(),
|
||||
Self::FileBusy => io::ErrorKind::Other,
|
||||
Self::NotSupported => io::ErrorKind::Other,
|
||||
Self::PermissionDenied(_) => io::ErrorKind::PermissionDenied,
|
||||
Self::NotCapable(_) => io::ErrorKind::Other,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ impl FsError {
|
|||
FsError::Io(err) => err,
|
||||
FsError::FileBusy => io::Error::new(self.kind(), "file busy"),
|
||||
FsError::NotSupported => io::Error::new(self.kind(), "not supported"),
|
||||
FsError::PermissionDenied(err) => {
|
||||
FsError::NotCapable(err) => {
|
||||
io::Error::new(self.kind(), format!("requires {err} access"))
|
||||
}
|
||||
}
|
||||
|
@ -65,8 +65,8 @@ impl From<FsError> for AnyError {
|
|||
FsError::Io(err) => AnyError::from(err),
|
||||
FsError::FileBusy => resource_unavailable(),
|
||||
FsError::NotSupported => not_supported(),
|
||||
FsError::PermissionDenied(err) => {
|
||||
custom_error("PermissionDenied", format!("permission denied: {err}"))
|
||||
FsError::NotCapable(err) => {
|
||||
custom_error("NotCapable", format!("permission denied: {err}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
import { core, internals, primordials } from "ext:core/mod.js";
|
||||
import { core, primordials } from "ext:core/mod.js";
|
||||
const {
|
||||
BadResourcePrototype,
|
||||
InterruptedPrototype,
|
||||
|
@ -101,13 +101,8 @@ class Conn {
|
|||
#writable;
|
||||
|
||||
constructor(rid, remoteAddr, localAddr) {
|
||||
if (internals.future) {
|
||||
ObjectDefineProperty(this, "rid", {
|
||||
enumerable: false,
|
||||
value: undefined,
|
||||
});
|
||||
}
|
||||
ObjectDefineProperty(this, internalRidSymbol, {
|
||||
__proto__: null,
|
||||
enumerable: false,
|
||||
value: rid,
|
||||
});
|
||||
|
@ -116,15 +111,6 @@ class Conn {
|
|||
this.#localAddr = localAddr;
|
||||
}
|
||||
|
||||
get rid() {
|
||||
internals.warnOnDeprecatedApi(
|
||||
"Deno.Conn.rid",
|
||||
new Error().stack,
|
||||
"Use `Deno.Conn` instance methods instead.",
|
||||
);
|
||||
return this.#rid;
|
||||
}
|
||||
|
||||
get remoteAddr() {
|
||||
return this.#remoteAddr;
|
||||
}
|
||||
|
@ -214,21 +200,13 @@ class TcpConn extends Conn {
|
|||
constructor(rid, remoteAddr, localAddr) {
|
||||
super(rid, remoteAddr, localAddr);
|
||||
ObjectDefineProperty(this, internalRidSymbol, {
|
||||
__proto__: null,
|
||||
enumerable: false,
|
||||
value: rid,
|
||||
});
|
||||
this.#rid = rid;
|
||||
}
|
||||
|
||||
get rid() {
|
||||
internals.warnOnDeprecatedApi(
|
||||
"Deno.TcpConn.rid",
|
||||
new Error().stack,
|
||||
"Use `Deno.TcpConn` instance methods instead.",
|
||||
);
|
||||
return this.#rid;
|
||||
}
|
||||
|
||||
setNoDelay(noDelay = true) {
|
||||
return op_set_nodelay(this.#rid, noDelay);
|
||||
}
|
||||
|
@ -244,20 +222,12 @@ class UnixConn extends Conn {
|
|||
constructor(rid, remoteAddr, localAddr) {
|
||||
super(rid, remoteAddr, localAddr);
|
||||
ObjectDefineProperty(this, internalRidSymbol, {
|
||||
__proto__: null,
|
||||
enumerable: false,
|
||||
value: rid,
|
||||
});
|
||||
this.#rid = rid;
|
||||
}
|
||||
|
||||
get rid() {
|
||||
internals.warnOnDeprecatedApi(
|
||||
"Deno.UnixConn.rid",
|
||||
new Error().stack,
|
||||
"Use `Deno.UnixConn` instance methods instead.",
|
||||
);
|
||||
return this.#rid;
|
||||
}
|
||||
}
|
||||
|
||||
class Listener {
|
||||
|
@ -267,13 +237,8 @@ class Listener {
|
|||
#promise = null;
|
||||
|
||||
constructor(rid, addr) {
|
||||
if (internals.future) {
|
||||
ObjectDefineProperty(this, "rid", {
|
||||
enumerable: false,
|
||||
value: undefined,
|
||||
});
|
||||
}
|
||||
ObjectDefineProperty(this, internalRidSymbol, {
|
||||
__proto__: null,
|
||||
enumerable: false,
|
||||
value: rid,
|
||||
});
|
||||
|
@ -281,15 +246,6 @@ class Listener {
|
|||
this.#addr = addr;
|
||||
}
|
||||
|
||||
get rid() {
|
||||
internals.warnOnDeprecatedApi(
|
||||
"Deno.Listener.rid",
|
||||
new Error().stack,
|
||||
"Use `Deno.Listener` instance methods instead.",
|
||||
);
|
||||
return this.#rid;
|
||||
}
|
||||
|
||||
get addr() {
|
||||
return this.#addr;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ import {
|
|||
op_tls_handshake,
|
||||
op_tls_key_null,
|
||||
op_tls_key_static,
|
||||
op_tls_key_static_from_file,
|
||||
op_tls_start,
|
||||
} from "ext:core/ops";
|
||||
const {
|
||||
|
@ -30,21 +29,13 @@ class TlsConn extends Conn {
|
|||
constructor(rid, remoteAddr, localAddr) {
|
||||
super(rid, remoteAddr, localAddr);
|
||||
ObjectDefineProperty(this, internalRidSymbol, {
|
||||
__proto__: null,
|
||||
enumerable: false,
|
||||
value: rid,
|
||||
});
|
||||
this.#rid = rid;
|
||||
}
|
||||
|
||||
get rid() {
|
||||
internals.warnOnDeprecatedApi(
|
||||
"Deno.TlsConn.rid",
|
||||
new Error().stack,
|
||||
"Use `Deno.TlsConn` instance methods instead.",
|
||||
);
|
||||
return this.#rid;
|
||||
}
|
||||
|
||||
handshake() {
|
||||
return op_tls_handshake(this.#rid);
|
||||
}
|
||||
|
@ -58,45 +49,23 @@ async function connectTls({
|
|||
alpnProtocols = undefined,
|
||||
keyFormat = undefined,
|
||||
cert = undefined,
|
||||
certFile = undefined,
|
||||
certChain = undefined,
|
||||
key = undefined,
|
||||
keyFile = undefined,
|
||||
privateKey = undefined,
|
||||
}) {
|
||||
if (transport !== "tcp") {
|
||||
throw new TypeError(`Unsupported transport: '${transport}'`);
|
||||
}
|
||||
let deprecatedCertFile = undefined;
|
||||
|
||||
// Deno.connectTls has an irregular option where you can just pass `certFile` and
|
||||
// not `keyFile`. In this case it's used for `caCerts` rather than the client key.
|
||||
if (certFile !== undefined && keyFile === undefined) {
|
||||
internals.warnOnDeprecatedApi(
|
||||
"Deno.ConnectTlsOptions.certFile",
|
||||
new Error().stack,
|
||||
"Pass the cert file's contents to the `Deno.ConnectTlsOptions.caCerts` option instead.",
|
||||
);
|
||||
|
||||
deprecatedCertFile = certFile;
|
||||
certFile = undefined;
|
||||
}
|
||||
|
||||
const keyPair = loadTlsKeyPair("Deno.connectTls", {
|
||||
keyFormat,
|
||||
cert,
|
||||
certFile,
|
||||
certChain,
|
||||
key,
|
||||
keyFile,
|
||||
privateKey,
|
||||
});
|
||||
// TODO(mmastrac): We only expose this feature via symbol for now. This should actually be a feature
|
||||
// in Deno.connectTls, however.
|
||||
const serverName = arguments[0][serverNameSymbol] ?? null;
|
||||
const { 0: rid, 1: localAddr, 2: remoteAddr } = await op_net_connect_tls(
|
||||
{ hostname, port },
|
||||
{ certFile: deprecatedCertFile, caCerts, alpnProtocols, serverName },
|
||||
{ caCerts, alpnProtocols, serverName },
|
||||
keyPair,
|
||||
);
|
||||
localAddr.transport = "tcp";
|
||||
|
@ -110,21 +79,13 @@ class TlsListener extends Listener {
|
|||
constructor(rid, addr) {
|
||||
super(rid, addr);
|
||||
ObjectDefineProperty(this, internalRidSymbol, {
|
||||
__proto__: null,
|
||||
enumerable: false,
|
||||
value: rid,
|
||||
});
|
||||
this.#rid = rid;
|
||||
}
|
||||
|
||||
get rid() {
|
||||
internals.warnOnDeprecatedApi(
|
||||
"Deno.TlsListener.rid",
|
||||
new Error().stack,
|
||||
"Use `Deno.TlsListener` instance methods instead.",
|
||||
);
|
||||
return this.#rid;
|
||||
}
|
||||
|
||||
async accept() {
|
||||
const { 0: rid, 1: localAddr, 2: remoteAddr } = await op_net_accept_tls(
|
||||
this.#rid,
|
||||
|
@ -144,10 +105,7 @@ function hasTlsKeyPairOptions(options) {
|
|||
if (options[resolverSymbol] !== undefined) {
|
||||
return true;
|
||||
}
|
||||
return (options.cert !== undefined || options.key !== undefined ||
|
||||
options.certFile !== undefined ||
|
||||
options.keyFile !== undefined || options.privateKey !== undefined ||
|
||||
options.certChain !== undefined);
|
||||
return (options.cert !== undefined || options.key !== undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,19 +115,8 @@ function hasTlsKeyPairOptions(options) {
|
|||
function loadTlsKeyPair(api, {
|
||||
keyFormat,
|
||||
cert,
|
||||
certFile,
|
||||
certChain,
|
||||
key,
|
||||
keyFile,
|
||||
privateKey,
|
||||
}) {
|
||||
if (internals.future) {
|
||||
certFile = undefined;
|
||||
certChain = undefined;
|
||||
keyFile = undefined;
|
||||
privateKey = undefined;
|
||||
}
|
||||
|
||||
// TODO(mmastrac): remove this temporary symbol when the API lands
|
||||
if (arguments[1][resolverSymbol] !== undefined) {
|
||||
return createTlsKeyResolver(arguments[1][resolverSymbol]);
|
||||
|
@ -180,68 +127,18 @@ function loadTlsKeyPair(api, {
|
|||
throw new TypeError('If `keyFormat` is specified, it must be "pem"');
|
||||
}
|
||||
|
||||
function exclusive(a1, a1v, a2, a2v) {
|
||||
if (a1v !== undefined && a2v !== undefined) {
|
||||
throw new TypeError(
|
||||
`Cannot specify both \`${a1}\` and \`${a2}\` for \`${api}\`.`,
|
||||
);
|
||||
}
|
||||
if (cert !== undefined && key === undefined) {
|
||||
throw new TypeError(
|
||||
`If \`cert\` is specified, \`key\` must be specified as well for \`${api}\`.`,
|
||||
);
|
||||
}
|
||||
if (cert === undefined && key !== undefined) {
|
||||
throw new TypeError(
|
||||
`If \`key\` is specified, \`cert\` must be specified as well for \`${api}\`.`,
|
||||
);
|
||||
}
|
||||
|
||||
// Ensure that only one pair is valid
|
||||
exclusive("certChain", certChain, "cert", cert);
|
||||
exclusive("certChain", certChain, "certFile", certFile);
|
||||
exclusive("key", key, "keyFile", keyFile);
|
||||
exclusive("key", key, "privateKey", privateKey);
|
||||
|
||||
function both(a1, a1v, a2, a2v) {
|
||||
if (a1v !== undefined && a2v === undefined) {
|
||||
throw new TypeError(
|
||||
`If \`${a1}\` is specified, \`${a2}\` must be specified as well for \`${api}\`.`,
|
||||
);
|
||||
}
|
||||
if (a1v === undefined && a2v !== undefined) {
|
||||
throw new TypeError(
|
||||
`If \`${a2}\` is specified, \`${a1}\` must be specified as well for \`${api}\`.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Pick one pair of cert/key, certFile/keyFile or certChain/privateKey
|
||||
both("cert", cert, "key", key);
|
||||
both("certFile", certFile, "keyFile", keyFile);
|
||||
both("certChain", certChain, "privateKey", privateKey);
|
||||
|
||||
if (certFile !== undefined) {
|
||||
internals.warnOnDeprecatedApi(
|
||||
"Deno.TlsCertifiedKeyOptions.keyFile",
|
||||
new Error().stack,
|
||||
"Pass the key file's contents to the `Deno.TlsCertifiedKeyPem.key` option instead.",
|
||||
);
|
||||
internals.warnOnDeprecatedApi(
|
||||
"Deno.TlsCertifiedKeyOptions.certFile",
|
||||
new Error().stack,
|
||||
"Pass the cert file's contents to the `Deno.TlsCertifiedKeyPem.cert` option instead.",
|
||||
);
|
||||
return op_tls_key_static_from_file(api, certFile, keyFile);
|
||||
} else if (certChain !== undefined) {
|
||||
if (api !== "Deno.connectTls") {
|
||||
throw new TypeError(
|
||||
`Invalid options 'certChain' and 'privateKey' for ${api}`,
|
||||
);
|
||||
}
|
||||
internals.warnOnDeprecatedApi(
|
||||
"Deno.TlsCertifiedKeyOptions.privateKey",
|
||||
new Error().stack,
|
||||
"Use the `Deno.TlsCertifiedKeyPem.key` option instead.",
|
||||
);
|
||||
internals.warnOnDeprecatedApi(
|
||||
"Deno.TlsCertifiedKeyOptions.certChain",
|
||||
new Error().stack,
|
||||
"Use the `Deno.TlsCertifiedKeyPem.cert` option instead.",
|
||||
);
|
||||
return op_tls_key_static(certChain, privateKey);
|
||||
} else if (cert !== undefined) {
|
||||
if (cert !== undefined) {
|
||||
return op_tls_key_static(cert, key);
|
||||
} else {
|
||||
return op_tls_key_null();
|
||||
|
|
174
ext/net/lib.deno_net.d.ts
vendored
174
ext/net/lib.deno_net.d.ts
vendored
|
@ -35,15 +35,6 @@ declare namespace Deno {
|
|||
/** Return the address of the `Listener`. */
|
||||
readonly addr: A;
|
||||
|
||||
/**
|
||||
* Return the rid of the `Listener`.
|
||||
*
|
||||
* @deprecated This will be removed in Deno 2.0. See the
|
||||
* {@link https://docs.deno.com/runtime/manual/advanced/migrate_deprecations | Deno 1.x to 2.x Migration Guide}
|
||||
* for migration instructions.
|
||||
*/
|
||||
readonly rid: number;
|
||||
|
||||
[Symbol.asyncIterator](): AsyncIterableIterator<T>;
|
||||
|
||||
/**
|
||||
|
@ -77,20 +68,61 @@ declare namespace Deno {
|
|||
export type UnixListener = Listener<UnixConn, UnixAddr>;
|
||||
|
||||
/** @category Network */
|
||||
export interface Conn<A extends Addr = Addr>
|
||||
extends Reader, Writer, Closer, Disposable {
|
||||
export interface Conn<A extends Addr = Addr> extends Disposable {
|
||||
/** Read the incoming data from the connection into an array buffer (`p`).
|
||||
*
|
||||
* Resolves to either the number of bytes read during the operation or EOF
|
||||
* (`null`) if there was nothing more to read.
|
||||
*
|
||||
* It is possible for a read to successfully return with `0` bytes. This
|
||||
* does not indicate EOF.
|
||||
*
|
||||
* **It is not guaranteed that the full buffer will be read in a single
|
||||
* call.**
|
||||
*
|
||||
* ```ts
|
||||
* // If the text "hello world" is received by the client:
|
||||
* const conn = await Deno.connect({ hostname: "example.com", port: 80 });
|
||||
* const buf = new Uint8Array(100);
|
||||
* const numberOfBytesRead = await conn.read(buf); // 11 bytes
|
||||
* const text = new TextDecoder().decode(buf); // "hello world"
|
||||
* ```
|
||||
*
|
||||
* @category I/O
|
||||
*/
|
||||
read(p: Uint8Array): Promise<number | null>;
|
||||
/** Write the contents of the array buffer (`p`) to the connection.
|
||||
*
|
||||
* Resolves to the number of bytes written.
|
||||
*
|
||||
* **It is not guaranteed that the full buffer will be written in a single
|
||||
* call.**
|
||||
*
|
||||
* ```ts
|
||||
* const conn = await Deno.connect({ hostname: "example.com", port: 80 });
|
||||
* const encoder = new TextEncoder();
|
||||
* const data = encoder.encode("Hello world");
|
||||
* const bytesWritten = await conn.write(data); // 11
|
||||
* ```
|
||||
*
|
||||
* @category I/O
|
||||
*/
|
||||
write(p: Uint8Array): Promise<number>;
|
||||
/** Closes the connection, freeing the resource.
|
||||
*
|
||||
* ```ts
|
||||
* const conn = await Deno.connect({ hostname: "example.com", port: 80 });
|
||||
*
|
||||
* // ...
|
||||
*
|
||||
* conn.close();
|
||||
* ```
|
||||
*/
|
||||
close(): void;
|
||||
/** The local address of the connection. */
|
||||
readonly localAddr: A;
|
||||
/** The remote address of the connection. */
|
||||
readonly remoteAddr: A;
|
||||
/**
|
||||
* The resource ID of the connection.
|
||||
*
|
||||
* @deprecated This will be removed in Deno 2.0. See the
|
||||
* {@link https://docs.deno.com/runtime/manual/advanced/migrate_deprecations | Deno 1.x to 2.x Migration Guide}
|
||||
* for migration instructions.
|
||||
*/
|
||||
readonly rid: number;
|
||||
/** Shuts down (`shutdown(2)`) the write side of the connection. Most
|
||||
* callers should just use `close()`. */
|
||||
closeWrite(): Promise<void>;
|
||||
|
@ -123,14 +155,6 @@ declare namespace Deno {
|
|||
* not happened yet. Calling this method is optional; the TLS handshake
|
||||
* will be completed automatically as soon as data is sent or received. */
|
||||
handshake(): Promise<TlsHandshakeInfo>;
|
||||
/**
|
||||
* The resource ID of the connection.
|
||||
*
|
||||
* @deprecated This will be removed in Deno 2.0. See the
|
||||
* {@link https://docs.deno.com/runtime/manual/advanced/migrate_deprecations | Deno 1.x to 2.x Migration Guide}
|
||||
* for migration instructions.
|
||||
*/
|
||||
readonly rid: number;
|
||||
}
|
||||
|
||||
/** @category Network */
|
||||
|
@ -199,16 +223,6 @@ declare namespace Deno {
|
|||
options: UnixListenOptions & { transport: "unix" },
|
||||
): UnixListener;
|
||||
|
||||
/** Provides TLS certified keys, ie: a key that has been certified by a trusted certificate authority.
|
||||
* A certified key generally consists of a private key and certificate part.
|
||||
*
|
||||
* @category Network
|
||||
*/
|
||||
export type TlsCertifiedKeyOptions =
|
||||
| TlsCertifiedKeyPem
|
||||
| TlsCertifiedKeyFromFile
|
||||
| TlsCertifiedKeyConnectTls;
|
||||
|
||||
/**
|
||||
* Provides certified key material from strings. The key material is provided in
|
||||
* `PEM`-format (Privacy Enhanced Mail, https://www.rfc-editor.org/rfc/rfc1422) which can be identified by having
|
||||
|
@ -235,59 +249,6 @@ declare namespace Deno {
|
|||
cert: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This will be removed in Deno 2.0. See the
|
||||
* {@link https://docs.deno.com/runtime/manual/advanced/migrate_deprecations | Deno 1.x to 2.x Migration Guide}
|
||||
* for migration instructions.
|
||||
*
|
||||
* @category Network
|
||||
*/
|
||||
export interface TlsCertifiedKeyFromFile {
|
||||
/** Path to a file containing a PEM formatted CA certificate. Requires
|
||||
* `--allow-read`.
|
||||
*
|
||||
* @tags allow-read
|
||||
* @deprecated This will be removed in Deno 2.0. See the
|
||||
* {@link https://docs.deno.com/runtime/manual/advanced/migrate_deprecations | Deno 1.x to 2.x Migration Guide}
|
||||
* for migration instructions.
|
||||
*/
|
||||
certFile: string;
|
||||
/** Path to a file containing a private key file. Requires `--allow-read`.
|
||||
*
|
||||
* @tags allow-read
|
||||
* @deprecated This will be removed in Deno 2.0. See the
|
||||
* {@link https://docs.deno.com/runtime/manual/advanced/migrate_deprecations | Deno 1.x to 2.x Migration Guide}
|
||||
* for migration instructions.
|
||||
*/
|
||||
keyFile: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This will be removed in Deno 2.0. See the
|
||||
* {@link https://docs.deno.com/runtime/manual/advanced/migrate_deprecations | Deno 1.x to 2.x Migration Guide}
|
||||
* for migration instructions.
|
||||
*
|
||||
* @category Network
|
||||
*/
|
||||
export interface TlsCertifiedKeyConnectTls {
|
||||
/**
|
||||
* Certificate chain in `PEM` format.
|
||||
*
|
||||
* @deprecated This will be removed in Deno 2.0. See the
|
||||
* {@link https://docs.deno.com/runtime/manual/advanced/migrate_deprecations | Deno 1.x to 2.x Migration Guide}
|
||||
* for migration instructions.
|
||||
*/
|
||||
certChain: string;
|
||||
/**
|
||||
* Private key in `PEM` format. RSA, EC, and PKCS8-format keys are supported.
|
||||
*
|
||||
* @deprecated This will be removed in Deno 2.0. See the
|
||||
* {@link https://docs.deno.com/runtime/manual/advanced/migrate_deprecations | Deno 1.x to 2.x Migration Guide}
|
||||
* for migration instructions.
|
||||
*/
|
||||
privateKey: string;
|
||||
}
|
||||
|
||||
/** @category Network */
|
||||
export interface ListenTlsOptions extends TcpListenOptions {
|
||||
transport?: "tcp";
|
||||
|
@ -316,7 +277,7 @@ declare namespace Deno {
|
|||
* @category Network
|
||||
*/
|
||||
export function listenTls(
|
||||
options: ListenTlsOptions & TlsCertifiedKeyOptions,
|
||||
options: ListenTlsOptions & TlsCertifiedKeyPem,
|
||||
): TlsListener;
|
||||
|
||||
/** @category Network */
|
||||
|
@ -359,14 +320,6 @@ declare namespace Deno {
|
|||
setNoDelay(noDelay?: boolean): void;
|
||||
/** Enable/disable keep-alive functionality. */
|
||||
setKeepAlive(keepAlive?: boolean): void;
|
||||
/**
|
||||
* The resource ID of the connection.
|
||||
*
|
||||
* @deprecated This will be removed in Deno 2.0. See the
|
||||
* {@link https://docs.deno.com/runtime/manual/advanced/migrate_deprecations | Deno 1.x to 2.x Migration Guide}
|
||||
* for migration instructions.
|
||||
*/
|
||||
readonly rid: number;
|
||||
}
|
||||
|
||||
/** @category Network */
|
||||
|
@ -376,16 +329,7 @@ declare namespace Deno {
|
|||
}
|
||||
|
||||
/** @category Network */
|
||||
export interface UnixConn extends Conn<UnixAddr> {
|
||||
/**
|
||||
* The resource ID of the connection.
|
||||
*
|
||||
* @deprecated This will be removed in Deno 2.0. See the
|
||||
* {@link https://docs.deno.com/runtime/manual/advanced/migrate_deprecations | Deno 1.x to 2.x Migration Guide}
|
||||
* for migration instructions.
|
||||
*/
|
||||
readonly rid: number;
|
||||
}
|
||||
export interface UnixConn extends Conn<UnixAddr> {}
|
||||
|
||||
/** Connects to the hostname (default is "127.0.0.1") and port on the named
|
||||
* transport (default is "tcp"), and resolves to the connection (`Conn`).
|
||||
|
@ -414,16 +358,6 @@ declare namespace Deno {
|
|||
*
|
||||
* @default {"127.0.0.1"} */
|
||||
hostname?: string;
|
||||
/** Path to a file containing a PEM formatted list of root certificates that will
|
||||
* be used in addition to the default root certificates to verify the peer's certificate. Requires
|
||||
* `--allow-read`.
|
||||
*
|
||||
* @tags allow-read
|
||||
* @deprecated This will be removed in Deno 2.0. See the
|
||||
* {@link https://docs.deno.com/runtime/manual/advanced/migrate_deprecations | Deno 1.x to 2.x Migration Guide}
|
||||
* for migration instructions.
|
||||
*/
|
||||
certFile?: string;
|
||||
/** A list of root certificates that will be used in addition to the
|
||||
* default root certificates to verify the peer's certificate.
|
||||
*
|
||||
|
@ -477,7 +411,7 @@ declare namespace Deno {
|
|||
* @category Network
|
||||
*/
|
||||
export function connectTls(
|
||||
options: ConnectTlsOptions & TlsCertifiedKeyOptions,
|
||||
options: ConnectTlsOptions & TlsCertifiedKeyPem,
|
||||
): Promise<TlsConn>;
|
||||
|
||||
/** @category Network */
|
||||
|
|
|
@ -115,7 +115,6 @@ deno_core::extension!(deno_net,
|
|||
|
||||
ops_tls::op_tls_key_null,
|
||||
ops_tls::op_tls_key_static,
|
||||
ops_tls::op_tls_key_static_from_file<P>,
|
||||
ops_tls::op_tls_cert_resolver_create,
|
||||
ops_tls::op_tls_cert_resolver_poll,
|
||||
ops_tls::op_tls_cert_resolver_resolve,
|
||||
|
|
|
@ -34,8 +34,6 @@ use deno_tls::new_resolver;
|
|||
use deno_tls::rustls::pki_types::ServerName;
|
||||
use deno_tls::rustls::ClientConnection;
|
||||
use deno_tls::rustls::ServerConfig;
|
||||
use deno_tls::webpki::types::CertificateDer;
|
||||
use deno_tls::webpki::types::PrivateKeyDer;
|
||||
use deno_tls::ServerConfigProvider;
|
||||
use deno_tls::SocketUse;
|
||||
use deno_tls::TlsKey;
|
||||
|
@ -213,32 +211,6 @@ pub fn op_tls_key_static(
|
|||
Ok(TlsKeysHolder::from(TlsKeys::Static(TlsKey(cert, key))))
|
||||
}
|
||||
|
||||
/// Legacy op -- will be removed in Deno 2.0.
|
||||
#[op2]
|
||||
#[cppgc]
|
||||
pub fn op_tls_key_static_from_file<NP>(
|
||||
state: &mut OpState,
|
||||
#[string] api: String,
|
||||
#[string] cert_file: String,
|
||||
#[string] key_file: String,
|
||||
) -> Result<TlsKeysHolder, AnyError>
|
||||
where
|
||||
NP: NetPermissions + 'static,
|
||||
{
|
||||
{
|
||||
let permissions = state.borrow_mut::<NP>();
|
||||
permissions.check_read(Path::new(&cert_file), &api)?;
|
||||
permissions.check_read(Path::new(&key_file), &api)?;
|
||||
}
|
||||
|
||||
let cert = load_certs_from_file(&cert_file)?;
|
||||
let key = load_private_keys_from_file(&key_file)?
|
||||
.into_iter()
|
||||
.next()
|
||||
.unwrap();
|
||||
Ok(TlsKeysHolder::from(TlsKeys::Static(TlsKey(cert, key))))
|
||||
}
|
||||
|
||||
#[op2]
|
||||
pub fn op_tls_cert_resolver_create<'s>(
|
||||
scope: &mut v8::HandleScope<'s>,
|
||||
|
@ -455,21 +427,6 @@ where
|
|||
Ok((rid, IpAddr::from(local_addr), IpAddr::from(remote_addr)))
|
||||
}
|
||||
|
||||
fn load_certs_from_file(
|
||||
path: &str,
|
||||
) -> Result<Vec<CertificateDer<'static>>, AnyError> {
|
||||
let cert_file = File::open(path)?;
|
||||
let reader = &mut BufReader::new(cert_file);
|
||||
load_certs(reader)
|
||||
}
|
||||
|
||||
fn load_private_keys_from_file(
|
||||
path: &str,
|
||||
) -> Result<Vec<PrivateKeyDer<'static>>, AnyError> {
|
||||
let key_bytes = std::fs::read(path)?;
|
||||
load_private_keys(&key_bytes)
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ListenTlsArgs {
|
||||
|
|
|
@ -97,7 +97,7 @@ url.workspace = true
|
|||
winapi.workspace = true
|
||||
x25519-dalek = { version = "2.0.0", features = ["static_secrets"] }
|
||||
x509-parser = "0.15.0"
|
||||
yoke = { version = "0.7.4", features = ["derive"] }
|
||||
yoke.workspace = true
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
windows-sys.workspace = true
|
||||
|
|
|
@ -29,6 +29,7 @@ if (process.env.CHILD) {
|
|||
const start = performance.now();
|
||||
|
||||
const options = {
|
||||
__proto__: null,
|
||||
"stdio": ["inherit", "inherit", "inherit", "ipc"],
|
||||
"env": { "CHILD": len.toString() },
|
||||
};
|
||||
|
|
|
@ -286,6 +286,25 @@ deno_core::extension!(deno_node,
|
|||
ops::winerror::op_node_sys_to_uv_error,
|
||||
ops::v8::op_v8_cached_data_version_tag,
|
||||
ops::v8::op_v8_get_heap_statistics,
|
||||
ops::v8::op_v8_get_wire_format_version,
|
||||
ops::v8::op_v8_new_deserializer,
|
||||
ops::v8::op_v8_new_serializer,
|
||||
ops::v8::op_v8_read_double,
|
||||
ops::v8::op_v8_read_header,
|
||||
ops::v8::op_v8_read_raw_bytes,
|
||||
ops::v8::op_v8_read_uint32,
|
||||
ops::v8::op_v8_read_uint64,
|
||||
ops::v8::op_v8_read_value,
|
||||
ops::v8::op_v8_release_buffer,
|
||||
ops::v8::op_v8_set_treat_array_buffer_views_as_host_objects,
|
||||
ops::v8::op_v8_transfer_array_buffer,
|
||||
ops::v8::op_v8_transfer_array_buffer_de,
|
||||
ops::v8::op_v8_write_double,
|
||||
ops::v8::op_v8_write_header,
|
||||
ops::v8::op_v8_write_raw_bytes,
|
||||
ops::v8::op_v8_write_uint32,
|
||||
ops::v8::op_v8_write_uint64,
|
||||
ops::v8::op_v8_write_value,
|
||||
ops::vm::op_vm_create_script,
|
||||
ops::vm::op_vm_create_context,
|
||||
ops::vm::op_vm_script_run_in_context,
|
||||
|
@ -339,6 +358,7 @@ deno_core::extension!(deno_node,
|
|||
ops::os::op_homedir<P>,
|
||||
op_node_build_os,
|
||||
op_npm_process_state,
|
||||
ops::require::op_require_can_parse_as_esm,
|
||||
ops::require::op_require_init_paths,
|
||||
ops::require::op_require_node_module_paths<P>,
|
||||
ops::require::op_require_proxy_path,
|
||||
|
|
|
@ -4,6 +4,7 @@ use aes::cipher::block_padding::Pkcs7;
|
|||
use aes::cipher::BlockDecryptMut;
|
||||
use aes::cipher::BlockEncryptMut;
|
||||
use aes::cipher::KeyIvInit;
|
||||
use deno_core::error::range_error;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::Resource;
|
||||
|
@ -157,6 +158,13 @@ impl Cipher {
|
|||
Aes256Gcm(Box::new(cipher))
|
||||
}
|
||||
"aes256" | "aes-256-cbc" => {
|
||||
if key.len() != 32 {
|
||||
return Err(range_error("Invalid key length"));
|
||||
}
|
||||
if iv.len() != 16 {
|
||||
return Err(type_error("Invalid initialization vector"));
|
||||
}
|
||||
|
||||
Aes256Cbc(Box::new(cbc::Encryptor::new(key.into(), iv.into())))
|
||||
}
|
||||
_ => return Err(type_error(format!("Unknown cipher {algorithm_name}"))),
|
||||
|
@ -346,6 +354,13 @@ impl Decipher {
|
|||
Aes256Gcm(Box::new(decipher))
|
||||
}
|
||||
"aes256" | "aes-256-cbc" => {
|
||||
if key.len() != 32 {
|
||||
return Err(range_error("Invalid key length"));
|
||||
}
|
||||
if iv.len() != 16 {
|
||||
return Err(type_error("Invalid initialization vector"));
|
||||
}
|
||||
|
||||
Aes256Cbc(Box::new(cbc::Decryptor::new(key.into(), iv.into())))
|
||||
}
|
||||
_ => return Err(type_error(format!("Unknown cipher {algorithm_name}"))),
|
||||
|
|
|
@ -220,13 +220,9 @@ pub fn op_node_create_cipheriv(
|
|||
#[string] algorithm: &str,
|
||||
#[buffer] key: &[u8],
|
||||
#[buffer] iv: &[u8],
|
||||
) -> u32 {
|
||||
state.resource_table.add(
|
||||
match cipher::CipherContext::new(algorithm, key, iv) {
|
||||
Ok(context) => context,
|
||||
Err(_) => return 0,
|
||||
},
|
||||
)
|
||||
) -> Result<u32, AnyError> {
|
||||
let context = cipher::CipherContext::new(algorithm, key, iv)?;
|
||||
Ok(state.resource_table.add(context))
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
|
@ -292,13 +288,9 @@ pub fn op_node_create_decipheriv(
|
|||
#[string] algorithm: &str,
|
||||
#[buffer] key: &[u8],
|
||||
#[buffer] iv: &[u8],
|
||||
) -> u32 {
|
||||
state.resource_table.add(
|
||||
match cipher::DecipherContext::new(algorithm, key, iv) {
|
||||
Ok(context) => context,
|
||||
Err(_) => return 0,
|
||||
},
|
||||
)
|
||||
) -> Result<u32, AnyError> {
|
||||
let context = cipher::DecipherContext::new(algorithm, key, iv)?;
|
||||
Ok(state.resource_table.add(context))
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
|
|
|
@ -6,6 +6,7 @@ use deno_core::error::AnyError;
|
|||
use deno_core::normalize_path;
|
||||
use deno_core::op2;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::v8;
|
||||
use deno_core::JsRuntimeInspector;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::OpState;
|
||||
|
@ -591,12 +592,14 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_require_break_on_next_statement(state: &mut OpState) {
|
||||
let inspector = state.borrow::<Rc<RefCell<JsRuntimeInspector>>>();
|
||||
inspector
|
||||
.borrow_mut()
|
||||
.wait_for_session_and_break_on_next_statement()
|
||||
#[op2(fast, reentrant)]
|
||||
pub fn op_require_break_on_next_statement(state: Rc<RefCell<OpState>>) {
|
||||
let inspector_rc = {
|
||||
let state = state.borrow();
|
||||
state.borrow::<Rc<RefCell<JsRuntimeInspector>>>().clone()
|
||||
};
|
||||
let mut inspector = inspector_rc.borrow_mut();
|
||||
inspector.wait_for_session_and_break_on_next_statement()
|
||||
}
|
||||
|
||||
fn url_to_file_path_string(url: &Url) -> Result<String, AnyError> {
|
||||
|
@ -612,3 +615,29 @@ fn url_to_file_path(url: &Url) -> Result<PathBuf, AnyError> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_require_can_parse_as_esm(
|
||||
scope: &mut v8::HandleScope,
|
||||
#[string] source: &str,
|
||||
) -> bool {
|
||||
let scope = &mut v8::TryCatch::new(scope);
|
||||
let Some(source) = v8::String::new(scope, source) else {
|
||||
return false;
|
||||
};
|
||||
let origin = v8::ScriptOrigin::new(
|
||||
scope,
|
||||
source.into(),
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
0,
|
||||
None,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
None,
|
||||
);
|
||||
let mut source = v8::script_compiler::Source::new(source, Some(&origin));
|
||||
v8::script_compiler::compile_module(scope, &mut source).is_some()
|
||||
}
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op2;
|
||||
use deno_core::v8;
|
||||
use deno_core::FastString;
|
||||
use deno_core::GarbageCollected;
|
||||
use deno_core::ToJsBuffer;
|
||||
use std::ptr::NonNull;
|
||||
use v8::ValueDeserializerHelper;
|
||||
use v8::ValueSerializerHelper;
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_v8_cached_data_version_tag() -> u32 {
|
||||
|
@ -30,3 +39,355 @@ pub fn op_v8_get_heap_statistics(
|
|||
buffer[12] = stats.used_global_handles_size() as f64;
|
||||
buffer[13] = stats.external_memory() as f64;
|
||||
}
|
||||
|
||||
pub struct Serializer<'a> {
|
||||
inner: v8::ValueSerializer<'a>,
|
||||
}
|
||||
|
||||
pub struct SerializerDelegate {
|
||||
obj: v8::Global<v8::Object>,
|
||||
}
|
||||
|
||||
impl<'a> v8::cppgc::GarbageCollected for Serializer<'a> {
|
||||
fn trace(&self, _visitor: &v8::cppgc::Visitor) {}
|
||||
}
|
||||
|
||||
impl SerializerDelegate {
|
||||
fn obj<'s>(
|
||||
&self,
|
||||
scope: &mut v8::HandleScope<'s>,
|
||||
) -> v8::Local<'s, v8::Object> {
|
||||
v8::Local::new(scope, &self.obj)
|
||||
}
|
||||
}
|
||||
|
||||
impl v8::ValueSerializerImpl for SerializerDelegate {
|
||||
fn get_shared_array_buffer_id<'s>(
|
||||
&self,
|
||||
scope: &mut v8::HandleScope<'s>,
|
||||
shared_array_buffer: v8::Local<'s, v8::SharedArrayBuffer>,
|
||||
) -> Option<u32> {
|
||||
let obj = self.obj(scope);
|
||||
let key = FastString::from_static("_getSharedArrayBufferId")
|
||||
.v8_string(scope)
|
||||
.into();
|
||||
if let Some(v) = obj.get(scope, key) {
|
||||
if let Ok(fun) = v.try_cast::<v8::Function>() {
|
||||
return fun
|
||||
.call(scope, obj.into(), &[shared_array_buffer.into()])
|
||||
.and_then(|ret| ret.uint32_value(scope));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
fn has_custom_host_object(&self, _isolate: &mut v8::Isolate) -> bool {
|
||||
false
|
||||
}
|
||||
fn throw_data_clone_error<'s>(
|
||||
&self,
|
||||
scope: &mut v8::HandleScope<'s>,
|
||||
message: v8::Local<'s, v8::String>,
|
||||
) {
|
||||
let obj = self.obj(scope);
|
||||
let key = FastString::from_static("_getDataCloneError")
|
||||
.v8_string(scope)
|
||||
.into();
|
||||
if let Some(v) = obj.get(scope, key) {
|
||||
let fun = v
|
||||
.try_cast::<v8::Function>()
|
||||
.expect("_getDataCloneError should be a function");
|
||||
if let Some(error) = fun.call(scope, obj.into(), &[message.into()]) {
|
||||
scope.throw_exception(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
let error = v8::Exception::type_error(scope, message);
|
||||
scope.throw_exception(error);
|
||||
}
|
||||
|
||||
fn write_host_object<'s>(
|
||||
&self,
|
||||
scope: &mut v8::HandleScope<'s>,
|
||||
object: v8::Local<'s, v8::Object>,
|
||||
_value_serializer: &dyn ValueSerializerHelper,
|
||||
) -> Option<bool> {
|
||||
let obj = self.obj(scope);
|
||||
let key = FastString::from_static("_writeHostObject")
|
||||
.v8_string(scope)
|
||||
.into();
|
||||
if let Some(v) = obj.get(scope, key) {
|
||||
if let Ok(v) = v.try_cast::<v8::Function>() {
|
||||
v.call(scope, obj.into(), &[object.into()])?;
|
||||
return Some(true);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn is_host_object<'s>(
|
||||
&self,
|
||||
_scope: &mut v8::HandleScope<'s>,
|
||||
_object: v8::Local<'s, v8::Object>,
|
||||
) -> Option<bool> {
|
||||
// should never be called because has_custom_host_object returns false
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[op2]
|
||||
#[cppgc]
|
||||
pub fn op_v8_new_serializer(
|
||||
scope: &mut v8::HandleScope,
|
||||
obj: v8::Local<v8::Object>,
|
||||
) -> Serializer<'static> {
|
||||
let obj = v8::Global::new(scope, obj);
|
||||
let inner =
|
||||
v8::ValueSerializer::new(scope, Box::new(SerializerDelegate { obj }));
|
||||
Serializer { inner }
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_v8_set_treat_array_buffer_views_as_host_objects(
|
||||
#[cppgc] ser: &Serializer,
|
||||
value: bool,
|
||||
) {
|
||||
ser
|
||||
.inner
|
||||
.set_treat_array_buffer_views_as_host_objects(value);
|
||||
}
|
||||
|
||||
#[op2]
|
||||
#[serde]
|
||||
pub fn op_v8_release_buffer(#[cppgc] ser: &Serializer) -> ToJsBuffer {
|
||||
ser.inner.release().into()
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_v8_transfer_array_buffer(
|
||||
#[cppgc] ser: &Serializer,
|
||||
#[smi] id: u32,
|
||||
array_buffer: v8::Local<v8::ArrayBuffer>,
|
||||
) {
|
||||
ser.inner.transfer_array_buffer(id, array_buffer);
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_v8_write_double(#[cppgc] ser: &Serializer, double: f64) {
|
||||
ser.inner.write_double(double);
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_v8_write_header(#[cppgc] ser: &Serializer) {
|
||||
ser.inner.write_header();
|
||||
}
|
||||
|
||||
#[op2]
|
||||
pub fn op_v8_write_raw_bytes(
|
||||
#[cppgc] ser: &Serializer,
|
||||
#[anybuffer] source: &[u8],
|
||||
) {
|
||||
ser.inner.write_raw_bytes(source);
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_v8_write_uint32(#[cppgc] ser: &Serializer, num: u32) {
|
||||
ser.inner.write_uint32(num);
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_v8_write_uint64(#[cppgc] ser: &Serializer, hi: u32, lo: u32) {
|
||||
let num = ((hi as u64) << 32) | (lo as u64);
|
||||
ser.inner.write_uint64(num);
|
||||
}
|
||||
|
||||
#[op2(nofast, reentrant)]
|
||||
pub fn op_v8_write_value(
|
||||
scope: &mut v8::HandleScope,
|
||||
#[cppgc] ser: &Serializer,
|
||||
value: v8::Local<v8::Value>,
|
||||
) -> Result<(), AnyError> {
|
||||
let context = scope.get_current_context();
|
||||
ser.inner.write_value(context, value);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
struct DeserBuffer {
|
||||
ptr: Option<NonNull<u8>>,
|
||||
// Hold onto backing store to keep the underlying buffer
|
||||
// alive while we hold a reference to it.
|
||||
_backing_store: v8::SharedRef<v8::BackingStore>,
|
||||
}
|
||||
|
||||
pub struct Deserializer<'a> {
|
||||
buf: DeserBuffer,
|
||||
inner: v8::ValueDeserializer<'a>,
|
||||
}
|
||||
|
||||
impl<'a> deno_core::GarbageCollected for Deserializer<'a> {}
|
||||
|
||||
pub struct DeserializerDelegate {
|
||||
obj: v8::Global<v8::Object>,
|
||||
}
|
||||
|
||||
impl GarbageCollected for DeserializerDelegate {
|
||||
fn trace(&self, _visitor: &v8::cppgc::Visitor) {}
|
||||
}
|
||||
|
||||
impl v8::ValueDeserializerImpl for DeserializerDelegate {
|
||||
fn read_host_object<'s>(
|
||||
&self,
|
||||
scope: &mut v8::HandleScope<'s>,
|
||||
_value_deserializer: &dyn v8::ValueDeserializerHelper,
|
||||
) -> Option<v8::Local<'s, v8::Object>> {
|
||||
let obj = v8::Local::new(scope, &self.obj);
|
||||
let key = FastString::from_static("_readHostObject")
|
||||
.v8_string(scope)
|
||||
.into();
|
||||
let scope = &mut v8::AllowJavascriptExecutionScope::new(scope);
|
||||
if let Some(v) = obj.get(scope, key) {
|
||||
if let Ok(v) = v.try_cast::<v8::Function>() {
|
||||
let result = v.call(scope, obj.into(), &[])?;
|
||||
match result.try_cast() {
|
||||
Ok(res) => return Some(res),
|
||||
Err(_) => {
|
||||
let msg =
|
||||
FastString::from_static("readHostObject must return an object")
|
||||
.v8_string(scope);
|
||||
let error = v8::Exception::type_error(scope, msg);
|
||||
scope.throw_exception(error);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[op2]
|
||||
#[cppgc]
|
||||
pub fn op_v8_new_deserializer(
|
||||
scope: &mut v8::HandleScope,
|
||||
obj: v8::Local<v8::Object>,
|
||||
buffer: v8::Local<v8::ArrayBufferView>,
|
||||
) -> Result<Deserializer<'static>, AnyError> {
|
||||
let offset = buffer.byte_offset();
|
||||
let len = buffer.byte_length();
|
||||
let backing_store = buffer.get_backing_store().ok_or_else(|| {
|
||||
generic_error("deserialization buffer has no backing store")
|
||||
})?;
|
||||
let (buf_slice, buf_ptr) = if let Some(data) = backing_store.data() {
|
||||
// SAFETY: the offset is valid for the underlying buffer because we're getting it directly from v8
|
||||
let data_ptr = unsafe { data.as_ptr().cast::<u8>().add(offset) };
|
||||
(
|
||||
// SAFETY: the len is valid, from v8, and the data_ptr is valid (as above)
|
||||
unsafe { std::slice::from_raw_parts(data_ptr.cast_const().cast(), len) },
|
||||
Some(data.cast()),
|
||||
)
|
||||
} else {
|
||||
(&[] as &[u8], None::<NonNull<u8>>)
|
||||
};
|
||||
let obj = v8::Global::new(scope, obj);
|
||||
let inner = v8::ValueDeserializer::new(
|
||||
scope,
|
||||
Box::new(DeserializerDelegate { obj }),
|
||||
buf_slice,
|
||||
);
|
||||
Ok(Deserializer {
|
||||
inner,
|
||||
buf: DeserBuffer {
|
||||
_backing_store: backing_store,
|
||||
ptr: buf_ptr,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_v8_transfer_array_buffer_de(
|
||||
#[cppgc] deser: &Deserializer,
|
||||
#[smi] id: u32,
|
||||
array_buffer: v8::Local<v8::ArrayBuffer>,
|
||||
) {
|
||||
// TODO(nathanwhit): also need binding for TransferSharedArrayBuffer, then call that if
|
||||
// array_buffer is shared
|
||||
deser.inner.transfer_array_buffer(id, array_buffer);
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_v8_read_double(
|
||||
#[cppgc] deser: &Deserializer,
|
||||
) -> Result<f64, AnyError> {
|
||||
let mut double = 0f64;
|
||||
if !deser.inner.read_double(&mut double) {
|
||||
return Err(type_error("ReadDouble() failed"));
|
||||
}
|
||||
Ok(double)
|
||||
}
|
||||
|
||||
#[op2(nofast)]
|
||||
pub fn op_v8_read_header(
|
||||
scope: &mut v8::HandleScope,
|
||||
#[cppgc] deser: &Deserializer,
|
||||
) -> bool {
|
||||
let context = scope.get_current_context();
|
||||
let res = deser.inner.read_header(context);
|
||||
res.unwrap_or_default()
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
#[number]
|
||||
pub fn op_v8_read_raw_bytes(
|
||||
#[cppgc] deser: &Deserializer,
|
||||
#[number] length: usize,
|
||||
) -> usize {
|
||||
let Some(buf_ptr) = deser.buf.ptr else {
|
||||
return 0;
|
||||
};
|
||||
if let Some(buf) = deser.inner.read_raw_bytes(length) {
|
||||
let ptr = buf.as_ptr();
|
||||
(ptr as usize) - (buf_ptr.as_ptr() as usize)
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_v8_read_uint32(
|
||||
#[cppgc] deser: &Deserializer,
|
||||
) -> Result<u32, AnyError> {
|
||||
let mut value = 0;
|
||||
if !deser.inner.read_uint32(&mut value) {
|
||||
return Err(type_error("ReadUint32() failed"));
|
||||
}
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
#[op2]
|
||||
#[serde]
|
||||
pub fn op_v8_read_uint64(
|
||||
#[cppgc] deser: &Deserializer,
|
||||
) -> Result<(u32, u32), AnyError> {
|
||||
let mut val = 0;
|
||||
if !deser.inner.read_uint64(&mut val) {
|
||||
return Err(type_error("ReadUint64() failed"));
|
||||
}
|
||||
|
||||
Ok(((val >> 32) as u32, val as u32))
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_v8_get_wire_format_version(#[cppgc] deser: &Deserializer) -> u32 {
|
||||
deser.inner.get_wire_format_version()
|
||||
}
|
||||
|
||||
#[op2(reentrant)]
|
||||
pub fn op_v8_read_value<'s>(
|
||||
scope: &mut v8::HandleScope<'s>,
|
||||
#[cppgc] deser: &Deserializer,
|
||||
) -> v8::Local<'s, v8::Value> {
|
||||
let context = scope.get_current_context();
|
||||
let val = deser.inner.read_value(context);
|
||||
val.unwrap_or_else(|| v8::null(scope).into())
|
||||
}
|
||||
|
|
|
@ -4,9 +4,11 @@
|
|||
|
||||
import { core, internals, primordials } from "ext:core/mod.js";
|
||||
import {
|
||||
op_import_sync,
|
||||
op_napi_open,
|
||||
op_require_as_file_path,
|
||||
op_require_break_on_next_statement,
|
||||
op_require_can_parse_as_esm,
|
||||
op_require_init_paths,
|
||||
op_require_is_deno_dir_package,
|
||||
op_require_is_request_relative,
|
||||
|
@ -900,16 +902,6 @@ Module.prototype.load = function (filename) {
|
|||
pathDirname(this.filename),
|
||||
);
|
||||
const extension = findLongestRegisteredExtension(filename);
|
||||
// allow .mjs to be overridden
|
||||
if (
|
||||
StringPrototypeEndsWith(filename, ".mjs") && !Module._extensions[".mjs"]
|
||||
) {
|
||||
throw createRequireEsmError(
|
||||
filename,
|
||||
moduleParentCache.get(this)?.filename,
|
||||
);
|
||||
}
|
||||
|
||||
Module._extensions[extension](this, this.filename);
|
||||
this.loaded = true;
|
||||
|
||||
|
@ -987,27 +979,24 @@ function wrapSafe(
|
|||
if (process.mainModule === cjsModuleInstance) {
|
||||
enrichCJSError(err.thrown);
|
||||
}
|
||||
if (isEsmSyntaxError(err.thrown)) {
|
||||
throw createRequireEsmError(
|
||||
filename,
|
||||
moduleParentCache.get(cjsModuleInstance)?.filename,
|
||||
);
|
||||
} else {
|
||||
throw err.thrown;
|
||||
}
|
||||
throw err.thrown;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
Module.prototype._compile = function (content, filename, format) {
|
||||
const compiledWrapper = wrapSafe(filename, content, this, format);
|
||||
|
||||
if (format === "module") {
|
||||
// TODO(https://github.com/denoland/deno/issues/24822): implement require esm
|
||||
throw createRequireEsmError(
|
||||
filename,
|
||||
moduleParentCache.get(module)?.filename,
|
||||
);
|
||||
return loadESMFromCJS(this, filename, content);
|
||||
}
|
||||
|
||||
let compiledWrapper;
|
||||
try {
|
||||
compiledWrapper = wrapSafe(filename, content, this, format);
|
||||
} catch (err) {
|
||||
if (err instanceof SyntaxError && op_require_can_parse_as_esm(content)) {
|
||||
return loadESMFromCJS(this, filename, content);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
const dirname = pathDirname(filename);
|
||||
|
@ -1065,12 +1054,7 @@ Module._extensions[".js"] = function (module, filename) {
|
|||
if (StringPrototypeEndsWith(filename, ".js")) {
|
||||
const pkg = op_require_read_closest_package_json(filename);
|
||||
if (pkg?.typ === "module") {
|
||||
// TODO(https://github.com/denoland/deno/issues/24822): implement require esm
|
||||
format = "module";
|
||||
throw createRequireEsmError(
|
||||
filename,
|
||||
moduleParentCache.get(module)?.filename,
|
||||
);
|
||||
} else if (pkg?.type === "commonjs") {
|
||||
format = "commonjs";
|
||||
}
|
||||
|
@ -1081,20 +1065,19 @@ Module._extensions[".js"] = function (module, filename) {
|
|||
module._compile(content, filename, format);
|
||||
};
|
||||
|
||||
function createRequireEsmError(filename, parent) {
|
||||
let message = `require() of ES Module ${filename}`;
|
||||
function loadESMFromCJS(module, filename, code) {
|
||||
const namespace = op_import_sync(
|
||||
url.pathToFileURL(filename).toString(),
|
||||
code,
|
||||
);
|
||||
|
||||
if (parent) {
|
||||
message += ` from ${parent}`;
|
||||
}
|
||||
|
||||
message +=
|
||||
` not supported. Instead change the require to a dynamic import() which is available in all CommonJS modules.`;
|
||||
const err = new Error(message);
|
||||
err.code = "ERR_REQUIRE_ESM";
|
||||
return err;
|
||||
module.exports = namespace;
|
||||
}
|
||||
|
||||
Module._extensions[".mjs"] = function (module, filename) {
|
||||
loadESMFromCJS(module, filename);
|
||||
};
|
||||
|
||||
function stripBOM(content) {
|
||||
if (StringPrototypeCharCodeAt(content, 0) === 0xfeff) {
|
||||
content = StringPrototypeSlice(content, 1);
|
||||
|
|
|
@ -60,7 +60,7 @@ export class BrotliDecompress extends Transform {
|
|||
#context;
|
||||
|
||||
// TODO(littledivy): use `options` argument
|
||||
constructor(_options = {}) {
|
||||
constructor(_options = { __proto__: null }) {
|
||||
super({
|
||||
// TODO(littledivy): use `encoding` argument
|
||||
transform(chunk, _encoding, callback) {
|
||||
|
@ -91,7 +91,7 @@ export class BrotliDecompress extends Transform {
|
|||
export class BrotliCompress extends Transform {
|
||||
#context;
|
||||
|
||||
constructor(options = {}) {
|
||||
constructor(options = { __proto__: null }) {
|
||||
super({
|
||||
// TODO(littledivy): use `encoding` argument
|
||||
transform(chunk, _encoding, callback) {
|
||||
|
|
|
@ -12,6 +12,28 @@ export const {
|
|||
S_IXUSR,
|
||||
S_IRGRP,
|
||||
S_IWGRP,
|
||||
S_IFBLK,
|
||||
S_IFCHR,
|
||||
S_IFDIR,
|
||||
S_IFIFO,
|
||||
S_IFLNK,
|
||||
S_IFMT,
|
||||
S_IFREG,
|
||||
S_IFSOCK,
|
||||
S_IRWXG,
|
||||
S_IRWXO,
|
||||
S_IRWXU,
|
||||
UV_DIRENT_BLOCK,
|
||||
UV_DIRENT_CHAR,
|
||||
UV_DIRENT_DIR,
|
||||
UV_DIRENT_FIFO,
|
||||
UV_DIRENT_FILE,
|
||||
UV_DIRENT_LINK,
|
||||
UV_DIRENT_SOCKET,
|
||||
UV_DIRENT_UNKNOWN,
|
||||
UV_FS_O_FILEMAP,
|
||||
UV_FS_SYMLINK_DIR,
|
||||
UV_FS_SYMLINK_JUNCTION,
|
||||
S_IXGRP,
|
||||
S_IROTH,
|
||||
S_IWOTH,
|
||||
|
|
|
@ -23,6 +23,7 @@ import {
|
|||
validateStringAfterArrayBufferView,
|
||||
} from "ext:deno_node/internal/fs/utils.mjs";
|
||||
import { promisify } from "ext:deno_node/internal/util.mjs";
|
||||
import { FileHandle } from "ext:deno_node/internal/fs/handle.ts";
|
||||
import { FsFile } from "ext:deno_fs/30_fs.js";
|
||||
|
||||
interface Writer {
|
||||
|
@ -30,7 +31,7 @@ interface Writer {
|
|||
}
|
||||
|
||||
export function writeFile(
|
||||
pathOrRid: string | number | URL,
|
||||
pathOrRid: string | number | URL | FileHandle,
|
||||
data: string | Uint8Array,
|
||||
optOrCallback: Encodings | CallbackWithError | WriteFileOptions | undefined,
|
||||
callback?: CallbackWithError,
|
||||
|
@ -45,6 +46,7 @@ export function writeFile(
|
|||
}
|
||||
|
||||
pathOrRid = pathOrRid instanceof URL ? pathFromURL(pathOrRid) : pathOrRid;
|
||||
pathOrRid = pathOrRid instanceof FileHandle ? pathOrRid.fd : pathOrRid;
|
||||
|
||||
const flag: string | undefined = isFileOptions(options)
|
||||
? options.flag
|
||||
|
|
|
@ -53,8 +53,8 @@ function denoEnvGet(name: string) {
|
|||
} catch (e) {
|
||||
if (
|
||||
ObjectPrototypeIsPrototypeOf(TypeErrorPrototype, e) ||
|
||||
// TODO(iuioiua): Use `PermissionDeniedPrototype` when it's available
|
||||
ObjectPrototypeIsPrototypeOf(Deno.errors.PermissionDenied.prototype, e)
|
||||
// TODO(iuioiua): Use `NotCapablePrototype` when it's available
|
||||
ObjectPrototypeIsPrototypeOf(Deno.errors.NotCapable.prototype, e)
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
@ -65,22 +65,26 @@ export function createWritableStdioStream(writer, name, warmup = false) {
|
|||
stream.once("close", () => writer?.close());
|
||||
ObjectDefineProperties(stream, {
|
||||
columns: {
|
||||
__proto__: null,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get: () =>
|
||||
writer?.isTerminal() ? Deno.consoleSize?.().columns : undefined,
|
||||
},
|
||||
rows: {
|
||||
__proto__: null,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get: () => writer?.isTerminal() ? Deno.consoleSize?.().rows : undefined,
|
||||
},
|
||||
isTTY: {
|
||||
__proto__: null,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get: () => writer?.isTerminal(),
|
||||
},
|
||||
getWindowSize: {
|
||||
__proto__: null,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
value: () =>
|
||||
|
@ -203,6 +207,7 @@ export const initStdin = (warmup = false) => {
|
|||
stdin.on("close", () => io.stdin?.close());
|
||||
stdin.fd = io.stdin ? io.STDIN_RID : -1;
|
||||
ObjectDefineProperty(stdin, "isTTY", {
|
||||
__proto__: null,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get() {
|
||||
|
@ -216,6 +221,7 @@ export const initStdin = (warmup = false) => {
|
|||
return stdin;
|
||||
};
|
||||
ObjectDefineProperty(stdin, "isRaw", {
|
||||
__proto__: null,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get() {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// deno-fmt-ignore-file
|
||||
// deno-lint-ignore-file
|
||||
import { nextTick } from "ext:deno_node/_next_tick.ts";
|
||||
import { EventEmitter as EE } from "ext:deno_node/_events.mjs";
|
||||
import { AbortController } from "ext:deno_web/03_abort_signal.js";
|
||||
import { Blob } from "ext:deno_web/09_file.js";
|
||||
import { StringDecoder } from "node:string_decoder";
|
||||
|
@ -1723,446 +1724,11 @@ var require_destroy = __commonJS({
|
|||
},
|
||||
});
|
||||
|
||||
// node_modules/events/events.js
|
||||
var require_events = __commonJS({
|
||||
"node_modules/events/events.js"(exports, module) {
|
||||
"use strict";
|
||||
var R = typeof Reflect === "object" ? Reflect : null;
|
||||
var ReflectApply = R && typeof R.apply === "function"
|
||||
? R.apply
|
||||
: function ReflectApply2(target, receiver, args) {
|
||||
return Function.prototype.apply.call(target, receiver, args);
|
||||
};
|
||||
var ReflectOwnKeys;
|
||||
if (R && typeof R.ownKeys === "function") {
|
||||
ReflectOwnKeys = R.ownKeys;
|
||||
} else if (Object.getOwnPropertySymbols) {
|
||||
ReflectOwnKeys = function ReflectOwnKeys2(target) {
|
||||
return Object.getOwnPropertyNames(target).concat(
|
||||
Object.getOwnPropertySymbols(target),
|
||||
);
|
||||
};
|
||||
} else {
|
||||
ReflectOwnKeys = function ReflectOwnKeys2(target) {
|
||||
return Object.getOwnPropertyNames(target);
|
||||
};
|
||||
}
|
||||
function ProcessEmitWarning(warning) {
|
||||
if (console && console.warn) {
|
||||
console.warn(warning);
|
||||
}
|
||||
}
|
||||
var NumberIsNaN = Number.isNaN || function NumberIsNaN2(value) {
|
||||
return value !== value;
|
||||
};
|
||||
function EventEmitter() {
|
||||
EventEmitter.init.call(this);
|
||||
}
|
||||
module.exports = EventEmitter;
|
||||
module.exports.once = once;
|
||||
EventEmitter.EventEmitter = EventEmitter;
|
||||
EventEmitter.prototype._events = void 0;
|
||||
EventEmitter.prototype._eventsCount = 0;
|
||||
EventEmitter.prototype._maxListeners = void 0;
|
||||
var defaultMaxListeners = 10;
|
||||
function checkListener(listener) {
|
||||
if (typeof listener !== "function") {
|
||||
throw new TypeError(
|
||||
'The "listener" argument must be of type Function. Received type ' +
|
||||
typeof listener,
|
||||
);
|
||||
}
|
||||
}
|
||||
Object.defineProperty(EventEmitter, "defaultMaxListeners", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return defaultMaxListeners;
|
||||
},
|
||||
set: function (arg) {
|
||||
if (typeof arg !== "number" || arg < 0 || NumberIsNaN(arg)) {
|
||||
throw new RangeError(
|
||||
'The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' +
|
||||
arg + ".",
|
||||
);
|
||||
}
|
||||
defaultMaxListeners = arg;
|
||||
},
|
||||
});
|
||||
EventEmitter.init = function () {
|
||||
if (
|
||||
this._events === void 0 ||
|
||||
this._events === Object.getPrototypeOf(this)._events
|
||||
) {
|
||||
this._events = /* @__PURE__ */ Object.create(null);
|
||||
this._eventsCount = 0;
|
||||
}
|
||||
this._maxListeners = this._maxListeners || void 0;
|
||||
};
|
||||
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
|
||||
if (typeof n !== "number" || n < 0 || NumberIsNaN(n)) {
|
||||
throw new RangeError(
|
||||
'The value of "n" is out of range. It must be a non-negative number. Received ' +
|
||||
n + ".",
|
||||
);
|
||||
}
|
||||
this._maxListeners = n;
|
||||
return this;
|
||||
};
|
||||
function _getMaxListeners(that) {
|
||||
if (that._maxListeners === void 0) {
|
||||
return EventEmitter.defaultMaxListeners;
|
||||
}
|
||||
return that._maxListeners;
|
||||
}
|
||||
EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
|
||||
return _getMaxListeners(this);
|
||||
};
|
||||
EventEmitter.prototype.emit = function emit(type) {
|
||||
var args = [];
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
args.push(arguments[i]);
|
||||
}
|
||||
var doError = type === "error";
|
||||
var events = this._events;
|
||||
if (events !== void 0) {
|
||||
doError = doError && events.error === void 0;
|
||||
} else if (!doError) {
|
||||
return false;
|
||||
}
|
||||
if (doError) {
|
||||
var er;
|
||||
if (args.length > 0) {
|
||||
er = args[0];
|
||||
}
|
||||
if (er instanceof Error) {
|
||||
throw er;
|
||||
}
|
||||
var err = new Error(
|
||||
"Unhandled error." + (er ? " (" + er.message + ")" : ""),
|
||||
);
|
||||
err.context = er;
|
||||
throw err;
|
||||
}
|
||||
var handler = events[type];
|
||||
if (handler === void 0) {
|
||||
return false;
|
||||
}
|
||||
if (typeof handler === "function") {
|
||||
ReflectApply(handler, this, args);
|
||||
} else {
|
||||
var len = handler.length;
|
||||
var listeners = arrayClone(handler, len);
|
||||
for (var i = 0; i < len; ++i) {
|
||||
ReflectApply(listeners[i], this, args);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
function _addListener(target, type, listener, prepend) {
|
||||
var m;
|
||||
var events;
|
||||
var existing;
|
||||
checkListener(listener);
|
||||
events = target._events;
|
||||
if (events === void 0) {
|
||||
events = target._events = /* @__PURE__ */ Object.create(null);
|
||||
target._eventsCount = 0;
|
||||
} else {
|
||||
if (events.newListener !== void 0) {
|
||||
target.emit(
|
||||
"newListener",
|
||||
type,
|
||||
listener.listener ? listener.listener : listener,
|
||||
);
|
||||
events = target._events;
|
||||
}
|
||||
existing = events[type];
|
||||
}
|
||||
if (existing === void 0) {
|
||||
existing = events[type] = listener;
|
||||
++target._eventsCount;
|
||||
} else {
|
||||
if (typeof existing === "function") {
|
||||
existing = events[type] = prepend
|
||||
? [listener, existing]
|
||||
: [existing, listener];
|
||||
} else if (prepend) {
|
||||
existing.unshift(listener);
|
||||
} else {
|
||||
existing.push(listener);
|
||||
}
|
||||
m = _getMaxListeners(target);
|
||||
if (m > 0 && existing.length > m && !existing.warned) {
|
||||
existing.warned = true;
|
||||
var w = new Error(
|
||||
"Possible EventEmitter memory leak detected. " + existing.length +
|
||||
" " + String(type) +
|
||||
" listeners added. Use emitter.setMaxListeners() to increase limit",
|
||||
);
|
||||
w.name = "MaxListenersExceededWarning";
|
||||
w.emitter = target;
|
||||
w.type = type;
|
||||
w.count = existing.length;
|
||||
ProcessEmitWarning(w);
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
EventEmitter.prototype.addListener = function addListener(type, listener) {
|
||||
return _addListener(this, type, listener, false);
|
||||
};
|
||||
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
|
||||
EventEmitter.prototype.prependListener = function prependListener(
|
||||
type,
|
||||
listener,
|
||||
) {
|
||||
return _addListener(this, type, listener, true);
|
||||
};
|
||||
function onceWrapper() {
|
||||
if (!this.fired) {
|
||||
this.target.removeListener(this.type, this.wrapFn);
|
||||
this.fired = true;
|
||||
if (arguments.length === 0) {
|
||||
return this.listener.call(this.target);
|
||||
}
|
||||
return this.listener.apply(this.target, arguments);
|
||||
}
|
||||
}
|
||||
function _onceWrap(target, type, listener) {
|
||||
var state = { fired: false, wrapFn: void 0, target, type, listener };
|
||||
var wrapped = onceWrapper.bind(state);
|
||||
wrapped.listener = listener;
|
||||
state.wrapFn = wrapped;
|
||||
return wrapped;
|
||||
}
|
||||
EventEmitter.prototype.once = function once2(type, listener) {
|
||||
checkListener(listener);
|
||||
this.on(type, _onceWrap(this, type, listener));
|
||||
return this;
|
||||
};
|
||||
EventEmitter.prototype.prependOnceListener = function prependOnceListener(
|
||||
type,
|
||||
listener,
|
||||
) {
|
||||
checkListener(listener);
|
||||
this.prependListener(type, _onceWrap(this, type, listener));
|
||||
return this;
|
||||
};
|
||||
EventEmitter.prototype.removeListener = function removeListener(
|
||||
type,
|
||||
listener,
|
||||
) {
|
||||
var list, events, position, i, originalListener;
|
||||
checkListener(listener);
|
||||
events = this._events;
|
||||
if (events === void 0) {
|
||||
return this;
|
||||
}
|
||||
list = events[type];
|
||||
if (list === void 0) {
|
||||
return this;
|
||||
}
|
||||
if (list === listener || list.listener === listener) {
|
||||
if (--this._eventsCount === 0) {
|
||||
this._events = /* @__PURE__ */ Object.create(null);
|
||||
} else {
|
||||
delete events[type];
|
||||
if (events.removeListener) {
|
||||
this.emit("removeListener", type, list.listener || listener);
|
||||
}
|
||||
}
|
||||
} else if (typeof list !== "function") {
|
||||
position = -1;
|
||||
for (i = list.length - 1; i >= 0; i--) {
|
||||
if (list[i] === listener || list[i].listener === listener) {
|
||||
originalListener = list[i].listener;
|
||||
position = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (position < 0) {
|
||||
return this;
|
||||
}
|
||||
if (position === 0) {
|
||||
list.shift();
|
||||
} else {
|
||||
spliceOne(list, position);
|
||||
}
|
||||
if (list.length === 1) {
|
||||
events[type] = list[0];
|
||||
}
|
||||
if (events.removeListener !== void 0) {
|
||||
this.emit("removeListener", type, originalListener || listener);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
|
||||
EventEmitter.prototype.removeAllListeners = function removeAllListeners(
|
||||
type,
|
||||
) {
|
||||
var listeners, events, i;
|
||||
events = this._events;
|
||||
if (events === void 0) {
|
||||
return this;
|
||||
}
|
||||
if (events.removeListener === void 0) {
|
||||
if (arguments.length === 0) {
|
||||
this._events = /* @__PURE__ */ Object.create(null);
|
||||
this._eventsCount = 0;
|
||||
} else if (events[type] !== void 0) {
|
||||
if (--this._eventsCount === 0) {
|
||||
this._events = /* @__PURE__ */ Object.create(null);
|
||||
} else {
|
||||
delete events[type];
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
if (arguments.length === 0) {
|
||||
var keys = Object.keys(events);
|
||||
var key;
|
||||
for (i = 0; i < keys.length; ++i) {
|
||||
key = keys[i];
|
||||
if (key === "removeListener") {
|
||||
continue;
|
||||
}
|
||||
this.removeAllListeners(key);
|
||||
}
|
||||
this.removeAllListeners("removeListener");
|
||||
this._events = /* @__PURE__ */ Object.create(null);
|
||||
this._eventsCount = 0;
|
||||
return this;
|
||||
}
|
||||
listeners = events[type];
|
||||
if (typeof listeners === "function") {
|
||||
this.removeListener(type, listeners);
|
||||
} else if (listeners !== void 0) {
|
||||
for (i = listeners.length - 1; i >= 0; i--) {
|
||||
this.removeListener(type, listeners[i]);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
function _listeners(target, type, unwrap) {
|
||||
var events = target._events;
|
||||
if (events === void 0) {
|
||||
return [];
|
||||
}
|
||||
var evlistener = events[type];
|
||||
if (evlistener === void 0) {
|
||||
return [];
|
||||
}
|
||||
if (typeof evlistener === "function") {
|
||||
return unwrap ? [evlistener.listener || evlistener] : [evlistener];
|
||||
}
|
||||
return unwrap
|
||||
? unwrapListeners(evlistener)
|
||||
: arrayClone(evlistener, evlistener.length);
|
||||
}
|
||||
EventEmitter.prototype.listeners = function listeners(type) {
|
||||
return _listeners(this, type, true);
|
||||
};
|
||||
EventEmitter.prototype.rawListeners = function rawListeners(type) {
|
||||
return _listeners(this, type, false);
|
||||
};
|
||||
EventEmitter.listenerCount = function (emitter, type) {
|
||||
if (typeof emitter.listenerCount === "function") {
|
||||
return emitter.listenerCount(type);
|
||||
} else {
|
||||
return listenerCount.call(emitter, type);
|
||||
}
|
||||
};
|
||||
EventEmitter.prototype.listenerCount = listenerCount;
|
||||
function listenerCount(type) {
|
||||
var events = this._events;
|
||||
if (events !== void 0) {
|
||||
var evlistener = events[type];
|
||||
if (typeof evlistener === "function") {
|
||||
return 1;
|
||||
} else if (evlistener !== void 0) {
|
||||
return evlistener.length;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EventEmitter.prototype.eventNames = function eventNames() {
|
||||
return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
|
||||
};
|
||||
function arrayClone(arr, n) {
|
||||
var copy = new Array(n);
|
||||
for (var i = 0; i < n; ++i) {
|
||||
copy[i] = arr[i];
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
function spliceOne(list, index) {
|
||||
for (; index + 1 < list.length; index++) {
|
||||
list[index] = list[index + 1];
|
||||
}
|
||||
list.pop();
|
||||
}
|
||||
function unwrapListeners(arr) {
|
||||
var ret = new Array(arr.length);
|
||||
for (var i = 0; i < ret.length; ++i) {
|
||||
ret[i] = arr[i].listener || arr[i];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
function once(emitter, name) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
function errorListener(err) {
|
||||
emitter.removeListener(name, resolver);
|
||||
reject(err);
|
||||
}
|
||||
function resolver() {
|
||||
if (typeof emitter.removeListener === "function") {
|
||||
emitter.removeListener("error", errorListener);
|
||||
}
|
||||
resolve([].slice.call(arguments));
|
||||
}
|
||||
|
||||
eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });
|
||||
if (name !== "error") {
|
||||
addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });
|
||||
}
|
||||
});
|
||||
}
|
||||
function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
|
||||
if (typeof emitter.on === "function") {
|
||||
eventTargetAgnosticAddListener(emitter, "error", handler, flags);
|
||||
}
|
||||
}
|
||||
function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
|
||||
if (typeof emitter.on === "function") {
|
||||
if (flags.once) {
|
||||
emitter.once(name, listener);
|
||||
} else {
|
||||
emitter.on(name, listener);
|
||||
}
|
||||
} else if (typeof emitter.addEventListener === "function") {
|
||||
emitter.addEventListener(name, function wrapListener(arg) {
|
||||
if (flags.once) {
|
||||
emitter.removeEventListener(name, wrapListener);
|
||||
}
|
||||
listener(arg);
|
||||
});
|
||||
} else {
|
||||
throw new TypeError(
|
||||
'The "emitter" argument must be of type EventEmitter. Received type ' +
|
||||
typeof emitter,
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// lib/internal/streams/legacy.js
|
||||
var require_legacy = __commonJS({
|
||||
"lib/internal/streams/legacy.js"(exports, module) {
|
||||
"use strict";
|
||||
var { ArrayIsArray, ObjectSetPrototypeOf } = require_primordials();
|
||||
var { EventEmitter: EE } = require_events();
|
||||
function Stream(opts) {
|
||||
EE.call(this, opts);
|
||||
}
|
||||
|
@ -2688,7 +2254,6 @@ var require_readable = __commonJS({
|
|||
} = require_primordials();
|
||||
module.exports = Readable;
|
||||
Readable.ReadableState = ReadableState;
|
||||
var { EventEmitter: EE } = require_events();
|
||||
var { Stream, prependListener } = require_legacy();
|
||||
var { Buffer: Buffer2 } = require_buffer();
|
||||
var { addAbortSignal } = require_add_abort_signal();
|
||||
|
@ -3722,7 +3287,6 @@ var require_writable = __commonJS({
|
|||
} = require_primordials();
|
||||
module.exports = Writable;
|
||||
Writable.WritableState = WritableState;
|
||||
var { EventEmitter: EE } = require_events();
|
||||
var Stream = require_legacy().Stream;
|
||||
var { Buffer: Buffer2 } = require_buffer();
|
||||
var destroyImpl = require_destroy();
|
||||
|
|
|
@ -13,7 +13,7 @@ import { clearTimeout, setTimeout } from "ext:deno_web/02_timers.js";
|
|||
/** Resolve a Promise after a given amount of milliseconds. */
|
||||
export function delay(
|
||||
ms: number,
|
||||
options: { signal?: AbortSignal } = {},
|
||||
options: { signal?: AbortSignal } = { __proto__: null },
|
||||
): Promise<void> {
|
||||
const { signal } = options;
|
||||
if (signal?.aborted) {
|
||||
|
|
|
@ -325,7 +325,10 @@ export function diffstr(A: string, B: string) {
|
|||
);
|
||||
}
|
||||
|
||||
function tokenize(string: string, { wordDiff = false } = {}): string[] {
|
||||
function tokenize(
|
||||
string: string,
|
||||
{ wordDiff = false } = { __proto__: null },
|
||||
): string[] {
|
||||
if (wordDiff) {
|
||||
// Split string on whitespace symbols
|
||||
const tokens = StringPrototypeSplit(string, WHITESPACE_SYMBOL_PATTERN);
|
||||
|
@ -450,7 +453,7 @@ export function diffstr(A: string, B: string) {
|
|||
*/
|
||||
function createColor(
|
||||
diffType: DiffType,
|
||||
{ background = false } = {},
|
||||
{ background = false } = { __proto__: null },
|
||||
): (s: string) => string {
|
||||
// TODO(@littledivy): Remove this when we can detect
|
||||
// true color terminals.
|
||||
|
@ -484,7 +487,7 @@ function createSign(diffType: DiffType): string {
|
|||
|
||||
export function buildMessage(
|
||||
diffResult: ReadonlyArray<DiffResult<string>>,
|
||||
{ stringDiff = false } = {},
|
||||
{ stringDiff = false } = { __proto__: null },
|
||||
): string[] {
|
||||
const messages: string[] = [], diffMessages: string[] = [];
|
||||
ArrayPrototypePush(messages, "");
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
// TODO(petamoriken): enable prefer-primordials for node polyfills
|
||||
// deno-lint-ignore-file prefer-primordials
|
||||
|
||||
import { primordials } from "ext:core/mod.js";
|
||||
import { Console } from "ext:deno_node/internal/console/constructor.mjs";
|
||||
import { windowOrWorkerGlobalScope } from "ext:runtime/98_global_scope_shared.js";
|
||||
// Don't rely on global `console` because during bootstrapping, it is pointing
|
||||
// to native `console` object provided by V8.
|
||||
const console = windowOrWorkerGlobalScope.console.value;
|
||||
|
||||
Object.assign(console, { Console });
|
||||
const { ObjectAssign } = primordials;
|
||||
|
||||
ObjectAssign(console, { Console });
|
||||
|
||||
export default console;
|
||||
|
||||
|
|
|
@ -51,6 +51,28 @@ export const {
|
|||
UV_FS_COPYFILE_EXCL,
|
||||
UV_FS_COPYFILE_FICLONE,
|
||||
UV_FS_COPYFILE_FICLONE_FORCE,
|
||||
S_IFBLK,
|
||||
S_IFCHR,
|
||||
S_IFDIR,
|
||||
S_IFIFO,
|
||||
S_IFLNK,
|
||||
S_IFMT,
|
||||
S_IFREG,
|
||||
S_IFSOCK,
|
||||
S_IRWXG,
|
||||
S_IRWXO,
|
||||
S_IRWXU,
|
||||
UV_DIRENT_BLOCK,
|
||||
UV_DIRENT_CHAR,
|
||||
UV_DIRENT_DIR,
|
||||
UV_DIRENT_FIFO,
|
||||
UV_DIRENT_FILE,
|
||||
UV_DIRENT_LINK,
|
||||
UV_DIRENT_SOCKET,
|
||||
UV_DIRENT_UNKNOWN,
|
||||
UV_FS_O_FILEMAP,
|
||||
UV_FS_SYMLINK_DIR,
|
||||
UV_FS_SYMLINK_JUNCTION,
|
||||
} = fsConstants;
|
||||
export const {
|
||||
RTLD_DEEPBIND,
|
||||
|
|
|
@ -242,7 +242,7 @@ export class Cipheriv extends Transform implements Cipher {
|
|||
): Buffer | string {
|
||||
// TODO(kt3k): throw ERR_INVALID_ARG_TYPE if data is not string, Buffer, or ArrayBufferView
|
||||
let buf = data;
|
||||
if (typeof data === "string" && typeof inputEncoding === "string") {
|
||||
if (typeof data === "string") {
|
||||
buf = Buffer.from(data, inputEncoding);
|
||||
}
|
||||
|
||||
|
@ -396,7 +396,7 @@ export class Decipheriv extends Transform implements Cipher {
|
|||
): Buffer | string {
|
||||
// TODO(kt3k): throw ERR_INVALID_ARG_TYPE if data is not string, Buffer, or ArrayBufferView
|
||||
let buf = data;
|
||||
if (typeof data === "string" && typeof inputEncoding === "string") {
|
||||
if (typeof data === "string") {
|
||||
buf = Buffer.from(data, inputEncoding);
|
||||
}
|
||||
|
||||
|
|
|
@ -133,12 +133,28 @@ export class FileHandle extends EventEmitter {
|
|||
}
|
||||
}
|
||||
|
||||
writeFile(data, options): Promise<void> {
|
||||
return fsCall(promises.writeFile, this, data, options);
|
||||
}
|
||||
|
||||
close(): Promise<void> {
|
||||
// Note that Deno.close is not async
|
||||
return Promise.resolve(core.close(this.fd));
|
||||
}
|
||||
}
|
||||
|
||||
function fsCall(fn, handle, ...args) {
|
||||
if (handle.fd === -1) {
|
||||
const err = new Error("file closed");
|
||||
throw Object.assign(err, {
|
||||
code: "EBADF",
|
||||
syscall: fn.name,
|
||||
});
|
||||
}
|
||||
|
||||
return fn(handle, ...args);
|
||||
}
|
||||
|
||||
export default {
|
||||
FileHandle,
|
||||
};
|
||||
|
|
|
@ -160,16 +160,8 @@ export class Pipe extends ConnectionWrap {
|
|||
}
|
||||
},
|
||||
(e) => {
|
||||
// TODO(cmorten): correct mapping of connection error to status code.
|
||||
let code: number;
|
||||
|
||||
if (e instanceof Deno.errors.NotFound) {
|
||||
code = codeMap.get("ENOENT")!;
|
||||
} else if (e instanceof Deno.errors.PermissionDenied) {
|
||||
code = codeMap.get("EACCES")!;
|
||||
} else {
|
||||
code = codeMap.get("ECONNREFUSED")!;
|
||||
}
|
||||
const code = codeMap.get(e.code ?? "UNKNOWN") ??
|
||||
codeMap.get("UNKNOWN")!;
|
||||
|
||||
try {
|
||||
this.afterConnect(req, code);
|
||||
|
@ -207,16 +199,10 @@ export class Pipe extends ConnectionWrap {
|
|||
try {
|
||||
listener = Deno.listen(listenOptions);
|
||||
} catch (e) {
|
||||
if (e instanceof Deno.errors.AddrInUse) {
|
||||
return codeMap.get("EADDRINUSE")!;
|
||||
} else if (e instanceof Deno.errors.AddrNotAvailable) {
|
||||
return codeMap.get("EADDRNOTAVAIL")!;
|
||||
} else if (e instanceof Deno.errors.PermissionDenied) {
|
||||
if (e instanceof Deno.errors.NotCapable) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
// TODO(cmorten): map errors to appropriate error codes.
|
||||
return codeMap.get("UNKNOWN")!;
|
||||
return codeMap.get(e.code ?? "UNKNOWN") ?? codeMap.get("UNKNOWN")!;
|
||||
}
|
||||
|
||||
const address = listener.addr as Deno.UnixAddr;
|
||||
|
|
|
@ -38,6 +38,7 @@ import { TextEncoder } from "ext:deno_web/08_text_encoding.js";
|
|||
import { Buffer } from "node:buffer";
|
||||
import { notImplemented } from "ext:deno_node/_utils.ts";
|
||||
import { HandleWrap } from "ext:deno_node/internal_binding/handle_wrap.ts";
|
||||
import { ownerSymbol } from "ext:deno_node/internal/async_hooks.ts";
|
||||
import {
|
||||
AsyncWrap,
|
||||
providerType,
|
||||
|
@ -343,7 +344,8 @@ export class LibuvStreamWrap extends HandleWrap {
|
|||
) {
|
||||
nread = codeMap.get("ECONNRESET")!;
|
||||
} else {
|
||||
nread = codeMap.get("UNKNOWN")!;
|
||||
this[ownerSymbol].destroy(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ import {
|
|||
INITIAL_ACCEPT_BACKOFF_DELAY,
|
||||
MAX_ACCEPT_BACKOFF_DELAY,
|
||||
} from "ext:deno_node/internal_binding/_listen.ts";
|
||||
import { nextTick } from "ext:deno_node/_next_tick.ts";
|
||||
|
||||
/** The type of TCP socket. */
|
||||
enum socketType {
|
||||
|
@ -211,16 +212,10 @@ export class TCP extends ConnectionWrap {
|
|||
try {
|
||||
listener = Deno.listen(listenOptions);
|
||||
} catch (e) {
|
||||
if (e instanceof Deno.errors.AddrInUse) {
|
||||
return codeMap.get("EADDRINUSE")!;
|
||||
} else if (e instanceof Deno.errors.AddrNotAvailable) {
|
||||
return codeMap.get("EADDRNOTAVAIL")!;
|
||||
} else if (e instanceof Deno.errors.PermissionDenied) {
|
||||
if (e instanceof Deno.errors.NotCapable) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
// TODO(cmorten): map errors to appropriate error codes.
|
||||
return codeMap.get("UNKNOWN")!;
|
||||
return codeMap.get(e.code ?? "UNKNOWN") ?? codeMap.get("UNKNOWN")!;
|
||||
}
|
||||
|
||||
const address = listener.addr as Deno.NetAddr;
|
||||
|
@ -228,7 +223,14 @@ export class TCP extends ConnectionWrap {
|
|||
this.#port = address.port;
|
||||
|
||||
this.#listener = listener;
|
||||
this.#accept();
|
||||
|
||||
// TODO(kt3k): Delays the accept() call 2 ticks. Deno.Listener can't be closed
|
||||
// synchronously when accept() is called. By delaying the accept() call,
|
||||
// the user can close the server synchronously in the callback of listen().
|
||||
// This workaround enables `npm:detect-port` to work correctly.
|
||||
// Remove these nextTick calls when the below issue resolved:
|
||||
// https://github.com/denoland/deno/issues/25480
|
||||
nextTick(nextTick, () => this.#accept());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -337,16 +337,10 @@ export class UDP extends HandleWrap {
|
|||
try {
|
||||
listener = DenoListenDatagram(listenOptions);
|
||||
} catch (e) {
|
||||
if (e instanceof Deno.errors.AddrInUse) {
|
||||
return codeMap.get("EADDRINUSE")!;
|
||||
} else if (e instanceof Deno.errors.AddrNotAvailable) {
|
||||
return codeMap.get("EADDRNOTAVAIL")!;
|
||||
} else if (e instanceof Deno.errors.PermissionDenied) {
|
||||
if (e instanceof Deno.errors.NotCapable) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
// TODO(cmorten): map errors to appropriate error codes.
|
||||
return codeMap.get("UNKNOWN")!;
|
||||
return codeMap.get(e.code ?? "UNKNOWN") ?? codeMap.get("UNKNOWN")!;
|
||||
}
|
||||
|
||||
const address = listener.addr as Deno.NetAddr;
|
||||
|
|
|
@ -478,6 +478,9 @@ export function parse(path: string): ParsedPath {
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
export const _makeLong = toNamespacedPath;
|
||||
|
||||
export default {
|
||||
basename,
|
||||
delimiter,
|
||||
|
@ -492,4 +495,5 @@ export default {
|
|||
resolve,
|
||||
sep,
|
||||
toNamespacedPath,
|
||||
_makeLong,
|
||||
};
|
||||
|
|
|
@ -953,6 +953,8 @@ export function parse(path: string): ParsedPath {
|
|||
return ret;
|
||||
}
|
||||
|
||||
export const _makeLong = toNamespacedPath;
|
||||
|
||||
export default {
|
||||
basename,
|
||||
delimiter,
|
||||
|
@ -967,4 +969,5 @@ export default {
|
|||
resolve,
|
||||
sep,
|
||||
toNamespacedPath,
|
||||
_makeLong,
|
||||
};
|
||||
|
|
|
@ -36,6 +36,7 @@ export const {
|
|||
resolve,
|
||||
sep,
|
||||
toNamespacedPath,
|
||||
_makeLong,
|
||||
} = path;
|
||||
export default path;
|
||||
export * from "ext:deno_node/path/common.ts";
|
||||
|
|
|
@ -18,6 +18,9 @@ export const {
|
|||
resolve,
|
||||
sep,
|
||||
toNamespacedPath,
|
||||
_makeLong,
|
||||
} = path.posix;
|
||||
|
||||
export const posix = path.posix;
|
||||
export const win32 = path.win32;
|
||||
export default path.posix;
|
||||
|
|
|
@ -18,6 +18,9 @@ export const {
|
|||
resolve,
|
||||
sep,
|
||||
toNamespacedPath,
|
||||
_makeLong,
|
||||
} = path.win32;
|
||||
|
||||
export const posix = path.posix;
|
||||
export const win32 = path.win32;
|
||||
export default path.win32;
|
||||
|
|
|
@ -403,6 +403,7 @@ StringDecoder.prototype.text = function text(
|
|||
|
||||
ObjectDefineProperties(StringDecoder.prototype, {
|
||||
lastNeed: {
|
||||
__proto__: null,
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get(this: StringDecoder): number {
|
||||
|
@ -410,6 +411,7 @@ ObjectDefineProperties(StringDecoder.prototype, {
|
|||
},
|
||||
},
|
||||
lastTotal: {
|
||||
__proto__: null,
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get(this: StringDecoder): number {
|
||||
|
|
|
@ -33,6 +33,7 @@ export function setTimeout(
|
|||
}
|
||||
|
||||
ObjectDefineProperty(setTimeout, promisify.custom, {
|
||||
__proto__: null,
|
||||
value: (timeout: number, ...args: unknown[]) => {
|
||||
return new Promise((cb) =>
|
||||
setTimeout(cb, timeout, ...new SafeArrayIterator(args))
|
||||
|
|
|
@ -177,6 +177,7 @@ export function inherits<T, U>(
|
|||
);
|
||||
}
|
||||
ObjectDefineProperty(ctor, "super_", {
|
||||
__proto__: null,
|
||||
value: superCtor,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
|
|
|
@ -6,15 +6,36 @@
|
|||
// TODO(petamoriken): enable prefer-primordials for node polyfills
|
||||
// deno-lint-ignore-file prefer-primordials
|
||||
|
||||
import { core } from "ext:core/mod.js";
|
||||
import { primordials } from "ext:core/mod.js";
|
||||
const { ObjectPrototypeToString } = primordials;
|
||||
import {
|
||||
op_v8_cached_data_version_tag,
|
||||
op_v8_get_heap_statistics,
|
||||
op_v8_get_wire_format_version,
|
||||
op_v8_new_deserializer,
|
||||
op_v8_new_serializer,
|
||||
op_v8_read_double,
|
||||
op_v8_read_header,
|
||||
op_v8_read_raw_bytes,
|
||||
op_v8_read_uint32,
|
||||
op_v8_read_uint64,
|
||||
op_v8_read_value,
|
||||
op_v8_release_buffer,
|
||||
op_v8_set_treat_array_buffer_views_as_host_objects,
|
||||
op_v8_transfer_array_buffer,
|
||||
op_v8_transfer_array_buffer_de,
|
||||
op_v8_write_double,
|
||||
op_v8_write_header,
|
||||
op_v8_write_raw_bytes,
|
||||
op_v8_write_uint32,
|
||||
op_v8_write_uint64,
|
||||
op_v8_write_value,
|
||||
} from "ext:core/ops";
|
||||
|
||||
import { Buffer } from "node:buffer";
|
||||
|
||||
import { notImplemented, warnNotImplemented } from "ext:deno_node/_utils.ts";
|
||||
import { notImplemented } from "ext:deno_node/_utils.ts";
|
||||
import { isArrayBufferView } from "ext:deno_node/internal/util/types.ts";
|
||||
|
||||
export function cachedDataVersionTag() {
|
||||
return op_v8_cached_data_version_tag();
|
||||
|
@ -71,65 +92,225 @@ export function takeCoverage() {
|
|||
export function writeHeapSnapshot() {
|
||||
notImplemented("v8.writeHeapSnapshot");
|
||||
}
|
||||
export function serialize(value) {
|
||||
return Buffer.from(core.serialize(value));
|
||||
// deno-lint-ignore no-explicit-any
|
||||
export function serialize(value: any) {
|
||||
const ser = new DefaultSerializer();
|
||||
ser.writeHeader();
|
||||
ser.writeValue(value);
|
||||
return ser.releaseBuffer();
|
||||
}
|
||||
export function deserialize(data) {
|
||||
return core.deserialize(data);
|
||||
export function deserialize(buffer: Buffer | ArrayBufferView | DataView) {
|
||||
if (!isArrayBufferView(buffer)) {
|
||||
throw new TypeError(
|
||||
"buffer must be a TypedArray or a DataView",
|
||||
);
|
||||
}
|
||||
const der = new DefaultDeserializer(buffer);
|
||||
der.readHeader();
|
||||
return der.readValue();
|
||||
}
|
||||
|
||||
const kHandle = Symbol("kHandle");
|
||||
|
||||
export class Serializer {
|
||||
[kHandle]: object;
|
||||
constructor() {
|
||||
warnNotImplemented("v8.Serializer.prototype.constructor");
|
||||
this[kHandle] = op_v8_new_serializer(this);
|
||||
}
|
||||
|
||||
_setTreatArrayBufferViewsAsHostObjects(value: boolean): void {
|
||||
op_v8_set_treat_array_buffer_views_as_host_objects(this[kHandle], value);
|
||||
}
|
||||
|
||||
releaseBuffer(): Buffer {
|
||||
warnNotImplemented("v8.DefaultSerializer.prototype.releaseBuffer");
|
||||
return Buffer.from("");
|
||||
return Buffer.from(op_v8_release_buffer(this[kHandle]));
|
||||
}
|
||||
|
||||
transferArrayBuffer(_id: number, _arrayBuffer: ArrayBuffer): void {
|
||||
warnNotImplemented("v8.DefaultSerializer.prototype.transferArrayBuffer");
|
||||
op_v8_transfer_array_buffer(this[kHandle], _id, _arrayBuffer);
|
||||
}
|
||||
|
||||
writeDouble(_value: number): void {
|
||||
warnNotImplemented("v8.DefaultSerializer.prototype.writeDouble");
|
||||
writeDouble(value: number): void {
|
||||
op_v8_write_double(this[kHandle], value);
|
||||
}
|
||||
|
||||
writeHeader(): void {
|
||||
warnNotImplemented("v8.DefaultSerializer.prototype.writeHeader");
|
||||
op_v8_write_header(this[kHandle]);
|
||||
}
|
||||
|
||||
writeRawBytes(_value: ArrayBufferView): void {
|
||||
warnNotImplemented("v8.DefaultSerializer.prototype.writeRawBytes");
|
||||
writeRawBytes(source: ArrayBufferView): void {
|
||||
if (!isArrayBufferView(source)) {
|
||||
throw new TypeError(
|
||||
"source must be a TypedArray or a DataView",
|
||||
);
|
||||
}
|
||||
op_v8_write_raw_bytes(this[kHandle], source);
|
||||
}
|
||||
|
||||
writeUint32(_value: number): void {
|
||||
warnNotImplemented("v8.DefaultSerializer.prototype.writeUint32");
|
||||
writeUint32(value: number): void {
|
||||
op_v8_write_uint32(this[kHandle], value);
|
||||
}
|
||||
|
||||
writeUint64(_hi: number, _lo: number): void {
|
||||
warnNotImplemented("v8.DefaultSerializer.prototype.writeUint64");
|
||||
writeUint64(hi: number, lo: number): void {
|
||||
op_v8_write_uint64(this[kHandle], hi, lo);
|
||||
}
|
||||
|
||||
// deno-lint-ignore no-explicit-any
|
||||
writeValue(_value: any): void {
|
||||
warnNotImplemented("v8.DefaultSerializer.prototype.writeValue");
|
||||
writeValue(value: any): void {
|
||||
op_v8_write_value(this[kHandle], value);
|
||||
}
|
||||
|
||||
_getDataCloneError = Error;
|
||||
}
|
||||
|
||||
export class Deserializer {
|
||||
buffer: ArrayBufferView;
|
||||
[kHandle]: object;
|
||||
constructor(buffer: ArrayBufferView) {
|
||||
if (!isArrayBufferView(buffer)) {
|
||||
throw new TypeError(
|
||||
"buffer must be a TypedArray or a DataView",
|
||||
);
|
||||
}
|
||||
this.buffer = buffer;
|
||||
this[kHandle] = op_v8_new_deserializer(this, buffer);
|
||||
}
|
||||
readRawBytes(length: number): Buffer {
|
||||
const offset = this._readRawBytes(length);
|
||||
return Buffer.from(
|
||||
this.buffer.buffer,
|
||||
this.buffer.byteOffset + offset,
|
||||
length,
|
||||
);
|
||||
}
|
||||
_readRawBytes(length: number): number {
|
||||
return op_v8_read_raw_bytes(this[kHandle], length);
|
||||
}
|
||||
getWireFormatVersion(): number {
|
||||
return op_v8_get_wire_format_version(this[kHandle]);
|
||||
}
|
||||
readDouble(): number {
|
||||
return op_v8_read_double(this[kHandle]);
|
||||
}
|
||||
readHeader(): boolean {
|
||||
return op_v8_read_header(this[kHandle]);
|
||||
}
|
||||
|
||||
readUint32(): number {
|
||||
return op_v8_read_uint32(this[kHandle]);
|
||||
}
|
||||
readUint64(): [hi: number, lo: number] {
|
||||
return op_v8_read_uint64(this[kHandle]);
|
||||
}
|
||||
readValue(): unknown {
|
||||
return op_v8_read_value(this[kHandle]);
|
||||
}
|
||||
transferArrayBuffer(
|
||||
id: number,
|
||||
arrayBuffer: ArrayBuffer | SharedArrayBuffer,
|
||||
): void {
|
||||
return op_v8_transfer_array_buffer_de(this[kHandle], id, arrayBuffer);
|
||||
}
|
||||
}
|
||||
export class Deserializer {
|
||||
constructor() {
|
||||
notImplemented("v8.Deserializer.prototype.constructor");
|
||||
}
|
||||
function arrayBufferViewTypeToIndex(abView: ArrayBufferView) {
|
||||
const type = ObjectPrototypeToString(abView);
|
||||
if (type === "[object Int8Array]") return 0;
|
||||
if (type === "[object Uint8Array]") return 1;
|
||||
if (type === "[object Uint8ClampedArray]") return 2;
|
||||
if (type === "[object Int16Array]") return 3;
|
||||
if (type === "[object Uint16Array]") return 4;
|
||||
if (type === "[object Int32Array]") return 5;
|
||||
if (type === "[object Uint32Array]") return 6;
|
||||
if (type === "[object Float32Array]") return 7;
|
||||
if (type === "[object Float64Array]") return 8;
|
||||
if (type === "[object DataView]") return 9;
|
||||
// Index 10 is FastBuffer.
|
||||
if (type === "[object BigInt64Array]") return 11;
|
||||
if (type === "[object BigUint64Array]") return 12;
|
||||
return -1;
|
||||
}
|
||||
export class DefaultSerializer extends Serializer {
|
||||
constructor() {
|
||||
warnNotImplemented("v8.DefaultSerializer.prototype.constructor");
|
||||
super();
|
||||
this._setTreatArrayBufferViewsAsHostObjects(true);
|
||||
}
|
||||
|
||||
// deno-lint-ignore no-explicit-any
|
||||
_writeHostObject(abView: any) {
|
||||
// Keep track of how to handle different ArrayBufferViews. The default
|
||||
// Serializer for Node does not use the V8 methods for serializing those
|
||||
// objects because Node's `Buffer` objects use pooled allocation in many
|
||||
// cases, and their underlying `ArrayBuffer`s would show up in the
|
||||
// serialization. Because a) those may contain sensitive data and the user
|
||||
// may not be aware of that and b) they are often much larger than the
|
||||
// `Buffer` itself, custom serialization is applied.
|
||||
let i = 10; // FastBuffer
|
||||
if (abView.constructor !== Buffer) {
|
||||
i = arrayBufferViewTypeToIndex(abView);
|
||||
if (i === -1) {
|
||||
throw new this._getDataCloneError(
|
||||
`Unserializable host object: ${abView}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
this.writeUint32(i);
|
||||
this.writeUint32(abView.byteLength);
|
||||
this.writeRawBytes(
|
||||
new Uint8Array(abView.buffer, abView.byteOffset, abView.byteLength),
|
||||
);
|
||||
}
|
||||
}
|
||||
export class DefaultDeserializer {
|
||||
constructor() {
|
||||
notImplemented("v8.DefaultDeserializer.prototype.constructor");
|
||||
|
||||
// deno-lint-ignore no-explicit-any
|
||||
function arrayBufferViewIndexToType(index: number): any {
|
||||
if (index === 0) return Int8Array;
|
||||
if (index === 1) return Uint8Array;
|
||||
if (index === 2) return Uint8ClampedArray;
|
||||
if (index === 3) return Int16Array;
|
||||
if (index === 4) return Uint16Array;
|
||||
if (index === 5) return Int32Array;
|
||||
if (index === 6) return Uint32Array;
|
||||
if (index === 7) return Float32Array;
|
||||
if (index === 8) return Float64Array;
|
||||
if (index === 9) return DataView;
|
||||
if (index === 10) return Buffer;
|
||||
if (index === 11) return BigInt64Array;
|
||||
if (index === 12) return BigUint64Array;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export class DefaultDeserializer extends Deserializer {
|
||||
constructor(buffer: ArrayBufferView) {
|
||||
super(buffer);
|
||||
}
|
||||
|
||||
_readHostObject() {
|
||||
const typeIndex = this.readUint32();
|
||||
const ctor = arrayBufferViewIndexToType(typeIndex);
|
||||
const byteLength = this.readUint32();
|
||||
const byteOffset = this._readRawBytes(byteLength);
|
||||
const BYTES_PER_ELEMENT = ctor?.BYTES_PER_ELEMENT ?? 1;
|
||||
|
||||
const offset = this.buffer.byteOffset + byteOffset;
|
||||
if (offset % BYTES_PER_ELEMENT === 0) {
|
||||
return new ctor(
|
||||
this.buffer.buffer,
|
||||
offset,
|
||||
byteLength / BYTES_PER_ELEMENT,
|
||||
);
|
||||
}
|
||||
// Copy to an aligned buffer first.
|
||||
const bufferCopy = Buffer.allocUnsafe(byteLength);
|
||||
Buffer.from(
|
||||
this.buffer.buffer,
|
||||
byteOffset,
|
||||
byteLength,
|
||||
).copy(bufferCopy);
|
||||
return new ctor(
|
||||
bufferCopy.buffer,
|
||||
bufferCopy.byteOffset,
|
||||
byteLength / BYTES_PER_ELEMENT,
|
||||
);
|
||||
}
|
||||
}
|
||||
export const promiseHooks = {
|
||||
|
|
|
@ -34,7 +34,7 @@ const kParsingContext = Symbol("script parsing context");
|
|||
export class Script {
|
||||
#inner;
|
||||
|
||||
constructor(code, options = {}) {
|
||||
constructor(code, options = { __proto__: null }) {
|
||||
code = `${code}`;
|
||||
if (typeof options === "string") {
|
||||
options = { filename: options };
|
||||
|
@ -80,7 +80,7 @@ export class Script {
|
|||
: undefined;
|
||||
}
|
||||
|
||||
#runInContext(contextifiedObject, options = {}) {
|
||||
#runInContext(contextifiedObject, options = { __proto__: null }) {
|
||||
validateObject(options, "options");
|
||||
|
||||
let timeout = options.timeout;
|
||||
|
@ -181,7 +181,10 @@ function getContextOptions(options) {
|
|||
}
|
||||
|
||||
let defaultContextNameIndex = 1;
|
||||
export function createContext(contextObject = {}, options = {}) {
|
||||
export function createContext(
|
||||
contextObject = {},
|
||||
options = { __proto__: null },
|
||||
) {
|
||||
if (isContext(contextObject)) {
|
||||
return contextObject;
|
||||
}
|
||||
|
@ -276,7 +279,7 @@ export function isContext(object) {
|
|||
return op_vm_is_context(object);
|
||||
}
|
||||
|
||||
export function compileFunction(code, params, options = {}) {
|
||||
export function compileFunction(code, params, options = { __proto__: null }) {
|
||||
validateString(code, "code");
|
||||
if (params !== undefined) {
|
||||
validateStringArray(params, "params");
|
||||
|
|
|
@ -267,7 +267,7 @@ class NodeWorker extends EventEmitter {
|
|||
}
|
||||
};
|
||||
|
||||
postMessage(message, transferOrOptions = {}) {
|
||||
postMessage(message, transferOrOptions = { __proto__: null }) {
|
||||
const prefix = "Failed to execute 'postMessage' on 'MessagePort'";
|
||||
webidl.requiredArguments(arguments.length, 1, prefix);
|
||||
message = webidl.converters.any(message);
|
||||
|
|
|
@ -186,7 +186,7 @@ const entries = ObjectEntries({
|
|||
});
|
||||
for (let i = 0; i < entries.length; ++i) {
|
||||
const { 0: key, 1: value } = entries[i];
|
||||
const desc = { value, enumerable: true };
|
||||
const desc = { __proto__: null, value, enumerable: true };
|
||||
ObjectDefineProperty(DOMException, key, desc);
|
||||
ObjectDefineProperty(DOMException.prototype, key, desc);
|
||||
}
|
||||
|
|
|
@ -392,6 +392,7 @@ const EventPrototype = Event.prototype;
|
|||
// Not spec compliant. The spec defines it as [LegacyUnforgeable]
|
||||
// but doing so has a big performance hit
|
||||
ReflectDefineProperty(Event.prototype, "isTrusted", {
|
||||
__proto__: null,
|
||||
enumerable: true,
|
||||
get: isTrusted,
|
||||
});
|
||||
|
@ -402,7 +403,10 @@ function defineEnumerableProps(
|
|||
) {
|
||||
for (let i = 0; i < props.length; ++i) {
|
||||
const prop = props[i];
|
||||
ReflectDefineProperty(Ctor.prototype, prop, { enumerable: true });
|
||||
ReflectDefineProperty(Ctor.prototype, prop, {
|
||||
__proto__: null,
|
||||
enumerable: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1274,6 +1278,7 @@ class CustomEvent extends Event {
|
|||
const CustomEventPrototype = CustomEvent.prototype;
|
||||
|
||||
ReflectDefineProperty(CustomEvent.prototype, "detail", {
|
||||
__proto__: null,
|
||||
enumerable: true,
|
||||
});
|
||||
|
||||
|
@ -1417,6 +1422,7 @@ function defineEventHandler(
|
|||
) {
|
||||
// HTML specification section 8.1.7.1
|
||||
ObjectDefineProperty(emitter, `on${name}`, {
|
||||
__proto__: null,
|
||||
get() {
|
||||
if (!this[_eventHandlers]) {
|
||||
return null;
|
||||
|
|
|
@ -5420,6 +5420,7 @@ class ReadableStream {
|
|||
// TODO(lucacasonato): should be moved to webidl crate
|
||||
ReadableStream.prototype[SymbolAsyncIterator] = ReadableStream.prototype.values;
|
||||
ObjectDefineProperty(ReadableStream.prototype, SymbolAsyncIterator, {
|
||||
__proto__: null,
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
|
|
|
@ -454,36 +454,42 @@ webidl.configureInterface(FileReader);
|
|||
const FileReaderPrototype = FileReader.prototype;
|
||||
|
||||
ObjectDefineProperty(FileReader, "EMPTY", {
|
||||
__proto__: null,
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
configurable: false,
|
||||
value: 0,
|
||||
});
|
||||
ObjectDefineProperty(FileReader, "LOADING", {
|
||||
__proto__: null,
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
configurable: false,
|
||||
value: 1,
|
||||
});
|
||||
ObjectDefineProperty(FileReader, "DONE", {
|
||||
__proto__: null,
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
configurable: false,
|
||||
value: 2,
|
||||
});
|
||||
ObjectDefineProperty(FileReader.prototype, "EMPTY", {
|
||||
__proto__: null,
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
configurable: false,
|
||||
value: 0,
|
||||
});
|
||||
ObjectDefineProperty(FileReader.prototype, "LOADING", {
|
||||
__proto__: null,
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
configurable: false,
|
||||
value: 1,
|
||||
});
|
||||
ObjectDefineProperty(FileReader.prototype, "DONE", {
|
||||
__proto__: null,
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
configurable: false,
|
||||
|
|
|
@ -35,6 +35,7 @@ class Location {
|
|||
url.password = "";
|
||||
ObjectDefineProperties(this, {
|
||||
hash: {
|
||||
__proto__: null,
|
||||
get() {
|
||||
return url.hash;
|
||||
},
|
||||
|
@ -47,6 +48,7 @@ class Location {
|
|||
enumerable: true,
|
||||
},
|
||||
host: {
|
||||
__proto__: null,
|
||||
get() {
|
||||
return url.host;
|
||||
},
|
||||
|
@ -59,6 +61,7 @@ class Location {
|
|||
enumerable: true,
|
||||
},
|
||||
hostname: {
|
||||
__proto__: null,
|
||||
get() {
|
||||
return url.hostname;
|
||||
},
|
||||
|
@ -71,6 +74,7 @@ class Location {
|
|||
enumerable: true,
|
||||
},
|
||||
href: {
|
||||
__proto__: null,
|
||||
get() {
|
||||
return url.href;
|
||||
},
|
||||
|
@ -83,12 +87,14 @@ class Location {
|
|||
enumerable: true,
|
||||
},
|
||||
origin: {
|
||||
__proto__: null,
|
||||
get() {
|
||||
return url.origin;
|
||||
},
|
||||
enumerable: true,
|
||||
},
|
||||
pathname: {
|
||||
__proto__: null,
|
||||
get() {
|
||||
return url.pathname;
|
||||
},
|
||||
|
@ -101,6 +107,7 @@ class Location {
|
|||
enumerable: true,
|
||||
},
|
||||
port: {
|
||||
__proto__: null,
|
||||
get() {
|
||||
return url.port;
|
||||
},
|
||||
|
@ -113,6 +120,7 @@ class Location {
|
|||
enumerable: true,
|
||||
},
|
||||
protocol: {
|
||||
__proto__: null,
|
||||
get() {
|
||||
return url.protocol;
|
||||
},
|
||||
|
@ -125,6 +133,7 @@ class Location {
|
|||
enumerable: true,
|
||||
},
|
||||
search: {
|
||||
__proto__: null,
|
||||
get() {
|
||||
return url.search;
|
||||
},
|
||||
|
@ -137,6 +146,7 @@ class Location {
|
|||
enumerable: true,
|
||||
},
|
||||
ancestorOrigins: {
|
||||
__proto__: null,
|
||||
get() {
|
||||
// TODO(nayeemrmn): Replace with a `DOMStringList` instance.
|
||||
return {
|
||||
|
@ -148,6 +158,7 @@ class Location {
|
|||
enumerable: true,
|
||||
},
|
||||
assign: {
|
||||
__proto__: null,
|
||||
value: function assign() {
|
||||
throw new DOMException(
|
||||
`Cannot call "location.assign()".`,
|
||||
|
@ -157,6 +168,7 @@ class Location {
|
|||
enumerable: true,
|
||||
},
|
||||
reload: {
|
||||
__proto__: null,
|
||||
value: function reload() {
|
||||
throw new DOMException(
|
||||
`Cannot call "location.reload()".`,
|
||||
|
@ -166,6 +178,7 @@ class Location {
|
|||
enumerable: true,
|
||||
},
|
||||
replace: {
|
||||
__proto__: null,
|
||||
value: function replace() {
|
||||
throw new DOMException(
|
||||
`Cannot call "location.replace()".`,
|
||||
|
@ -175,12 +188,14 @@ class Location {
|
|||
enumerable: true,
|
||||
},
|
||||
toString: {
|
||||
__proto__: null,
|
||||
value: function toString() {
|
||||
return url.href;
|
||||
},
|
||||
enumerable: true,
|
||||
},
|
||||
[SymbolFor("Deno.privateCustomInspect")]: {
|
||||
__proto__: null,
|
||||
value: function (inspect, inspectOptions) {
|
||||
return `${this.constructor.name} ${
|
||||
inspect({
|
||||
|
@ -203,6 +218,7 @@ class Location {
|
|||
|
||||
ObjectDefineProperties(Location.prototype, {
|
||||
[SymbolToStringTag]: {
|
||||
__proto__: null,
|
||||
value: "Location",
|
||||
configurable: true,
|
||||
},
|
||||
|
@ -224,6 +240,7 @@ class WorkerLocation {
|
|||
|
||||
ObjectDefineProperties(WorkerLocation.prototype, {
|
||||
hash: {
|
||||
__proto__: null,
|
||||
get() {
|
||||
const url = WeakMapPrototypeGet(workerLocationUrls, this);
|
||||
if (url == null) {
|
||||
|
@ -235,6 +252,7 @@ ObjectDefineProperties(WorkerLocation.prototype, {
|
|||
enumerable: true,
|
||||
},
|
||||
host: {
|
||||
__proto__: null,
|
||||
get() {
|
||||
const url = WeakMapPrototypeGet(workerLocationUrls, this);
|
||||
if (url == null) {
|
||||
|
@ -246,6 +264,7 @@ ObjectDefineProperties(WorkerLocation.prototype, {
|
|||
enumerable: true,
|
||||
},
|
||||
hostname: {
|
||||
__proto__: null,
|
||||
get() {
|
||||
const url = WeakMapPrototypeGet(workerLocationUrls, this);
|
||||
if (url == null) {
|
||||
|
@ -257,6 +276,7 @@ ObjectDefineProperties(WorkerLocation.prototype, {
|
|||
enumerable: true,
|
||||
},
|
||||
href: {
|
||||
__proto__: null,
|
||||
get() {
|
||||
const url = WeakMapPrototypeGet(workerLocationUrls, this);
|
||||
if (url == null) {
|
||||
|
@ -268,6 +288,7 @@ ObjectDefineProperties(WorkerLocation.prototype, {
|
|||
enumerable: true,
|
||||
},
|
||||
origin: {
|
||||
__proto__: null,
|
||||
get() {
|
||||
const url = WeakMapPrototypeGet(workerLocationUrls, this);
|
||||
if (url == null) {
|
||||
|
@ -279,6 +300,7 @@ ObjectDefineProperties(WorkerLocation.prototype, {
|
|||
enumerable: true,
|
||||
},
|
||||
pathname: {
|
||||
__proto__: null,
|
||||
get() {
|
||||
const url = WeakMapPrototypeGet(workerLocationUrls, this);
|
||||
if (url == null) {
|
||||
|
@ -290,6 +312,7 @@ ObjectDefineProperties(WorkerLocation.prototype, {
|
|||
enumerable: true,
|
||||
},
|
||||
port: {
|
||||
__proto__: null,
|
||||
get() {
|
||||
const url = WeakMapPrototypeGet(workerLocationUrls, this);
|
||||
if (url == null) {
|
||||
|
@ -301,6 +324,7 @@ ObjectDefineProperties(WorkerLocation.prototype, {
|
|||
enumerable: true,
|
||||
},
|
||||
protocol: {
|
||||
__proto__: null,
|
||||
get() {
|
||||
const url = WeakMapPrototypeGet(workerLocationUrls, this);
|
||||
if (url == null) {
|
||||
|
@ -312,6 +336,7 @@ ObjectDefineProperties(WorkerLocation.prototype, {
|
|||
enumerable: true,
|
||||
},
|
||||
search: {
|
||||
__proto__: null,
|
||||
get() {
|
||||
const url = WeakMapPrototypeGet(workerLocationUrls, this);
|
||||
if (url == null) {
|
||||
|
@ -323,6 +348,7 @@ ObjectDefineProperties(WorkerLocation.prototype, {
|
|||
enumerable: true,
|
||||
},
|
||||
toString: {
|
||||
__proto__: null,
|
||||
value: function toString() {
|
||||
const url = WeakMapPrototypeGet(workerLocationUrls, this);
|
||||
if (url == null) {
|
||||
|
@ -335,10 +361,12 @@ ObjectDefineProperties(WorkerLocation.prototype, {
|
|||
writable: true,
|
||||
},
|
||||
[SymbolToStringTag]: {
|
||||
__proto__: null,
|
||||
value: "WorkerLocation",
|
||||
configurable: true,
|
||||
},
|
||||
[SymbolFor("Deno.privateCustomInspect")]: {
|
||||
__proto__: null,
|
||||
value: function (inspect, inspectOptions) {
|
||||
return `${this.constructor.name} ${
|
||||
inspect({
|
||||
|
|
|
@ -132,14 +132,17 @@ class MessagePort extends EventTarget {
|
|||
constructor() {
|
||||
super();
|
||||
ObjectDefineProperty(this, MessagePortReceiveMessageOnPortSymbol, {
|
||||
__proto__: null,
|
||||
value: false,
|
||||
enumerable: false,
|
||||
});
|
||||
ObjectDefineProperty(this, nodeWorkerThreadCloseCb, {
|
||||
__proto__: null,
|
||||
value: null,
|
||||
enumerable: false,
|
||||
});
|
||||
ObjectDefineProperty(this, nodeWorkerThreadCloseCbInvoked, {
|
||||
__proto__: null,
|
||||
value: false,
|
||||
enumerable: false,
|
||||
});
|
||||
|
|
|
@ -907,6 +907,7 @@ const GPUDeviceLostInfoPrototype = GPUDeviceLostInfo.prototype;
|
|||
function GPUObjectBaseMixin(name, type) {
|
||||
type.prototype[_label] = null;
|
||||
ObjectDefineProperty(type.prototype, "label", {
|
||||
__proto__: null,
|
||||
/**
|
||||
* @return {string | null}
|
||||
*/
|
||||
|
|
|
@ -753,6 +753,7 @@ function createDictionaryConverter(name, ...dictionaries) {
|
|||
defaultValues[member.key] = member.converter(idlMemberValue, {});
|
||||
} else {
|
||||
ObjectDefineProperty(defaultValues, member.key, {
|
||||
__proto__: null,
|
||||
get() {
|
||||
return member.converter(idlMemberValue, member.defaultValue);
|
||||
},
|
||||
|
@ -1076,6 +1077,7 @@ function mixinPairIterable(name, prototype, dataSymbol, keyKey, valueKey) {
|
|||
function createDefaultIterator(target, kind) {
|
||||
const iterator = ObjectCreate(iteratorPrototype);
|
||||
ObjectDefineProperty(iterator, _iteratorInternal, {
|
||||
__proto__: null,
|
||||
value: { target, kind, index: 0 },
|
||||
configurable: true,
|
||||
});
|
||||
|
@ -1149,6 +1151,7 @@ function configureInterface(interface_) {
|
|||
configureProperties(interface_);
|
||||
configureProperties(interface_.prototype);
|
||||
ObjectDefineProperty(interface_.prototype, SymbolToStringTag, {
|
||||
__proto__: null,
|
||||
value: interface_.name,
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
|
@ -1170,12 +1173,14 @@ function configureProperties(obj) {
|
|||
typeof descriptor.value === "function"
|
||||
) {
|
||||
ObjectDefineProperty(obj, key, {
|
||||
__proto__: null,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
});
|
||||
} else if (ReflectHas(descriptor, "get")) {
|
||||
ObjectDefineProperty(obj, key, {
|
||||
__proto__: null,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
});
|
||||
|
@ -1189,6 +1194,7 @@ const setlikeInner = Symbol("[[set]]");
|
|||
function setlike(obj, objPrototype, readonly) {
|
||||
ObjectDefineProperties(obj, {
|
||||
size: {
|
||||
__proto__: null,
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get() {
|
||||
|
@ -1197,6 +1203,7 @@ function setlike(obj, objPrototype, readonly) {
|
|||
},
|
||||
},
|
||||
[SymbolIterator]: {
|
||||
__proto__: null,
|
||||
configurable: true,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
|
@ -1206,6 +1213,7 @@ function setlike(obj, objPrototype, readonly) {
|
|||
},
|
||||
},
|
||||
entries: {
|
||||
__proto__: null,
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
|
@ -1215,6 +1223,7 @@ function setlike(obj, objPrototype, readonly) {
|
|||
},
|
||||
},
|
||||
keys: {
|
||||
__proto__: null,
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
|
@ -1224,6 +1233,7 @@ function setlike(obj, objPrototype, readonly) {
|
|||
},
|
||||
},
|
||||
values: {
|
||||
__proto__: null,
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
|
@ -1233,6 +1243,7 @@ function setlike(obj, objPrototype, readonly) {
|
|||
},
|
||||
},
|
||||
forEach: {
|
||||
__proto__: null,
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
|
@ -1242,6 +1253,7 @@ function setlike(obj, objPrototype, readonly) {
|
|||
},
|
||||
},
|
||||
has: {
|
||||
__proto__: null,
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
|
@ -1255,6 +1267,7 @@ function setlike(obj, objPrototype, readonly) {
|
|||
if (!readonly) {
|
||||
ObjectDefineProperties(obj, {
|
||||
add: {
|
||||
__proto__: null,
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
|
@ -1264,6 +1277,7 @@ function setlike(obj, objPrototype, readonly) {
|
|||
},
|
||||
},
|
||||
delete: {
|
||||
__proto__: null,
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
|
@ -1273,6 +1287,7 @@ function setlike(obj, objPrototype, readonly) {
|
|||
},
|
||||
},
|
||||
clear: {
|
||||
__proto__: null,
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
|
|
|
@ -627,15 +627,19 @@ class WebSocket extends EventTarget {
|
|||
|
||||
ObjectDefineProperties(WebSocket, {
|
||||
CONNECTING: {
|
||||
__proto__: null,
|
||||
value: 0,
|
||||
},
|
||||
OPEN: {
|
||||
__proto__: null,
|
||||
value: 1,
|
||||
},
|
||||
CLOSING: {
|
||||
__proto__: null,
|
||||
value: 2,
|
||||
},
|
||||
CLOSED: {
|
||||
__proto__: null,
|
||||
value: 3,
|
||||
},
|
||||
});
|
||||
|
|
|
@ -11,7 +11,7 @@ const AUTOBAHN_TESTSUITE_DOCKER =
|
|||
"crossbario/autobahn-testsuite:0.8.2@sha256:5d4ba3aa7d6ab2fdbf6606f3f4ecbe4b66f205ce1cbc176d6cdf650157e52242";
|
||||
|
||||
const self = Deno.execPath();
|
||||
$`${self} run -A --unstable --config ${pwd}/../../../tests/config/deno.json ${pwd}/autobahn_server.js`
|
||||
$`${self} run -A --config ${pwd}/../../../tests/config/deno.json ${pwd}/autobahn_server.js`
|
||||
.spawn();
|
||||
|
||||
for (let i = 0; i < 6; i++) {
|
||||
|
|
|
@ -119,6 +119,7 @@ function createStorage(persistent) {
|
|||
set(target, key, value) {
|
||||
if (typeof key === "symbol") {
|
||||
return ReflectDefineProperty(target, key, {
|
||||
__proto__: null,
|
||||
value,
|
||||
configurable: true,
|
||||
});
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue