diff --git a/bridge/svix-bridge/src/config/mod.rs b/bridge/svix-bridge/src/config/mod.rs index d8f185919..4c9f98989 100644 --- a/bridge/svix-bridge/src/config/mod.rs +++ b/bridge/svix-bridge/src/config/mod.rs @@ -3,10 +3,13 @@ use std::borrow::Cow; use std::collections::HashMap; use std::io::{Error, ErrorKind}; use std::net::SocketAddr; +use std::path::PathBuf; use svix_bridge_plugin_queue::config::{ into_receiver_output, QueueConsumerConfig, ReceiverOutputOpts as QueueOutOpts, }; -use svix_bridge_types::{ReceiverInputOpts, ReceiverOutput, SenderInput, TransformationConfig}; +use svix_bridge_types::{ + ReceiverInputOpts, ReceiverOutput, SenderInput, SenderOutputOpts, TransformationConfig, +}; use tracing::Level; #[derive(Deserialize)] @@ -104,6 +107,7 @@ pub enum SenderConfig { feature = "sqs" ))] QueueConsumer(QueueConsumerConfig), + JsModule(JsModuleSenderConfig), } impl TryFrom for Box { @@ -117,6 +121,7 @@ impl TryFrom for Box { feature = "sqs" ))] SenderConfig::QueueConsumer(backend) => backend.into_sender_input(), + SenderConfig::JsModule(inner) => inner.into_sender_input(), } } } @@ -154,5 +159,29 @@ impl ReceiverConfig { } } +#[derive(Deserialize)] +pub struct JsModuleSenderConfig { + pub name: String, + pub input: JsModuleSenderInputOpts, + #[serde(default)] + pub transformation: Option, + pub output: SenderOutputOpts, +} + +impl JsModuleSenderConfig { + fn into_sender_input(self) -> Result, &'static str> { + // FIXME: need to make it so we can use latest deno for transformations before we can + // connect the new module code. + todo!() + } +} + +#[derive(Deserialize)] +#[serde(tag = "type", rename_all = "lowercase")] +pub enum JsModuleSenderInputOpts { + #[serde(rename = "js-module")] + JsModule { module_path: PathBuf }, +} + #[cfg(test)] mod tests; diff --git a/bridge/svix-bridge/src/config/tests.rs b/bridge/svix-bridge/src/config/tests.rs index ec66bc849..23f5a5edd 100644 --- a/bridge/svix-bridge/src/config/tests.rs +++ b/bridge/svix-bridge/src/config/tests.rs @@ -1,6 +1,9 @@ use super::Config; -use crate::config::{LogFormat, LogLevel, SenderConfig}; +use crate::config::{ + JsModuleSenderConfig, JsModuleSenderInputOpts, LogFormat, LogLevel, SenderConfig, +}; use std::collections::HashMap; +use std::path::PathBuf; use svix_bridge_plugin_queue::config::{QueueConsumerConfig, RabbitMqInputOpts, SenderInputOpts}; use svix_bridge_types::{SenderOutputOpts, SvixSenderOutputOpts}; @@ -485,3 +488,43 @@ fn test_variable_substitution_repeated_lookups() { panic!("sender did not match expected pattern"); } } + +#[test] +fn test_js_module_sender_input_ok() { + let src = r#" + senders: + - name: "js-module-example" + input: + type: "js-module" + # FIXME: custom module loader needed to use yaml keys for src + module_path: "./my-module.js" + transformation: | + function handler(input) { + return { + appId: "xxxxx", + message: { + eventType: "lipsum.word-lengths.changed", + payload: { lengths: input.lengths } + } + }; + } + output: + type: "svix" + token: "x" + "#; + let cfg = Config::from_src(src, Some(HashMap::new()).as_ref()).unwrap(); + + if let SenderConfig::JsModule(JsModuleSenderConfig { + input: JsModuleSenderInputOpts::JsModule { module_path, .. }, + transformation, + output: SenderOutputOpts::Svix(SvixSenderOutputOpts { token, .. }), + .. + }) = &cfg.senders[0] + { + assert_eq!(module_path, &PathBuf::from("./my-module.js")); + assert!(transformation.is_some()); + assert_eq!(token, "x"); + } else { + panic!("sender did not match expected pattern"); + } +}