From e8ff3df57c5d99be10aa2fe601c348b9123ae02e Mon Sep 17 00:00:00 2001 From: Nyannyacha Date: Tue, 25 Feb 2025 22:59:39 +0000 Subject: [PATCH 1/5] chore: add/update integration tests for import_map feature --- .../bar/index.ts | 0 .../test_cases/with-import-map-2/deno.jsonc | 5 ++++ .../import_map.json | 0 .../index.ts | 0 .../test_cases/with-import-map/bar/index.ts | 3 +++ .../deno.jsonc | 0 .../base/test_cases/with-import-map/index.ts | 10 ++++++++ crates/base/tests/integration_tests.rs | 23 ++++++++++++++++++- examples/serve/data.json | 3 +++ 9 files changed, 43 insertions(+), 1 deletion(-) rename crates/base/test_cases/{with_import_map => with-import-map-2}/bar/index.ts (100%) create mode 100644 crates/base/test_cases/with-import-map-2/deno.jsonc rename crates/base/test_cases/{with_import_map => with-import-map-2}/import_map.json (100%) rename crates/base/test_cases/{with_import_map => with-import-map-2}/index.ts (100%) create mode 100644 crates/base/test_cases/with-import-map/bar/index.ts rename crates/base/test_cases/{with_import_map => with-import-map}/deno.jsonc (100%) create mode 100644 crates/base/test_cases/with-import-map/index.ts create mode 100644 examples/serve/data.json diff --git a/crates/base/test_cases/with_import_map/bar/index.ts b/crates/base/test_cases/with-import-map-2/bar/index.ts similarity index 100% rename from crates/base/test_cases/with_import_map/bar/index.ts rename to crates/base/test_cases/with-import-map-2/bar/index.ts diff --git a/crates/base/test_cases/with-import-map-2/deno.jsonc b/crates/base/test_cases/with-import-map-2/deno.jsonc new file mode 100644 index 000000000..3ff20c331 --- /dev/null +++ b/crates/base/test_cases/with-import-map-2/deno.jsonc @@ -0,0 +1,5 @@ +{ + // https://github.com/denoland/deno/issues/25226#issuecomment-2311454504 + "workspace": [], + "importMap": "./import_map.json" +} diff --git a/crates/base/test_cases/with_import_map/import_map.json b/crates/base/test_cases/with-import-map-2/import_map.json similarity index 100% rename from crates/base/test_cases/with_import_map/import_map.json rename to crates/base/test_cases/with-import-map-2/import_map.json diff --git a/crates/base/test_cases/with_import_map/index.ts b/crates/base/test_cases/with-import-map-2/index.ts similarity index 100% rename from crates/base/test_cases/with_import_map/index.ts rename to crates/base/test_cases/with-import-map-2/index.ts diff --git a/crates/base/test_cases/with-import-map/bar/index.ts b/crates/base/test_cases/with-import-map/bar/index.ts new file mode 100644 index 000000000..0fe8ad854 --- /dev/null +++ b/crates/base/test_cases/with-import-map/bar/index.ts @@ -0,0 +1,3 @@ +const bar = "bar"; + +export default bar; diff --git a/crates/base/test_cases/with_import_map/deno.jsonc b/crates/base/test_cases/with-import-map/deno.jsonc similarity index 100% rename from crates/base/test_cases/with_import_map/deno.jsonc rename to crates/base/test_cases/with-import-map/deno.jsonc diff --git a/crates/base/test_cases/with-import-map/index.ts b/crates/base/test_cases/with-import-map/index.ts new file mode 100644 index 000000000..92352e9b4 --- /dev/null +++ b/crates/base/test_cases/with-import-map/index.ts @@ -0,0 +1,10 @@ +import foo from "foo/index.ts"; + +console.log(foo); + +Deno.serve(() => { + return new Response( + JSON.stringify({ message: "ok" }), + { headers: { "Content-Type": "application/json" } }, + ); +}); diff --git a/crates/base/tests/integration_tests.rs b/crates/base/tests/integration_tests.rs index ba8b3e16e..897549ebc 100644 --- a/crates/base/tests/integration_tests.rs +++ b/crates/base/tests/integration_tests.rs @@ -122,11 +122,32 @@ async fn test_custom_readable_stream_response() { ); } +#[tokio::test] +#[serial] +async fn test_import_map_inlined() { + integration_test!( + "./test_cases/with-import-map", + NON_SECURE_PORT, + "", + None, + None, + None, + (|resp| async { + let res = resp.unwrap(); + assert!(res.status().as_u16() == 200); + + let body_bytes = res.bytes().await.unwrap(); + assert_eq!(body_bytes, r#"{"message":"ok"}"#); + }), + TerminationToken::new() + ); +} + #[tokio::test] #[serial] async fn test_import_map_file_path() { integration_test!( - "./test_cases/with_import_map", + "./test_cases/with-import-map-2", NON_SECURE_PORT, "", None, diff --git a/examples/serve/data.json b/examples/serve/data.json new file mode 100644 index 000000000..aff884449 --- /dev/null +++ b/examples/serve/data.json @@ -0,0 +1,3 @@ +{ + "meow": 1 +} From 696db51fd8613c11e60b411dcf182aaf621b753f Mon Sep 17 00:00:00 2001 From: Nyannyacha Date: Wed, 26 Feb 2025 04:19:46 +0000 Subject: [PATCH 2/5] fix: check main field in package.json as well if byonm is enabled --- crates/base/src/runtime/mod.rs | 18 ++++++++++++++++-- crates/deno_facade/eszip/mod.rs | 31 ++++++++++++++++++++++++------- crates/deno_facade/graph.rs | 1 + 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/crates/base/src/runtime/mod.rs b/crates/base/src/runtime/mod.rs index 7534e4c4f..6f75ab1ed 100644 --- a/crates/base/src/runtime/mod.rs +++ b/crates/base/src/runtime/mod.rs @@ -35,6 +35,7 @@ use deno::deno_http; use deno::deno_http::DefaultHttpPropertyExtractor; use deno::deno_io; use deno::deno_net; +use deno::deno_package_json; use deno::deno_telemetry; use deno::deno_tls; use deno::deno_tls::deno_native_certs::load_native_certs; @@ -528,7 +529,7 @@ where } } if !is_some_entry_point && !found { - bail!("could not find an appropriate entrypoint"); + main_module_url = Some(base_dir_url.clone()); } } if is_some_entry_point { @@ -561,11 +562,24 @@ where let mut builder = DenoOptionsBuilder::new(); - if let Some(module_url) = main_module_url { + if let Some(module_url) = main_module_url.as_ref() { builder.set_entrypoint(Some(module_url.to_file_path().unwrap())); } emitter_factory.set_deno_options(builder.build()?); + let deno_options = emitter_factory.deno_options()?; + if !is_some_entry_point + && main_module_url.is_some_and(|it| it == base_dir_url) + { + if deno_options + .workspace() + .root_pkg_json() + .and_then(|it| it.main(deno_package_json::NodeModuleKind::Cjs)) + .is_none() + { + bail!("could not find an appropriate entrypoint"); + } + } let mut metadata = Metadata::default(); let eszip = generate_binary_eszip( &mut metadata, diff --git a/crates/deno_facade/eszip/mod.rs b/crates/deno_facade/eszip/mod.rs index 6e8745a58..cc4a2d4c3 100644 --- a/crates/deno_facade/eszip/mod.rs +++ b/crates/deno_facade/eszip/mod.rs @@ -14,6 +14,7 @@ use deno::deno_fs::FileSystem; use deno::deno_fs::RealFs; use deno::deno_graph; use deno::deno_npm::NpmSystemInfo; +use deno::deno_package_json; use deno::deno_path_util; use deno::deno_path_util::normalize_path; use deno::npm::InnerCliNpmResolverRef; @@ -701,13 +702,29 @@ pub async fn generate_binary_eszip( ) -> Result { let deno_options = emitter_factory.deno_options()?.clone(); let args = if let Some(path) = deno_options.entrypoint() { - CreateGraphArgs::File(if !path.is_absolute() { - let initial_cwd = - std::env::current_dir().with_context(|| "failed getting cwd")?; - normalize_path(initial_cwd.join(path)) + if path.is_file() { + Some(CreateGraphArgs::File(if !path.is_absolute() { + let initial_cwd = + std::env::current_dir().with_context(|| "failed getting cwd")?; + normalize_path(initial_cwd.join(path)) + } else { + path.to_path_buf() + })) + } else if path.is_dir() { + deno_options + .use_byonm() + .then(|| { + let workspace = deno_options.workspace(); + workspace + .root_pkg_json() + .and_then(|it| it.main(deno_package_json::NodeModuleKind::Cjs)) + .map(|it| CreateGraphArgs::File(workspace.root_dir_path().join(it))) + }) + .flatten() } else { - path.to_path_buf() - }) + None + } + .context("failed to determine entrypoint")? } else { let Some(module_code) = maybe_module_code.as_ref() else { bail!("entrypoint or module code must be specified"); @@ -1005,7 +1022,7 @@ async fn include_glob_patterns_in_eszip( .map_err(|_| anyhow!("failed to convert to file path from url"))?; let relative_path = relative_file_base.specifier_key(&path_url); - if path.exists() { + if path.exists() && path.is_file() { let specifier = format!("static:{}", relative_path); eszip.add_opaque_data( diff --git a/crates/deno_facade/graph.rs b/crates/deno_facade/graph.rs index e9c20df9b..2f6766045 100644 --- a/crates/deno_facade/graph.rs +++ b/crates/deno_facade/graph.rs @@ -44,6 +44,7 @@ pub async fn create_eszip_from_graph_raw( npm_packages: None, }) } + pub enum CreateGraphArgs<'a> { File(PathBuf), Code { path: PathBuf, code: &'a FastString }, From 55973acbc91cc0de69531e9b31274eb449ed0553 Mon Sep 17 00:00:00 2001 From: Nyannyacha Date: Wed, 26 Feb 2025 04:20:04 +0000 Subject: [PATCH 3/5] chore: add integration tests for commonjs --- crates/base/src/utils/test_utils.rs | 52 +++- .../test_cases/commonjs-custom-main/meow.js | 13 + .../commonjs-custom-main/package.json | 5 + .../commonjs-express-websocket/index.js | 15 ++ .../commonjs-express-websocket/package.json | 12 + .../base/test_cases/commonjs-express/index.js | 13 + .../test_cases/commonjs-express/package.json | 8 + .../commonjs-hono-websocket/index.js | 29 +++ .../commonjs-hono-websocket/package.json | 9 + crates/base/test_cases/commonjs-hono/index.js | 14 + .../test_cases/commonjs-hono/package.json | 8 + .../commonjs-no-type-field/index.js | 13 + .../commonjs-no-type-field/package.json | 4 + .../test_cases/commonjs-ws-websocket/index.js | 10 + .../commonjs-ws-websocket/package.json | 7 + crates/base/test_cases/commonjs/index.js | 13 + crates/base/test_cases/commonjs/package.json | 4 + crates/base/tests/integration_tests.rs | 239 +++++++++++++++--- 18 files changed, 425 insertions(+), 43 deletions(-) create mode 100644 crates/base/test_cases/commonjs-custom-main/meow.js create mode 100644 crates/base/test_cases/commonjs-custom-main/package.json create mode 100644 crates/base/test_cases/commonjs-express-websocket/index.js create mode 100644 crates/base/test_cases/commonjs-express-websocket/package.json create mode 100644 crates/base/test_cases/commonjs-express/index.js create mode 100644 crates/base/test_cases/commonjs-express/package.json create mode 100644 crates/base/test_cases/commonjs-hono-websocket/index.js create mode 100644 crates/base/test_cases/commonjs-hono-websocket/package.json create mode 100644 crates/base/test_cases/commonjs-hono/index.js create mode 100644 crates/base/test_cases/commonjs-hono/package.json create mode 100644 crates/base/test_cases/commonjs-no-type-field/index.js create mode 100644 crates/base/test_cases/commonjs-no-type-field/package.json create mode 100644 crates/base/test_cases/commonjs-ws-websocket/index.js create mode 100644 crates/base/test_cases/commonjs-ws-websocket/package.json create mode 100644 crates/base/test_cases/commonjs/index.js create mode 100644 crates/base/test_cases/commonjs/package.json diff --git a/crates/base/src/utils/test_utils.rs b/crates/base/src/utils/test_utils.rs index d7682354c..e9f28c2c6 100644 --- a/crates/base/src/utils/test_utils.rs +++ b/crates/base/src/utils/test_utils.rs @@ -1,23 +1,24 @@ #![allow(dead_code)] use std::marker::PhantomPinned; +use std::path::Path; use std::path::PathBuf; use std::sync::Arc; use std::task::ready; use std::task::Poll; use std::time::Duration; -use crate::server::ServerFlags; -use crate::worker::pool::SupervisorPolicy; -use crate::worker::pool::WorkerPoolPolicy; -use crate::worker::TerminationToken; -use crate::worker::{self}; - use anyhow::bail; use anyhow::Context; use anyhow::Error; use either::Either::Right; use ext_event_worker::events::WorkerEventWithMetadata; +use ext_workers::context::MainWorkerRuntimeOpts; +use ext_workers::context::Timing; +use ext_workers::context::UserWorkerRuntimeOpts; +use ext_workers::context::WorkerContextInitOpts; +use ext_workers::context::WorkerRequestMsg; +use ext_workers::context::WorkerRuntimeOpts; use futures_util::future::BoxFuture; use futures_util::Future; use futures_util::FutureExt; @@ -25,20 +26,20 @@ use http_v02::Request; use http_v02::Response; use hyper_v014::Body; use pin_project::pin_project; - -use ext_workers::context::MainWorkerRuntimeOpts; -use ext_workers::context::Timing; -use ext_workers::context::UserWorkerRuntimeOpts; -use ext_workers::context::WorkerContextInitOpts; -use ext_workers::context::WorkerRequestMsg; -use ext_workers::context::WorkerRuntimeOpts; use scopeguard::ScopeGuard; +use tokio::process::Command; use tokio::sync::mpsc; use tokio::sync::oneshot; use tokio::sync::Notify; use tokio::time::timeout; use tokio_util::sync::CancellationToken; +use crate::server::ServerFlags; +use crate::worker; +use crate::worker::pool::SupervisorPolicy; +use crate::worker::pool::WorkerPoolPolicy; +use crate::worker::TerminationToken; + pub struct CreateTestUserWorkerArgs( WorkerContextInitOpts, Option, @@ -372,6 +373,31 @@ pub fn test_user_runtime_opts() -> UserWorkerRuntimeOpts { } } +pub async fn ensure_npm_package_installed

(path: P) +where + P: AsRef, +{ + let cwd = std::env::current_dir().unwrap(); + let path = cwd.join(path); + + assert!(path.is_dir()); + + let output = Command::new("npm") + .current_dir(path) + .arg("i") + .output() + .await + .unwrap(); + + if !output.status.success() { + let stdout = String::from_utf8_lossy(&output.stdout); + let stderr = String::from_utf8_lossy(&output.stderr); + panic!( + "failed to execute npm command\n\nSTDOUT: ${stdout}\n\nSTDERR: ${stderr}" + ); + } +} + async fn wait_termination(token: TerminationToken) { token.outbound.cancelled().await; } diff --git a/crates/base/test_cases/commonjs-custom-main/meow.js b/crates/base/test_cases/commonjs-custom-main/meow.js new file mode 100644 index 000000000..58e5fc4db --- /dev/null +++ b/crates/base/test_cases/commonjs-custom-main/meow.js @@ -0,0 +1,13 @@ +const http = require("http"); + +console.log(require); + +const server = http.createServer((_, resp) => { + resp.writeHead(200, { + "content-type": "text-plain", + }); + resp.write("meow"); + resp.end(); +}); + +server.listen(8080); diff --git a/crates/base/test_cases/commonjs-custom-main/package.json b/crates/base/test_cases/commonjs-custom-main/package.json new file mode 100644 index 000000000..77dc295f8 --- /dev/null +++ b/crates/base/test_cases/commonjs-custom-main/package.json @@ -0,0 +1,5 @@ +{ + "workspaces": [], + "type": "commonjs", + "main": "meow.js" +} diff --git a/crates/base/test_cases/commonjs-express-websocket/index.js b/crates/base/test_cases/commonjs-express-websocket/index.js new file mode 100644 index 000000000..b7a34a28e --- /dev/null +++ b/crates/base/test_cases/commonjs-express-websocket/index.js @@ -0,0 +1,15 @@ +const express = require("express"); +const app = express(); +const expressWs = require("express-ws")(app); +const port = 8080; + +expressWs.app.ws("/commonjs-express-websocket", (ws) => { + ws.send("meow"); + ws.on("message", (msg) => { + ws.send(msg); + }); +}); + +app.listen(port, () => { + console.log(`app listening on port ${port}`); +}); diff --git a/crates/base/test_cases/commonjs-express-websocket/package.json b/crates/base/test_cases/commonjs-express-websocket/package.json new file mode 100644 index 000000000..2d4ae3b71 --- /dev/null +++ b/crates/base/test_cases/commonjs-express-websocket/package.json @@ -0,0 +1,12 @@ +{ + "workspaces": [], + "type": "commonjs", + "main": "index.js", + "dependencies": { + "express": "^4.21.2", + "express-ws": "^5.0.2" + }, + "devDependencies": { + "@types/express-ws": "^3.0.5" + } +} diff --git a/crates/base/test_cases/commonjs-express/index.js b/crates/base/test_cases/commonjs-express/index.js new file mode 100644 index 000000000..0539e8537 --- /dev/null +++ b/crates/base/test_cases/commonjs-express/index.js @@ -0,0 +1,13 @@ +const express = require("express"); +const app = express(); +const port = 8080; + +console.log(require); + +app.get("/commonjs-express", (_, res) => { + res.send("meow"); +}); + +app.listen(port, () => { + console.log(`app listening on port ${port}`); +}); diff --git a/crates/base/test_cases/commonjs-express/package.json b/crates/base/test_cases/commonjs-express/package.json new file mode 100644 index 000000000..9dbdeaea7 --- /dev/null +++ b/crates/base/test_cases/commonjs-express/package.json @@ -0,0 +1,8 @@ +{ + "workspaces": [], + "type": "commonjs", + "main": "index.js", + "dependencies": { + "express": "^4.21.2" + } +} diff --git a/crates/base/test_cases/commonjs-hono-websocket/index.js b/crates/base/test_cases/commonjs-hono-websocket/index.js new file mode 100644 index 000000000..e66c315b7 --- /dev/null +++ b/crates/base/test_cases/commonjs-hono-websocket/index.js @@ -0,0 +1,29 @@ +const { serve } = require("@hono/node-server"); +const { Hono } = require("hono"); +const { createNodeWebSocket } = require("@hono/node-ws"); + +const app = new Hono(); +const { upgradeWebSocket, injectWebSocket } = createNodeWebSocket({ app }); +const port = 8080; + +app.get( + "/commonjs-hono-websocket", + upgradeWebSocket(() => { + return { + onOpen(_evt, ws) { + ws.send("meow"); + }, + onMessage(evt, ws) { + ws.send(evt.data); + }, + }; + }), +); + +const server = serve({ + fetch: app.fetch, + port, + overrideGlobalObjects: false, +}); + +injectWebSocket(server); diff --git a/crates/base/test_cases/commonjs-hono-websocket/package.json b/crates/base/test_cases/commonjs-hono-websocket/package.json new file mode 100644 index 000000000..e55869f02 --- /dev/null +++ b/crates/base/test_cases/commonjs-hono-websocket/package.json @@ -0,0 +1,9 @@ +{ + "workspaces": [], + "type": "commonjs", + "dependencies": { + "@hono/node-server": "^1.13.8", + "@hono/node-ws": "^1.1.0", + "hono": "^4.7.2" + } +} diff --git a/crates/base/test_cases/commonjs-hono/index.js b/crates/base/test_cases/commonjs-hono/index.js new file mode 100644 index 000000000..8977a6ade --- /dev/null +++ b/crates/base/test_cases/commonjs-hono/index.js @@ -0,0 +1,14 @@ +const { serve } = require("@hono/node-server"); +const { Hono } = require("hono"); +const app = new Hono(); +const port = 8080; + +app.get("/commonjs-hono", (c) => { + return c.text("meow"); +}); + +serve({ + fetch: app.fetch, + port, + overrideGlobalObjects: false, +}); diff --git a/crates/base/test_cases/commonjs-hono/package.json b/crates/base/test_cases/commonjs-hono/package.json new file mode 100644 index 000000000..f14fefb67 --- /dev/null +++ b/crates/base/test_cases/commonjs-hono/package.json @@ -0,0 +1,8 @@ +{ + "workspaces": [], + "type": "commonjs", + "dependencies": { + "@hono/node-server": "^1.13.8", + "hono": "^4.7.2" + } +} diff --git a/crates/base/test_cases/commonjs-no-type-field/index.js b/crates/base/test_cases/commonjs-no-type-field/index.js new file mode 100644 index 000000000..58e5fc4db --- /dev/null +++ b/crates/base/test_cases/commonjs-no-type-field/index.js @@ -0,0 +1,13 @@ +const http = require("http"); + +console.log(require); + +const server = http.createServer((_, resp) => { + resp.writeHead(200, { + "content-type": "text-plain", + }); + resp.write("meow"); + resp.end(); +}); + +server.listen(8080); diff --git a/crates/base/test_cases/commonjs-no-type-field/package.json b/crates/base/test_cases/commonjs-no-type-field/package.json new file mode 100644 index 000000000..340bb2682 --- /dev/null +++ b/crates/base/test_cases/commonjs-no-type-field/package.json @@ -0,0 +1,4 @@ +{ + "workspaces": [], + "main": "index.js" +} diff --git a/crates/base/test_cases/commonjs-ws-websocket/index.js b/crates/base/test_cases/commonjs-ws-websocket/index.js new file mode 100644 index 000000000..50eef8924 --- /dev/null +++ b/crates/base/test_cases/commonjs-ws-websocket/index.js @@ -0,0 +1,10 @@ +const { WebSocketServer } = require("ws"); +const wss = new WebSocketServer({ port: 8080 }); + +wss.on("connection", function connection(ws) { + ws.on("message", function message(data) { + ws.send(data); + }); + + ws.send("meow"); +}); diff --git a/crates/base/test_cases/commonjs-ws-websocket/package.json b/crates/base/test_cases/commonjs-ws-websocket/package.json new file mode 100644 index 000000000..46bc32bc9 --- /dev/null +++ b/crates/base/test_cases/commonjs-ws-websocket/package.json @@ -0,0 +1,7 @@ +{ + "workspaces": [], + "type": "commonjs", + "dependencies": { + "ws": "^8.18.1" + } +} diff --git a/crates/base/test_cases/commonjs/index.js b/crates/base/test_cases/commonjs/index.js new file mode 100644 index 000000000..58e5fc4db --- /dev/null +++ b/crates/base/test_cases/commonjs/index.js @@ -0,0 +1,13 @@ +const http = require("http"); + +console.log(require); + +const server = http.createServer((_, resp) => { + resp.writeHead(200, { + "content-type": "text-plain", + }); + resp.write("meow"); + resp.end(); +}); + +server.listen(8080); diff --git a/crates/base/test_cases/commonjs/package.json b/crates/base/test_cases/commonjs/package.json new file mode 100644 index 000000000..77b3fcd34 --- /dev/null +++ b/crates/base/test_cases/commonjs/package.json @@ -0,0 +1,4 @@ +{ + "workspaces": [], + "type": "commonjs" +} diff --git a/crates/base/tests/integration_tests.rs b/crates/base/tests/integration_tests.rs index 897549ebc..7d602ff91 100644 --- a/crates/base/tests/integration_tests.rs +++ b/crates/base/tests/integration_tests.rs @@ -26,6 +26,7 @@ use base::server::ServerFlags; use base::server::ServerHealth; use base::server::Tls; use base::utils::test_utils::create_test_user_worker; +use base::utils::test_utils::ensure_npm_package_installed; use base::utils::test_utils::test_user_runtime_opts; use base::utils::test_utils::test_user_worker_pool_policy; use base::utils::test_utils::TestBedBuilder; @@ -57,8 +58,8 @@ use http::Request; use http::Response as HttpResponse; use http::StatusCode; use http_utils::utils::get_upgrade_type; +use http_v02 as http; use http_v02::HeaderValue; -use http_v02::{self as http}; use hyper::body::to_bytes; use hyper::Body; use hyper_v014 as hyper; @@ -932,7 +933,7 @@ async fn test_worker_boot_with_invalid_entrypoint() { assert!(result.is_err()); assert!(format!("{:#}", result.unwrap_err()) - .starts_with("worker boot error: failed to read path")); + .starts_with("worker boot error: failed to determine entrypoint")); } #[tokio::test] @@ -995,9 +996,9 @@ async fn req_failure_case_cpu_time_exhausted() { let buf = to_bytes(res.body_mut()).await.unwrap(); assert_eq!( - buf, - "{\"msg\":\"WorkerRequestCancelled: request has been cancelled by supervisor\"}" - ); + buf, + "{\"msg\":\"WorkerRequestCancelled: request has been cancelled by supervisor\"}" + ); tb.exit(Duration::from_secs(TESTBED_DEADLINE_SEC)).await; } @@ -1023,9 +1024,9 @@ async fn req_failure_case_cpu_time_exhausted_2() { let buf = to_bytes(res.body_mut()).await.unwrap(); assert_eq!( - buf, - "{\"msg\":\"WorkerRequestCancelled: request has been cancelled by supervisor\"}" - ); + buf, + "{\"msg\":\"WorkerRequestCancelled: request has been cancelled by supervisor\"}" + ); tb.exit(Duration::from_secs(TESTBED_DEADLINE_SEC)).await; } @@ -1051,10 +1052,10 @@ async fn req_failure_case_wall_clock_reached() { let buf = to_bytes(res.body_mut()).await.unwrap(); assert!( - buf == "{\"msg\":\"InvalidWorkerResponse: user worker failed to respond\"}" - || buf - == "{\"msg\":\"WorkerRequestCancelled: request has been cancelled by supervisor\"}" - ); + buf == "{\"msg\":\"InvalidWorkerResponse: user worker failed to respond\"}" + || buf + == "{\"msg\":\"WorkerRequestCancelled: request has been cancelled by supervisor\"}" + ); tb.exit(Duration::from_secs(TESTBED_DEADLINE_SEC)).await; } @@ -1080,9 +1081,9 @@ async fn req_failture_case_memory_limit_1() { let buf = to_bytes(res.body_mut()).await.unwrap(); assert_eq!( - buf, - "{\"msg\":\"WorkerRequestCancelled: request has been cancelled by supervisor\"}" - ); + buf, + "{\"msg\":\"WorkerRequestCancelled: request has been cancelled by supervisor\"}" + ); tb.exit(Duration::from_secs(TESTBED_DEADLINE_SEC)).await; } @@ -1108,9 +1109,9 @@ async fn req_failture_case_memory_limit_2() { let buf = to_bytes(res.body_mut()).await.unwrap(); assert_eq!( - buf, - "{\"msg\":\"WorkerRequestCancelled: request has been cancelled by supervisor\"}" - ); + buf, + "{\"msg\":\"WorkerRequestCancelled: request has been cancelled by supervisor\"}" + ); tb.exit(Duration::from_secs(TESTBED_DEADLINE_SEC)).await; } @@ -1140,11 +1141,11 @@ async fn req_failure_case_wall_clock_reached_less_than_100ms() { let buf = to_bytes(res.body_mut()).await.unwrap(); assert!( - buf == "{\"msg\":\"InvalidWorkerResponse: user worker failed to respond\"}" - || buf == "{\"msg\":\"InvalidWorkerCreation: worker did not respond in time\"}" - || buf - == "{\"msg\":\"WorkerRequestCancelled: request has been cancelled by supervisor\"}" - ); + buf == "{\"msg\":\"InvalidWorkerResponse: user worker failed to respond\"}" + || buf == "{\"msg\":\"InvalidWorkerCreation: worker did not respond in time\"}" + || buf + == "{\"msg\":\"WorkerRequestCancelled: request has been cancelled by supervisor\"}" + ); tb.exit(Duration::from_secs(TESTBED_DEADLINE_SEC)).await; } @@ -2365,9 +2366,9 @@ async fn test_should_render_detailed_failed_to_create_graph_error() { assert_eq!(status, 500); assert!(payload.msg.starts_with( - "InvalidWorkerCreation: worker boot error: failed to create the graph: \ - Relative import path \"oak\" not prefixed with" - )); + "InvalidWorkerCreation: worker boot error: failed to create the graph: \ + Relative import path \"oak\" not prefixed with" + )); }), TerminationToken::new() ); @@ -2387,9 +2388,9 @@ async fn test_should_render_detailed_failed_to_create_graph_error() { assert_eq!(status, 500); assert!(payload.msg.starts_with( - "InvalidWorkerCreation: worker boot error: failed to create the graph: \ - Module not found \"file://" - )); + "InvalidWorkerCreation: worker boot error: failed to create the graph: \ + Module not found \"file://" + )); }), TerminationToken::new() ); @@ -2826,13 +2827,191 @@ async fn test_tmp_fs_should_not_be_available_in_import_stmt() { dbg!(&payload.msg); assert!(payload.msg.starts_with( "InvalidWorkerResponse: event loop error while evaluating the module: \ - TypeError: Module not found: file:///tmp/meowmeow.ts" + TypeError: Module not found: file:///tmp/meowmeow.ts" )); }), TerminationToken::new() ); } +#[tokio::test] +#[serial] +async fn test_commonjs() { + integration_test!( + "./test_cases/main", + NON_SECURE_PORT, + "commonjs", + None, + None, + None, + (|resp| async { + let resp = resp.unwrap(); + assert_eq!(resp.status().as_u16(), 200); + assert_eq!(resp.text().await.unwrap().as_str(), "meow"); + }), + TerminationToken::new() + ); +} + +#[tokio::test] +#[serial] +async fn test_commonjs_no_type_field_in_package_json() { + integration_test!( + "./test_cases/main", + NON_SECURE_PORT, + "commonjs-no-type-field", + None, + None, + None, + (|resp| async { + let resp = resp.unwrap(); + assert_eq!(resp.status().as_u16(), 500); + }), + TerminationToken::new() + ); +} + +#[tokio::test] +#[serial] +async fn test_commonjs_custom_main() { + integration_test!( + "./test_cases/main", + NON_SECURE_PORT, + "commonjs-custom-main", + None, + None, + None, + (|resp| async { + let resp = resp.unwrap(); + assert_eq!(resp.status().as_u16(), 200); + assert_eq!(resp.text().await.unwrap().as_str(), "meow"); + }), + TerminationToken::new() + ); +} + +#[tokio::test] +#[serial] +async fn test_commonjs_express() { + ensure_npm_package_installed("./test_cases/commonjs-express").await; + integration_test!( + "./test_cases/main", + NON_SECURE_PORT, + "commonjs-express", + None, + None, + None, + (|resp| async { + let resp = resp.unwrap(); + assert_eq!(resp.status().as_u16(), 200); + assert_eq!(resp.text().await.unwrap().as_str(), "meow"); + }), + TerminationToken::new() + ); +} + +#[tokio::test] +#[serial] +async fn test_commonjs_hono() { + ensure_npm_package_installed("./test_cases/commonjs-hono").await; + integration_test!( + "./test_cases/main", + NON_SECURE_PORT, + "commonjs-hono", + None, + None, + None, + (|resp| async { + let resp = resp.unwrap(); + assert_eq!(resp.status().as_u16(), 200); + assert_eq!(resp.text().await.unwrap().as_str(), "meow"); + }), + TerminationToken::new() + ); +} + +async fn test_commonjs_websocket(prefix: String) { + ensure_npm_package_installed(format!( + "./test_cases/commonjs-{}-websocket", + &prefix + )) + .await; + let nonce = tungstenite::handshake::client::generate_key(); + let client = Client::new(); + let req = client + .request( + Method::GET, + format!( + "http://localhost:{}/commonjs-{}-websocket", + NON_SECURE_PORT, prefix + ), + ) + .header(header::CONNECTION, "upgrade") + .header(header::UPGRADE, "websocket") + .header(header::SEC_WEBSOCKET_KEY, &nonce) + .header(header::SEC_WEBSOCKET_VERSION, "13") + .build() + .unwrap(); + + let original = RequestBuilder::from_parts(client, req); + let request_builder = Some(original); + + integration_test!( + "./test_cases/main", + NON_SECURE_PORT, + "", + None, + request_builder, + None, + (|resp| async { + let res = resp.unwrap(); + let accepted = get_upgrade_type(res.headers()); + + assert!(res.status().as_u16() == 101); + assert!(accepted.is_some()); + assert_eq!(accepted.as_ref().unwrap(), "websocket"); + + let upgraded = res.upgrade().await.unwrap(); + let mut ws = WebSocketStream::from_raw_socket( + upgraded.compat(), + tungstenite::protocol::Role::Client, + None, + ) + .await; + + assert_eq!( + ws.next().await.unwrap().unwrap().into_text().unwrap(), + "meow" + ); + + ws.send(Message::Text("meow!!".into())).await.unwrap(); + assert_eq!( + ws.next().await.unwrap().unwrap().into_text().unwrap(), + "meow!!" + ); + }), + TerminationToken::new() + ); +} + +#[tokio::test] +#[serial] +async fn test_commonjs_ws_websocket() { + test_commonjs_websocket(String::from("ws")).await; +} + +#[tokio::test] +#[serial] +async fn test_commonjs_hono_websocket() { + test_commonjs_websocket(String::from("hono")).await; +} + +#[tokio::test] +#[serial] +async fn test_commonjs_express_websocket() { + test_commonjs_websocket(String::from("express")).await; +} + #[tokio::test] #[serial] async fn test_supabase_ai_gte() { From 402685cc2293a63f2914b40edf3cf9a2902550e8 Mon Sep 17 00:00:00 2001 From: Nyannyacha Date: Wed, 26 Feb 2025 04:29:16 +0000 Subject: [PATCH 4/5] chore: add examples for commonjs --- examples/commonjs-hono-websocket/index.js | 29 +++++++++++++++++++ examples/commonjs-hono-websocket/package.json | 9 ++++++ examples/commonjs-hono/index.js | 14 +++++++++ examples/commonjs-hono/package.json | 8 +++++ 4 files changed, 60 insertions(+) create mode 100644 examples/commonjs-hono-websocket/index.js create mode 100644 examples/commonjs-hono-websocket/package.json create mode 100644 examples/commonjs-hono/index.js create mode 100644 examples/commonjs-hono/package.json diff --git a/examples/commonjs-hono-websocket/index.js b/examples/commonjs-hono-websocket/index.js new file mode 100644 index 000000000..e66c315b7 --- /dev/null +++ b/examples/commonjs-hono-websocket/index.js @@ -0,0 +1,29 @@ +const { serve } = require("@hono/node-server"); +const { Hono } = require("hono"); +const { createNodeWebSocket } = require("@hono/node-ws"); + +const app = new Hono(); +const { upgradeWebSocket, injectWebSocket } = createNodeWebSocket({ app }); +const port = 8080; + +app.get( + "/commonjs-hono-websocket", + upgradeWebSocket(() => { + return { + onOpen(_evt, ws) { + ws.send("meow"); + }, + onMessage(evt, ws) { + ws.send(evt.data); + }, + }; + }), +); + +const server = serve({ + fetch: app.fetch, + port, + overrideGlobalObjects: false, +}); + +injectWebSocket(server); diff --git a/examples/commonjs-hono-websocket/package.json b/examples/commonjs-hono-websocket/package.json new file mode 100644 index 000000000..e55869f02 --- /dev/null +++ b/examples/commonjs-hono-websocket/package.json @@ -0,0 +1,9 @@ +{ + "workspaces": [], + "type": "commonjs", + "dependencies": { + "@hono/node-server": "^1.13.8", + "@hono/node-ws": "^1.1.0", + "hono": "^4.7.2" + } +} diff --git a/examples/commonjs-hono/index.js b/examples/commonjs-hono/index.js new file mode 100644 index 000000000..f7cb0e122 --- /dev/null +++ b/examples/commonjs-hono/index.js @@ -0,0 +1,14 @@ +const { serve } = require("@hono/node-server"); +const { Hono } = require("hono"); +const app = new Hono(); +const port = 8080; + +app.get("/commonjs-hono", (c) => { + return c.text("Hello, World!"); +}); + +serve({ + fetch: app.fetch, + port, + overrideGlobalObjects: false, +}); diff --git a/examples/commonjs-hono/package.json b/examples/commonjs-hono/package.json new file mode 100644 index 000000000..f14fefb67 --- /dev/null +++ b/examples/commonjs-hono/package.json @@ -0,0 +1,8 @@ +{ + "workspaces": [], + "type": "commonjs", + "dependencies": { + "@hono/node-server": "^1.13.8", + "hono": "^4.7.2" + } +} From f825e46d360a12762cbc1ce5dd38b0aa68729e6c Mon Sep 17 00:00:00 2001 From: Nyannyacha Date: Wed, 26 Feb 2025 04:44:41 +0000 Subject: [PATCH 5/5] stamp: make clippy happy --- crates/base/src/runtime/mod.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/crates/base/src/runtime/mod.rs b/crates/base/src/runtime/mod.rs index 6f75ab1ed..a7d2f2838 100644 --- a/crates/base/src/runtime/mod.rs +++ b/crates/base/src/runtime/mod.rs @@ -570,15 +570,13 @@ where let deno_options = emitter_factory.deno_options()?; if !is_some_entry_point && main_module_url.is_some_and(|it| it == base_dir_url) - { - if deno_options + && deno_options .workspace() .root_pkg_json() .and_then(|it| it.main(deno_package_json::NodeModuleKind::Cjs)) .is_none() - { - bail!("could not find an appropriate entrypoint"); - } + { + bail!("could not find an appropriate entrypoint"); } let mut metadata = Metadata::default(); let eszip = generate_binary_eszip(