strava-ruby-client 2.3.0 → 3.0.0.pre.1

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.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +60 -48
  3. data/LICENSE.md +1 -1
  4. data/README.md +100 -80
  5. data/bin/strava-activities.rb +2 -0
  6. data/bin/strava-oauth-token +43 -35
  7. data/bin/strava-refresh-token +32 -0
  8. data/lib/strava/api/client.rb +46 -6
  9. data/lib/strava/api/cursor.rb +26 -2
  10. data/lib/strava/api/endpoints/activities.rb +10 -7
  11. data/lib/strava/api/endpoints/athletes.rb +2 -2
  12. data/lib/strava/api/endpoints/clubs.rb +5 -5
  13. data/lib/strava/api/endpoints/gears.rb +1 -1
  14. data/lib/strava/api/endpoints/segment_efforts.rb +2 -2
  15. data/lib/strava/api/endpoints/segments.rb +3 -3
  16. data/lib/strava/api/pagination.rb +1 -2
  17. data/lib/strava/models/achievement.rb +1 -0
  18. data/lib/strava/models/activity_stats.rb +1 -0
  19. data/lib/strava/models/activity_total.rb +5 -9
  20. data/lib/strava/models/activity_zone.rb +4 -1
  21. data/lib/strava/models/base_stream.rb +12 -0
  22. data/lib/strava/models/club_activity.rb +22 -0
  23. data/lib/strava/models/{club_member.rb → club_athlete.rb} +5 -2
  24. data/lib/strava/models/club_event.rb +6 -4
  25. data/lib/strava/models/comment.rb +7 -2
  26. data/lib/strava/models/destination.rb +12 -0
  27. data/lib/strava/models/{activity.rb → detailed_activity.rb} +51 -103
  28. data/lib/strava/models/{athlete.rb → detailed_athlete.rb} +20 -14
  29. data/lib/strava/models/{club.rb → detailed_club.rb} +10 -3
  30. data/lib/strava/models/{gear.rb → detailed_gear.rb} +10 -7
  31. data/lib/strava/models/{photo.rb → detailed_photo.rb} +13 -5
  32. data/lib/strava/models/{photos.rb → detailed_photos.rb} +2 -1
  33. data/lib/strava/models/{segment.rb → detailed_segment.rb} +18 -24
  34. data/lib/strava/models/{segment_effort.rb → detailed_segment_effort.rb} +23 -17
  35. data/lib/strava/models/explorer_segment.rb +8 -5
  36. data/lib/strava/models/heart_rate_zone_ranges.rb +1 -0
  37. data/lib/strava/models/kudoser.rb +1 -0
  38. data/lib/strava/models/lap.rb +18 -16
  39. data/lib/strava/models/lat_lng.rb +46 -0
  40. data/lib/strava/models/local_legend.rb +16 -0
  41. data/lib/strava/models/meta_activity.rb +13 -0
  42. data/lib/strava/models/meta_athlete.rb +14 -0
  43. data/lib/strava/models/meta_club.rb +12 -0
  44. data/lib/strava/models/mixins/{time.rb → average_speed.rb} +6 -29
  45. data/lib/strava/models/mixins/elapsed_time.rb +20 -0
  46. data/lib/strava/models/mixins/elevation_difference.rb +39 -0
  47. data/lib/strava/models/mixins/elevation_gain.rb +39 -0
  48. data/lib/strava/models/mixins/estimated_moving_time.rb +20 -0
  49. data/lib/strava/models/mixins/moving_time.rb +20 -0
  50. data/lib/strava/models/mixins/sport_type.rb +73 -0
  51. data/lib/strava/models/mixins/time_in_hours.rb +26 -0
  52. data/lib/strava/models/mixins/{elevation.rb → total_elevation_gain.rb} +1 -1
  53. data/lib/strava/models/photos_summary.rb +12 -0
  54. data/lib/strava/models/photos_summary_primary.rb +15 -0
  55. data/lib/strava/models/power_zone_ranges.rb +1 -0
  56. data/lib/strava/models/route.rb +14 -13
  57. data/lib/strava/models/similar_activities.rb +2 -0
  58. data/lib/strava/models/split.rb +8 -6
  59. data/lib/strava/models/stats_visibility.rb +11 -0
  60. data/lib/strava/models/stream_set.rb +2 -1
  61. data/lib/strava/models/summary_activity.rb +71 -0
  62. data/lib/strava/models/summary_athlete.rb +31 -0
  63. data/lib/strava/models/summary_club.rb +34 -0
  64. data/lib/strava/models/summary_gear.rb +18 -0
  65. data/lib/strava/models/summary_pr_segment_effort.rb +16 -0
  66. data/lib/strava/models/summary_segment.rb +34 -0
  67. data/lib/strava/models/summary_segment_effort.rb +16 -0
  68. data/lib/strava/models/timed_zone_range.rb +1 -0
  69. data/lib/strava/models/token.rb +1 -1
  70. data/lib/strava/models/trend.rb +1 -0
  71. data/lib/strava/models/updatable_activity.rb +16 -0
  72. data/lib/strava/models/upload.rb +2 -0
  73. data/lib/strava/models/waypoint.rb +15 -0
  74. data/lib/strava/models/xoms.rb +13 -0
  75. data/lib/strava/models/zone_range.rb +1 -0
  76. data/lib/strava/models/zones.rb +1 -0
  77. data/lib/strava/version.rb +1 -1
  78. data/lib/strava/webhooks/models/event.rb +1 -1
  79. data/lib/strava-ruby-client.rb +55 -30
  80. metadata +47 -18
  81. data/lib/strava/api/endpoints/running_races.rb +0 -20
  82. data/lib/strava/models/club_admin.rb +0 -15
  83. data/lib/strava/models/running_race.rb +0 -35
  84. data/lib/strava/models/segment_stats.rb +0 -17
