1use anyhow::{Context, Result};
2use config::{create_config, Config};
3use std::collections::HashMap;
4use wasm_metadata::Producers;
5use wit_component::{metadata, ComponentEncoder, DecodedWasm, StringEncoding};
6
7pub mod config;
8mod walrus_ops;
9
10const ADAPTER: &[u8] = include_bytes!("../lib/adapter.wasm");
11const WIT_METADATA: &[u8] = include_bytes!("../lib/package.wasm");
12
13pub fn create_component(values: Vec<(String, String)>) -> Result<Vec<u8>> {
14 let mut config = walrus::ModuleConfig::new();
15 config.generate_name_section(false);
17 let mut module = config.parse(ADAPTER)?;
18 module.name = Some("static-config".into());
19
20 let mut properties = HashMap::new();
21 for (key, value) in values {
22 properties.insert(key, value);
23 }
24
25 let config = &Config {
26 overrides: properties.into_iter().collect(),
27 };
28 create_config(&mut module, config)?;
29
30 let component_type_section_id = module
31 .customs
32 .iter()
33 .find_map(|(id, section)| {
34 let name = section.name();
35 if name.starts_with("component-type:")
36 && section.as_any().is::<walrus::RawCustomSection>()
37 {
38 Some(id)
39 } else {
40 None
41 }
42 })
43 .context("Unable to find component type section")?;
44
45 let mut component_section = *module
48 .customs
49 .delete(component_type_section_id)
50 .context("Unable to find component section")?
51 .into_any()
52 .downcast::<walrus::RawCustomSection>()
53 .unwrap();
54
55 let (resolve, pkg_id) = match wit_component::decode(WIT_METADATA)? {
56 DecodedWasm::WitPackage(resolve, pkg_id) => (resolve, pkg_id),
57 DecodedWasm::Component(..) => {
58 anyhow::bail!("expected a WIT package, found a component")
59 }
60 };
61
62 let world = resolve.select_world(&[pkg_id], Some("adapter"))?;
63
64 let mut producers = Producers::default();
65 producers.add("processed-by", "static-config", env!("CARGO_PKG_VERSION"));
66
67 component_section.data =
68 metadata::encode(&resolve, world, StringEncoding::UTF8, Some(&producers))?;
69
70 module.customs.add(component_section);
71
72 let bytes = module.emit_wasm();
73
74 let mut encoder = ComponentEncoder::default().validate(true).module(&bytes)?;
76 let encoded = encoder.encode()?;
77
78 Ok(encoded)
79}