use wasm_bindgen::prelude::*;
use bnto_core::NoopContext;
use bnto_core::errors::BntoError;
use bnto_core::processor::{FileData, NodeInput, NodeOutput, NodeProcessor};
use bnto_core::progress::ProgressReporter;
use crate::clean::CleanSpreadsheet;
use crate::rename::RenameColumns;
fn bnto_err_to_js(error: BntoError) -> JsValue {
JsError::new(&error.to_string()).into()
}
fn build_combined_result(output: NodeOutput) -> Result<JsValue, JsValue> {
let file = output
.files
.into_iter()
.next()
.ok_or_else(|| JsValue::from_str("No output file produced"))?;
let metadata_json = serde_json::to_string(&output.metadata)
.map_err(|e| JsValue::from_str(&format!("Failed to serialize metadata: {e}")))?;
let result = js_sys::Object::new();
js_sys::Reflect::set(&result, &"metadata".into(), &metadata_json.into())
.map_err(|_| JsValue::from_str("Failed to set metadata on result object"))?;
let bytes = file
.data
.into_bytes()
.map_err(|e| JsValue::from_str(&format!("Failed to read output file data: {e}")))?;
let uint8 = js_sys::Uint8Array::from(bytes.as_slice());
js_sys::Reflect::set(&result, &"data".into(), &uint8)
.map_err(|_| JsValue::from_str("Failed to set data on result object"))?;
js_sys::Reflect::set(&result, &"filename".into(), &file.filename.into())
.map_err(|_| JsValue::from_str("Failed to set filename on result object"))?;
js_sys::Reflect::set(&result, &"mimeType".into(), &file.mime_type.into())
.map_err(|_| JsValue::from_str("Failed to set mimeType on result object"))?;
Ok(result.into())
}
#[wasm_bindgen]
pub fn clean_spreadsheet_combined(
data: &[u8],
filename: &str,
params_json: &str,
progress_callback: js_sys::Function,
) -> Result<JsValue, JsValue> {
let params: serde_json::Map<String, serde_json::Value> =
serde_json::from_str(params_json).unwrap_or_default();
let input = NodeInput {
data: FileData::Bytes(data.to_vec()),
filename: filename.to_string(),
mime_type: None,
params,
};
let processor = CleanSpreadsheet::new();
let progress = ProgressReporter::new(move |percent, message| {
let _ = progress_callback.call2(
&JsValue::NULL,
&JsValue::from(percent),
&JsValue::from(message),
);
});
let output = processor
.process(input, &progress, &NoopContext)
.map_err(bnto_err_to_js)?;
build_combined_result(output)
}
#[wasm_bindgen]
pub fn rename_spreadsheet_columns_combined(
data: &[u8],
filename: &str,
params_json: &str,
progress_callback: js_sys::Function,
) -> Result<JsValue, JsValue> {
let params: serde_json::Map<String, serde_json::Value> =
serde_json::from_str(params_json).unwrap_or_default();
let input = NodeInput {
data: FileData::Bytes(data.to_vec()),
filename: filename.to_string(),
mime_type: Some("text/csv".to_string()),
params,
};
let processor = RenameColumns::new();
let progress = ProgressReporter::new(move |percent, message| {
let _ = progress_callback.call2(
&JsValue::NULL,
&JsValue::from(percent),
&JsValue::from(message),
);
});
let output = processor
.process(input, &progress, &NoopContext)
.map_err(bnto_err_to_js)?;
build_combined_result(output)
}