diff --git a/Gemfile.lock b/Gemfile.lock index 9b14156..fd5a943 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,7 +3,7 @@ PATH specs: evva (0.9.0) colorize (~> 1.0) - csv (>= 3.0) + csv (~> 3.0) safe_yaml (~> 1.0) GEM diff --git a/changelog.md b/changelog.md index 34e2976..75d53a2 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,8 @@ ## [Unreleased] +- Support optional people properties in Kotlin: `innerValue` is now `Any?` and optional special properties use `value?.key` + ## [0.9.0] - 2026-09-04 - Add `Platform` column support in the events sheet and `filter_by_platforms` configuration to filter generated events by platform diff --git a/lib/evva/kotlin_generator.rb b/lib/evva/kotlin_generator.rb index cfbaab3..aec8e25 100644 --- a/lib/evva/kotlin_generator.rb +++ b/lib/evva/kotlin_generator.rb @@ -84,11 +84,21 @@ def people_properties(people_bundle, file_name, enums_file_name, destinations_fi properties = people_bundle.map do |property| type = native_type(property.type) + value_fetcher = "value" + + if special_property?(type) + if type.end_with?("?") + # optional value, we need ? to access a parameter + value_fetcher += "?" + end + value_fetcher += ".key" + end + { class_name: camelize(property.property_name), property_name: constantize(property.property_name), type: type, - is_special_property: special_property?(property.type), + value_fetcher: value_fetcher, destinations: property.destinations.map { |p| constantize(p) }, } end diff --git a/lib/evva/templates/kotlin/people_properties.kt b/lib/evva/templates/kotlin/people_properties.kt index 4d3dd85..a47a8a2 100644 --- a/lib/evva/templates/kotlin/people_properties.kt +++ b/lib/evva/templates/kotlin/people_properties.kt @@ -1,6 +1,6 @@ sealed class <%= class_name %>( property: <%= enums_class_name %>, - val innerValue: Any, + val innerValue: Any?, val destinations: Array<<%= destinations_class_name %>> = emptyArray(), ) { val name = property.key @@ -10,7 +10,7 @@ sealed class <%= class_name %>( val value: <%= property[:type] %>, ) : <%= class_name %>( property = <%= enums_class_name %>.<%= property[:property_name] %>, - innerValue = value<% if property[:is_special_property] %>.key<% end %>, + innerValue = <%= property[:value_fetcher] %>, <%- if property[:destinations].count > 0 -%> destinations = arrayOf( <%- property[:destinations].each_with_index do |d, index| -%> diff --git a/spec/lib/evva/kotlin_generator_spec.rb b/spec/lib/evva/kotlin_generator_spec.rb index 2ff6dad..a6f6974 100644 --- a/spec/lib/evva/kotlin_generator_spec.rb +++ b/spec/lib/evva/kotlin_generator_spec.rb @@ -156,9 +156,10 @@ describe "#people_properties" do subject { generator.people_properties(people_bundle, "AnalyticsProperty", "AnalyticsProperties", "AnalyticsDestinations") } let(:people_bundle) { [ - Evva::AnalyticsProperty.new("rounds_with_wear", "String", []), + Evva::AnalyticsProperty.new("rounds_with_wear", "String?", []), Evva::AnalyticsProperty.new("last_active_at", "Date", []), - Evva::AnalyticsProperty.new("wear_platform", "WearableAppPlatform", ["firebase", "custom destination"]), + Evva::AnalyticsProperty.new("upgrade_source", "PremiumFrom", []), + Evva::AnalyticsProperty.new("wear_platform", "WearableAppPlatform?", ["firebase", "custom destination"]), ] } let(:expected) { <<-Kotlin @@ -170,13 +171,13 @@ sealed class AnalyticsProperty( property: AnalyticsProperties, - val innerValue: Any, + val innerValue: Any?, val destinations: Array = emptyArray(), ) { val name = property.key data class RoundsWithWear( - val value: String, + val value: String?, ) : AnalyticsProperty( property = AnalyticsProperties.ROUNDS_WITH_WEAR, innerValue = value, @@ -189,11 +190,18 @@ innerValue = value, ) + data class UpgradeSource( + val value: PremiumFrom, + ) : AnalyticsProperty( + property = AnalyticsProperties.UPGRADE_SOURCE, + innerValue = value.key, + ) + data class WearPlatform( - val value: WearableAppPlatform, + val value: WearableAppPlatform?, ) : AnalyticsProperty( property = AnalyticsProperties.WEAR_PLATFORM, - innerValue = value.key, + innerValue = value?.key, destinations = arrayOf( AnalyticsDestinations.FIREBASE, AnalyticsDestinations.CUSTOM_DESTINATION,