use napi::{Result, bindgen_prelude::*, JsObject};
use std::collections::HashMap;
use briefcase_core::{
Input, Output, ModelParameters, ExecutionContext, DecisionSnapshot,
Snapshot, SnapshotType, SnapshotMetadata
};
#[napi]
pub struct JsInput {
inner: Input,
}
#[napi]
impl JsInput {
#[napi(constructor)]
pub fn new(name: String, value: serde_json::Value, data_type: String) -> Self {
Self {
inner: Input::new(name, value, data_type),
}
}
#[napi(getter)]
pub fn name(&self) -> String {
self.inner.name.clone()
}
#[napi(getter)]
pub fn value(&self) -> serde_json::Value {
self.inner.value.clone()
}
#[napi(getter)]
pub fn data_type(&self) -> String {
self.inner.data_type.clone()
}
#[napi]
pub fn to_object(&self) -> Result<serde_json::Value> {
Ok(serde_json::json!({
"name": self.inner.name,
"value": self.inner.value,
"data_type": self.inner.data_type,
}))
}
}
#[napi]
pub struct JsOutput {
inner: Output,
}
#[napi]
impl JsOutput {
#[napi(constructor)]
pub fn new(name: String, value: serde_json::Value, data_type: String) -> Self {
Self {
inner: Output::new(name, value, data_type),
}
}
#[napi]
pub fn with_confidence(&mut self, confidence: f64) -> &Self {
self.inner = self.inner.clone().with_confidence(confidence);
self
}
#[napi(getter)]
pub fn name(&self) -> String {
self.inner.name.clone()
}
#[napi(getter)]
pub fn value(&self) -> serde_json::Value {
self.inner.value.clone()
}
#[napi(getter)]
pub fn data_type(&self) -> String {
self.inner.data_type.clone()
}
#[napi(getter)]
pub fn confidence(&self) -> Option<f64> {
self.inner.confidence
}
#[napi]
pub fn to_object(&self) -> Result<serde_json::Value> {
let mut obj = serde_json::json!({
"name": self.inner.name,
"value": self.inner.value,
"data_type": self.inner.data_type,
});
if let Some(confidence) = self.inner.confidence {
obj["confidence"] = serde_json::Value::Number(
serde_json::Number::from_f64(confidence).unwrap()
);
}
Ok(obj)
}
}
#[napi]
pub struct JsModelParameters {
inner: ModelParameters,
}
#[napi]
impl JsModelParameters {
#[napi(constructor)]
pub fn new(model_name: String) -> Self {
Self {
inner: ModelParameters::new(model_name),
}
}
#[napi]
pub fn with_provider(&mut self, provider: String) -> &Self {
self.inner = self.inner.clone().with_provider(provider);
self
}
#[napi]
pub fn with_parameter(&mut self, key: String, value: serde_json::Value) -> &Self {
self.inner = self.inner.clone().with_parameter(key, value);
self
}
#[napi(getter)]
pub fn model_name(&self) -> String {
self.inner.model_name.clone()
}
#[napi(getter)]
pub fn provider(&self) -> Option<String> {
self.inner.provider.clone()
}
#[napi(getter)]
pub fn parameters(&self) -> HashMap<String, serde_json::Value> {
self.inner.parameters.clone()
}
}
#[napi]
pub struct JsExecutionContext {
inner: ExecutionContext,
}
#[napi]
impl JsExecutionContext {
#[napi(constructor)]
pub fn new() -> Self {
Self {
inner: ExecutionContext::new(),
}
}
#[napi]
pub fn with_environment(&mut self, environment: String) -> &Self {
self.inner = self.inner.clone().with_environment(environment);
self
}
#[napi]
pub fn with_service_name(&mut self, service_name: String) -> &Self {
self.inner = self.inner.clone().with_service_name(service_name);
self
}
#[napi]
pub fn with_version(&mut self, version: String) -> &Self {
self.inner = self.inner.clone().with_version(version);
self
}
#[napi]
pub fn with_custom_field(&mut self, key: String, value: serde_json::Value) -> &Self {
self.inner = self.inner.clone().with_custom_field(key, value);
self
}
#[napi(getter)]
pub fn environment(&self) -> Option<String> {
self.inner.environment.clone()
}
#[napi(getter)]
pub fn service_name(&self) -> Option<String> {
self.inner.service_name.clone()
}
#[napi(getter)]
pub fn version(&self) -> Option<String> {
self.inner.version.clone()
}
}
#[napi]
pub struct JsDecisionSnapshot {
pub inner: DecisionSnapshot,
}
#[napi]
impl JsDecisionSnapshot {
#[napi(constructor)]
pub fn new(function_name: String) -> Self {
Self {
inner: DecisionSnapshot::new(function_name),
}
}
#[napi]
pub fn with_module(&mut self, module_name: String) -> &Self {
self.inner = self.inner.clone().with_module(module_name);
self
}
#[napi]
pub fn add_input(&mut self, input: &JsInput) -> &Self {
self.inner = self.inner.clone().add_input(input.inner.clone());
self
}
#[napi]
pub fn add_output(&mut self, output: &JsOutput) -> &Self {
self.inner = self.inner.clone().add_output(output.inner.clone());
self
}
#[napi]
pub fn with_model_parameters(&mut self, params: &JsModelParameters) -> &Self {
self.inner = self.inner.clone().with_model_parameters(params.inner.clone());
self
}
#[napi]
pub fn with_execution_time(&mut self, time_ms: f64) -> &Self {
self.inner = self.inner.clone().with_execution_time(time_ms);
self
}
#[napi]
pub fn add_tag(&mut self, key: String, value: String) -> &Self {
self.inner = self.inner.clone().add_tag(key, value);
self
}
#[napi(getter)]
pub fn function_name(&self) -> String {
self.inner.function_name.clone()
}
#[napi(getter)]
pub fn module_name(&self) -> Option<String> {
self.inner.module_name.clone()
}
#[napi(getter)]
pub fn execution_time_ms(&self) -> Option<f64> {
self.inner.execution_time_ms
}
#[napi(getter)]
pub fn tags(&self) -> HashMap<String, String> {
self.inner.tags.clone()
}
#[napi]
pub fn to_object(&self) -> Result<serde_json::Value> {
serde_json::to_value(&self.inner)
.map_err(|e| napi::Error::from_reason(format!("Serialization error: {}", e)))
}
}
#[napi]
pub struct JsSnapshot {
pub inner: Snapshot,
}
#[napi]
impl JsSnapshot {
#[napi(constructor)]
pub fn new(snapshot_type: String) -> Result<Self> {
let snap_type = match snapshot_type.as_str() {
"session" => SnapshotType::Session,
"decision" => SnapshotType::Decision,
"batch" => SnapshotType::Batch,
_ => return Err(napi::Error::from_reason(
format!("Invalid snapshot type: {}", snapshot_type)
)),
};
Ok(Self {
inner: Snapshot::new(snap_type),
})
}
#[napi]
pub fn add_decision(&mut self, decision: &JsDecisionSnapshot) {
self.inner.add_decision(decision.inner.clone());
}
#[napi(getter)]
pub fn snapshot_type(&self) -> String {
format!("{:?}", self.inner.snapshot_type).to_lowercase()
}
#[napi(getter)]
pub fn decision_count(&self) -> u32 {
self.inner.decisions.len() as u32
}
#[napi]
pub fn to_object(&self) -> Result<serde_json::Value> {
serde_json::to_value(&self.inner)
.map_err(|e| napi::Error::from_reason(format!("Serialization error: {}", e)))
}
}
#[napi]
pub struct JsSnapshotQuery {
pub inner: briefcase_core::storage::SnapshotQuery,
}
#[napi]
impl JsSnapshotQuery {
#[napi(constructor)]
pub fn new() -> Self {
Self {
inner: briefcase_core::storage::SnapshotQuery::new(),
}
}
#[napi]
pub fn with_function_name(&mut self, function_name: String) -> &Self {
self.inner = self.inner.clone().with_function_name(function_name);
self
}
#[napi]
pub fn with_module_name(&mut self, module_name: String) -> &Self {
self.inner = self.inner.clone().with_module_name(module_name);
self
}
#[napi]
pub fn with_limit(&mut self, limit: u32) -> &Self {
self.inner = self.inner.clone().with_limit(limit as usize);
self
}
#[napi]
pub fn with_offset(&mut self, offset: u32) -> &Self {
self.inner = self.inner.clone().with_offset(offset as usize);
self
}
#[napi]
pub fn with_tag(&mut self, key: String, value: String) -> &Self {
self.inner = self.inner.clone().with_tag(key, value);
self
}
}