From 5bd54edf4751e6f16cd24062087dd29ae0384d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=83=A5=EB=83=90=EC=B1=A0?= Date: Mon, 7 Oct 2024 14:10:23 +0900 Subject: [PATCH] chore: make sure that we can use javascript as an entrypoint (#424) * chore: make sure that we can use js script as an entrypoint * chore: add js flavored examples * stamp: clippy --- .../eszip-js/npm-supabase-js/index.js | 2 + .../test_cases/eszip-js/serve-js/index.js | 4 + crates/base/test_cases/main_eszip/index.ts | 65 ++++++++++ .../serve-declarative-style-js/index.js | 10 ++ crates/base/test_cases/serve-js/index.js | 4 + crates/base/tests/integration_tests.rs | 116 +++++++++++++++++- examples/serve-declarative-style-js/index.js | 10 ++ examples/serve-js/index.js | 4 + 8 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 crates/base/test_cases/eszip-js/npm-supabase-js/index.js create mode 100644 crates/base/test_cases/eszip-js/serve-js/index.js create mode 100644 crates/base/test_cases/main_eszip/index.ts create mode 100644 crates/base/test_cases/serve-declarative-style-js/index.js create mode 100644 crates/base/test_cases/serve-js/index.js create mode 100644 examples/serve-declarative-style-js/index.js create mode 100644 examples/serve-js/index.js diff --git a/crates/base/test_cases/eszip-js/npm-supabase-js/index.js b/crates/base/test_cases/eszip-js/npm-supabase-js/index.js new file mode 100644 index 00000000..75a6e2fe --- /dev/null +++ b/crates/base/test_cases/eszip-js/npm-supabase-js/index.js @@ -0,0 +1,2 @@ +import { createClient } from "npm:@supabase/supabase-js@2.42.0"; +Deno.serve((_req) => new Response(`${typeof createClient}`)); diff --git a/crates/base/test_cases/eszip-js/serve-js/index.js b/crates/base/test_cases/eszip-js/serve-js/index.js new file mode 100644 index 00000000..484bbe3a --- /dev/null +++ b/crates/base/test_cases/eszip-js/serve-js/index.js @@ -0,0 +1,4 @@ +Deno.serve(req => { + console.log(req.headers.get("content-type")); + return new Response("meow"); +}); \ No newline at end of file diff --git a/crates/base/test_cases/main_eszip/index.ts b/crates/base/test_cases/main_eszip/index.ts new file mode 100644 index 00000000..49c70a82 --- /dev/null +++ b/crates/base/test_cases/main_eszip/index.ts @@ -0,0 +1,65 @@ +console.log('main function started'); + +Deno.serve(async (req: Request) => { + console.log(req.url); + const url = new URL(req.url); + const { pathname } = url; + const path_parts = pathname.split("/"); + const service_name = path_parts[1]; + const maybeEszip = new Uint8Array(await req.arrayBuffer()); + + if (!service_name || service_name === "") { + const error = { msg: "missing function name in request" } + return new Response( + JSON.stringify(error), + { status: 400, headers: { "Content-Type": "application/json" } }, + ) + } + + const servicePath = `./test_cases/${service_name}`; + console.error(`serving the request with ${servicePath}`); + + const createWorker = async () => { + const memoryLimitMb = 150; + const workerTimeoutMs = 10 * 60 * 1000; + const cpuTimeSoftLimitMs = 10 * 60 * 1000; + const cpuTimeHardLimitMs = 10 * 60 * 1000; + const noModuleCache = false; + const importMapPath = null; + const envVarsObj = Deno.env.toObject(); + const envVars = Object.keys(envVarsObj).map(k => [k, envVarsObj[k]]); + + return await EdgeRuntime.userWorkers.create({ + servicePath, + memoryLimitMb, + workerTimeoutMs, + cpuTimeSoftLimitMs, + cpuTimeHardLimitMs, + noModuleCache, + importMapPath, + envVars, + maybeEszip + }); + } + + const callWorker = async () => { + try { + const worker = await createWorker(); + return await worker.fetch(req); + } catch (e) { + console.error(e); + + // if (e instanceof Deno.errors.WorkerRequestCancelled) { + // return await callWorker(); + // } + + const error = { msg: e.toString() } + return new Response( + JSON.stringify(error), + { status: 500, headers: { "Content-Type": "application/json" } }, + ); + } + } + + return callWorker(); +}) diff --git a/crates/base/test_cases/serve-declarative-style-js/index.js b/crates/base/test_cases/serve-declarative-style-js/index.js new file mode 100644 index 00000000..e0b1f5d0 --- /dev/null +++ b/crates/base/test_cases/serve-declarative-style-js/index.js @@ -0,0 +1,10 @@ +export default { + /** + * @param {Request} req + * @returns {void} + */ + fetch(req) { + console.log(req.headers.get("content-type")); + return new Response("meow"); + } +} diff --git a/crates/base/test_cases/serve-js/index.js b/crates/base/test_cases/serve-js/index.js new file mode 100644 index 00000000..484bbe3a --- /dev/null +++ b/crates/base/test_cases/serve-js/index.js @@ -0,0 +1,4 @@ +Deno.serve(req => { + console.log(req.headers.get("content-type")); + return new Response("meow"); +}); \ No newline at end of file diff --git a/crates/base/tests/integration_tests.rs b/crates/base/tests/integration_tests.rs index e0632576..d28327bb 100644 --- a/crates/base/tests/integration_tests.rs +++ b/crates/base/tests/integration_tests.rs @@ -4,14 +4,14 @@ mod integration_test_helper; use http_v02 as http; use hyper_v014 as hyper; use reqwest_v011 as reqwest; -use sb_graph::EszipPayloadKind; +use sb_graph::{emitter::EmitterFactory, generate_binary_eszip, EszipPayloadKind}; use std::{ borrow::Cow, collections::HashMap, io::{self, Cursor}, net::{IpAddr, Ipv4Addr, SocketAddr}, - path::Path, + path::{Path, PathBuf}, sync::Arc, time::Duration, }; @@ -2388,6 +2388,118 @@ async fn test_should_render_detailed_failed_to_create_graph_error() { } } +#[tokio::test] +#[serial] +async fn test_js_entrypoint() { + { + integration_test!( + "./test_cases/main", + NON_SECURE_PORT, + "serve-js", + None, + None, + None, + None, + (|resp| async { + let resp = resp.unwrap(); + assert_eq!(resp.status().as_u16(), 200); + let msg = resp.text().await.unwrap(); + assert_eq!(msg, "meow"); + }), + TerminationToken::new() + ); + } + + { + integration_test!( + "./test_cases/main", + NON_SECURE_PORT, + "serve-declarative-style-js", + None, + None, + None, + None, + (|resp| async { + let resp = resp.unwrap(); + assert_eq!(resp.status().as_u16(), 200); + let msg = resp.text().await.unwrap(); + assert_eq!(msg, "meow"); + }), + TerminationToken::new() + ); + } + + let get_eszip_buf = |path: &'static str| async move { + generate_binary_eszip( + PathBuf::from(path), + #[allow(clippy::arc_with_non_send_sync)] + Arc::new(EmitterFactory::new()), + None, + None, + None, + ) + .await + .unwrap() + .into_bytes() + }; + + { + let buf = get_eszip_buf("./test_cases/eszip-js/serve-js/index.js").await; + let client = Client::new(); + let req = client + .request( + Method::POST, + format!("http://localhost:{}/meow", NON_SECURE_PORT), + ) + .body(buf); + + integration_test!( + "./test_cases/main_eszip", + NON_SECURE_PORT, + "", + None, + None, + Some(req), + None, + (|resp| async { + let resp = resp.unwrap(); + assert_eq!(resp.status().as_u16(), 200); + let msg = resp.text().await.unwrap(); + assert_eq!(msg, "meow"); + }), + TerminationToken::new() + ); + } + + { + let buf = get_eszip_buf("./test_cases/eszip-js/npm-supabase-js/index.js").await; + let client = Client::new(); + let req = client + .request( + Method::POST, + format!("http://localhost:{}/meow", NON_SECURE_PORT), + ) + .body(buf); + + integration_test!( + "./test_cases/main_eszip", + NON_SECURE_PORT, + "", + None, + None, + Some(req), + None, + (|resp| async { + let resp = resp.unwrap(); + assert_eq!(resp.status().as_u16(), 200); + let msg = resp.text().await.unwrap(); + assert_eq!(msg, "function"); + }), + TerminationToken::new() + ); + } +} + #[derive(Deserialize)] struct ErrorResponsePayload { msg: String, diff --git a/examples/serve-declarative-style-js/index.js b/examples/serve-declarative-style-js/index.js new file mode 100644 index 00000000..1e6518ba --- /dev/null +++ b/examples/serve-declarative-style-js/index.js @@ -0,0 +1,10 @@ +export default { + /** + * @param {Request} req + * @returns {void} + */ + fetch(req) { + console.log(req.headers.get("content-type")); + return new Response("Hello, world"); + } +} diff --git a/examples/serve-js/index.js b/examples/serve-js/index.js new file mode 100644 index 00000000..be192dac --- /dev/null +++ b/examples/serve-js/index.js @@ -0,0 +1,4 @@ +Deno.serve(req => { + console.log(req.headers.get("content-type")); + return new Response("Hello, world"); +}); \ No newline at end of file