@@ -8,7 +8,6 @@ module Strava
8
8
  include Endpoints::Clubs
9
9
  include Endpoints::Gears
10
10
  include Endpoints::Routes
11
- include Endpoints::RunningRaces
12
11
  include Endpoints::SegmentEfforts
13
12
  include Endpoints::Segments
14
13
  include Endpoints::Streams
@@ -41,7 +40,7 @@ module Strava
41
40
  private
42
41
 
43
42
  #
44
- # paginates requests
43
+ # Paginates requests using per_page.
45
44
  #
46
45
  # @param [String] path url for request
47
46
  # @param [Hash] options hash containing settings
@@ -52,21 +51,62 @@ module Strava
52
51
  #
53
52
  # @return [Strava::Api::Pagination]
54
53
  #
55
- def paginate(path, options, model)
54
+ def paginate(path, options, model, &block)
55
+ raise ArgumentError, 'per_page' if options.key(:page_size)
56
+
57
+ paginate_with_cursor(path, options, model, &block)
58
+ end
59
+
60
+ #
61
+ # Paginates requests using a cursor, using per_page or page_size.
62
+ #
63
+ # @param [String] path url for request
64
+ # @param [Hash] options hash containing settings
65
+ # @param [Class] model by Class
66
+ #
67
+ # @example
68
+ # paginate("activity/comments", {page_size: 72}, Strava::Models::Comment)
69
+ # paginate("athlete/activities", {per_page: 72}, Strava::Models::Activity)
70
+ #
71
+ # @return [Strava::Api::Pagination]
72
+ #
73
+ def paginate_with_cursor(path, options, model)
74
+ # avoid retrieving unnecessary items
75
+ if options.key?(:limit)
76
+ if options.key?(:per_page) && options[:per_page] > options[:limit]
77
+ options = options.merge(per_page: options[:limit])
78
+ elsif options.key?(:page_size) && options[:page_size] > options[:limit]
79
+ options = options.merge(page_size: options[:limit])
80
+ end
81
+ end
82
+
56
83
  collection = []
57
84
  web_response = nil
58
- if block_given?
85
+
86
+ if block_given? || options.key?(:page_size) || options.key?(:per_page)
59
87
  Cursor.new(self, path, options).each do |page|
60
88
  web_response = page # response of the last request made
61
89
  page.each do |row|
90
+ break if options.key?(:limit) && collection.size >= options[:limit]
91
+
62
92
  m = model.new(row)
63
- yield m
93
+ yield m if block_given?
64
94
  collection << m
65
95
  end
96
+ break if options.key?(:limit) && collection.size >= options[:limit]
66
97
  end
