evva 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a759833afbdc6f48b186bce87555b4fae3da30812de523ddae04468244a7aee9
4
- data.tar.gz: 421625130a0be7491b0e49ea5b6cdb434b7cb3a6f7c52d20adf02ff6f11ca205
3
+ metadata.gz: 2ee0a5c710dfc85ab04a707bd4792bbab9a59c81aceff7394f6efe243c2deb5d
4
+ data.tar.gz: d53cec7c07687a96dc24c8fb65f8a32f2e523af19b51ef72f7558fb2c8068dc6
5
5
  SHA512:
6
- metadata.gz: a9bd2cc069ab15eed7a02c6ed444f22579236446a7a3b7b9c1772df26deefaf442dd568334ab0903059f056a65fc1a7ceadb3e6fd6df1975a6d097ab7bffeca8
7
- data.tar.gz: d8f1f9574a97f4060924514d99102abcdad78d71d75cd0a378bb94423f1cd359de171908fe11c8579370035ddab2a31eb0e429e8a27b27aef1b56cd12ba9de92
6
+ metadata.gz: 6b7267254416b123602b3d5f3ba7c5d0577d255b981ba9404ab28e2e02dcebc0d8f08f4373af847508502c5a0d41cb3f05733b98a98d79f0c226b871f1eae607
7
+ data.tar.gz: 80ee70c43aec3f46304afc0647446f25cf874acc9a60f48521adb292918936c9fba62f127079daa7a97956d279470a324f30fb3ca7fa12de654c4a166c6451ad
data/Gemfile.lock CHANGED
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- evva (0.9.0)
4
+ evva (0.11.0)
5
5
  colorize (~> 1.0)
6
- csv (>= 3.0)
6
+ csv (~> 3.0)
7
7
  safe_yaml (~> 1.0)
8
8
 
9
9
  GEM
data/changelog.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.11.0] - 2026-11-09
6
+
7
+ - **Breaking:** Kotlin enum constants (events, people properties, special property enums and destinations) are now generated in PascalCase, e.g. `RoundStarted` instead of `ROUND_STARTED`. The `key` values are unchanged
8
+
9
+ ## [0.10.0] - 2026-10-13
10
+
11
+ - Support optional people properties in Kotlin: `innerValue` is now `Any?` and optional special properties use `value?.key`
12
+
5
13
  ## [0.9.0] - 2026-09-04
6
14
 
7
15
  - Add `Platform` column support in the events sheet and `filter_by_platforms` configuration to filter generated events by platform
@@ -47,11 +47,11 @@ module Evva
47
47
  }
48
48
  end
49
49
 
50
- destinations = event.destinations.map { |p| constantize(p) }
50
+ destinations = event.destinations.map { |p| pascalize(p) }
51
51
 
52
52
  {
53
53
  class_name: camelize(event.event_name),
54
- event_name: constantize(event.event_name),
54
+ event_name: pascalize(event.event_name),
55
55
  properties: properties,
56
56
  destinations: destinations
57
57
  }
@@ -67,7 +67,7 @@ module Evva
67
67
 
68
68
  events = bundle.map(&:event_name).map do |event_name|
69
69
  {
70
- name: constantize(event_name),
70
+ name: pascalize(event_name),
71
71
  value: event_name,
72
72
  }
73
73
  end
@@ -84,12 +84,22 @@ module Evva
84
84
 
85
85
  properties = people_bundle.map do |property|
86
86
  type = native_type(property.type)
87
+ value_fetcher = "value"
88
+
89
+ if special_property?(type)
90
+ if type.end_with?("?")
91
+ # optional value, we need ? to access a parameter
92
+ value_fetcher += "?"
93
+ end
94
+ value_fetcher += ".key"
95
+ end
96
+
87
97
  {
88
98
  class_name: camelize(property.property_name),
89
- property_name: constantize(property.property_name),
99
+ property_name: pascalize(property.property_name),
90
100
  type: type,
91
- is_special_property: special_property?(property.type),
92
- destinations: property.destinations.map { |p| constantize(p) },
101
+ value_fetcher: value_fetcher,
102
+ destinations: property.destinations.map { |p| pascalize(p) },
93
103
  }
94
104
  end
95
105
 
