Added file upload support

This commit is contained in:
2026-06-04 04:20:05 -04:00
parent 4effcc7597
commit 67ad91b673
23 changed files with 665 additions and 20 deletions

View File

@@ -165,6 +165,7 @@ fn ts_type_expression(shape: &TypeShape) -> String {
.map(ts_type_expression)
.collect::<Vec<_>>()
.join(" | "),
TypeShape::Upload(_) => "File".to_string(),
}
}

View File

@@ -118,6 +118,9 @@ fn py_type_expression(shape: &TypeShape) -> String {
.map(py_type_expression)
.collect::<Vec<_>>()
.join(" | "),
// The Python (PyO3) client is a consumer, not an upload origin; a file
// input surfaces as raw bytes on this target.
TypeShape::Upload(_) => "bytes".to_string(),
}
}

View File

@@ -440,5 +440,8 @@ fn rust_type_from_shape(shape: &TypeShape, ctx: &mut EnumCtx) -> String {
// Value so the consumer can match on the runtime variant.
"serde_json::Value".to_string()
}
// The Rust adapter does not yet wire multipart; a file input surfaces
// as raw bytes until upload dispatch lands on this target.
TypeShape::Upload(_) => "Vec<u8>".to_string(),
}
}

View File

@@ -296,5 +296,6 @@ fn ts_type_expression(shape: &TypeShape) -> String {
.map(ts_type_expression)
.collect::<Vec<_>>()
.join(" | "),
TypeShape::Upload(_) => "File".to_string(),
}
}

View File

@@ -46,6 +46,15 @@ pub enum TypeShape {
Enum(Vec<String>),
/// Multi-arm union with two or more non-null branches.
Union(Vec<TypeShape>),
/// Binary file input. Carries the declarative `File(...)` constraints.
Upload(UploadConstraints),
}
#[derive(Debug, Clone, Default)]
pub struct UploadConstraints {
pub max_size: Option<u64>,
pub content_types: Vec<String>,
}
@@ -273,6 +282,7 @@ fn parse_type_shape(node: &KdlNode) -> Result<TypeShape> {
"list" => Ok(TypeShape::List(Box::new(type_child_of(node, "list")?))),
"optional" => Ok(TypeShape::Optional(Box::new(type_child_of(node, "optional")?))),
"enum" => Ok(TypeShape::Enum(parse_string_args(node))),
"upload" => Ok(TypeShape::Upload(parse_upload_constraints(node))),
"union" => {
let children = node.children()
.ok_or_else(|| anyhow!("union: missing children"))?;
@@ -285,6 +295,20 @@ fn parse_type_shape(node: &KdlNode) -> Result<TypeShape> {
}
fn parse_upload_constraints(node: &KdlNode) -> UploadConstraints {
let max_size = node.entry("max-size")
.and_then(|e| e.value().as_integer())
.map(|i| i as u64);
let content_types = node.children()
.map(|children| children.nodes().iter()
.filter(|n| n.name().value() == "content-type")
.filter_map(|n| first_string_arg(n).ok())
.collect())
.unwrap_or_default();
UploadConstraints { max_size, content_types }
}
fn parse_function(node: &KdlNode) -> Result<MizanFunction> {
let name = first_string_arg(node)
.context("`function` requires a name as its first argument")?;