use super::RegistryBase;
use super::external::ExternalPack;
use crate::template::{PresetInfo, Theme};
use anyhow::Context;
use serde_json::Value;
pub fn merge_pack_into_registry(base: &mut RegistryBase, pack: ExternalPack) -> anyhow::Result<()> {
eprintln!(
"[flow-builder] loading external pack: {}",
pack.metadata.name
);
for (name, source) in pack.primitives {
if base.handlebars.has_template(&name) {
eprintln!(
"[flow-builder] warning: primitive '{}' overrides built-in",
name
);
}
base.handlebars
.register_partial(&name, source)
.with_context(|| format!("registering external primitive '{}'", name))?;
}
for (name, theme_json) in pack.themes {
let theme: Theme = serde_json::from_value(theme_json)
.with_context(|| format!("parsing external theme '{}'", name))?;
base.themes.insert(theme);
}
for (name, preset_file) in pack.presets {
if base.presets.contains_key(&name) {
eprintln!(
"[flow-builder] warning: preset '{}' overrides built-in",
name
);
}
base.handlebars
.register_template_string(&name, &preset_file.source)
.with_context(|| format!("registering external preset '{}'", name))?;
let info = PresetInfo {
name: name.clone(),
category: preset_file.schema["x-category"]
.as_str()
.unwrap_or("custom")
.to_string(),
title: preset_file.schema["title"]
.as_str()
.unwrap_or(&name)
.to_string(),
description: preset_file.schema["description"]
.as_str()
.unwrap_or("")
.to_string(),
tags: extract_string_array(&preset_file.schema["x-tags"]),
use_cases: extract_string_array(&preset_file.schema["x-use-cases"]),
example: preset_file
.schema
.get("x-example")
.cloned()
.unwrap_or(Value::Null),
schema: preset_file.schema,
template_source: preset_file.source,
};
base.presets.insert(name, info);
}
Ok(())
}
fn extract_string_array(value: &Value) -> Vec<String> {
value
.as_array()
.map(|arr| {
arr.iter()
.filter_map(|v| v.as_str().map(String::from))
.collect()
})
.unwrap_or_default()
}