@@ -103,7 +113,7 @@ module Evva
103
113
 
104
114
  properties = people_bundle.map(&:property_name).map do |property_name|
105
115
  {
106
- name: constantize(property_name),
116
+ name: pascalize(property_name),
107
117
  value: property_name,
108
118
  }
109
119
  end
@@ -117,7 +127,7 @@ module Evva
117
127
  enums = enums_bundle.map do |enum|
118
128
  values = enum.values.map do |value|
119
129
  {
120
- name: constantize(value),
130
+ name: pascalize(value),
121
131
  value: value,
122
132
  }
123
133
  end
@@ -136,7 +146,7 @@ module Evva
136
146
  header_footer_wrapper do
137
147
  class_name = file_name
138
148
 
139
- destinations = bundle.map { |d| constantize(d) }
149
+ destinations = bundle.map { |d| pascalize(d) }
140
150
 
141
151
  template_from(DESTINATIONS_TEMPLATE).result(binding)
142
152
  end
@@ -171,8 +181,9 @@ module Evva
171
181
  string.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }.gsub("/", "::")
172
182
  end
173
183
 
174
- def constantize(string)
175
- string.tr(" ", "_").upcase
184
+ def pascalize(string)
185
+ name = string.to_s.split(/[^\p{Alnum}]+/).map(&:capitalize).join
186
+ name.match?(/\A\p{L}/) ? name : "_#{name}"
176
187
  end
177
188
 
178
189
  def native_type(type)
