From 635c3627c96df0dc46fe3fe8f4e8b7f4a01fd29e Mon Sep 17 00:00:00 2001 From: J M <2364004+Blu-J@users.noreply.github.com> Date: Mon, 18 Jul 2022 15:46:32 -0600 Subject: [PATCH] feat: Variable args (#1667) * feat: Variable args * chore: Make the assert error message not wrong --- backend/src/procedure/js_scripts.rs | 60 +++++++++++++++++-- .../scripts/test-package/0.3.0.3/embassy.js | 13 ++++ libs/js_engine/src/artifacts/loadModule.js | 3 +- libs/js_engine/src/lib.rs | 13 +++- 4 files changed, 81 insertions(+), 8 deletions(-) diff --git a/backend/src/procedure/js_scripts.rs b/backend/src/procedure/js_scripts.rs index c83440e63..72f55b346 100644 --- a/backend/src/procedure/js_scripts.rs +++ b/backend/src/procedure/js_scripts.rs @@ -45,7 +45,10 @@ impl PathForVolumeId for Volumes { #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "kebab-case")] -pub struct JsProcedure {} +pub struct JsProcedure { + #[serde(default)] + args: Vec, +} impl JsProcedure { pub fn validate(&self, _volumes: &Volumes) -> Result<(), color_eyre::eyre::Report> { @@ -71,7 +74,7 @@ impl JsProcedure { Box::new(volumes.clone()), ) .await? - .run_action(name, input); + .run_action(name, input, self.args.clone()); let output: ErrorValue = match timeout { Some(timeout_duration) => tokio::time::timeout(timeout_duration, running_action) .await @@ -105,7 +108,7 @@ impl JsProcedure { ) .await? .read_only_effects() - .run_action(name, input); + .run_action(name, input, self.args.clone()); let output: ErrorValue = match timeout { Some(timeout_duration) => tokio::time::timeout(timeout_duration, running_action) .await @@ -145,7 +148,7 @@ fn unwrap_known_error Deserialize<'de>>( #[tokio::test] async fn js_action_execute() { - let js_action = JsProcedure {}; + let js_action = JsProcedure { args: vec![] }; let path: PathBuf = "test/js_action_execute/" .parse::() .unwrap() @@ -200,7 +203,7 @@ async fn js_action_execute() { #[tokio::test] async fn js_action_execute_error() { - let js_action = JsProcedure {}; + let js_action = JsProcedure { args: vec![] }; let path: PathBuf = "test/js_action_execute/" .parse::() .unwrap() @@ -244,7 +247,52 @@ async fn js_action_execute_error() { #[tokio::test] async fn js_action_fetch() { - let js_action = JsProcedure {}; + let js_action = JsProcedure { args: vec![] }; + let path: PathBuf = "test/js_action_execute/" + .parse::() + .unwrap() + .canonicalize() + .unwrap(); + let package_id = "test-package".parse().unwrap(); + let package_version: Version = "0.3.0.3".parse().unwrap(); + let name = ProcedureName::Action("fetch".parse().unwrap()); + let volumes: Volumes = serde_json::from_value(serde_json::json!({ + "main": { + "type": "data" + }, + "compat": { + "type": "assets" + }, + "filebrowser" :{ + "package-id": "filebrowser", + "path": "data", + "readonly": true, + "type": "pointer", + "volume-id": "main", + } + })) + .unwrap(); + let input: Option = None; + let timeout = Some(Duration::from_secs(10)); + js_action + .execute::( + &path, + &package_id, + &package_version, + name, + &volumes, + input, + timeout, + ) + .await + .unwrap() + .unwrap(); +} +#[tokio::test] +async fn js_action_var_arg() { + let js_action = JsProcedure { + args: vec![42.into()], + }; let path: PathBuf = "test/js_action_execute/" .parse::() .unwrap() diff --git a/backend/test/js_action_execute/package-data/scripts/test-package/0.3.0.3/embassy.js b/backend/test/js_action_execute/package-data/scripts/test-package/0.3.0.3/embassy.js index 38b86ea2f..190b47812 100644 --- a/backend/test/js_action_execute/package-data/scripts/test-package/0.3.0.3/embassy.js +++ b/backend/test/js_action_execute/package-data/scripts/test-package/0.3.0.3/embassy.js @@ -758,5 +758,18 @@ export const action = { qr: false, } } + }, + + async fetch(_effects, _input, testInput) { + + assert(testInput == 42, "Input should be passed in"); + return { + result: { + copyable: false, + message: "Done", + version: "0", + qr: false, + } + } } } \ No newline at end of file diff --git a/libs/js_engine/src/artifacts/loadModule.js b/libs/js_engine/src/artifacts/loadModule.js index a7217dc44..3d9a04f9f 100644 --- a/libs/js_engine/src/artifacts/loadModule.js +++ b/libs/js_engine/src/artifacts/loadModule.js @@ -68,6 +68,7 @@ const fetch = async (url, options = null) => { const currentFunction = Deno.core.opSync("current_function"); const input = Deno.core.opSync("get_input"); +const variable_args = Deno.core.opSync("get_variable_args"); const setState = (x) => Deno.core.opSync("set_value", x); const effects = { writeFile, @@ -93,6 +94,6 @@ const runFunction = jsonPointerValue(mainModule, currentFunction); error(`Expecting ${ currentFunction } to be a function`); throw new Error(`Expecting ${ currentFunction } to be a function`); } - const answer = await runFunction(effects, input); + const answer = await runFunction(effects, input, ...variable_args); setState(answer); })(); diff --git a/libs/js_engine/src/lib.rs b/libs/js_engine/src/lib.rs index 238e15ca2..695fd763d 100644 --- a/libs/js_engine/src/lib.rs +++ b/libs/js_engine/src/lib.rs @@ -87,6 +87,7 @@ struct JsContext { package_id: PackageId, volumes: Arc, input: Value, + variable_args: Vec, } #[derive(Clone, Default)] @@ -218,6 +219,7 @@ impl JsExecutionEnvironment { self, procedure_name: ProcedureName, input: Option, + variable_args: Vec, ) -> Result { let input = match serde_json::to_value(input) { Ok(a) => a, @@ -231,7 +233,8 @@ impl JsExecutionEnvironment { } }; let safer_handle: NonDetachingJoinHandle<_> = - tokio::task::spawn_blocking(move || self.execute(procedure_name, input)).into(); + tokio::task::spawn_blocking(move || self.execute(procedure_name, input, variable_args)) + .into(); let output = safer_handle .await .map_err(|err| (JsError::Tokio, format!("Tokio gave us the error: {}", err)))??; @@ -266,6 +269,7 @@ impl JsExecutionEnvironment { fns::log_debug::decl(), fns::log_info::decl(), fns::get_input::decl(), + fns::get_variable_args::decl(), fns::set_value::decl(), fns::is_sandboxed::decl(), ] @@ -275,6 +279,7 @@ impl JsExecutionEnvironment { &self, procedure_name: ProcedureName, input: Value, + variable_args: Vec, ) -> Result { let base_directory = self.base_directory.clone(); let answer_state = AnswerState::default(); @@ -287,6 +292,7 @@ impl JsExecutionEnvironment { version: self.version.clone(), sandboxed: self.sandboxed, input, + variable_args, }; let ext = Extension::builder() .ops(Self::declarations()) @@ -675,6 +681,11 @@ mod fns { Ok(ctx.input.clone()) } #[op] + fn get_variable_args(state: &mut OpState) -> Result, AnyError> { + let ctx = state.borrow::(); + Ok(ctx.variable_args.clone()) + } + #[op] fn set_value(state: &mut OpState, value: Value) -> Result<(), AnyError> { let mut answer = state.borrow::().0.lock(); *answer = value;