@@ -33,10 +33,12 @@ use crate::{
3333 Component ,
3434 DalContext ,
3535 Func ,
36+ Prop ,
3637 PropKind ,
3738 WsEvent ,
3839 component:: resource:: ResourceData ,
3940 func:: intrinsics:: IntrinsicFunc ,
41+ prop:: PropError ,
4042 workspace_snapshot:: node_weight:: {
4143 NodeWeight ,
4244 reason_node_weight:: Reason ,
@@ -60,10 +62,16 @@ pub enum AttributesError {
6062 AttributeValue ( #[ from] crate :: attribute:: value:: AttributeValueError ) ,
6163 #[ error( "attribute value {0} not from component {1}" ) ]
6264 AttributeValueNotFromComponent ( AttributeValueId , ComponentId ) ,
65+ #[ error(
66+ "cannot update create-only property at path '{0}' when component has a resource attached"
67+ ) ]
68+ CannotUpdateCreateOnlyProperty ( String ) ,
6369 #[ error( "component error: {0}" ) ]
6470 Component ( #[ from] crate :: ComponentError ) ,
6571 #[ error( "func error: {0}" ) ]
6672 Func ( #[ from] crate :: FuncError ) ,
73+ #[ error( "prop error: {0}" ) ]
74+ Prop ( #[ from] PropError ) ,
6775 #[ error( "serde json error: {0}" ) ]
6876 SerdeJson ( #[ from] serde_json:: Error ) ,
6977 #[ error( "source component not found: {0}" ) ]
@@ -214,6 +222,17 @@ pub async fn update_attributes_without_validation(
214222 update_attributes_inner ( ctx, component_id, updates) . await
215223}
216224
225+ /// Helper function to check if a prop has the "si_create_only_prop" widget option
226+ fn is_create_only_prop ( prop : & Prop ) -> bool {
227+ if let Some ( widget_options) = & prop. widget_options {
228+ widget_options
229+ . iter ( )
230+ . any ( |option| option. label ( ) == "si_create_only_prop" )
231+ } else {
232+ false
233+ }
234+ }
235+
217236async fn get_before_prop_value_source (
218237 ctx : & DalContext ,
219238 av_id : AttributeValueId ,
@@ -278,6 +297,20 @@ async fn update_attributes_inner(
278297 // Create the attribute at the given pa th if it does not exist
279298 let path = av_to_set. path ( ) ;
280299 let target_av_id = av_to_set. clone ( ) . vivify ( ctx, component_id) . await ?;
300+
301+ // Check if this is a create-only property and component has a resource
302+ let prop_id = AttributeValue :: prop_id ( ctx, target_av_id) . await ?;
303+ let prop = Prop :: get_by_id ( ctx, prop_id) . await ?;
304+ if is_create_only_prop ( & prop)
305+ && Component :: resource_by_id ( ctx, component_id)
306+ . await ?
307+ . is_some ( )
308+ {
309+ return Err ( AttributesError :: CannotUpdateCreateOnlyProperty (
310+ path. to_string ( ) ,
311+ ) ) ;
312+ }
313+
281314 let before_value_source = get_before_prop_value_source ( ctx, target_av_id) . await ?;
282315 let mut after_value_source: Option < PropValueSource > = None ;
283316
0 commit comments