@@ -1,6 +1,6 @@
1
1
  sealed class <%= class_name %>(
2
2
  property: <%= enums_class_name %>,
3
- val innerValue: Any,
3
+ val innerValue: Any?,
4
4
  val destinations: Array<<%= destinations_class_name %>> = emptyArray(),
5
5
  ) {
6
6
  val name = property.key
@@ -10,7 +10,7 @@ sealed class <%= class_name %>(
10
10
  val value: <%= property[:type] %>,
11
11
  ) : <%= class_name %>(
12
12
  property = <%= enums_class_name %>.<%= property[:property_name] %>,
13
- innerValue = value<% if property[:is_special_property] %>.key<% end %>,
13
+ innerValue = <%= property[:value_fetcher] %>,
14
14
  <%- if property[:destinations].count > 0 -%>
15
15
  destinations = arrayOf(
16
16
  <%- property[:destinations].each_with_index do |d, index| -%>
data/lib/evva/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Evva
2
- VERSION = "0.9.0".freeze
3
- VERSION_UPDATED_AT = "2026-09-04".freeze
2
+ VERSION = "0.11.0".freeze
3
+ VERSION_UPDATED_AT = "2026-11-09".freeze
4
4
  end
@@ -29,13 +29,13 @@ sealed class AnalyticsEvent(
29
29
  val name = event.key
30
30
 
31
31
  data object CpPageView : AnalyticsEvent(
32
- event = AnalyticsEvents.CP_PAGE_VIEW,
32
+ event = AnalyticsEvents.CpPageView,
33
33
  )
34
34
 
35
35
  data object CpPageView2 : AnalyticsEvent(
36
- event = AnalyticsEvents.CP_PAGE_VIEW_2,
36
+ event = AnalyticsEvents.CpPageView2,
37
37
  destinations = arrayOf(
38
- AnalyticsDestinations.FIREBASE,
38
+ AnalyticsDestinations.Firebase,
39
39
  ),
40
40
  )
41
41
 
@@ -43,14 +43,14 @@ sealed class AnalyticsEvent(
43
43
  val courseId: Long,
44
44
  val courseName: String,
45
45
  ) : AnalyticsEvent(
46
- event = AnalyticsEvents.CP_PAGE_VIEW_A,
46
+ event = AnalyticsEvents.CpPageViewA,
47
47
  properties = mapOf(
48
48
  "course_id" to courseId,
49
49
  "course_name" to courseName,
50
50
  ),
51
51
  destinations = arrayOf(
52
- AnalyticsDestinations.FIREBASE,
53
- AnalyticsDestinations.CUSTOM_DESTINATION,
52
+ AnalyticsDestinations.Firebase,
53
+ AnalyticsDestinations.CustomDestination,
54
54
  ),
55
55
  )
56
56
 
@@ -59,14 +59,14 @@ sealed class AnalyticsEvent(
59
59
  val courseName: String,
60
60
  val fromScreen: CourseProfileSource,
61
61
  ) : AnalyticsEvent(
62
- event = AnalyticsEvents.CP_PAGE_VIEW_B,
62
+ event = AnalyticsEvents.CpPageViewB,
63
63
  properties = mapOf(
64
64
  "course_id" to courseId,
65
65
  "course_name" to courseName,
66
66
  "from_screen" to fromScreen.key,
67
67
  ),
68
68
  destinations = arrayOf(
69
- AnalyticsDestinations.FIREBASE,
69
+ AnalyticsDestinations.Firebase,
70
70
  ),
71
71
  )
72
72
 
@@ -75,7 +75,7 @@ sealed class AnalyticsEvent(
75
75
  val courseName: String,
76
76
  val fromScreen: CourseProfileSource?,
77
77
  ) : AnalyticsEvent(
78
- event = AnalyticsEvents.CP_PAGE_VIEW_C,
78
+ event = AnalyticsEvents.CpPageViewC,
79
79
  properties = mapOf(
80
80
  "course_id" to courseId,
81
81
  "course_name" to courseName,
@@ -88,7 +88,7 @@ sealed class AnalyticsEvent(
88
88
  val courseName: String,
89
89
  val viewedAt: String,
90
90
  ) : AnalyticsEvent(
91
- event = AnalyticsEvents.CP_PAGE_VIEW_D,
91
+ event = AnalyticsEvents.CpPageViewD,
92
92
  properties = mapOf(
93
93
  "course_id" to courseId,
94
94
  "course_name" to courseName,
@@ -106,7 +106,7 @@ Kotlin
106
106
  subject { generator.special_property_enums(enums) }
107
107
  let(:enums) { [
108
108
  Evva::AnalyticsEnum.new("CourseProfileSource", ["course_discovery", "synced_courses"]),
109
- Evva::AnalyticsEnum.new("PremiumFrom", ["Course Profile", "Round Setup"]),
109
+ Evva::AnalyticsEnum.new("PremiumFrom", ["Course Profile", "Round Setup", "PAYWALL", "push-notification v2"]),
110
110
  ] }
111
111
  let(:expected) {
112
112
  <<-Kotlin
@@ -117,17 +117,37 @@ package com.hole19golf.hole19.analytics
117
117
  */
118
118
 
119
119
  enum class CourseProfileSource(val key: String) {
120
- COURSE_DISCOVERY("course_discovery"),
121
- SYNCED_COURSES("synced_courses"),
120
+ CourseDiscovery("course_discovery"),
121
+ SyncedCourses("synced_courses"),
122
122
  }
123
123
 
124
124
  enum class PremiumFrom(val key: String) {
125
- COURSE_PROFILE("Course Profile"),
126
- ROUND_SETUP("Round Setup"),
125
+ CourseProfile("Course Profile"),
126
+ RoundSetup("Round Setup"),
127
+ Paywall("PAYWALL"),
128
+ PushNotificationV2("push-notification v2"),
127
129
  }
128
130
  Kotlin
129
131
  }
130
132
  it { should eq expected }
133
+
134
+ context "when values do not start with a letter or use non-ASCII letters" do
135
+ let(:enums) { [
136
+ Evva::AnalyticsEnum.new("HoleCount", ["9 holes", "_2fa", "日本語"]),
137
+ ] }
138
+
139
+ let(:expected_enum) {
140
+ <<-Kotlin
141
+ enum class HoleCount(val key: String) {
142
+ _9Holes("9 holes"),
143
+ _2fa("_2fa"),
144
+ 日本語("日本語"),
145
+ }
146
+ Kotlin
147
+ }
148
+
149
+ it { should include expected_enum }
150
+ end
131
151
  end
132
152
 
133
153
  describe "#event_enum" do
@@ -145,8 +165,8 @@ package com.hole19golf.hole19.analytics
145
165
  */
146
166
 
147
167
  enum class AnalyticsEvents(val key: String) {
148
- NAV_FEED_TAP("nav_feed_tap"),
149
- NAV_PERFORMANCE_TAP("nav_performance_tap"),
168
+ NavFeedTap("nav_feed_tap"),
169
+ NavPerformanceTap("nav_performance_tap"),
150
170
  }
151
171
  Kotlin
152
172
  }
@@ -156,9 +176,10 @@ Kotlin
156
176
  describe "#people_properties" do
157
177
  subject { generator.people_properties(people_bundle, "AnalyticsProperty", "AnalyticsProperties", "AnalyticsDestinations") }
158
178
  let(:people_bundle) { [
159
- Evva::AnalyticsProperty.new("rounds_with_wear", "String", []),
179
+ Evva::AnalyticsProperty.new("rounds_with_wear", "String?", []),
160
180
  Evva::AnalyticsProperty.new("last_active_at", "Date", []),
161
- Evva::AnalyticsProperty.new("wear_platform", "WearableAppPlatform", ["firebase", "custom destination"]),
181
+ Evva::AnalyticsProperty.new("upgrade_source", "PremiumFrom", []),
182
+ Evva::AnalyticsProperty.new("wear_platform", "WearableAppPlatform?", ["firebase", "custom destination"]),
162
183
  ] }
163
184
  let(:expected) {
164
185
  <<-Kotlin
@@ -170,33 +191,40 @@ package com.hole19golf.hole19.analytics
170
191
 
171
192
  sealed class AnalyticsProperty(
172
193
  property: AnalyticsProperties,
173
- val innerValue: Any,
194
+ val innerValue: Any?,
174
195
  val destinations: Array<AnalyticsDestinations> = emptyArray(),
175
196
  ) {
176
197
  val name = property.key
177
198
 
178
199
  data class RoundsWithWear(
179
- val value: String,
200
+ val value: String?,
180
201
  ) : AnalyticsProperty(
181
- property = AnalyticsProperties.ROUNDS_WITH_WEAR,
202
+ property = AnalyticsProperties.RoundsWithWear,
182
203
  innerValue = value,
183
204
  )
184
205
 
185
206
  data class LastActiveAt(
186
207
  val value: String,
187
208
  ) : AnalyticsProperty(
188
- property = AnalyticsProperties.LAST_ACTIVE_AT,
209
+ property = AnalyticsProperties.LastActiveAt,
189
210
  innerValue = value,
190
211
  )
191
212
 
192
- data class WearPlatform(
193
- val value: WearableAppPlatform,
213
+ data class UpgradeSource(
214
+ val value: PremiumFrom,
194
215
  ) : AnalyticsProperty(
195
- property = AnalyticsProperties.WEAR_PLATFORM,
216
+ property = AnalyticsProperties.UpgradeSource,
196
217
  innerValue = value.key,
218
+ )
219
+
220
+ data class WearPlatform(
221
+ val value: WearableAppPlatform?,
222
+ ) : AnalyticsProperty(
223
+ property = AnalyticsProperties.WearPlatform,
224
+ innerValue = value?.key,
197
225
  destinations = arrayOf(
198
- AnalyticsDestinations.FIREBASE,
199
- AnalyticsDestinations.CUSTOM_DESTINATION,
226
+ AnalyticsDestinations.Firebase,
227
+ AnalyticsDestinations.CustomDestination,
200
228
  ),
201
229
  )
202
230
  }
@@ -221,8 +249,8 @@ package com.hole19golf.hole19.analytics
221
249
  */
222
250
 
223
251
  enum class AnalyticsProperties(val key: String) {
224
- ROUNDS_WITH_WEAR("rounds_with_wear"),
225
- WEAR_PLATFORM("wear_platform"),
252
+ RoundsWithWear("rounds_with_wear"),
253
+ WearPlatform("wear_platform"),
226
254
  }
227
255
  Kotlin
228
256
  }
@@ -244,8 +272,8 @@ package com.hole19golf.hole19.analytics
244
272
  */
245
273
 
246
274
  enum class AnalyticsDestinations {
247
- FIREBASE,
248
- WHATEVER_YOU_WANT_REALLY,
275
+ Firebase,
276
+ WhateverYouWantReally,
249
277
  }
250
278
  Kotlin
251
279
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: evva
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - André Andrade
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2026-09-04 00:00:00.000000000 Z
13
+ date: 2026-11-09 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: colorize