diff --git a/crates/wick/wick-component-cli/src/utils.rs b/crates/wick/wick-component-cli/src/utils.rs index abd8b2e5..2de37856 100644 --- a/crates/wick/wick-component-cli/src/utils.rs +++ b/crates/wick/wick-component-cli/src/utils.rs @@ -29,20 +29,35 @@ pub fn parse_args(args: &[String], sig: &OperationSignature) -> Result { - if is_valid(value) { - coerce_string(name, value, input.ty())? - } else { - // if it's not valid JSON then it's a bare string. - value.into() + + let value = if value.starts_with('@') { + let path = value.trim_start_matches('@'); + + match input.ty() { + Type::String => Value::String(std::fs::read_to_string(path)?), + Type::Bytes => { + let bytes: wick_packet::Base64Bytes = std::fs::read(path)?.into(); + serde_json::to_value(bytes).unwrap() } + _ => encode(&std::fs::read_to_string(path)?), + } + } else { + match input.ty() { + // Datetime can be parsed from a string or a number but numbers need to be stringified. + // Strings must be explicit because a bare number will be parsed as a number. + Type::Datetime | Type::String => { + if is_valid(value) { + coerce_string(name, value, input.ty())? + } else { + // if it's not valid JSON then it's a bare string. + value.into() + } + } + // serde_json does an adequate job on the rest. + _ => encode(value), } - // serde_json does an adequate job on the rest. - _ => encode(value), }; + // Note on above: complex objects with embedded Datetime/Strings // may not be parsed correctly but that's an edge case we're ignoring for now. diff --git a/src/utils.rs b/src/utils.rs index b20af8a5..eaa08ecf 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -205,8 +205,16 @@ pub(crate) async fn print_stream_json( pub(crate) fn parse_config_string(source: Option<&str>) -> Result> { let component_config = match source { Some(c) => { - let config = serde_json::from_str::(c) - .map_err(|e| anyhow::anyhow!("Failed to parse config argument as JSON: {}", e))?; + let config = if c.starts_with('@') { + let path = c.trim_start_matches('@'); + let source = std::fs::read_to_string(path)?; + serde_json::from_str::(&source) + .map_err(|e| anyhow::anyhow!("Failed to parse {} as JSON: {}", path, e))? + } else { + serde_json::from_str::(c) + .map_err(|e| anyhow::anyhow!("Failed to parse config argument as JSON: {}", e))? + }; + let ctx = LiquidJsonConfig::make_context( None, None,