mirror of
https://github.com/denoland/deno.git
synced 2025-02-08 07:16:56 -05:00
Merge branch 'main' into poc_worker_data
This commit is contained in:
commit
c19a9d9794
60 changed files with 747 additions and 264 deletions
38
Cargo.lock
generated
38
Cargo.lock
generated
|
@ -1425,6 +1425,7 @@ dependencies = [
|
|||
"deno_io",
|
||||
"filetime",
|
||||
"fs3",
|
||||
"junction",
|
||||
"libc",
|
||||
"log",
|
||||
"nix 0.26.2",
|
||||
|
@ -1651,7 +1652,7 @@ dependencies = [
|
|||
"elliptic-curve",
|
||||
"errno 0.2.8",
|
||||
"faster-hex",
|
||||
"h2 0.3.22",
|
||||
"h2 0.3.24",
|
||||
"hkdf",
|
||||
"http 0.2.11",
|
||||
"idna 0.3.0",
|
||||
|
@ -1926,7 +1927,7 @@ dependencies = [
|
|||
"deno_net",
|
||||
"deno_tls",
|
||||
"fastwebsockets",
|
||||
"h2 0.4.0",
|
||||
"h2 0.4.2",
|
||||
"http 1.0.0",
|
||||
"http-body-util",
|
||||
"hyper 1.1.0",
|
||||
|
@ -2985,9 +2986,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.22"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178"
|
||||
checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
|
@ -3004,9 +3005,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.4.0"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1d308f63daf4181410c242d34c11f928dcb3aa105852019e043c9d1f4e4368a"
|
||||
checksum = "31d030e59af851932b72ceebadf4a2b5986dba4c3b99dd2493f8273a0f151943"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
|
@ -3256,7 +3257,7 @@ dependencies = [
|
|||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2 0.3.22",
|
||||
"h2 0.3.24",
|
||||
"http 0.2.11",
|
||||
"http-body 0.4.5",
|
||||
"httparse",
|
||||
|
@ -3279,7 +3280,7 @@ dependencies = [
|
|||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"h2 0.4.0",
|
||||
"h2 0.4.2",
|
||||
"http 1.0.0",
|
||||
"http-body 1.0.0",
|
||||
"httparse",
|
||||
|
@ -5126,7 +5127,7 @@ dependencies = [
|
|||
"encoding_rs",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2 0.3.22",
|
||||
"h2 0.3.24",
|
||||
"http 0.2.11",
|
||||
"http-body 0.4.5",
|
||||
"hyper 0.14.27",
|
||||
|
@ -6483,7 +6484,7 @@ dependencies = [
|
|||
"flate2",
|
||||
"futures",
|
||||
"glob",
|
||||
"h2 0.4.0",
|
||||
"h2 0.4.2",
|
||||
"http 1.0.0",
|
||||
"http-body-util",
|
||||
"hyper 1.1.0",
|
||||
|
@ -7178,6 +7179,12 @@ version = "0.11.0+wasi-snapshot-preview1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasite"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.89"
|
||||
|
@ -7285,7 +7292,7 @@ dependencies = [
|
|||
"codespan-reporting",
|
||||
"log",
|
||||
"naga",
|
||||
"parking_lot 0.12.1",
|
||||
"parking_lot 0.11.2",
|
||||
"profiling",
|
||||
"raw-window-handle",
|
||||
"ron",
|
||||
|
@ -7326,7 +7333,7 @@ dependencies = [
|
|||
"naga",
|
||||
"objc",
|
||||
"once_cell",
|
||||
"parking_lot 0.12.1",
|
||||
"parking_lot 0.11.2",
|
||||
"profiling",
|
||||
"range-alloc",
|
||||
"raw-window-handle",
|
||||
|
@ -7378,11 +7385,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "whoami"
|
||||
version = "1.4.1"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50"
|
||||
checksum = "0fec781d48b41f8163426ed18e8fc2864c12937df9ce54c88ede7bd47270893e"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
"redox_syscall 0.4.1",
|
||||
"wasite",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ flate2 = { version = "1.0.26", default-features = false }
|
|||
fs3 = "0.5.0"
|
||||
futures = "0.3.21"
|
||||
glob = "0.3.1"
|
||||
h2 = "0.4"
|
||||
h2 = "0.4.2"
|
||||
http = "1.0"
|
||||
http-body-util = "0.1"
|
||||
http_v02 = { package = "http", version = "0.2.9" }
|
||||
|
@ -194,6 +194,7 @@ nix = "=0.26.2"
|
|||
|
||||
# windows deps
|
||||
fwdansi = "=1.1.0"
|
||||
junction = "=0.2.0"
|
||||
winapi = "=0.3.9"
|
||||
windows-sys = { version = "0.48.0", features = ["Win32_Media"] }
|
||||
winres = "=0.1.12"
|
||||
|
|
|
@ -154,7 +154,7 @@ zstd.workspace = true
|
|||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
fwdansi.workspace = true
|
||||
junction = "=0.2.0"
|
||||
junction.workspace = true
|
||||
winapi = { workspace = true, features = ["knownfolders", "mswsock", "objbase", "shlobj", "tlhelp32", "winbase", "winerror", "winsock2"] }
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
|
|
|
@ -542,17 +542,32 @@
|
|||
"description": "List of unstable features to enable.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
"broadcast-channel",
|
||||
"bare-node-builtins",
|
||||
"byonm",
|
||||
"cron",
|
||||
"ffi",
|
||||
"fs",
|
||||
"http",
|
||||
"kv",
|
||||
"net",
|
||||
"sloppy-imports",
|
||||
"temporal",
|
||||
"unsafe-proto",
|
||||
"webgpu",
|
||||
"worker-options"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of this JSR package. Must be scoped",
|
||||
"examples": ["@luca/flag"]
|
||||
"pattern": "^@[a-z0-9-]+/[a-z0-9-]+$"
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of this JSR package.",
|
||||
"examples": ["0.1.0", "1.0.0"]
|
||||
"description": "The version of this JSR package."
|
||||
},
|
||||
"exports": {
|
||||
"oneOf": [
|
||||
|
|
|
@ -97,9 +97,9 @@ async fn prepare_publish(
|
|||
deno_json: &ConfigFile,
|
||||
source_cache: Arc<ParsedSourceCache>,
|
||||
graph: Arc<deno_graph::ModuleGraph>,
|
||||
cli_options: Arc<CliOptions>,
|
||||
mapped_resolver: Arc<MappedSpecifierResolver>,
|
||||
sloppy_imports_resolver: Option<SloppyImportsResolver>,
|
||||
bare_node_builtins: bool,
|
||||
diagnostics_collector: &PublishDiagnosticsCollector,
|
||||
) -> Result<Rc<PreparedPublishPackage>, AnyError> {
|
||||
let config_path = deno_json.specifier.to_file_path().unwrap();
|
||||
|
@ -145,6 +145,7 @@ async fn prepare_publish(
|
|||
|
||||
let diagnostics_collector = diagnostics_collector.clone();
|
||||
let tarball = deno_core::unsync::spawn_blocking(move || {
|
||||
let bare_node_builtins = cli_options.unstable_bare_node_builtins();
|
||||
let unfurler = SpecifierUnfurler::new(
|
||||
&mapped_resolver,
|
||||
sloppy_imports_resolver.as_ref(),
|
||||
|
@ -152,6 +153,7 @@ async fn prepare_publish(
|
|||
);
|
||||
tar::create_gzipped_tarball(
|
||||
&dir_path,
|
||||
&cli_options,
|
||||
LazyGraphSourceParser::new(&source_cache, &graph),
|
||||
&diagnostics_collector,
|
||||
&unfurler,
|
||||
|
@ -745,7 +747,6 @@ async fn prepare_packages_for_publishing(
|
|||
let type_checker = cli_factory.type_checker().await?;
|
||||
let fs = cli_factory.fs();
|
||||
let cli_options = cli_factory.cli_options();
|
||||
let bare_node_builtins = cli_options.unstable_bare_node_builtins();
|
||||
|
||||
if members.len() > 1 {
|
||||
println!("Publishing a workspace...");
|
||||
|
@ -776,15 +777,16 @@ async fn prepare_packages_for_publishing(
|
|||
None
|
||||
};
|
||||
let graph = graph.clone();
|
||||
let cli_options = cli_options.clone();
|
||||
async move {
|
||||
let package = prepare_publish(
|
||||
&member.package_name,
|
||||
&member.config_file,
|
||||
source_cache.clone(),
|
||||
graph,
|
||||
cli_options,
|
||||
mapped_resolver,
|
||||
sloppy_imports_resolver,
|
||||
bare_node_builtins,
|
||||
diagnostics_collector,
|
||||
)
|
||||
.await
|
||||
|
@ -952,7 +954,7 @@ pub async fn publish(
|
|||
&& !publish_flags.allow_dirty
|
||||
&& check_if_git_repo_dirty(cli_options.initial_cwd()).await
|
||||
{
|
||||
bail!("Aborting due to uncomitted changes",);
|
||||
bail!("Aborting due to uncommitted changes. Check in source code or run with --allow-dirty");
|
||||
}
|
||||
|
||||
perform_publish(
|
||||
|
|
|
@ -14,6 +14,7 @@ use std::io::Write;
|
|||
use std::path::Path;
|
||||
use tar::Header;
|
||||
|
||||
use crate::args::CliOptions;
|
||||
use crate::cache::LazyGraphSourceParser;
|
||||
use crate::tools::registry::paths::PackagePath;
|
||||
use crate::util::fs::FileCollector;
|
||||
|
@ -39,6 +40,7 @@ pub struct PublishableTarball {
|
|||
|
||||
pub fn create_gzipped_tarball(
|
||||
dir: &Path,
|
||||
cli_options: &CliOptions,
|
||||
source_parser: LazyGraphSourceParser,
|
||||
diagnostics_collector: &PublishDiagnosticsCollector,
|
||||
unfurler: &SpecifierUnfurler,
|
||||
|
@ -70,7 +72,7 @@ pub fn create_gzipped_tarball(
|
|||
})
|
||||
.ignore_git_folder()
|
||||
.ignore_node_modules()
|
||||
.ignore_vendor_folder()
|
||||
.set_vendor_folder(cli_options.vendor_dir_path().map(ToOwned::to_owned))
|
||||
.use_gitignore()
|
||||
.collect_file_patterns(file_patterns)?;
|
||||
|
||||
|
|
|
@ -261,6 +261,7 @@ pub struct FileCollector<TFilter: Fn(WalkEntry) -> bool> {
|
|||
ignore_git_folder: bool,
|
||||
ignore_node_modules: bool,
|
||||
ignore_vendor_folder: bool,
|
||||
vendor_folder: Option<PathBuf>,
|
||||
use_gitignore: bool,
|
||||
}
|
||||
|
||||
|
@ -271,6 +272,7 @@ impl<TFilter: Fn(WalkEntry) -> bool> FileCollector<TFilter> {
|
|||
ignore_git_folder: false,
|
||||
ignore_node_modules: false,
|
||||
ignore_vendor_folder: false,
|
||||
vendor_folder: None,
|
||||
use_gitignore: false,
|
||||
}
|
||||
}
|
||||
|
@ -285,6 +287,11 @@ impl<TFilter: Fn(WalkEntry) -> bool> FileCollector<TFilter> {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn set_vendor_folder(mut self, vendor_folder: Option<PathBuf>) -> Self {
|
||||
self.vendor_folder = vendor_folder;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn ignore_git_folder(mut self) -> Self {
|
||||
self.ignore_git_folder = true;
|
||||
self
|
||||
|
@ -389,22 +396,10 @@ impl<TFilter: Fn(WalkEntry) -> bool> FileCollector<TFilter> {
|
|||
iterator.skip_current_dir();
|
||||
}
|
||||
} else if is_dir {
|
||||
let should_ignore_dir = path
|
||||
.file_name()
|
||||
.map(|dir_name| {
|
||||
let dir_name = dir_name.to_string_lossy().to_lowercase();
|
||||
let is_ignored_file = match dir_name.as_str() {
|
||||
"node_modules" => self.ignore_node_modules,
|
||||
"vendor" => self.ignore_vendor_folder,
|
||||
".git" => self.ignore_git_folder,
|
||||
_ => false,
|
||||
};
|
||||
// allow the user to opt out of ignoring by explicitly specifying the dir
|
||||
file != path && is_ignored_file
|
||||
})
|
||||
.unwrap_or(false)
|
||||
|| !visited_paths.insert(path.clone());
|
||||
if should_ignore_dir {
|
||||
let opt_out_ignore = file == path;
|
||||
let should_ignore_dir = !opt_out_ignore && self.is_ignored_dir(&path);
|
||||
if should_ignore_dir || !visited_paths.insert(path.clone()) {
|
||||
iterator.skip_current_dir();
|
||||
}
|
||||
} else if (self.file_filter)(WalkEntry {
|
||||
|
@ -419,6 +414,31 @@ impl<TFilter: Fn(WalkEntry) -> bool> FileCollector<TFilter> {
|
|||
}
|
||||
Ok(target_files)
|
||||
}
|
||||
|
||||
fn is_ignored_dir(&self, path: &Path) -> bool {
|
||||
path
|
||||
.file_name()
|
||||
.map(|dir_name| {
|
||||
let dir_name = dir_name.to_string_lossy().to_lowercase();
|
||||
let is_ignored_file = match dir_name.as_str() {
|
||||
"node_modules" => self.ignore_node_modules,
|
||||
"vendor" => self.ignore_vendor_folder,
|
||||
".git" => self.ignore_git_folder,
|
||||
_ => false,
|
||||
};
|
||||
is_ignored_file
|
||||
})
|
||||
.unwrap_or(false)
|
||||
|| self.is_vendor_folder(path)
|
||||
}
|
||||
|
||||
fn is_vendor_folder(&self, path: &Path) -> bool {
|
||||
self
|
||||
.vendor_folder
|
||||
.as_ref()
|
||||
.map(|vendor_folder| path == *vendor_folder)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
/// Collects module specifiers that satisfy the given predicate as a file path, by recursively walking `include`.
|
||||
|
|
|
@ -163,7 +163,7 @@ function createImageBitmap(
|
|||
sh = undefined,
|
||||
options = undefined,
|
||||
) {
|
||||
const prefix = "Failed to call 'createImageBitmap'";
|
||||
const prefix = "Failed to execute 'createImageBitmap'";
|
||||
|
||||
// Overload: createImageBitmap(image [, options ])
|
||||
if (arguments.length < 3) {
|
||||
|
|
|
@ -466,7 +466,7 @@ class Request {
|
|||
}
|
||||
|
||||
clone() {
|
||||
const prefix = "Failed to call 'Request.clone'";
|
||||
const prefix = "Failed to execute 'Request.clone'";
|
||||
webidl.assertBranded(this, RequestPrototype);
|
||||
if (this[_body] && this[_body].unusable()) {
|
||||
throw new TypeError("Body is unusable.");
|
||||
|
|
|
@ -256,7 +256,7 @@ class Response {
|
|||
* @returns {Response}
|
||||
*/
|
||||
static redirect(url, status = 302) {
|
||||
const prefix = "Failed to call 'Response.redirect'";
|
||||
const prefix = "Failed to execute 'Response.redirect'";
|
||||
url = webidl.converters["USVString"](url, prefix, "Argument 1");
|
||||
status = webidl.converters["unsigned short"](status, prefix, "Argument 2");
|
||||
|
||||
|
@ -283,7 +283,7 @@ class Response {
|
|||
* @returns {Response}
|
||||
*/
|
||||
static json(data = undefined, init = {}) {
|
||||
const prefix = "Failed to call 'Response.json'";
|
||||
const prefix = "Failed to execute 'Response.json'";
|
||||
data = webidl.converters.any(data);
|
||||
init = webidl.converters["ResponseInit_fast"](init, prefix, "Argument 2");
|
||||
|
||||
|
|
|
@ -313,7 +313,7 @@ function fetch(input, init = {}) {
|
|||
let opPromise = undefined;
|
||||
// 1.
|
||||
const result = new Promise((resolve, reject) => {
|
||||
const prefix = "Failed to call 'fetch'";
|
||||
const prefix = "Failed to execute 'fetch'";
|
||||
webidl.requiredArguments(arguments.length, 1, prefix);
|
||||
// 2.
|
||||
const requestObject = new Request(input, init);
|
||||
|
@ -425,7 +425,7 @@ function handleWasmStreaming(source, rid) {
|
|||
try {
|
||||
const res = webidl.converters["Response"](
|
||||
source,
|
||||
"Failed to call 'WebAssembly.compileStreaming'",
|
||||
"Failed to execute 'WebAssembly.compileStreaming'",
|
||||
"Argument 1",
|
||||
);
|
||||
|
||||
|
|
|
@ -35,3 +35,4 @@ nix.workspace = true
|
|||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = { workspace = true, features = ["winbase"] }
|
||||
junction.workspace = true
|
||||
|
|
|
@ -64,6 +64,8 @@ pub enum FsFileType {
|
|||
File,
|
||||
#[serde(rename = "dir")]
|
||||
Directory,
|
||||
#[serde(rename = "junction")]
|
||||
Junction,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
|
|
|
@ -810,6 +810,9 @@ fn symlink(
|
|||
FsFileType::Directory => {
|
||||
std::os::windows::fs::symlink_dir(oldpath, newpath)?;
|
||||
}
|
||||
FsFileType::Junction => {
|
||||
junction::create(oldpath, newpath)?;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
#![deny(clippy::print_stderr)]
|
||||
#![deny(clippy::print_stdout)]
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
|
|
@ -505,7 +505,6 @@ pub async fn op_http2_client_get_response_body_chunk(
|
|||
return Ok((Some(data.to_vec()), false));
|
||||
}
|
||||
DataOrTrailers::Trailers(trailers) => {
|
||||
println!("{trailers:?}");
|
||||
if let Some(trailers_tx) = RcRef::map(&resource, |r| &r.trailers_tx)
|
||||
.borrow_mut()
|
||||
.await
|
||||
|
|
|
@ -437,6 +437,7 @@ mod impl_ {
|
|||
(client, server)
|
||||
}
|
||||
|
||||
#[allow(clippy::print_stdout)]
|
||||
#[tokio::test]
|
||||
async fn bench_ipc() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// A simple round trip benchmark for quick dev feedback.
|
||||
|
|
|
@ -97,17 +97,16 @@ where
|
|||
{
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
// Guarantee that "from" is absolute.
|
||||
let from = if from.starts_with("file:///") {
|
||||
Url::parse(&from)?.to_file_path().unwrap()
|
||||
let from_url = if from.starts_with("file:///") {
|
||||
Url::parse(&from)?
|
||||
} else {
|
||||
deno_core::resolve_path(
|
||||
&from,
|
||||
&(fs.cwd().map_err(AnyError::from)).context("Unable to get CWD")?,
|
||||
)
|
||||
.unwrap()
|
||||
.to_file_path()
|
||||
.unwrap()
|
||||
};
|
||||
let from = url_to_file_path(&from_url)?;
|
||||
|
||||
ensure_read_permission::<P>(state, &from)?;
|
||||
|
||||
|
@ -420,8 +419,7 @@ where
|
|||
|
||||
let referrer = deno_core::url::Url::from_file_path(&pkg.path).unwrap();
|
||||
if let Some(exports) = &pkg.exports {
|
||||
node_resolver
|
||||
.package_exports_resolve(
|
||||
let r = node_resolver.package_exports_resolve(
|
||||
&pkg.path,
|
||||
&expansion,
|
||||
exports,
|
||||
|
@ -430,14 +428,12 @@ where
|
|||
resolution::REQUIRE_CONDITIONS,
|
||||
NodeResolutionMode::Execution,
|
||||
permissions,
|
||||
)
|
||||
.map(|r| {
|
||||
Some(if r.scheme() == "file" {
|
||||
r.to_file_path().unwrap().to_string_lossy().to_string()
|
||||
)?;
|
||||
Ok(Some(if r.scheme() == "file" {
|
||||
url_to_file_path_string(&r)?
|
||||
} else {
|
||||
r.to_string()
|
||||
})
|
||||
})
|
||||
}))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
|
@ -510,8 +506,7 @@ where
|
|||
|
||||
if let Some(exports) = &pkg.exports {
|
||||
let referrer = Url::from_file_path(parent_path).unwrap();
|
||||
node_resolver
|
||||
.package_exports_resolve(
|
||||
let r = node_resolver.package_exports_resolve(
|
||||
&pkg.path,
|
||||
&format!(".{expansion}"),
|
||||
exports,
|
||||
|
@ -520,14 +515,12 @@ where
|
|||
resolution::REQUIRE_CONDITIONS,
|
||||
NodeResolutionMode::Execution,
|
||||
permissions,
|
||||
)
|
||||
.map(|r| {
|
||||
Some(if r.scheme() == "file" {
|
||||
r.to_file_path().unwrap().to_string_lossy().to_string()
|
||||
)?;
|
||||
Ok(Some(if r.scheme() == "file" {
|
||||
url_to_file_path_string(&r)?
|
||||
} else {
|
||||
r.to_string()
|
||||
})
|
||||
})
|
||||
}))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
|
@ -575,32 +568,35 @@ where
|
|||
#[string]
|
||||
pub fn op_require_package_imports_resolve<P>(
|
||||
state: &mut OpState,
|
||||
#[string] parent_filename: String,
|
||||
#[string] referrer_filename: String,
|
||||
#[string] request: String,
|
||||
) -> Result<Option<String>, AnyError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
let parent_path = PathBuf::from(&parent_filename);
|
||||
ensure_read_permission::<P>(state, &parent_path)?;
|
||||
let referrer_path = PathBuf::from(&referrer_filename);
|
||||
ensure_read_permission::<P>(state, &referrer_path)?;
|
||||
let node_resolver = state.borrow::<Rc<NodeResolver>>();
|
||||
let permissions = state.borrow::<P>();
|
||||
let pkg = node_resolver
|
||||
.load_package_json(permissions, parent_path.join("package.json"))?;
|
||||
let Some(pkg) = node_resolver
|
||||
.get_closest_package_json_from_path(&referrer_path, permissions)?
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
if pkg.imports.is_some() {
|
||||
let referrer =
|
||||
deno_core::url::Url::from_file_path(&parent_filename).unwrap();
|
||||
node_resolver
|
||||
.package_imports_resolve(
|
||||
let referrer_url =
|
||||
deno_core::url::Url::from_file_path(&referrer_filename).unwrap();
|
||||
let url = node_resolver.package_imports_resolve(
|
||||
&request,
|
||||
&referrer,
|
||||
&referrer_url,
|
||||
NodeModuleKind::Cjs,
|
||||
Some(&pkg),
|
||||
resolution::REQUIRE_CONDITIONS,
|
||||
NodeResolutionMode::Execution,
|
||||
permissions,
|
||||
)
|
||||
.map(|r| Some(r.to_string()))
|
||||
)?;
|
||||
Ok(Some(url_to_file_path_string(&url)?))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
|
@ -613,3 +609,17 @@ pub fn op_require_break_on_next_statement(state: &mut OpState) {
|
|||
.borrow_mut()
|
||||
.wait_for_session_and_break_on_next_statement()
|
||||
}
|
||||
|
||||
fn url_to_file_path_string(url: &Url) -> Result<String, AnyError> {
|
||||
let file_path = url_to_file_path(url)?;
|
||||
Ok(file_path.to_string_lossy().to_string())
|
||||
}
|
||||
|
||||
fn url_to_file_path(url: &Url) -> Result<PathBuf, AnyError> {
|
||||
match url.to_file_path() {
|
||||
Ok(file_path) => Ok(file_path),
|
||||
Err(()) => {
|
||||
deno_core::anyhow::bail!("failed to convert '{}' to file path", url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1181,6 +1181,25 @@ function createRequire(filenameOrUrl) {
|
|||
return createRequireFromPath(filename);
|
||||
}
|
||||
|
||||
function isBuiltin(moduleName) {
|
||||
if (typeof moduleName !== "string") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (StringPrototypeStartsWith(moduleName, "node:")) {
|
||||
moduleName = StringPrototypeSlice(moduleName, 5);
|
||||
} else if (moduleName === "test") {
|
||||
// test is only a builtin if it has the "node:" scheme
|
||||
// see https://github.com/nodejs/node/blob/73025c4dec042e344eeea7912ed39f7b7c4a3991/test/parallel/test-module-isBuiltin.js#L14
|
||||
return false;
|
||||
}
|
||||
|
||||
return moduleName in nativeModuleExports &&
|
||||
!StringPrototypeStartsWith(moduleName, "internal/");
|
||||
}
|
||||
|
||||
Module.isBuiltin = isBuiltin;
|
||||
|
||||
Module.createRequire = createRequire;
|
||||
|
||||
Module._initPaths = function () {
|
||||
|
@ -1249,7 +1268,7 @@ internals.requireImpl = {
|
|||
nativeModuleExports,
|
||||
};
|
||||
|
||||
export { builtinModules, createRequire, Module };
|
||||
export { builtinModules, createRequire, isBuiltin, Module };
|
||||
export const _cache = Module._cache;
|
||||
export const _extensions = Module._extensions;
|
||||
export const _findPath = Module._findPath;
|
||||
|
|
|
@ -7,7 +7,7 @@ import { CallbackWithError } from "ext:deno_node/_fs/_fs_common.ts";
|
|||
import { pathFromURL } from "ext:deno_web/00_infra.js";
|
||||
import { promisify } from "ext:deno_node/internal/util.mjs";
|
||||
|
||||
type SymlinkType = "file" | "dir";
|
||||
type SymlinkType = "file" | "dir" | "junction";
|
||||
|
||||
export function symlink(
|
||||
target: string | URL,
|
||||
|
|
|
@ -820,13 +820,16 @@ Object.defineProperty(OutgoingMessage.prototype, "_headerNames", {
|
|||
),
|
||||
});
|
||||
|
||||
export const validateHeaderName = hideStackFrames((name) => {
|
||||
export const validateHeaderName = hideStackFrames(
|
||||
(name: string, label?: string): void => {
|
||||
if (typeof name !== "string" || !name || !checkIsHttpToken(name)) {
|
||||
throw new ERR_INVALID_HTTP_TOKEN("Header name", name);
|
||||
throw new ERR_INVALID_HTTP_TOKEN(label || "Header name", name);
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
export const validateHeaderValue = hideStackFrames((name, value) => {
|
||||
export const validateHeaderValue = hideStackFrames(
|
||||
(name: string, value: string): void => {
|
||||
if (value === undefined) {
|
||||
throw new ERR_HTTP_INVALID_HEADER_VALUE(value, name);
|
||||
}
|
||||
|
@ -834,7 +837,8 @@ export const validateHeaderValue = hideStackFrames((name, value) => {
|
|||
debug('Header "%s" contains invalid characters', name);
|
||||
throw new ERR_INVALID_CHAR("header content", name);
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
export function parseUniqueHeadersOption(headers) {
|
||||
if (!Array.isArray(headers)) {
|
||||
|
|
|
@ -38,6 +38,7 @@ import {
|
|||
OutgoingMessage,
|
||||
parseUniqueHeadersOption,
|
||||
validateHeaderName,
|
||||
validateHeaderValue,
|
||||
} from "ext:deno_node/_http_outgoing.ts";
|
||||
import { ok as assert } from "node:assert";
|
||||
import { kOutHeaders } from "ext:deno_node/internal/http.ts";
|
||||
|
@ -1824,6 +1825,8 @@ export {
|
|||
METHODS,
|
||||
OutgoingMessage,
|
||||
STATUS_CODES,
|
||||
validateHeaderName,
|
||||
validateHeaderValue,
|
||||
};
|
||||
export default {
|
||||
Agent,
|
||||
|
@ -1840,4 +1843,6 @@ export default {
|
|||
ServerResponse,
|
||||
request,
|
||||
get,
|
||||
validateHeaderName,
|
||||
validateHeaderValue,
|
||||
};
|
||||
|
|
|
@ -20,6 +20,7 @@ import { ERR_OUT_OF_RANGE } from "ext:deno_node/internal/errors.ts";
|
|||
import { emitWarning } from "node:process";
|
||||
import {
|
||||
clearTimeout as clearTimeout_,
|
||||
setImmediate as setImmediate_,
|
||||
setInterval as setInterval_,
|
||||
setTimeout as setTimeout_,
|
||||
} from "ext:deno_web/02_timers.js";
|
||||
|
@ -115,6 +116,35 @@ Timeout.prototype[Symbol.toPrimitive] = function () {
|
|||
return this[kTimerId];
|
||||
};
|
||||
|
||||
// Immediate constructor function.
|
||||
export function Immediate(callback, args) {
|
||||
this._immediateId = setImmediate_(callback, args);
|
||||
}
|
||||
|
||||
// Make sure the linked list only shows the minimal necessary information.
|
||||
Immediate.prototype[inspect.custom] = function (_, options) {
|
||||
return inspect(this, {
|
||||
...options,
|
||||
// Only inspect one level.
|
||||
depth: 0,
|
||||
// It should not recurse.
|
||||
customInspect: false,
|
||||
});
|
||||
};
|
||||
|
||||
// FIXME(nathanwhit): actually implement {ref,unref,hasRef} once deno_core supports it
|
||||
Immediate.prototype.unref = function () {
|
||||
return this;
|
||||
};
|
||||
|
||||
Immediate.prototype.ref = function () {
|
||||
return this;
|
||||
};
|
||||
|
||||
Immediate.prototype.hasRef = function () {
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} msecs
|
||||
* @param {string} name
|
||||
|
|
|
@ -11,6 +11,7 @@ const {
|
|||
|
||||
import {
|
||||
activeTimers,
|
||||
Immediate,
|
||||
setUnrefTimeout,
|
||||
Timeout,
|
||||
} from "ext:deno_node/internal/timers.mjs";
|
||||
|
@ -21,7 +22,6 @@ import * as timers from "ext:deno_web/02_timers.js";
|
|||
|
||||
const clearTimeout_ = timers.clearTimeout;
|
||||
const clearInterval_ = timers.clearInterval;
|
||||
const setImmediate_ = timers.setImmediate;
|
||||
|
||||
export function setTimeout(
|
||||
callback: (...args: unknown[]) => void,
|
||||
|
@ -70,15 +70,21 @@ export function clearInterval(timeout?: Timeout | number | string) {
|
|||
}
|
||||
clearInterval_(id);
|
||||
}
|
||||
// TODO(bartlomieju): implement the 'NodeJS.Immediate' versions of the timers.
|
||||
// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/1163ead296d84e7a3c80d71e7c81ecbd1a130e9a/types/node/v12/globals.d.ts#L1120-L1131
|
||||
export function setImmediate(
|
||||
cb: (...args: unknown[]) => void,
|
||||
...args: unknown[]
|
||||
): Timeout {
|
||||
return setImmediate_(cb, ...args);
|
||||
return new Immediate(cb, ...args);
|
||||
}
|
||||
export function clearImmediate(immediate: Immediate) {
|
||||
if (immediate == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME(nathanwhit): will probably change once
|
||||
// deno_core has proper support for immediates
|
||||
clearTimeout_(immediate._immediateId);
|
||||
}
|
||||
export const clearImmediate = clearTimeout;
|
||||
|
||||
export default {
|
||||
setTimeout,
|
||||
|
|
|
@ -8,21 +8,25 @@ import {
|
|||
op_host_recv_ctrl,
|
||||
op_host_recv_message,
|
||||
op_host_terminate_worker,
|
||||
op_message_port_recv_message_sync,
|
||||
op_require_read_closest_package_json,
|
||||
} from "ext:core/ops";
|
||||
import { BroadcastChannel } from "ext:deno_broadcast_channel/01_broadcast_channel.js";
|
||||
import {
|
||||
deserializeJsMessageData,
|
||||
MessageChannel,
|
||||
MessagePort,
|
||||
MessagePortIdSymbol,
|
||||
MessagePortPrototype,
|
||||
serializeJsMessageData,
|
||||
} from "ext:deno_web/13_message_port.js";
|
||||
import * as webidl from "ext:deno_webidl/00_webidl.js";
|
||||
import { log } from "ext:runtime/06_util.js";
|
||||
import { notImplemented } from "ext:deno_node/_utils.ts";
|
||||
import { EventEmitter, once } from "node:events";
|
||||
import { BroadcastChannel } from "ext:deno_broadcast_channel/01_broadcast_channel.js";
|
||||
import { isAbsolute, resolve } from "node:path";
|
||||
|
||||
const { ObjectPrototypeIsPrototypeOf } = primordials;
|
||||
const {
|
||||
Error,
|
||||
Symbol,
|
||||
|
@ -415,6 +419,7 @@ internals.__initWorkerThreads = (
|
|||
parentPort = self as ParentPort;
|
||||
workerData = maybeWorkerData;
|
||||
defaultExport.workerData = workerData;
|
||||
defaultExport.parentPort = parentPort;
|
||||
|
||||
const initPromise = PromisePrototypeThen(
|
||||
once(
|
||||
|
@ -504,9 +509,24 @@ export function markAsUntransferable() {
|
|||
export function moveMessagePortToContext() {
|
||||
notImplemented("moveMessagePortToContext");
|
||||
}
|
||||
export function receiveMessageOnPort() {
|
||||
notImplemented("receiveMessageOnPort");
|
||||
|
||||
/**
|
||||
* @param { MessagePort } port
|
||||
* @returns {object | undefined}
|
||||
*/
|
||||
export function receiveMessageOnPort(port: MessagePort): object | undefined {
|
||||
if (!(ObjectPrototypeIsPrototypeOf(MessagePortPrototype, port))) {
|
||||
const err = new TypeError(
|
||||
'The "port" argument must be a MessagePort instance',
|
||||
);
|
||||
err["code"] = "ERR_INVALID_ARG_TYPE";
|
||||
throw err;
|
||||
}
|
||||
const data = op_message_port_recv_message_sync(port[MessagePortIdSymbol]);
|
||||
if (data === null) return undefined;
|
||||
return { message: deserializeJsMessageData(data)[0] };
|
||||
}
|
||||
|
||||
export {
|
||||
BroadcastChannel,
|
||||
MessageChannel,
|
||||
|
|
|
@ -239,10 +239,12 @@ impl NodeResolver {
|
|||
Some(resolved_specifier)
|
||||
}
|
||||
} else if specifier.starts_with('#') {
|
||||
let pkg_config = self.get_closest_package_json(referrer, permissions)?;
|
||||
Some(self.package_imports_resolve(
|
||||
specifier,
|
||||
referrer,
|
||||
NodeModuleKind::Esm,
|
||||
pkg_config.as_ref(),
|
||||
conditions,
|
||||
mode,
|
||||
permissions,
|
||||
|
@ -525,11 +527,13 @@ impl NodeResolver {
|
|||
None
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(super) fn package_imports_resolve(
|
||||
&self,
|
||||
name: &str,
|
||||
referrer: &ModuleSpecifier,
|
||||
referrer_kind: NodeModuleKind,
|
||||
referrer_pkg_json: Option<&PackageJson>,
|
||||
conditions: &[&str],
|
||||
mode: NodeResolutionMode,
|
||||
permissions: &dyn NodePermissions,
|
||||
|
@ -544,12 +548,10 @@ impl NodeResolver {
|
|||
}
|
||||
|
||||
let mut package_json_path = None;
|
||||
if let Some(package_config) =
|
||||
self.get_closest_package_json(referrer, permissions)?
|
||||
{
|
||||
if package_config.exists {
|
||||
package_json_path = Some(package_config.path.clone());
|
||||
if let Some(imports) = &package_config.imports {
|
||||
if let Some(pkg_json) = &referrer_pkg_json {
|
||||
if pkg_json.exists {
|
||||
package_json_path = Some(pkg_json.path.clone());
|
||||
if let Some(imports) = &pkg_json.imports {
|
||||
if imports.contains_key(name) && !name.contains('*') {
|
||||
let target = imports.get(name).unwrap();
|
||||
let maybe_resolved = self.resolve_package_target(
|
||||
|
@ -1121,7 +1123,19 @@ impl NodeResolver {
|
|||
url: &ModuleSpecifier,
|
||||
permissions: &dyn NodePermissions,
|
||||
) -> Result<Option<PackageJson>, AnyError> {
|
||||
let Some(package_json_path) = self.get_closest_package_json_path(url)?
|
||||
let Ok(file_path) = url.to_file_path() else {
|
||||
return Ok(None);
|
||||
};
|
||||
self.get_closest_package_json_from_path(&file_path, permissions)
|
||||
}
|
||||
|
||||
pub fn get_closest_package_json_from_path(
|
||||
&self,
|
||||
file_path: &Path,
|
||||
permissions: &dyn NodePermissions,
|
||||
) -> Result<Option<PackageJson>, AnyError> {
|
||||
let Some(package_json_path) =
|
||||
self.get_closest_package_json_path(file_path)?
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
@ -1132,11 +1146,8 @@ impl NodeResolver {
|
|||
|
||||
fn get_closest_package_json_path(
|
||||
&self,
|
||||
url: &ModuleSpecifier,
|
||||
file_path: &Path,
|
||||
) -> Result<Option<PathBuf>, AnyError> {
|
||||
let Ok(file_path) = url.to_file_path() else {
|
||||
return Ok(None);
|
||||
};
|
||||
let current_dir = deno_core::strip_unc_prefix(
|
||||
self.fs.realpath_sync(file_path.parent().unwrap())?,
|
||||
);
|
||||
|
|
|
@ -395,7 +395,7 @@ class URL {
|
|||
* @param {string} [base]
|
||||
*/
|
||||
static canParse(url, base = undefined) {
|
||||
const prefix = "Failed to call 'URL.canParse'";
|
||||
const prefix = "Failed to execute 'URL.canParse'";
|
||||
webidl.requiredArguments(arguments.length, 1, prefix);
|
||||
url = webidl.converters.DOMString(url, prefix, "Argument 1");
|
||||
if (base !== undefined) {
|
||||
|
|
|
@ -1507,7 +1507,7 @@ function checkThis(thisArg) {
|
|||
// https://html.spec.whatwg.org/#dom-reporterror
|
||||
function reportError(error) {
|
||||
checkThis(this);
|
||||
const prefix = "Failed to call 'reportError'";
|
||||
const prefix = "Failed to execute 'reportError'";
|
||||
webidl.requiredArguments(arguments.length, 1, prefix);
|
||||
reportException(error);
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ const illegalConstructorKey = Symbol("illegalConstructorKey");
|
|||
|
||||
class AbortSignal extends EventTarget {
|
||||
static any(signals) {
|
||||
const prefix = "Failed to call 'AbortSignal.any'";
|
||||
const prefix = "Failed to execute 'AbortSignal.any'";
|
||||
webidl.requiredArguments(arguments.length, 1, prefix);
|
||||
return createDependentAbortSignal(signals, prefix);
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ class AbortSignal extends EventTarget {
|
|||
}
|
||||
|
||||
static timeout(millis) {
|
||||
const prefix = "Failed to call 'AbortSignal.timeout'";
|
||||
const prefix = "Failed to execute 'AbortSignal.timeout'";
|
||||
webidl.requiredArguments(arguments.length, 1, prefix);
|
||||
millis = webidl.converters["unsigned long long"](
|
||||
millis,
|
||||
|
|
|
@ -573,7 +573,7 @@ function extractSizeAlgorithm(strategy) {
|
|||
[chunk],
|
||||
undefined,
|
||||
webidl.converters["unrestricted double"],
|
||||
"Failed to call `sizeAlgorithm`",
|
||||
"Failed to execute `sizeAlgorithm`",
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -3551,7 +3551,7 @@ function setUpReadableByteStreamControllerFromUnderlyingSource(
|
|||
[controller],
|
||||
underlyingSource,
|
||||
webidl.converters.any,
|
||||
"Failed to call 'startAlgorithm' on 'ReadableByteStreamController'",
|
||||
"Failed to execute 'startAlgorithm' on 'ReadableByteStreamController'",
|
||||
);
|
||||
}
|
||||
if (underlyingSourceDict.pull !== undefined) {
|
||||
|
@ -3561,7 +3561,7 @@ function setUpReadableByteStreamControllerFromUnderlyingSource(
|
|||
[controller],
|
||||
underlyingSource,
|
||||
webidl.converters["Promise<undefined>"],
|
||||
"Failed to call 'pullAlgorithm' on 'ReadableByteStreamController'",
|
||||
"Failed to execute 'pullAlgorithm' on 'ReadableByteStreamController'",
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
@ -3572,7 +3572,7 @@ function setUpReadableByteStreamControllerFromUnderlyingSource(
|
|||
[reason],
|
||||
underlyingSource,
|
||||
webidl.converters["Promise<undefined>"],
|
||||
"Failed to call 'cancelAlgorithm' on 'ReadableByteStreamController'",
|
||||
"Failed to execute 'cancelAlgorithm' on 'ReadableByteStreamController'",
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
@ -3664,7 +3664,7 @@ function setUpReadableStreamDefaultControllerFromUnderlyingSource(
|
|||
[controller],
|
||||
underlyingSource,
|
||||
webidl.converters.any,
|
||||
"Failed to call 'startAlgorithm' on 'ReadableStreamDefaultController'",
|
||||
"Failed to execute 'startAlgorithm' on 'ReadableStreamDefaultController'",
|
||||
);
|
||||
}
|
||||
if (underlyingSourceDict.pull !== undefined) {
|
||||
|
@ -3674,7 +3674,7 @@ function setUpReadableStreamDefaultControllerFromUnderlyingSource(
|
|||
[controller],
|
||||
underlyingSource,
|
||||
webidl.converters["Promise<undefined>"],
|
||||
"Failed to call 'pullAlgorithm' on 'ReadableStreamDefaultController'",
|
||||
"Failed to execute 'pullAlgorithm' on 'ReadableStreamDefaultController'",
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
@ -3685,7 +3685,7 @@ function setUpReadableStreamDefaultControllerFromUnderlyingSource(
|
|||
[reason],
|
||||
underlyingSource,
|
||||
webidl.converters["Promise<undefined>"],
|
||||
"Failed to call 'cancelAlgorithm' on 'ReadableStreamDefaultController'",
|
||||
"Failed to execute 'cancelAlgorithm' on 'ReadableStreamDefaultController'",
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
@ -3791,7 +3791,7 @@ function setUpTransformStreamDefaultControllerFromTransformer(
|
|||
[chunk, controller],
|
||||
transformer,
|
||||
webidl.converters["Promise<undefined>"],
|
||||
"Failed to call 'transformAlgorithm' on 'TransformStreamDefaultController'",
|
||||
"Failed to execute 'transformAlgorithm' on 'TransformStreamDefaultController'",
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
@ -3802,7 +3802,7 @@ function setUpTransformStreamDefaultControllerFromTransformer(
|
|||
[controller],
|
||||
transformer,
|
||||
webidl.converters["Promise<undefined>"],
|
||||
"Failed to call 'flushAlgorithm' on 'TransformStreamDefaultController'",
|
||||
"Failed to execute 'flushAlgorithm' on 'TransformStreamDefaultController'",
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
@ -3813,7 +3813,7 @@ function setUpTransformStreamDefaultControllerFromTransformer(
|
|||
[reason],
|
||||
transformer,
|
||||
webidl.converters["Promise<undefined>"],
|
||||
"Failed to call 'cancelAlgorithm' on 'TransformStreamDefaultController'",
|
||||
"Failed to execute 'cancelAlgorithm' on 'TransformStreamDefaultController'",
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
@ -3907,7 +3907,7 @@ function setUpWritableStreamDefaultControllerFromUnderlyingSink(
|
|||
[controller],
|
||||
underlyingSink,
|
||||
webidl.converters.any,
|
||||
"Failed to call 'startAlgorithm' on 'WritableStreamDefaultController'",
|
||||
"Failed to execute 'startAlgorithm' on 'WritableStreamDefaultController'",
|
||||
);
|
||||
}
|
||||
if (underlyingSinkDict.write !== undefined) {
|
||||
|
@ -3917,7 +3917,7 @@ function setUpWritableStreamDefaultControllerFromUnderlyingSink(
|
|||
[chunk, controller],
|
||||
underlyingSink,
|
||||
webidl.converters["Promise<undefined>"],
|
||||
"Failed to call 'writeAlgorithm' on 'WritableStreamDefaultController'",
|
||||
"Failed to execute 'writeAlgorithm' on 'WritableStreamDefaultController'",
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
@ -3928,7 +3928,7 @@ function setUpWritableStreamDefaultControllerFromUnderlyingSink(
|
|||
[],
|
||||
underlyingSink,
|
||||
webidl.converters["Promise<undefined>"],
|
||||
"Failed to call 'closeAlgorithm' on 'WritableStreamDefaultController'",
|
||||
"Failed to execute 'closeAlgorithm' on 'WritableStreamDefaultController'",
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
@ -3939,7 +3939,7 @@ function setUpWritableStreamDefaultControllerFromUnderlyingSink(
|
|||
[reason],
|
||||
underlyingSink,
|
||||
webidl.converters["Promise<undefined>"],
|
||||
"Failed to call 'abortAlgorithm' on 'WritableStreamDefaultController'",
|
||||
"Failed to execute 'abortAlgorithm' on 'WritableStreamDefaultController'",
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
@ -5196,7 +5196,7 @@ class ReadableStream {
|
|||
webidl.requiredArguments(
|
||||
arguments.length,
|
||||
1,
|
||||
"Failed to call 'ReadableStream.from'",
|
||||
"Failed to execute 'ReadableStream.from'",
|
||||
);
|
||||
asyncIterable = webidl.converters.any(asyncIterable);
|
||||
|
||||
|
@ -6209,7 +6209,7 @@ class TransformStream {
|
|||
[this[_controller]],
|
||||
transformer,
|
||||
webidl.converters.any,
|
||||
"Failed to call 'start' on 'TransformStreamDefaultController'",
|
||||
"Failed to execute 'start' on 'TransformStreamDefaultController'",
|
||||
),
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -83,6 +83,7 @@ webidl.configureInterface(MessageChannel);
|
|||
const MessageChannelPrototype = MessageChannel.prototype;
|
||||
|
||||
const _id = Symbol("id");
|
||||
const MessagePortIdSymbol = _id;
|
||||
const _enabled = Symbol("enabled");
|
||||
|
||||
/**
|
||||
|
@ -380,6 +381,7 @@ export {
|
|||
deserializeJsMessageData,
|
||||
MessageChannel,
|
||||
MessagePort,
|
||||
MessagePortIdSymbol,
|
||||
MessagePortPrototype,
|
||||
serializeJsMessageData,
|
||||
structuredClone,
|
||||
|
|
6
ext/web/internal.d.ts
vendored
6
ext/web/internal.d.ts
vendored
|
@ -110,4 +110,10 @@ declare module "ext:deno_web/13_message_port.js" {
|
|||
data: Uint8Array;
|
||||
transferables: Transferable[];
|
||||
}
|
||||
const MessageChannel: typeof MessageChannel;
|
||||
const MessagePort: typeof MessagePort;
|
||||
const MessagePortIdSymbol: typeof MessagePortIdSymbol;
|
||||
function deserializeJsMessageData(
|
||||
messageData: messagePort.MessageData,
|
||||
): [object, object[]];
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ pub use crate::message_port::create_entangled_message_port;
|
|||
use crate::message_port::op_message_port_create_entangled;
|
||||
use crate::message_port::op_message_port_post_message;
|
||||
use crate::message_port::op_message_port_recv_message;
|
||||
use crate::message_port::op_message_port_recv_message_sync;
|
||||
pub use crate::message_port::JsMessageData;
|
||||
pub use crate::message_port::MessagePort;
|
||||
|
||||
|
@ -78,6 +79,7 @@ deno_core::extension!(deno_web,
|
|||
op_message_port_create_entangled,
|
||||
op_message_port_post_message,
|
||||
op_message_port_recv_message,
|
||||
op_message_port_recv_message_sync,
|
||||
compression::op_compression_new,
|
||||
compression::op_compression_write,
|
||||
compression::op_compression_finish,
|
||||
|
|
|
@ -17,6 +17,7 @@ use deno_core::Resource;
|
|||
use deno_core::ResourceId;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use tokio::sync::mpsc::error::TryRecvError;
|
||||
use tokio::sync::mpsc::unbounded_channel;
|
||||
use tokio::sync::mpsc::UnboundedReceiver;
|
||||
use tokio::sync::mpsc::UnboundedSender;
|
||||
|
@ -227,3 +228,22 @@ pub async fn op_message_port_recv_message(
|
|||
let cancel = RcRef::map(resource.clone(), |r| &r.cancel);
|
||||
resource.port.recv(state).or_cancel(cancel).await?
|
||||
}
|
||||
|
||||
#[op2]
|
||||
#[serde]
|
||||
pub fn op_message_port_recv_message_sync(
|
||||
state: &mut OpState, // Rc<RefCell<OpState>>,
|
||||
#[smi] rid: ResourceId,
|
||||
) -> Result<Option<JsMessageData>, AnyError> {
|
||||
let resource = state.resource_table.get::<MessagePortResource>(rid)?;
|
||||
let mut rx = resource.port.rx.borrow_mut();
|
||||
|
||||
match rx.try_recv() {
|
||||
Ok((d, t)) => Ok(Some(JsMessageData {
|
||||
data: d,
|
||||
transferables: serialize_transferables(state, t),
|
||||
})),
|
||||
Err(TryRecvError::Empty) => Ok(None),
|
||||
Err(TryRecvError::Disconnected) => Ok(None),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -417,9 +417,14 @@ class WebSocket extends EventTarget {
|
|||
switch (kind) {
|
||||
case 0: {
|
||||
/* string */
|
||||
const data = op_ws_get_buffer_as_string(rid);
|
||||
if (data === undefined) {
|
||||
break;
|
||||
}
|
||||
|
||||
this[_serverHandleIdleTimeout]();
|
||||
const event = new MessageEvent("message", {
|
||||
data: op_ws_get_buffer_as_string(rid),
|
||||
data,
|
||||
origin: this[_url],
|
||||
});
|
||||
setIsTrusted(event, true);
|
||||
|
@ -428,9 +433,14 @@ class WebSocket extends EventTarget {
|
|||
}
|
||||
case 1: {
|
||||
/* binary */
|
||||
const d = op_ws_get_buffer(rid);
|
||||
if (d == undefined) {
|
||||
break;
|
||||
}
|
||||
|
||||
this[_serverHandleIdleTimeout]();
|
||||
// deno-lint-ignore prefer-primordials
|
||||
const buffer = op_ws_get_buffer(rid).buffer;
|
||||
const buffer = d.buffer;
|
||||
let data;
|
||||
if (this.binaryType === "blob") {
|
||||
data = new Blob([buffer]);
|
||||
|
|
|
@ -703,9 +703,11 @@ pub async fn op_ws_close(
|
|||
pub fn op_ws_get_buffer(
|
||||
state: &mut OpState,
|
||||
#[smi] rid: ResourceId,
|
||||
) -> Result<ToJsBuffer, AnyError> {
|
||||
let resource = state.resource_table.get::<ServerWebSocket>(rid)?;
|
||||
Ok(resource.buffer.take().unwrap().into())
|
||||
) -> Option<ToJsBuffer> {
|
||||
let Ok(resource) = state.resource_table.get::<ServerWebSocket>(rid) else {
|
||||
return None;
|
||||
};
|
||||
resource.buffer.take().map(ToJsBuffer::from)
|
||||
}
|
||||
|
||||
#[op2]
|
||||
|
@ -713,9 +715,11 @@ pub fn op_ws_get_buffer(
|
|||
pub fn op_ws_get_buffer_as_string(
|
||||
state: &mut OpState,
|
||||
#[smi] rid: ResourceId,
|
||||
) -> Result<String, AnyError> {
|
||||
let resource = state.resource_table.get::<ServerWebSocket>(rid)?;
|
||||
Ok(resource.string.take().unwrap())
|
||||
) -> Option<String> {
|
||||
let Ok(resource) = state.resource_table.get::<ServerWebSocket>(rid) else {
|
||||
return None;
|
||||
};
|
||||
resource.string.take()
|
||||
}
|
||||
|
||||
#[op2]
|
||||
|
|
|
@ -477,6 +477,13 @@ itest!(run_existing_npm_package_with_subpath {
|
|||
copy_temp_dir: Some("npm/run_existing_npm_package_with_subpath/"),
|
||||
});
|
||||
|
||||
itest!(cjs_pkg_imports {
|
||||
args: "run -A npm/cjs_pkg_imports/main.ts",
|
||||
output: "npm/cjs_pkg_imports/main.out",
|
||||
envs: env_vars_for_npm_tests(),
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn parallel_downloading() {
|
||||
let (out, _err) = util::run_and_collect_output_with_args(
|
||||
|
|
|
@ -589,6 +589,46 @@ fn not_includes_gitignored_dotenv() {
|
|||
assert_not_contains!(output, ".env");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn not_includes_vendor_dir_only_when_vendor_true() {
|
||||
let context = publish_context_builder().build();
|
||||
let temp_dir = context.temp_dir().path();
|
||||
temp_dir.join("deno.json").write_json(&json!({
|
||||
"name": "@foo/bar",
|
||||
"version": "1.0.0",
|
||||
"exports": "./main.ts",
|
||||
}));
|
||||
|
||||
temp_dir.join("main.ts").write("");
|
||||
let vendor_folder = temp_dir.join("vendor");
|
||||
vendor_folder.create_dir_all();
|
||||
vendor_folder.join("vendor.ts").write("");
|
||||
|
||||
let publish_cmd = context.new_command().args("publish --dry-run");
|
||||
{
|
||||
let output = publish_cmd.run();
|
||||
output.assert_exit_code(0);
|
||||
let output = output.combined_output();
|
||||
assert_contains!(output, "main.ts");
|
||||
assert_contains!(output, "vendor.ts");
|
||||
}
|
||||
|
||||
// with vendor
|
||||
{
|
||||
temp_dir.join("deno.json").write_json(&json!({
|
||||
"name": "@foo/bar",
|
||||
"version": "1.0.0",
|
||||
"exports": "./main.ts",
|
||||
"vendor": true,
|
||||
}));
|
||||
let output = publish_cmd.run();
|
||||
output.assert_exit_code(0);
|
||||
let output = output.combined_output();
|
||||
assert_contains!(output, "main.ts");
|
||||
assert_not_contains!(output, "vendor.ts");
|
||||
}
|
||||
}
|
||||
|
||||
fn publish_context_builder() -> TestContextBuilder {
|
||||
TestContextBuilder::new()
|
||||
.use_http_server()
|
||||
|
@ -630,7 +670,7 @@ fn allow_dirty() {
|
|||
.run();
|
||||
output.assert_exit_code(1);
|
||||
let output = output.combined_output();
|
||||
assert_contains!(output, "Aborting due to uncomitted changes");
|
||||
assert_contains!(output, "Aborting due to uncommitted changes. Check in source code or run with --allow-dirty");
|
||||
|
||||
let output = context
|
||||
.new_command()
|
||||
|
|
|
@ -104,6 +104,8 @@
|
|||
"test-util.js",
|
||||
"test-webcrypto-sign-verify.js",
|
||||
"test-whatwg-url-properties.js",
|
||||
// needs replace ".on" => ".addEventListener" in L29
|
||||
"test-worker-message-port-receive-message.js",
|
||||
"test-zlib-convenience-methods.js",
|
||||
"test-zlib-empty-buffer.js",
|
||||
"test-zlib-invalid-input.js",
|
||||
|
@ -365,6 +367,7 @@
|
|||
// TODO(lev): ClientRequest.socket is not polyfilled so this test keeps
|
||||
// failing
|
||||
//"test-http-client-set-timeout.js",
|
||||
"test-http-header-validators.js",
|
||||
"test-http-localaddress.js",
|
||||
// TODO(bartlomieju): temporarily disabled while we iterate on the HTTP client
|
||||
// "test-http-outgoing-buffer.js",
|
||||
|
@ -664,6 +667,7 @@
|
|||
"test-whatwg-url-custom-tostringtag.js",
|
||||
"test-whatwg-url-override-hostname.js",
|
||||
"test-whatwg-url-properties.js",
|
||||
"test-worker-message-port-receive-message.js",
|
||||
"test-zlib-close-after-error.js",
|
||||
"test-zlib-close-after-write.js",
|
||||
"test-zlib-convenience-methods.js",
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
// deno-fmt-ignore-file
|
||||
// deno-lint-ignore-file
|
||||
|
||||
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
|
||||
// Taken from Node 18.12.1
|
||||
// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually.
|
||||
|
||||
'use strict';
|
||||
require('../common');
|
||||
const assert = require('assert');
|
||||
const { validateHeaderName, validateHeaderValue } = require('http');
|
||||
|
||||
// Expected static methods
|
||||
isFunc(validateHeaderName, 'validateHeaderName');
|
||||
isFunc(validateHeaderValue, 'validateHeaderValue');
|
||||
|
||||
// Expected to be useful as static methods
|
||||
console.log('validateHeaderName');
|
||||
// - when used with valid header names - should not throw
|
||||
[
|
||||
'user-agent',
|
||||
'USER-AGENT',
|
||||
'User-Agent',
|
||||
'x-forwarded-for',
|
||||
].forEach((name) => {
|
||||
console.log('does not throw for "%s"', name);
|
||||
validateHeaderName(name);
|
||||
});
|
||||
|
||||
// - when used with invalid header names:
|
||||
[
|
||||
'איקס-פורוורד-פור',
|
||||
'x-forwarded-fםr',
|
||||
].forEach((name) => {
|
||||
console.log('throws for: "%s"', name.slice(0, 50));
|
||||
assert.throws(
|
||||
() => validateHeaderName(name),
|
||||
{ code: 'ERR_INVALID_HTTP_TOKEN' }
|
||||
);
|
||||
});
|
||||
|
||||
console.log('validateHeaderValue');
|
||||
// - when used with valid header values - should not throw
|
||||
[
|
||||
['x-valid', 1],
|
||||
['x-valid', '1'],
|
||||
['x-valid', 'string'],
|
||||
].forEach(([name, value]) => {
|
||||
console.log('does not throw for "%s"', name);
|
||||
validateHeaderValue(name, value);
|
||||
});
|
||||
|
||||
// - when used with invalid header values:
|
||||
[
|
||||
// [header, value, expectedCode]
|
||||
['x-undefined', undefined, 'ERR_HTTP_INVALID_HEADER_VALUE'],
|
||||
['x-bad-char', 'לא תקין', 'ERR_INVALID_CHAR'],
|
||||
].forEach(([name, value, code]) => {
|
||||
console.log('throws %s for: "%s: %s"', code, name, value);
|
||||
assert.throws(
|
||||
() => validateHeaderValue(name, value),
|
||||
{ code }
|
||||
);
|
||||
});
|
||||
|
||||
// Misc.
|
||||
function isFunc(v, ttl) {
|
||||
assert.ok(v.constructor === Function, `${ttl} is expected to be a function`);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
// deno-fmt-ignore-file
|
||||
// deno-lint-ignore-file
|
||||
|
||||
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
|
||||
// Taken from Node 18.12.1
|
||||
// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually.
|
||||
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const { MessageChannel, receiveMessageOnPort } = require('worker_threads');
|
||||
|
||||
const { port1, port2 } = new MessageChannel();
|
||||
|
||||
const message1 = { hello: 'world' };
|
||||
const message2 = { foo: 'bar' };
|
||||
|
||||
// Make sure receiveMessageOnPort() works in a FIFO way, the same way it does
|
||||
// when we’re using events.
|
||||
assert.strictEqual(receiveMessageOnPort(port2), undefined);
|
||||
port1.postMessage(message1);
|
||||
port1.postMessage(message2);
|
||||
assert.deepStrictEqual(receiveMessageOnPort(port2), { message: message1 });
|
||||
assert.deepStrictEqual(receiveMessageOnPort(port2), { message: message2 });
|
||||
assert.strictEqual(receiveMessageOnPort(port2), undefined);
|
||||
assert.strictEqual(receiveMessageOnPort(port2), undefined);
|
||||
|
||||
// Make sure message handlers aren’t called.
|
||||
port2.addEventListener('message', common.mustNotCall());
|
||||
port1.postMessage(message1);
|
||||
assert.deepStrictEqual(receiveMessageOnPort(port2), { message: message1 });
|
||||
port1.close();
|
||||
|
||||
for (const value of [null, 0, -1, {}, []]) {
|
||||
assert.throws(() => receiveMessageOnPort(value), {
|
||||
name: 'TypeError',
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
message: 'The "port" argument must be a MessagePort instance'
|
||||
});
|
||||
}
|
3
tests/testdata/npm/cjs_pkg_imports/main.out
vendored
Normal file
3
tests/testdata/npm/cjs_pkg_imports/main.out
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
Download http://localhost:4545/npm/registry/@denotest/cjs-pkg-imports
|
||||
Download http://localhost:4545/npm/registry/@denotest/cjs-pkg-imports/1.0.0.tgz
|
||||
{ crypto: Crypto { subtle: SubtleCrypto {} }, number: 5 }
|
3
tests/testdata/npm/cjs_pkg_imports/main.ts
vendored
Normal file
3
tests/testdata/npm/cjs_pkg_imports/main.ts
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
import crypto from "npm:@denotest/cjs-pkg-imports";
|
||||
|
||||
console.log(crypto);
|
2
tests/testdata/npm/compare_globals/main.out
vendored
2
tests/testdata/npm/compare_globals/main.out
vendored
|
@ -4,7 +4,7 @@ Download http://localhost:4545/npm/registry/@denotest/globals
|
|||
[UNORDERED_END]
|
||||
[UNORDERED_START]
|
||||
Download http://localhost:4545/npm/registry/@denotest/globals/1.0.0.tgz
|
||||
Download http://localhost:4545/npm/registry/@types/node/node-18.8.2.tgz
|
||||
Download http://localhost:4545/npm/registry/@types/node/node-18.16.19.tgz
|
||||
[UNORDERED_END]
|
||||
Check file:///[WILDCARD]/npm/compare_globals/main.ts
|
||||
true
|
||||
|
|
7
tests/testdata/npm/registry/@denotest/cjs-pkg-imports/1.0.0/index.js
vendored
Normal file
7
tests/testdata/npm/registry/@denotest/cjs-pkg-imports/1.0.0/index.js
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
const crypto = require("#crypto");
|
||||
const number = require("#number");
|
||||
|
||||
module.exports = {
|
||||
crypto,
|
||||
number,
|
||||
};
|
1
tests/testdata/npm/registry/@denotest/cjs-pkg-imports/1.0.0/number.js
vendored
Normal file
1
tests/testdata/npm/registry/@denotest/cjs-pkg-imports/1.0.0/number.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
module.exports = 5;
|
13
tests/testdata/npm/registry/@denotest/cjs-pkg-imports/1.0.0/package.json
vendored
Normal file
13
tests/testdata/npm/registry/@denotest/cjs-pkg-imports/1.0.0/package.json
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "@denotest/cjs-pkg-imports",
|
||||
"version": "1.0.0",
|
||||
"imports": {
|
||||
"#crypto": {
|
||||
"node": "./sub/dist/crypto.js",
|
||||
"default": "./sub/dist/crypto.mjs"
|
||||
},
|
||||
"#number": {
|
||||
"node": "./number.js"
|
||||
}
|
||||
}
|
||||
}
|
1
tests/testdata/npm/registry/@denotest/cjs-pkg-imports/1.0.0/sub/dist/crypto.js
vendored
Normal file
1
tests/testdata/npm/registry/@denotest/cjs-pkg-imports/1.0.0/sub/dist/crypto.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
module.exports = require('node:crypto').webcrypto;
|
1
tests/testdata/npm/registry/@denotest/cjs-pkg-imports/1.0.0/sub/dist/crypto.mjs
vendored
Normal file
1
tests/testdata/npm/registry/@denotest/cjs-pkg-imports/1.0.0/sub/dist/crypto.mjs
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export default crypto;
|
BIN
tests/testdata/npm/registry/@types/node/node-18.16.19.tgz
vendored
Normal file
BIN
tests/testdata/npm/registry/@types/node/node-18.16.19.tgz
vendored
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -1,7 +1,7 @@
|
|||
Warning: Resolving "url" as "node:url" at file:///[WILDCARD]/publish/bare_node_builtins/mod.ts:1:22. If you want to use a built-in Node module, add a "node:" prefix.
|
||||
Warning: Resolving "url" as "node:url" at file:///[WILDCARD]/publish/bare_node_builtins/mod.ts:1:22. If you want to use a built-in Node module, add a "node:" prefix.
|
||||
Download http://localhost:4545/npm/registry/@types/node
|
||||
Download http://localhost:4545/npm/registry/@types/node/node-18.8.2.tgz
|
||||
Download http://localhost:4545/npm/registry/@types/node/node-18.16.19.tgz
|
||||
Check file:///[WILDCARD]/publish/bare_node_builtins/mod.ts
|
||||
Checking for slow types in the public API...
|
||||
Check file:///[WILDCARD]/publish/bare_node_builtins/mod.ts
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Download http://localhost:4545/npm/registry/@types/node
|
||||
Download http://localhost:4545/npm/registry/@types/node/node-18.8.2.tgz
|
||||
Download http://localhost:4545/npm/registry/@types/node/node-18.16.19.tgz
|
||||
Check file:///[WILDCARD]/publish/bare_node_builtins/mod.ts
|
||||
Checking for slow types in the public API...
|
||||
Check file:///[WILDCARD]/publish/bare_node_builtins/mod.ts
|
||||
|
|
|
@ -105,3 +105,20 @@ Deno.test({
|
|||
}
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "SYNC: symlink junction",
|
||||
fn() {
|
||||
const dir: string = Deno.makeTempDirSync();
|
||||
const linkedDir: string = dir + "-junction";
|
||||
|
||||
try {
|
||||
symlinkSync(dir, linkedDir, "junction");
|
||||
const stat = Deno.lstatSync(linkedDir);
|
||||
assert(stat.isSymlink);
|
||||
} finally {
|
||||
Deno.removeSync(dir);
|
||||
Deno.removeSync(linkedDir);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
import { createRequire, Module } from "node:module";
|
||||
import { createRequire, isBuiltin, Module } from "node:module";
|
||||
import { assert, assertEquals } from "@std/assert/mod.ts";
|
||||
import process from "node:process";
|
||||
import * as path from "node:path";
|
||||
|
@ -70,3 +70,16 @@ Deno.test("Built-in Node modules have `node:` prefix", () => {
|
|||
|
||||
assert(thrown);
|
||||
});
|
||||
|
||||
Deno.test("[node/module isBuiltin] recognizes node builtins", () => {
|
||||
assert(isBuiltin("node:fs"));
|
||||
assert(isBuiltin("node:test"));
|
||||
assert(isBuiltin("fs"));
|
||||
assert(isBuiltin("buffer"));
|
||||
|
||||
assert(!isBuiltin("internal/errors"));
|
||||
assert(!isBuiltin("test"));
|
||||
assert(!isBuiltin(""));
|
||||
// deno-lint-ignore no-explicit-any
|
||||
assert(!isBuiltin(undefined as any));
|
||||
});
|
||||
|
|
|
@ -33,13 +33,13 @@ Deno.test("[node/timers setInterval]", () => {
|
|||
Deno.test("[node/timers setImmediate]", () => {
|
||||
{
|
||||
const { clearImmediate, setImmediate } = timers;
|
||||
const id = setImmediate(() => {});
|
||||
clearImmediate(id);
|
||||
const imm = setImmediate(() => {});
|
||||
clearImmediate(imm);
|
||||
}
|
||||
|
||||
{
|
||||
const id = timers.setImmediate(() => {});
|
||||
timers.clearImmediate(id);
|
||||
const imm = timers.setImmediate(() => {});
|
||||
timers.clearImmediate(imm);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -60,3 +60,13 @@ Deno.test("[node/timers refresh cancelled timer]", () => {
|
|||
clearTimeout(p);
|
||||
p.refresh();
|
||||
});
|
||||
|
||||
Deno.test("[node/timers setImmediate returns Immediate object]", () => {
|
||||
const { clearImmediate, setImmediate } = timers;
|
||||
|
||||
const imm = setImmediate(() => {});
|
||||
imm.unref();
|
||||
imm.ref();
|
||||
imm.hasRef();
|
||||
clearImmediate(imm);
|
||||
});
|
||||
|
|
|
@ -54,8 +54,7 @@ macro_rules! assert_not_contains {
|
|||
|
||||
#[track_caller]
|
||||
pub fn assert_wildcard_match(actual: &str, expected: &str) {
|
||||
if !expected.contains("[WILDCARD]") && !expected.contains("[UNORDERED_START]")
|
||||
{
|
||||
if !expected.contains("[WILD") && !expected.contains("[UNORDERED_START]") {
|
||||
pretty_assertions::assert_eq!(actual, expected);
|
||||
} else {
|
||||
match crate::wildcard_match_detailed(expected, actual) {
|
||||
|
|
|
@ -674,21 +674,43 @@ pub fn wildcard_match_detailed(
|
|||
let parts = parse_wildcard_pattern_text(&pattern).unwrap();
|
||||
|
||||
let mut was_last_wildcard = false;
|
||||
let mut was_last_wildline = false;
|
||||
for (i, part) in parts.iter().enumerate() {
|
||||
match part {
|
||||
WildcardPatternPart::Wildcard => {
|
||||
output_lines.push("<WILDCARD />".to_string());
|
||||
}
|
||||
WildcardPatternPart::Wildline => {
|
||||
output_lines.push("<WILDLINE />".to_string());
|
||||
}
|
||||
WildcardPatternPart::Wildnum(times) => {
|
||||
if current_text.len() < *times {
|
||||
output_lines
|
||||
.push(format!("==== HAD MISSING WILDCHARS({}) ====", times));
|
||||
output_lines.push(colors::red(annotate_whitespace(current_text)));
|
||||
return WildcardMatchResult::Fail(output_lines.join("\n"));
|
||||
}
|
||||
output_lines.push(format!("<WILDCHARS({}) />", times));
|
||||
current_text = ¤t_text[*times..];
|
||||
}
|
||||
WildcardPatternPart::Text(search_text) => {
|
||||
let is_last = i + 1 == parts.len();
|
||||
let search_index = if is_last && was_last_wildcard {
|
||||
// search from the end of the file
|
||||
current_text.rfind(search_text)
|
||||
} else if was_last_wildline {
|
||||
if is_last {
|
||||
find_last_text_on_line(search_text, current_text)
|
||||
} else {
|
||||
find_first_text_on_line(search_text, current_text)
|
||||
}
|
||||
} else {
|
||||
current_text.find(search_text)
|
||||
};
|
||||
match search_index {
|
||||
Some(found_index) if was_last_wildcard || found_index == 0 => {
|
||||
Some(found_index)
|
||||
if was_last_wildcard || was_last_wildline || found_index == 0 =>
|
||||
{
|
||||
output_lines.push(format!(
|
||||
"<FOUND>{}</FOUND>",
|
||||
colors::gray(annotate_whitespace(search_text))
|
||||
|
@ -707,11 +729,12 @@ pub fn wildcard_match_detailed(
|
|||
return WildcardMatchResult::Fail(output_lines.join("\n"));
|
||||
}
|
||||
None => {
|
||||
let was_wildcard_or_line = was_last_wildcard || was_last_wildline;
|
||||
let mut max_found_index = 0;
|
||||
for (index, _) in search_text.char_indices() {
|
||||
let sub_string = &search_text[..index];
|
||||
if let Some(found_index) = current_text.find(sub_string) {
|
||||
if was_last_wildcard || found_index == 0 {
|
||||
if was_wildcard_or_line || found_index == 0 {
|
||||
max_found_index = index;
|
||||
} else {
|
||||
break;
|
||||
|
@ -720,7 +743,7 @@ pub fn wildcard_match_detailed(
|
|||
break;
|
||||
}
|
||||
}
|
||||
if !was_last_wildcard && max_found_index > 0 {
|
||||
if !was_wildcard_or_line && max_found_index > 0 {
|
||||
output_lines.push(format!(
|
||||
"<FOUND>{}</FOUND>",
|
||||
colors::gray(annotate_whitespace(
|
||||
|
@ -731,13 +754,13 @@ pub fn wildcard_match_detailed(
|
|||
output_lines
|
||||
.push("==== COULD NOT FIND SEARCH TEXT ====".to_string());
|
||||
output_lines.push(colors::green(annotate_whitespace(
|
||||
if was_last_wildcard {
|
||||
if was_wildcard_or_line {
|
||||
search_text
|
||||
} else {
|
||||
&search_text[max_found_index..]
|
||||
},
|
||||
)));
|
||||
if was_last_wildcard && max_found_index > 0 {
|
||||
if was_wildcard_or_line && max_found_index > 0 {
|
||||
output_lines.push(format!(
|
||||
"==== MAX FOUND ====\n{}",
|
||||
colors::red(annotate_whitespace(
|
||||
|
@ -766,6 +789,7 @@ pub fn wildcard_match_detailed(
|
|||
}
|
||||
WildcardPatternPart::UnorderedLines(expected_lines) => {
|
||||
assert!(!was_last_wildcard, "unsupported");
|
||||
assert!(!was_last_wildline, "unsupported");
|
||||
let mut actual_lines = Vec::with_capacity(expected_lines.len());
|
||||
for _ in 0..expected_lines.len() {
|
||||
match current_text.find('\n') {
|
||||
|
@ -823,9 +847,10 @@ pub fn wildcard_match_detailed(
|
|||
}
|
||||
}
|
||||
was_last_wildcard = matches!(part, WildcardPatternPart::Wildcard);
|
||||
was_last_wildline = matches!(part, WildcardPatternPart::Wildline);
|
||||
}
|
||||
|
||||
if was_last_wildcard || current_text.is_empty() {
|
||||
if was_last_wildcard || was_last_wildline || current_text.is_empty() {
|
||||
WildcardMatchResult::Success
|
||||
} else {
|
||||
output_lines.push("==== HAD TEXT AT END OF FILE ====".to_string());
|
||||
|
@ -837,6 +862,8 @@ pub fn wildcard_match_detailed(
|
|||
#[derive(Debug)]
|
||||
enum WildcardPatternPart<'a> {
|
||||
Wildcard,
|
||||
Wildline,
|
||||
Wildnum(usize),
|
||||
Text(&'a str),
|
||||
UnorderedLines(Vec<&'a str>),
|
||||
}
|
||||
|
@ -860,6 +887,8 @@ fn parse_wildcard_pattern_text(
|
|||
|
||||
enum InnerPart<'a> {
|
||||
Wildcard,
|
||||
Wildline,
|
||||
Wildnum(usize),
|
||||
UnorderedLines(Vec<&'a str>),
|
||||
Char,
|
||||
}
|
||||
|
@ -872,9 +901,29 @@ fn parse_wildcard_pattern_text(
|
|||
|
||||
impl<'a> Parser<'a> {
|
||||
fn parse(mut self) -> ParseResult<'a, Vec<WildcardPatternPart<'a>>> {
|
||||
fn parse_num(input: &str) -> ParseResult<usize> {
|
||||
let num_char_count =
|
||||
input.chars().take_while(|c| c.is_ascii_digit()).count();
|
||||
if num_char_count == 0 {
|
||||
return ParseError::backtrace();
|
||||
}
|
||||
let (char_text, input) = input.split_at(num_char_count);
|
||||
let value = str::parse::<usize>(char_text).unwrap();
|
||||
Ok((input, value))
|
||||
}
|
||||
|
||||
fn parse_wild_num(input: &str) -> ParseResult<usize> {
|
||||
let (input, _) = tag("[WILDCHARS(")(input)?;
|
||||
let (input, times) = parse_num(input)?;
|
||||
let (input, _) = tag(")]")(input)?;
|
||||
ParseResult::Ok((input, times))
|
||||
}
|
||||
|
||||
while !self.current_input.is_empty() {
|
||||
let (next_input, inner_part) = or3(
|
||||
let (next_input, inner_part) = or5(
|
||||
map(tag("[WILDCARD]"), |_| InnerPart::Wildcard),
|
||||
map(tag("[WILDLINE]"), |_| InnerPart::Wildline),
|
||||
map(parse_wild_num, InnerPart::Wildnum),
|
||||
map(parse_unordered_lines, |lines| {
|
||||
InnerPart::UnorderedLines(lines)
|
||||
}),
|
||||
|
@ -885,6 +934,14 @@ fn parse_wildcard_pattern_text(
|
|||
self.queue_previous_text(next_input);
|
||||
self.parts.push(WildcardPatternPart::Wildcard);
|
||||
}
|
||||
InnerPart::Wildline => {
|
||||
self.queue_previous_text(next_input);
|
||||
self.parts.push(WildcardPatternPart::Wildline);
|
||||
}
|
||||
InnerPart::Wildnum(times) => {
|
||||
self.queue_previous_text(next_input);
|
||||
self.parts.push(WildcardPatternPart::Wildnum(times));
|
||||
}
|
||||
InnerPart::UnorderedLines(expected_lines) => {
|
||||
self.queue_previous_text(next_input);
|
||||
self
|
||||
|
@ -923,6 +980,38 @@ fn parse_wildcard_pattern_text(
|
|||
})(text)
|
||||
}
|
||||
|
||||
fn find_first_text_on_line(
|
||||
search_text: &str,
|
||||
current_text: &str,
|
||||
) -> Option<usize> {
|
||||
let end_search_pos = current_text.find('\n').unwrap_or(current_text.len());
|
||||
let found_pos = current_text.find(search_text)?;
|
||||
if found_pos <= end_search_pos {
|
||||
Some(found_pos)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn find_last_text_on_line(
|
||||
search_text: &str,
|
||||
current_text: &str,
|
||||
) -> Option<usize> {
|
||||
let end_search_pos = current_text.find('\n').unwrap_or(current_text.len());
|
||||
let mut best_match = None;
|
||||
let mut search_pos = 0;
|
||||
while let Some(new_pos) = current_text[search_pos..].find(search_text) {
|
||||
search_pos += new_pos;
|
||||
if search_pos <= end_search_pos {
|
||||
best_match = Some(search_pos);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
search_pos += 1;
|
||||
}
|
||||
best_match
|
||||
}
|
||||
|
||||
pub fn with_pty(deno_args: &[&str], action: impl FnMut(Pty)) {
|
||||
let context = TestContextBuilder::default().use_temp_cwd().build();
|
||||
context.new_command().args_vec(deno_args).with_pty(action);
|
||||
|
@ -1318,6 +1407,19 @@ grault",
|
|||
multiline_pattern,
|
||||
&multi_line_builder("garply", None),
|
||||
));
|
||||
|
||||
// wildline
|
||||
assert!(wildcard_match("foo[WILDLINE]baz", "foobarbaz"));
|
||||
assert!(wildcard_match("foo[WILDLINE]bar", "foobarbar"));
|
||||
assert!(!wildcard_match("foo[WILDLINE]baz", "fooba\nrbaz"));
|
||||
assert!(wildcard_match("foo[WILDLINE]", "foobar"));
|
||||
|
||||
// wildnum
|
||||
assert!(wildcard_match("foo[WILDCHARS(3)]baz", "foobarbaz"));
|
||||
assert!(!wildcard_match("foo[WILDCHARS(4)]baz", "foobarbaz"));
|
||||
assert!(!wildcard_match("foo[WILDCHARS(2)]baz", "foobarbaz"));
|
||||
assert!(!wildcard_match("foo[WILDCHARS(1)]baz", "foobarbaz"));
|
||||
assert!(!wildcard_match("foo[WILDCHARS(20)]baz", "foobarbaz"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1352,4 +1454,26 @@ grault",
|
|||
|
||||
assert_eq!(size, Some(120380 * 1024));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_first_text_on_line() {
|
||||
let text = "foo\nbar\nbaz";
|
||||
assert_eq!(find_first_text_on_line("foo", text), Some(0));
|
||||
assert_eq!(find_first_text_on_line("oo", text), Some(1));
|
||||
assert_eq!(find_first_text_on_line("o", text), Some(1));
|
||||
assert_eq!(find_first_text_on_line("o\nbar", text), Some(2));
|
||||
assert_eq!(find_first_text_on_line("f", text), Some(0));
|
||||
assert_eq!(find_first_text_on_line("bar", text), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_last_text_on_line() {
|
||||
let text = "foo\nbar\nbaz";
|
||||
assert_eq!(find_last_text_on_line("foo", text), Some(0));
|
||||
assert_eq!(find_last_text_on_line("oo", text), Some(1));
|
||||
assert_eq!(find_last_text_on_line("o", text), Some(2));
|
||||
assert_eq!(find_last_text_on_line("o\nbar", text), Some(2));
|
||||
assert_eq!(find_last_text_on_line("f", text), Some(0));
|
||||
assert_eq!(find_last_text_on_line("bar", text), None);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6904,7 +6904,6 @@
|
|||
"the-iframe-element": {
|
||||
"cross-origin-to-whom-part-2.window.html": false,
|
||||
"cross-origin-to-whom.window.html": false,
|
||||
"sandbox-top-navigation-child-special-cases.tentative.sub.window.html": false,
|
||||
"sandbox-top-navigation-child.tentative.sub.window.html": false,
|
||||
"sandbox-top-navigation-escalate-privileges.tentative.sub.window.html": false,
|
||||
"sandbox-top-navigation-grandchild.tentative.sub.window.html": false
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
NOTE: This file should not be manually edited. Please edit `tests/node_compat/config.json` and run `deno task setup` in `tools/node_compat` dir instead.
|
||||
|
||||
Total: 2999
|
||||
Total: 2998
|
||||
|
||||
- [abort/test-abort-backtrace.js](https://github.com/nodejs/node/tree/v18.12.1/test/abort/test-abort-backtrace.js)
|
||||
- [abort/test-abort-fatal-error.js](https://github.com/nodejs/node/tree/v18.12.1/test/abort/test-abort-fatal-error.js)
|
||||
|
@ -1052,7 +1052,6 @@ Total: 2999
|
|||
- [parallel/test-http-header-overflow.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-header-overflow.js)
|
||||
- [parallel/test-http-header-owstext.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-header-owstext.js)
|
||||
- [parallel/test-http-header-read.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-header-read.js)
|
||||
- [parallel/test-http-header-validators.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-header-validators.js)
|
||||
- [parallel/test-http-hex-write.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-hex-write.js)
|
||||
- [parallel/test-http-highwatermark.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-highwatermark.js)
|
||||
- [parallel/test-http-host-header-ipv6-fail.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-host-header-ipv6-fail.js)
|
||||
|
@ -2711,7 +2710,6 @@ Total: 2999
|
|||
- [parallel/test-worker-message-port-message-port-transferring.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-message-port-transferring.js)
|
||||
- [parallel/test-worker-message-port-move.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-move.js)
|
||||
- [parallel/test-worker-message-port-multiple-sharedarraybuffers.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-multiple-sharedarraybuffers.js)
|
||||
- [parallel/test-worker-message-port-receive-message.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-receive-message.js)
|
||||
- [parallel/test-worker-message-port-terminate-transfer-list.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-terminate-transfer-list.js)
|
||||
- [parallel/test-worker-message-port-transfer-closed.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-transfer-closed.js)
|
||||
- [parallel/test-worker-message-port-transfer-duplicate.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-worker-message-port-transfer-duplicate.js)
|
||||
|
|
Loading…
Add table
Reference in a new issue