67
98
  else
68
- web_response = get(path, options)
99
+ page_options = if options.key?(:limit)
100
+ options.dup.tap do |copy|
101
+ copy[:page_size] = copy.delete(:limit)
102
+ end
103
+ else
104
+ options
105
+ end
106
+ web_response = get(path, page_options)
69
107
  collection = web_response.map do |row|
108
+ break if options.key?(:limit) && collection.size >= options[:limit]
109
+
70
110
  model.new(row)
71
111
  end
72
112
  end
@@ -10,10 +10,16 @@ module Strava
10
10
  def initialize(client, path, params = {})
11
11
  @client = client
12
12
  @path = path
13
- @params = params
13
+ @params = params.key?(:limit) ? params.dup.tap { |p| p.delete :limit } : params
14
14
  end
15
15
 
16
- def each
16
+ def each(&block)
17
+ params[:page_size] ? each_cursor(&block) : each_page(&block)
18
+ end
19
+
20
+ private
21
+
22
+ def each_page
17
23
  next_page = 1
18
24
  loop do
19
25
  query = params.merge(page: next_page)
@@ -24,6 +30,24 @@ module Strava
24
30
  next_page += 1
25
31
  end
26
32
  end
33
+
34
+ def each_cursor
35
+ cursor = nil
36
+ query = params
37
+ loop do
38
+ response = client.get(path, query)
39
+ break unless response.any?
40
+
41
+ yield response
42
+
43
+ break if response.size < params[:page_size]
44
+
45
+ cursor = response.last&.[]('cursor')
46
+ break unless cursor.present?
47
+
48
+ query = params.merge(after_cursor: cursor)
49
+ end
50
+ end
27
51
  end
28
52
  end
29
53
  end
@@ -8,7 +8,7 @@ module Strava
8
8
  # Create an activity.
9
9
  #
10
10
  def create_activity(options = {})
11
- Strava::Models::Activity.new(post('activities', options))
11
+ Strava::Models::DetailedActivity.new(post('activities', options))
12
12
  end
13
13
 
14
14
  #
@@ -19,7 +19,7 @@ module Strava
19
19
  #
20
20
  def activity(id_or_options, options = {})
21
21
  id, options = parse_args(id_or_options, options)
22
- Strava::Models::Activity.new(get("activities/#{id}", options))
22
+ Strava::Models::DetailedActivity.new(get("activities/#{id}", options))
23
23
  end
24
24
 
25
25
  #
@@ -29,12 +29,15 @@ module Strava
29
29
  # Activity id.
30
30
  # @option options [Integer] :page
31
31
  # Page number.
32
+ # @option options [Integer] :page_size
33
+ # Number of items per page. Defaults to 30.
32
34
  # @option options [Integer] :per_page
33
35
  # Number of items per page. Defaults to 30.
36
+ # @deprecated use {page_size}
34
37
  #
35
38
  def activity_comments(id_or_options, options = {}, &block)
36
39
  id, options = parse_args(id_or_options, options)
37
- paginate "activities/#{id}/comments", options, Strava::Models::Comment, &block
40
+ paginate_with_cursor "activities/#{id}/comments", options, Strava::Models::Comment, &block
38
41
  end
39
42
 
40
43
  #
@@ -50,7 +53,7 @@ module Strava
50
53
  def activity_photos(id_or_options, options = {}, &block)
51
54
  id, options = parse_args(id_or_options, options)
52
55
  options[:size] = 5000 unless options[:size] # to retrieve full size photos
53
- paginate "activities/#{id}/photos", options, Strava::Models::Photo, &block
56
+ paginate "activities/#{id}/photos", options, Strava::Models::DetailedPhoto, &block
54
57
  end
55
58
 
56
59
  #
@@ -65,7 +68,7 @@ module Strava
65
68
  #
66
69
  def activity_kudos(id_or_options, options = {}, &block)
67
70
  id, options = parse_args(id_or_options, options)
68
- paginate "activities/#{id}/kudos", options, Strava::Models::Athlete, &block
71
+ paginate "activities/#{id}/kudos", options, Strava::Models::SummaryAthlete, &block
69
72
  end
70
73
 
71
74
  #
@@ -97,7 +100,7 @@ module Strava
97
100
  options = options.dup if options.key?(:after) || options.key?(:before)
