mechanics-core 0.1.0

mechanics automation framework (core)
Documentation
use super::{MechanicsState, endpoint_response_to_js_value, parse_endpoint_call_options_js};
use crate::executor::CustomModuleLoader;
use boa_engine::{
    Context, JsArgs, JsError, JsNativeError, Module, NativeFunction, js_string,
    module::SyntheticModuleInitializer, object::FunctionObjectBuilder,
};
use std::rc::Rc;

pub(super) fn register(loader: &Rc<CustomModuleLoader>, context: &mut Context) {
    let endpoint = FunctionObjectBuilder::new(
        context.realm(),
        NativeFunction::from_async_fn(async |_, args, ctx| {
            let endpoint = args
                .get_or_undefined(0)
                .as_string()
                .ok_or(JsError::from_native(
                    JsNativeError::typ().with_message("endpoint is not a string"),
                ))?;
            let options = args.get_or_undefined(1).clone();
            let req_options = parse_endpoint_call_options_js(options, &mut ctx.borrow_mut())?;

            let state = {
                let ctx_ref = ctx.borrow();
                ctx_ref
                    .get_data::<MechanicsState>()
                    .cloned()
                    .ok_or(JsError::from_native(
                        JsNativeError::typ().with_message("Invalid state"),
                    ))?
            };
            let endpoint_name = endpoint.to_std_string_lossy();
            let (endpoint, prepared) = state.endpoint(&endpoint_name).ok_or(
                JsError::from_native(JsNativeError::typ().with_message("Endpoint not found")),
            )?;

            let res = endpoint
                .execute(
                    state.endpoint_http_client(),
                    prepared,
                    state.default_timeout_ms(),
                    state.default_response_max_bytes(),
                    &req_options,
                )
                .await
                .map_err(JsError::from_rust)?;

            endpoint_response_to_js_value(res, &mut ctx.borrow_mut())
        }),
    )
    .length(2)
    .name("endpoint")
    .build();

    let endpoint_module = Module::synthetic(
        &[js_string!("default")],
        SyntheticModuleInitializer::from_copy_closure_with_captures(
            |module, f, _ctx| module.set_export(&js_string!("default"), f.clone().into()),
            endpoint,
        ),
        None,
        None,
        context,
    );
    loader.define_module(js_string!("mechanics:endpoint"), endpoint_module);
}