From 35166883e8607e1f2af6b9fb6eb80a182d4e4fef Mon Sep 17 00:00:00 2001 From: HugoCasa Date: Fri, 15 Sep 2023 13:19:38 +0200 Subject: [PATCH] feat: bun absolute/relative imports + tests (#2286) * feat: bun relative imports + tests * fix: add missing .sqlx --- ...55ddd99c4ad1f46b876dd86e372b84d806ecd.json | 1 - ...17cbcf1013ae311c36b42d423bf6a02fa016c.json | 1 - ...04e797527841cd97dba80c271cbefafae65cc.json | 1 - ...ee85b191263989b0c78b2bfce77e796e96825.json | 1 - ...f6f580f15bca96d9746c9359e98ca793f8f1f.json | 1 - ...6e03e870ccc3b353401439bc0ed8ff219249b.json | 1 - ...5eedc09bceb82bca349f3e31c8513ebbf0192.json | 1 - ...32580dc7f7a9e5a67026f8c0b3077f371fc62.json | 22 ++ backend/tests/fixtures/base.sql | 53 ----- backend/tests/fixtures/relative_bun.sql | 44 ++++ backend/tests/fixtures/relative_deno.sql | 44 ++++ backend/tests/fixtures/relative_python.sql | 41 ++++ backend/tests/fixtures/schedule.sql | 52 +++++ backend/tests/worker.rs | 210 +++++++++++++++++- backend/windmill-worker/loader.bun.ts | 18 +- 15 files changed, 423 insertions(+), 68 deletions(-) create mode 100644 backend/.sqlx/query-ef6795d93423f98eea82eb18e6332580dc7f7a9e5a67026f8c0b3077f371fc62.json create mode 100644 backend/tests/fixtures/relative_bun.sql create mode 100644 backend/tests/fixtures/relative_deno.sql create mode 100644 backend/tests/fixtures/relative_python.sql create mode 100644 backend/tests/fixtures/schedule.sql diff --git a/backend/.sqlx/query-123c0608e229c29187009b7961355ddd99c4ad1f46b876dd86e372b84d806ecd.json b/backend/.sqlx/query-123c0608e229c29187009b7961355ddd99c4ad1f46b876dd86e372b84d806ecd.json index 1b8084742c..7718e05ccf 100644 --- a/backend/.sqlx/query-123c0608e229c29187009b7961355ddd99c4ad1f46b876dd86e372b84d806ecd.json +++ b/backend/.sqlx/query-123c0608e229c29187009b7961355ddd99c4ad1f46b876dd86e372b84d806ecd.json @@ -37,7 +37,6 @@ "bash", "postgresql", "nativets", - "Nativets", "bun", "mysql", "bigquery", diff --git a/backend/.sqlx/query-25bef6a248f3ee0ea2cbcc376c217cbcf1013ae311c36b42d423bf6a02fa016c.json b/backend/.sqlx/query-25bef6a248f3ee0ea2cbcc376c217cbcf1013ae311c36b42d423bf6a02fa016c.json index bf591ef11c..9d082a6772 100644 --- a/backend/.sqlx/query-25bef6a248f3ee0ea2cbcc376c217cbcf1013ae311c36b42d423bf6a02fa016c.json +++ b/backend/.sqlx/query-25bef6a248f3ee0ea2cbcc376c217cbcf1013ae311c36b42d423bf6a02fa016c.json @@ -67,7 +67,6 @@ "bash", "postgresql", "nativets", - "Nativets", "bun", "mysql", "bigquery", diff --git a/backend/.sqlx/query-438b5b5d29b05846c2e074cad2404e797527841cd97dba80c271cbefafae65cc.json b/backend/.sqlx/query-438b5b5d29b05846c2e074cad2404e797527841cd97dba80c271cbefafae65cc.json index a5dee163e5..1166260449 100644 --- a/backend/.sqlx/query-438b5b5d29b05846c2e074cad2404e797527841cd97dba80c271cbefafae65cc.json +++ b/backend/.sqlx/query-438b5b5d29b05846c2e074cad2404e797527841cd97dba80c271cbefafae65cc.json @@ -28,7 +28,6 @@ "bash", "postgresql", "nativets", - "Nativets", "bun", "mysql", "bigquery", diff --git a/backend/.sqlx/query-5cd89ab614d3cac80fb81627267ee85b191263989b0c78b2bfce77e796e96825.json b/backend/.sqlx/query-5cd89ab614d3cac80fb81627267ee85b191263989b0c78b2bfce77e796e96825.json index 1517c8d1d4..eabf671894 100644 --- a/backend/.sqlx/query-5cd89ab614d3cac80fb81627267ee85b191263989b0c78b2bfce77e796e96825.json +++ b/backend/.sqlx/query-5cd89ab614d3cac80fb81627267ee85b191263989b0c78b2bfce77e796e96825.json @@ -42,7 +42,6 @@ "bash", "postgresql", "nativets", - "Nativets", "bun", "mysql", "bigquery", diff --git a/backend/.sqlx/query-65835f2e5ad38f7cc6b147dadfef6f580f15bca96d9746c9359e98ca793f8f1f.json b/backend/.sqlx/query-65835f2e5ad38f7cc6b147dadfef6f580f15bca96d9746c9359e98ca793f8f1f.json index bfe7c41f64..c52efca4c0 100644 --- a/backend/.sqlx/query-65835f2e5ad38f7cc6b147dadfef6f580f15bca96d9746c9359e98ca793f8f1f.json +++ b/backend/.sqlx/query-65835f2e5ad38f7cc6b147dadfef6f580f15bca96d9746c9359e98ca793f8f1f.json @@ -42,7 +42,6 @@ "bash", "postgresql", "nativets", - "Nativets", "bun", "mysql", "bigquery", diff --git a/backend/.sqlx/query-9e8c3ff3d6b31e366e15beda1e96e03e870ccc3b353401439bc0ed8ff219249b.json b/backend/.sqlx/query-9e8c3ff3d6b31e366e15beda1e96e03e870ccc3b353401439bc0ed8ff219249b.json index 6308bf3bb2..fead4ba250 100644 --- a/backend/.sqlx/query-9e8c3ff3d6b31e366e15beda1e96e03e870ccc3b353401439bc0ed8ff219249b.json +++ b/backend/.sqlx/query-9e8c3ff3d6b31e366e15beda1e96e03e870ccc3b353401439bc0ed8ff219249b.json @@ -60,7 +60,6 @@ "bash", "postgresql", "nativets", - "Nativets", "bun", "mysql", "bigquery", diff --git a/backend/.sqlx/query-b224cdd1221fc9e7227ef8e8c025eedc09bceb82bca349f3e31c8513ebbf0192.json b/backend/.sqlx/query-b224cdd1221fc9e7227ef8e8c025eedc09bceb82bca349f3e31c8513ebbf0192.json index 38f81da395..c90719118a 100644 --- a/backend/.sqlx/query-b224cdd1221fc9e7227ef8e8c025eedc09bceb82bca349f3e31c8513ebbf0192.json +++ b/backend/.sqlx/query-b224cdd1221fc9e7227ef8e8c025eedc09bceb82bca349f3e31c8513ebbf0192.json @@ -42,7 +42,6 @@ "bash", "postgresql", "nativets", - "Nativets", "bun", "mysql", "bigquery", diff --git a/backend/.sqlx/query-ef6795d93423f98eea82eb18e6332580dc7f7a9e5a67026f8c0b3077f371fc62.json b/backend/.sqlx/query-ef6795d93423f98eea82eb18e6332580dc7f7a9e5a67026f8c0b3077f371fc62.json new file mode 100644 index 0000000000..08c5851944 --- /dev/null +++ b/backend/.sqlx/query-ef6795d93423f98eea82eb18e6332580dc7f7a9e5a67026f8c0b3077f371fc62.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT hash FROM script WHERE path = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "hash", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + false + ] + }, + "hash": "ef6795d93423f98eea82eb18e6332580dc7f7a9e5a67026f8c0b3077f371fc62" +} diff --git a/backend/tests/fixtures/base.sql b/backend/tests/fixtures/base.sql index 16c0d7bb72..f406e603d4 100644 --- a/backend/tests/fixtures/base.sql +++ b/backend/tests/fixtures/base.sql @@ -17,59 +17,6 @@ INSERT INTO workspace_settings (workspace_id) VALUES insert INTO token(token, email, label, super_admin) VALUES ('SECRET_TOKEN', 'test@windmill.dev', 'test token', true); -INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock) VALUES ( -'test-workspace', -'system', -' -export async function main(fail: boolean = true) { - if (fail) { - throw new Error("Failed") - } - - return "OK" -} -', -'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"fail":{"default":true,"description":"","type":"boolean"}},"required":[],"type":"object"}', -'', -'', -'f/system/failing_script', -28028598712388162, 'deno', ''); - -INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock) VALUES ( -'test-workspace', -'system', -' -export async function main() { - return "Error handler"; -} -', -'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"path":{"default":null,"description":"","type":"string"},"schedule_path":{"default":null,"description":"","type":"string"},"error":{"default":null,"description":"","properties":{},"type":"object"}},"required":["path","schedule_path","error"],"type":"object"}', -'', -'', -'f/system/schedule_error_handler', -28028598712388161, 'deno', ''); - -INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock) VALUES ( -'test-workspace', -'system', -' -export async function main() { - return "Recovery handler"; -} -', -'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"path":{"default":null,"description":"","type":"string"},"schedule_path":{"default":null,"description":"","type":"string"},"previous_job_error":{"default":null,"description":"","type":"string"},"result":{"default":null,"description":"","type":"string"}},"required":["path","schedule_path","previous_job_error","result"],"type":"object"}', -'', -'', -'f/system/schedule_recovery_handler', -28028598712388160, 'deno', ''); - -INSERT INTO public.flow(workspace_id, edited_by, value, schema, summary, description, path) VALUES ( -'test-workspace', -'system', -'{"modules": [{"id": "a", "value": {"path": "f/system/failing_script", "type": "script", "input_transforms": {"fail": {"expr": "flow_input.fail", "type": "javascript"}}}}]}', -'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"fail":{"default":true,"description":"","type":"boolean","format":""}},"required":[],"type":"object"}', -'', -'', -'f/system/failing_flow' -); - GRANT ALL PRIVILEGES ON TABLE workspace_key TO windmill_admin; GRANT ALL PRIVILEGES ON TABLE workspace_key TO windmill_user; diff --git a/backend/tests/fixtures/relative_bun.sql b/backend/tests/fixtures/relative_bun.sql new file mode 100644 index 0000000000..fdc2676661 --- /dev/null +++ b/backend/tests/fixtures/relative_bun.sql @@ -0,0 +1,44 @@ +INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock) VALUES ( +'test-workspace', +'test-user', +' +export function main() { + return "f/system/same_folder_script"; +} +', +'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}', +'', +'', +'f/system/same_folder_script', -28028598712388162, 'bun', ''); + +INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock) VALUES ( +'test-workspace', +'test-user', +' +export function main() { + return "f/system_relative/different_folder_script"; +} +', +'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}', +'', +'', +'f/system_relative/different_folder_script', -28028598712388161, 'bun', ''); + + +INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock) VALUES ( +'test-workspace', +'test-user', +' +import { main as test1 } from "/f/system/same_folder_script.ts"; +import { main as test2 } from "../system/same_folder_script.ts"; +import { main as test3 } from "/f/system_relative/different_folder_script.ts"; +import { main as test4 } from "./different_folder_script.ts"; + +export function main() { + return [test1(), test2(), test3(), test4()]; +} +', +'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}', +'', +'', +'f/system_relative/nested_script', -28028598712388160, 'bun', ''); \ No newline at end of file diff --git a/backend/tests/fixtures/relative_deno.sql b/backend/tests/fixtures/relative_deno.sql new file mode 100644 index 0000000000..4dff715110 --- /dev/null +++ b/backend/tests/fixtures/relative_deno.sql @@ -0,0 +1,44 @@ +INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock) VALUES ( +'test-workspace', +'test-user', +' +export function main() { + return "f/system/same_folder_script"; +} +', +'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}', +'', +'', +'f/system/same_folder_script', -28028598712388162, 'deno', ''); + +INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock) VALUES ( +'test-workspace', +'test-user', +' +export function main() { + return "f/system_relative/different_folder_script"; +} +', +'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}', +'', +'', +'f/system_relative/different_folder_script', -28028598712388161, 'deno', ''); + + +INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock) VALUES ( +'test-workspace', +'test-user', +' +import { main as test1 } from "/f/system/same_folder_script.ts"; +import { main as test2 } from "../system/same_folder_script.ts"; +import { main as test3 } from "/f/system_relative/different_folder_script.ts"; +import { main as test4 } from "./different_folder_script.ts"; + +export function main() { + return [test1(), test2(), test3(), test4()]; +} +', +'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}', +'', +'', +'f/system_relative/nested_script', -28028598712388160, 'deno', ''); \ No newline at end of file diff --git a/backend/tests/fixtures/relative_python.sql b/backend/tests/fixtures/relative_python.sql new file mode 100644 index 0000000000..ea8e5798a1 --- /dev/null +++ b/backend/tests/fixtures/relative_python.sql @@ -0,0 +1,41 @@ +INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock) VALUES ( +'test-workspace', +'test-user', +' +def main(): + return "f/system/same_folder_script" +', +'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}', +'', +'', +'f/system/same_folder_script', -28028598712388162, 'python3', ''); + +INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock) VALUES ( +'test-workspace', +'test-user', +' +def main(): + return "f/system_relative/different_folder_script" +', +'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}', +'', +'', +'f/system_relative/different_folder_script', -28028598712388161, 'python3', ''); + + +INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock) VALUES ( +'test-workspace', +'test-user', +' +from f.system.same_folder_script import main as test1 +from ..system.same_folder_script import main as test2 +from f.system_relative.different_folder_script import main as test3 +from .different_folder_script import main as test4 + +def main(): + return [test1(), test2(), test3(), test4()] +', +'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{},"required":[],"type":"object"}', +'', +'', +'f/system_relative/nested_script', -28028598712388160, 'python3', ''); \ No newline at end of file diff --git a/backend/tests/fixtures/schedule.sql b/backend/tests/fixtures/schedule.sql new file mode 100644 index 0000000000..4df1690aa3 --- /dev/null +++ b/backend/tests/fixtures/schedule.sql @@ -0,0 +1,52 @@ +INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock) VALUES ( +'test-workspace', +'system', +' +export async function main(fail: boolean = true) { + if (fail) { + throw new Error("Failed") + } + + return "OK" +} +', +'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"fail":{"default":true,"description":"","type":"boolean"}},"required":[],"type":"object"}', +'', +'', +'f/system/failing_script', -28028598712388162, 'deno', ''); + +INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock) VALUES ( +'test-workspace', +'system', +' +export async function main() { + return "Error handler"; +} +', +'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"path":{"default":null,"description":"","type":"string"},"schedule_path":{"default":null,"description":"","type":"string"},"error":{"default":null,"description":"","properties":{},"type":"object"}},"required":["path","schedule_path","error"],"type":"object"}', +'', +'', +'f/system/schedule_error_handler', -28028598712388161, 'deno', ''); + +INSERT INTO public.script(workspace_id, created_by, content, schema, summary, description, path, hash, language, lock) VALUES ( +'test-workspace', +'system', +' +export async function main() { + return "Recovery handler"; +} +', +'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"path":{"default":null,"description":"","type":"string"},"schedule_path":{"default":null,"description":"","type":"string"},"previous_job_error":{"default":null,"description":"","type":"string"},"result":{"default":null,"description":"","type":"string"}},"required":["path","schedule_path","previous_job_error","result"],"type":"object"}', +'', +'', +'f/system/schedule_recovery_handler', -28028598712388160, 'deno', ''); + +INSERT INTO public.flow(workspace_id, edited_by, value, schema, summary, description, path) VALUES ( +'test-workspace', +'system', +'{"modules": [{"id": "a", "value": {"path": "f/system/failing_script", "type": "script", "input_transforms": {"fail": {"expr": "flow_input.fail", "type": "javascript"}}}}]}', +'{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"fail":{"default":true,"description":"","type":"boolean","format":""}},"required":[],"type":"object"}', +'', +'', +'f/system/failing_flow' +); \ No newline at end of file diff --git a/backend/tests/worker.rs b/backend/tests/worker.rs index 4781165a42..45b32a0b3f 100644 --- a/backend/tests/worker.rs +++ b/backend/tests/worker.rs @@ -22,7 +22,7 @@ use windmill_api_client::types::{ use sqlx::query; #[cfg(feature = "enterprise")] -use windmill_api_client::types::{EditSchedule, NewSchedule, ScriptArgs}; +use windmill_api_client::types::{EditSchedule, NewSchedule, ScriptArgs, NewScript, NewScriptLanguage}; use windmill_common::worker::WORKER_CONFIG; use windmill_common::{ @@ -34,6 +34,8 @@ use windmill_common::{ use windmill_queue::PushIsolationLevel; use serde::Serialize; +use std::str::FromStr; + #[derive(Debug, sqlx::FromRow, Serialize)] pub struct CompletedJob { pub workspace_id: String, @@ -878,7 +880,7 @@ impl RunJob { args, /* user */ "test-user", /* email */ "test@windmill.dev", - /* permissioned_as */ "u/admin".to_string(), + /* permissioned_as */ "u/test-user".to_string(), /* scheduled_for_o */ None, /* schedule_path */ None, /* parent_job */ None, @@ -2616,7 +2618,7 @@ async fn test_rust_client(db: Pool) { #[cfg(feature = "enterprise")] -#[sqlx::test(fixtures("base"))] +#[sqlx::test(fixtures("base", "schedule"))] async fn test_script_schedule_handlers(db: Pool) { initialize_tracing().await; let server = ApiServer::start(db.clone()).await; @@ -2750,7 +2752,7 @@ async fn test_script_schedule_handlers(db: Pool) { #[cfg(feature = "enterprise")] -#[sqlx::test(fixtures("base"))] +#[sqlx::test(fixtures("base", "schedule"))] async fn test_flow_schedule_handlers(db: Pool) { initialize_tracing().await; let server = ApiServer::start(db.clone()).await; @@ -2883,3 +2885,203 @@ async fn test_flow_schedule_handlers(db: Pool) { ) .await; } + + +async fn run_deployed_relative_imports(db: &Pool, script_content: String, language: ScriptLang) { + initialize_tracing().await; + let server = ApiServer::start(db.clone()).await; + let port = server.addr.port(); + let client = windmill_api_client::create_client( + &format!("http://localhost:{port}"), + "SECRET_TOKEN".to_string(), + ); + + client.create_script( + "test-workspace", + &NewScript { + language: NewScriptLanguage::from_str(language.as_str()).unwrap(), + content: script_content, + path: "f/system/test_import".to_string(), + concurrent_limit: vec![], + concurrency_time_window_s: vec![], + cache_ttl: None, + dedicated_worker: None, + description: "".to_string(), + draft_only: None, + envs: vec![], + is_template: None, + kind: None, + parent_hash: None, + lock: vec![], + summary: "".to_string(), + tag: None, + schema: std::collections::HashMap::new(), + }, + ).await.unwrap(); + + let mut completed = listen_for_completed_jobs(&db).await; + let db2 = db.clone(); + in_test_worker(&db, async move { + completed.next().await; // deployed script + + let script = + query!("SELECT hash FROM script WHERE path = $1", "f/system/test_import".to_string()) + .fetch_one(&db2) + .await + .unwrap(); + + let job = RunJob::from(JobPayload::ScriptHash { + path: "f/system/test_import".to_string(), + hash: ScriptHash(script.hash), + concurrent_limit: None, + concurrency_time_window_s: None, + cache_ttl: None, + dedicated_worker: None, + language, + }).push(&db2).await; + + + completed.next().await; // completed job + + + let result = completed_job(job, &db2).await.json_result().unwrap(); + + + assert_eq!(result, serde_json::json!(["f/system/same_folder_script", "f/system/same_folder_script", "f/system_relative/different_folder_script", "f/system_relative/different_folder_script"])); + + }, port).await; +} + + +async fn run_preview_relative_imports(db: &Pool, script_content: String, language: ScriptLang) { + initialize_tracing().await; + let server = ApiServer::start(db.clone()).await; + let port = server.addr.port(); + + let mut completed = listen_for_completed_jobs(&db).await; + let db2 = db.clone(); + in_test_worker(&db, async move { + let job = RunJob::from(JobPayload::Code(RawCode { + content: script_content, + path: Some("f/system/test_import".to_string()), + language, + lock: None, + concurrent_limit: None, + concurrency_time_window_s: None, + cache_ttl: None, + })).push(&db2).await; + + + completed.next().await; // completed job + + + let result = completed_job(job, &db2).await.json_result().unwrap(); + + + assert_eq!(result, serde_json::json!(["f/system/same_folder_script", "f/system/same_folder_script", "f/system_relative/different_folder_script", "f/system_relative/different_folder_script"])); + + }, port).await; +} + + +#[sqlx::test(fixtures("base", "relative_bun"))] +async fn test_relative_imports_bun(db: Pool) { + let content = r#" +import { main as test1 } from "/f/system/same_folder_script.ts"; +import { main as test2 } from "./same_folder_script.ts"; +import { main as test3 } from "/f/system_relative/different_folder_script.ts"; +import { main as test4 } from "../system_relative/different_folder_script.ts"; + +export async function main() { + return [test1(), test2(), test3(), test4()]; +} +"#.to_string(); + + run_deployed_relative_imports(&db, content.clone(), ScriptLang::Bun).await; + run_preview_relative_imports(&db, content, ScriptLang::Bun).await; +} + + +#[sqlx::test(fixtures("base", "relative_bun"))] +async fn test_nested_imports_bun(db: Pool) { + + let content = r#" +import { main as test } from "/f/system_relative/nested_script.ts"; + +export async function main() { + return test(); +} +"#.to_string(); + + run_deployed_relative_imports(&db, content.clone(), ScriptLang::Bun).await; + run_preview_relative_imports(&db, content, ScriptLang::Bun).await; +} + + +#[sqlx::test(fixtures("base", "relative_deno"))] +async fn test_relative_imports_deno(db: Pool) { + let content = r#" +import { main as test1 } from "/f/system/same_folder_script.ts"; +import { main as test2 } from "./same_folder_script.ts"; +import { main as test3 } from "/f/system_relative/different_folder_script.ts"; +import { main as test4 } from "../system_relative/different_folder_script.ts"; + +export async function main() { + return [test1(), test2(), test3(), test4()]; +} +"#.to_string(); + + run_deployed_relative_imports(&db, content.clone(), ScriptLang::Deno).await; + run_preview_relative_imports(&db, content, ScriptLang::Deno).await; + +} + + +#[sqlx::test(fixtures("base", "relative_deno"))] +async fn test_nested_imports_deno(db: Pool) { + + let content = r#" +import { main as test } from "/f/system_relative/nested_script.ts"; + +export async function main() { + return test(); +} +"#.to_string(); + + run_deployed_relative_imports(&db, content.clone(), ScriptLang::Deno).await; + run_preview_relative_imports(&db, content, ScriptLang::Deno).await; +} + + +#[sqlx::test(fixtures("base", "relative_python"))] +async fn test_relative_imports_python(db: Pool) { + let content = r#" +from f.system.same_folder_script import main as test1 +from .same_folder_script import main as test2 +from f.system_relative.different_folder_script import main as test3 +from ..system_relative.different_folder_script import main as test4 + +def main(): + return [test1(), test2(), test3(), test4()] +"#.to_string(); + + run_deployed_relative_imports(&db, content.clone(), ScriptLang::Python3).await; + run_preview_relative_imports(&db, content, ScriptLang::Python3).await; + +} + + +#[sqlx::test(fixtures("base", "relative_python"))] +async fn test_nested_imports_python(db: Pool) { + + let content = r#" + +from f.system_relative.nested_script import main as test + +def main(): + return test() +"#.to_string(); + + run_deployed_relative_imports(&db, content.clone(), ScriptLang::Python3).await; + run_preview_relative_imports(&db, content, ScriptLang::Python3).await; +} \ No newline at end of file diff --git a/backend/windmill-worker/loader.bun.ts b/backend/windmill-worker/loader.bun.ts index efdc9dcf0a..3419fed0f0 100644 --- a/backend/windmill-worker/loader.bun.ts +++ b/backend/windmill-worker/loader.bun.ts @@ -24,15 +24,25 @@ const p = { loader: "tsx", }; }); - build.onResolve({ filter: /(?!\.\/main\.ts)\..*\.ts$/ }, (args) => { - const cdir = resolve("./"); + const cdir = resolve("./"); + const cdirNoPrivate = cdir.replace(/^\/private/, ""); // for macos + const filter = new RegExp( + `^(?!\\.\/main\\.ts)(?!${cdir}\/main\\.ts)(?!(?:/private)?${cdirNoPrivate}\/wrapper\\.ts).*\\.ts$` + ); + build.onResolve({ filter }, (args) => { const file_path = args.importer == "./main.ts" || args.importer == resolve("./main.ts") ? current_path : args.importer.replace(cdir + "/", ""); - const url = `${base_internal_url}/api/w/${w_id}/scripts/raw/p/${file_path}/../${args.path}`; - const file = resolve("./" + current_path + "/../" + args.path + ".url"); + const isRelative = !args.path.startsWith("/"); + + const url = isRelative + ? `${base_internal_url}/api/w/${w_id}/scripts/raw/p/${file_path}/../${args.path}` + : `${base_internal_url}/api/w/${w_id}/scripts/raw/p/${args.path}`; + const file = isRelative + ? resolve("./" + current_path + "/../" + args.path + ".url") + : resolve("./" + args.path + ".url"); mkdirSync(dirname(file), { recursive: true }); writeFileSync(file, url); return {