98
101
  options[:after] = options[:after].to_i if options[:after]
99
102
  options[:before] = options[:before].to_i if options[:before]
100
- paginate 'athlete/activities', options, Strava::Models::Activity, &block
103
+ paginate 'athlete/activities', options, Strava::Models::SummaryActivity, &block
101
104
  end
102
105
 
103
106
  #
@@ -133,7 +136,7 @@ module Strava
133
136
  #
134
137
  def update_activity(id_or_options, options = {})
135
138
  id, options = parse_args(id_or_options, options)
136
- Strava::Models::Activity.new(put("activities/#{id}", options))
139
+ Strava::Models::DetailedActivity.new(put("activities/#{id}", options))
137
140
  end
138
141
  end
139
142
  end
@@ -8,7 +8,7 @@ module Strava
8
8
  # Returns the currently authenticated athlete.
9
9
  #
10
10
  def athlete
11
- Strava::Models::Athlete.new(get('athlete'))
11
+ Strava::Models::DetailedAthlete.new(get('athlete'))
12
12
  end
13
13
 
14
14
  #
@@ -36,7 +36,7 @@ module Strava
36
36
  # The weight of the athlete in kilograms.
37
37
  #
38
38
  def update_athlete(options = {})
39
- Strava::Models::Athlete.new(put('athlete', options))
39
+ Strava::Models::DetailedAthlete.new(put('athlete', options))
40
40
  end
41
41
  end
42
42
  end
@@ -16,7 +16,7 @@ module Strava
16
16
  #
17
17
  def club_activities(id_or_options, options = {}, &block)
18
18
  id, options = parse_args(id_or_options, options)
19
- paginate "clubs/#{id}/activities", options, Strava::Models::Activity, &block
19
+ paginate "clubs/#{id}/activities", options, Strava::Models::ClubActivity, &block
20
20
  end
21
21
 
22
22
  #
@@ -46,7 +46,7 @@ module Strava
46
46
  #
47
47
  def club_admins(id_or_options, options = {}, &block)
48
48
  id, options = parse_args(id_or_options, options)
49
- paginate "clubs/#{id}/admins", options, Strava::Models::ClubAdmin, &block
49
+ paginate "clubs/#{id}/admins", options, Strava::Models::ClubAthlete, &block
50
50
  end
51
51
 
52
52
  #
@@ -57,7 +57,7 @@ module Strava
57
57
  #
58
58
  def club(id_or_options, options = {})
59
59
  id, options = parse_args(id_or_options, options)
60
- Strava::Models::Club.new(get("clubs/#{id}", options))
60
+ Strava::Models::DetailedClub.new(get("clubs/#{id}", options))
61
61
  end
62
62
 
63
63
  #
@@ -72,7 +72,7 @@ module Strava
72
72
  #
73
73
  def club_members(id_or_options, options = {}, &block)
74
74
  id, options = parse_args(id_or_options, options)
75
- paginate "clubs/#{id}/members", options, Strava::Models::ClubMember, &block
75
+ paginate "clubs/#{id}/members", options, Strava::Models::ClubAthlete, &block
76
76
  end
77
77
 
78
78
  #
@@ -84,7 +84,7 @@ module Strava
84
84
  # Number of items per page. Defaults to 30.
85
85
  #
86
86
  def athlete_clubs(options = {}, &block)
87
- paginate 'athlete/clubs', options, Strava::Models::Club, &block
87
+ paginate 'athlete/clubs', options, Strava::Models::SummaryClub, &block
88
88
  end
89
89
  end
90
90
  end
@@ -12,7 +12,7 @@ module Strava
12
12
  #
13
13
  def gear(id_or_options, options = {})
14
14
  id, options = parse_args(id_or_options, options)
15
- Strava::Models::Gear.new(get("gear/#{id}", options))
15
+ Strava::Models::DetailedGear.new(get("gear/#{id}", options))
16
16
  end
17
17
  end
18
18
  end
@@ -12,7 +12,7 @@ module Strava
12
12
  #
13
13
  def segment_effort(id_or_options, options = {})
14
14
  id, options = parse_args(id_or_options, options)
