spin_manifest/schema/
v1.rs1use serde::Deserialize;
2
3use spin_serde::FixedStringVersion;
4
5pub use super::common::{
6 ComponentBuildConfig as ComponentBuildConfigV1, ComponentSource as ComponentSourceV1,
7 Variable as VariableV1, WasiFilesMount as WasiFilesMountV1,
8};
9
10type Map<K, V> = indexmap::IndexMap<K, V>;
11
12#[derive(Deserialize)]
14#[serde(deny_unknown_fields)]
15pub struct AppManifestV1 {
16 #[serde(alias = "spin_version")]
18 #[allow(dead_code)]
19 spin_manifest_version: FixedStringVersion<1>,
20 pub name: String,
22 #[serde(default)]
24 pub version: String,
25 #[serde(default)]
27 pub description: String,
28 #[serde(default)]
30 pub authors: Vec<String>,
31 pub trigger: AppTriggerV1,
33 #[serde(default)]
35 pub variables: Map<String, VariableV1>,
36 #[serde(rename = "component")]
38 #[serde(default)]
39 pub components: Vec<ComponentV1>,
40}
41
42#[derive(Deserialize)]
44pub struct AppTriggerV1 {
45 #[serde(rename = "type")]
47 pub trigger_type: String,
48 #[serde(flatten)]
50 pub config: toml::Table,
51}
52
53#[derive(Deserialize)]
55#[serde(deny_unknown_fields)]
56pub struct ComponentV1 {
57 pub id: String,
59 pub source: ComponentSourceV1,
61 pub trigger: toml::Table,
63 #[serde(default)]
65 pub description: String,
66 #[serde(default)]
68 pub config: Map<String, String>,
69 #[serde(default)]
71 pub environment: Map<String, String>,
72 #[serde(default)]
74 pub files: Vec<WasiFilesMountV1>,
75 #[serde(default)]
77 pub exclude_files: Vec<String>,
78 #[serde(default)]
80 pub allowed_http_hosts: Vec<String>,
81 #[serde(default)]
83 pub allowed_outbound_hosts: Option<Vec<String>>,
84 #[serde(default)]
86 pub key_value_stores: Vec<String>,
87 #[serde(default)]
89 pub sqlite_databases: Vec<String>,
90 #[serde(default)]
92 pub ai_models: Vec<String>,
93 #[serde(default)]
95 pub build: Option<ComponentBuildConfigV1>,
96}
97
98#[cfg(test)]
99mod tests {
100 use toml::toml;
101
102 use super::*;
103
104 #[derive(Deserialize)]
105 #[allow(dead_code)]
106 struct FakeGlobalTriggerConfig {
107 global_option: bool,
108 }
109
110 #[derive(Deserialize)]
111 #[allow(dead_code)]
112 struct FakeTriggerConfig {
113 option: Option<bool>,
114 }
115
116 #[test]
117 fn deserializing_trigger_configs() {
118 let manifest = AppManifestV1::deserialize(toml! {
119 spin_manifest_version = "1"
120 name = "trigger-configs"
121 trigger = { type = "fake", global_option = true }
122 [[component]]
123 id = "my-component"
124 source = "example.wasm"
125 [component.trigger]
126 option = true
127 })
128 .unwrap();
129
130 FakeGlobalTriggerConfig::deserialize(manifest.trigger.config).unwrap();
131
132 FakeTriggerConfig::deserialize(manifest.components[0].trigger.clone()).unwrap();
133 }
134}