diff --git a/lib/components/fabro-tool/src/workflow_version.rs b/lib/components/fabro-tool/src/workflow_version.rs index 8adb193f8..38be81c8b 100644 --- a/lib/components/fabro-tool/src/workflow_version.rs +++ b/lib/components/fabro-tool/src/workflow_version.rs @@ -21,8 +21,9 @@ pub struct FabroWorkflowVersionCreateParams { #[schemars(with = "String")] pub entrypoint: WorkflowPath, /// All local dependencies, keyed by package-relative path. Values are text - /// contents. - #[serde(deserialize_with = "fabro_types::deserialize_unique_map")] + /// contents. Tool arguments arrive as an already-parsed JSON value on + /// every production route, so duplicate keys have collapsed (last wins) + /// before this type sees them; there is no byte-level guard to add here. #[schemars(with = "BTreeMap")] pub files: BTreeMap, } @@ -127,12 +128,6 @@ mod tests { fn workflow_version_request_rejects_unknown_fields_and_invalid_paths() { let valid = json!({"entrypoint": "workflow", "files": {"workflow": "digraph W {}"}}); validate(valid.clone()).unwrap(); - assert!( - serde_json::from_str::( - r#"{"entrypoint":"workflow","files":{"workflow":"a","workflow":"b"}}"# - ) - .is_err() - ); for field in [ "cwd", "url", diff --git a/lib/foundation/fabro-types/src/lib.rs b/lib/foundation/fabro-types/src/lib.rs index a398b827b..e678a8a1f 100644 --- a/lib/foundation/fabro-types/src/lib.rs +++ b/lib/foundation/fabro-types/src/lib.rs @@ -197,7 +197,7 @@ pub use workflow_path::{ }; pub use workflow_version::{ MAX_WORKFLOW_VERSION_BYTES, MAX_WORKFLOW_VERSION_DEPENDENCIES, MAX_WORKFLOW_VERSION_FILE_BYTES, - MAX_WORKFLOW_VERSION_FILES, WorkflowVersion, WorkflowVersionShapeError, deserialize_unique_map, + MAX_WORKFLOW_VERSION_FILES, WorkflowVersion, WorkflowVersionShapeError, validate_workflow_source_paths, }; pub use workflow_version_id::{WorkflowVersionId, WorkflowVersionIdParseError}; diff --git a/lib/foundation/fabro-types/src/workflow_version.rs b/lib/foundation/fabro-types/src/workflow_version.rs index 297e485d6..a957f1b36 100644 --- a/lib/foundation/fabro-types/src/workflow_version.rs +++ b/lib/foundation/fabro-types/src/workflow_version.rs @@ -236,17 +236,6 @@ impl<'de> Deserialize<'de> for WorkflowVersion { } } -/// Deserialize a map while rejecting duplicate keys, which serde would -/// otherwise silently collapse to the last value. -pub fn deserialize_unique_map<'de, D, K, V>(deserializer: D) -> Result, D::Error> -where - D: Deserializer<'de>, - K: Deserialize<'de> + Ord + fmt::Display, - V: Deserialize<'de>, -{ - UniqueBTreeMap::deserialize(deserializer).map(|map| map.0) -} - struct UniqueBTreeMap(BTreeMap); impl<'de, K, V> Deserialize<'de> for UniqueBTreeMap