15
- Strava::Models::SegmentEffort.new(get("segment_efforts/#{id}", options))
15
+ Strava::Models::DetailedSegmentEffort.new(get("segment_efforts/#{id}", options))
16
16
  end
17
17
 
18
18
  #
@@ -27,7 +27,7 @@ module Strava
27
27
  #
28
28
  def segment_efforts(id_or_options, options = {}, &block)
29
29
  id, options = parse_args(id_or_options, options)
30
- paginate "segments/#{id}/all_efforts", options, Strava::Models::SegmentEffort, &block
30
+ paginate "segments/#{id}/all_efforts", options, Strava::Models::DetailedSegmentEffort, &block
31
31
  end
32
32
  end
33
33
  end
@@ -34,7 +34,7 @@ module Strava
34
34
  # Number of items per page. Defaults to 30.
35
35
  #
36
36
  def starred_segments(options = {}, &block)
37
- paginate 'segments/starred', options, Strava::Models::Segment, &block
37
+ paginate 'segments/starred', options, Strava::Models::SummarySegment, &block
38
38
  end
39
39
 
40
40
  #
@@ -45,7 +45,7 @@ module Strava
45
45
  #
46
46
  def segment(id_or_options, options = {})
47
47
  id, options = parse_args(id_or_options, options)
48
- Strava::Models::Segment.new(get("segments/#{id}", options))
48
+ Strava::Models::DetailedSegment.new(get("segments/#{id}", options))
49
49
  end
50
50
 
51
51
  #
@@ -59,7 +59,7 @@ module Strava
59
59
  def star_segment(id_or_options, options = {})
60
60
  id, options = parse_args(id_or_options, options)
61
61
  throw ArgumentError.new('Required argument :starred missing') if options[:starred].nil?
62
- Strava::Models::Segment.new(put("segments/#{id}/starred", options))
62
+ Strava::Models::DetailedSegment.new(put("segments/#{id}/starred", options))
63
63
  end
64
64
  end
65
65
  end
@@ -29,8 +29,7 @@ module Strava
29
29
  # @return [Strava::Web::ApiResponse]
30
30
  #
31
31
  def http_response
32
- @http_response ||=
33
- Strava::Web::ApiResponse.new(deep_copy(@web_response).http_response)
32
+ @http_response ||= Strava::Web::ApiResponse.new(deep_copy(@web_response).http_response)
34
33
  end
35
34
 
36
35
  #
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Strava
4
4
  module Models
5
+ # Undocumented
5
6
  class Achievement < Strava::Models::Response
6
7
  property 'rank'
7
8
  property 'type'
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Strava
4
4
  module Models
5
+ # https://developers.strava.com/docs/reference/#api-models-ActivityStats
5
6
  class ActivityStats < Strava::Models::Response
6
7
  property 'biggest_ride_distance'
7
8
  property 'biggest_climb_elevation_gain'
@@ -2,18 +2,14 @@
2
2
 
3
3
  module Strava
4
4
  module Models
5
+ # https://developers.strava.com/docs/reference/#api-models-ActivityTotal
5
6
  class ActivityTotal < Strava::Models::Response
6
- include Mixins::Distance
7
- include Mixins::Time
8
- include Mixins::Elevation
9
-
10
7
  property 'count'
8
+ include Mixins::Distance
9
+ include Mixins::MovingTime
10
+ include Mixins::ElapsedTime
11
+ include Mixins::ElevationGain
11
12
  property 'achievement_count'
12
- property 'elevation_gain'
13
-
14
- def total_elevation_gain
15
- elevation_gain
16
- end
17
13
  end
18
14
  end
19
15
  end
@@ -2,14 +2,17 @@
2
2
 
3
3
  module Strava
4
4
  module Models
5
+ # https://developers.strava.com/docs/reference/#api-models-ActivityZone
5
6
  class ActivityZone < Strava::Models::Response
6
7
  property 'score'
7
8
  property 'distribution_buckets', transform_with: ->(v) { v.map { |r| Strava::Models::TimedZoneRange.new(r) } }
8
9
  property 'type'
9
- property 'resource_state'
10
10
  property 'sensor_based'
11
11
  property 'points'
12
12
  property 'custom_zones'
13
+ property 'max'
14
+ # undocumented
15
+ property 'resource_state'
13
16
  end
14
17
  end
