@@ -54,13 +54,7 @@ defmodule Plausible.Goal do
5454 |> validate_event_name_and_page_path ( )
5555 |> validate_page_path_for_scroll_goal ( )
5656 |> maybe_put_display_name ( )
57- |> validate_change ( :custom_props , fn :custom_props , custom_props ->
58- if map_size ( custom_props ) > @ max_custom_props_per_goal do
59- [ custom_props: "use at most #{ @ max_custom_props_per_goal } properties per goal" ]
60- else
61- [ ]
62- end
63- end )
57+ |> validate_change ( :custom_props , & validate_custom_props / 2 )
6458 |> unique_constraint ( :display_name , name: :goals_display_name_unique )
6559 |> unique_constraint ( :event_name , name: :goals_event_config_unique )
6660 |> unique_constraint ( [ :page_path , :scroll_threshold ] ,
@@ -183,6 +177,35 @@ defmodule Plausible.Goal do
183177 |> update_change ( :display_name , & String . trim / 1 )
184178 |> validate_required ( :display_name )
185179 end
180+
181+ defp validate_custom_props ( :custom_props , custom_props ) when is_map ( custom_props ) do
182+ cond do
183+ map_size ( custom_props ) > @ max_custom_props_per_goal ->
184+ [ custom_props: "use at most #{ @ max_custom_props_per_goal } properties per goal" ]
185+
186+ not Enum . all? ( custom_props , fn { k , v } ->
187+ is_binary ( k ) and is_binary ( v )
188+ end ) ->
189+ [ custom_props: "must be a map with string keys and string values" ]
190+
191+ Enum . any? ( custom_props , fn { k , _v } ->
192+ String . length ( k ) not in 1 .. Plausible.Props . max_prop_key_length ( )
193+ end ) ->
194+ [
195+ custom_props: "key length is 1..#{ Plausible.Props . max_prop_key_length ( ) } characters"
196+ ]
197+
198+ Enum . any? ( custom_props , fn { _k , v } ->
199+ String . length ( v ) not in 1 .. Plausible.Props . max_prop_value_length ( )
200+ end ) ->
201+ [
202+ custom_props: "value length is 1..#{ Plausible.Props . max_prop_value_length ( ) } characters"
203+ ]
204+
205+ true ->
206+ [ ]
207+ end
208+ end
186209end
187210
188211defimpl Jason.Encoder , for: Plausible.Goal do
@@ -191,7 +214,7 @@ defimpl Jason.Encoder, for: Plausible.Goal do
191214
192215 value
193216 |> Map . put ( :goal_type , Plausible.Goal . type ( value ) )
194- |> Map . take ( [ :id , :goal_type , :event_name , :page_path ] )
217+ |> Map . take ( [ :id , :goal_type , :event_name , :page_path , :custom_props ] )
195218 |> Map . put ( :domain , domain )
196219 |> Map . put ( :display_name , value . display_name )
197220 |> Jason.Encode . map ( opts )
0 commit comments