15
18
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Strava
4
+ module Models
5
+ # https://developers.strava.com/docs/reference/#api-models-BaseStream
6
+ class BaseStream < Strava::Models::Response
7
+ property 'original_size'
8
+ property 'resolution'
9
+ property 'series_type'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Strava
4
+ module Models
5
+ # https://developers.strava.com/docs/reference/#api-models-ClubActivity
6
+ class ClubActivity < Strava::Models::Response
7
+ include Mixins::ElevationGain
8
+ include Mixins::SportType
9
+
10
+ property 'athlete', transform_with: ->(v) { Strava::Models::MetaAthlete.new(v) }
11
+ property 'name'
12
+ include Mixins::Distance
13
+ include Mixins::MovingTime
14
+ include Mixins::ElapsedTime
15
+ include Mixins::TotalElevationGain
16
+ include Mixins::SportType
17
+ property 'workout_type'
18
+ # undocumented
19
+ property 'resource_state'
20
+ end
21
+ end
22
+ end
@@ -2,12 +2,15 @@
2
2
 
3
3
  module Strava
4
4
  module Models
5
- class ClubMember < Strava::Models::Response
5
+ # https://developers.strava.com/docs/reference/#api-models-ClubAthlete
6
+ class ClubAthlete < Strava::Models::Response
6
7
  property 'resource_state'
7
8
  property 'firstname'
8
9
  property 'lastname'
9
- property 'owner'
10
+ property 'member'
10
11
  property 'admin'
12
+ property 'owner'
13
+ # undocumented
11
14
  property 'membership'
12
15
 
13
16
  def name
@@ -2,16 +2,17 @@
2
2
 
3
3
  module Strava
4
4
  module Models
5
+ # Unodcumented
5
6
  class ClubEvent < Strava::Models::Response
6
7
  property 'id'
7
8
  property 'resource_state'
8
9
  property 'title'
9
10
  property 'description'
10
11
  property 'club_id'
11
- property 'club', transform_with: ->(c) { Strava::Models::Club.new(c) }
12
- property 'organizing_athlete', transform_with: ->(oa) { Strava::Models::Athlete.new(oa) }
12
+ property 'club', transform_with: ->(c) { Strava::Models::SummaryClub.new(c) }
13
+ property 'organizing_athlete', transform_with: ->(oa) { Strava::Models::SummaryAthlete.new(oa) }
13
14
  property 'activity_type'
14
- property 'created_at', transform_with: ->(v) { Time.parse(v) }
15
+ property 'created_at', transform_with: ->(v) { Time.parse(v) if v&.length&.positive? }
15
16
  property 'route_id'
16
17
  property 'route', transform_with: ->(r) { Strava::Models::Route.new(r) }
17
18
  property 'women_only'
@@ -21,7 +22,8 @@ module Strava
21
22
  property 'upcoming_occurrences', transform_with: ->(upcoming) { upcoming.map { |o| Time.parse(o) } }
22
23
  property 'zone'
23
24
  property 'address'
24
- property 'start_latlng'
25
+ property 'joined'
26
+ property 'start_latlng', transform_with: ->(v) { Strava::Models::LatLng.new(v) }
25
27
 
26
28
  def strava_url
27
29
  "https://www.strava.com/clubs/#{club_id}/group_events/#{id}"
@@ -5,10 +5,15 @@ module Strava
5
5
  class Comment < Strava::Models::Response
6
6
  property 'id'
7
7
  property 'activity_id'
8
- property 'resource_state'
9
8
  property 'text'
10
9
  property 'created_at', transform_with: ->(v) { Time.parse(v) }
11
- property 'athlete', transform_with: ->(v) { Strava::Models::Athlete.new(v) }
10
+ property 'athlete', transform_with: ->(v) { Strava::Models::SummaryAthlete.new(v) }
11
+ # undocumented
12
+ property 'post_id'
13
+ property 'resource_state'
14
+ property 'mentions_metadata'
15
+ property 'reaction_count'
16
+ property 'has_reacted'
12
17
  end
13
18
  end
14
19
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Strava
4
+ module Models
5
+ # Undocumented
6
+ class Destination < Strava::Models::Response
7
+ property 'href'
8
+ property 'type'
9
+ property 'name'
10
+ end
11
+ end
12
+ end