smplkit 3.0.101 → 3.0.103

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: 023cc1c779a1121f562c18522ac3df12441aa82f224b886dcf51b92856607d9f
4
- data.tar.gz: 38edf4febecc1c929d086456450d8b836ae5c73866aec3031d2f9c1bbce1eea4
3
+ metadata.gz: b4885e5b0997b0792d5b2a40437167f76818c0dca5185d78428d54ef6b650f4c
4
+ data.tar.gz: 75915674e533382f9ce457cffe2f5347c15bf24c2f26ec105fb3503d28c3b442
5
5
  SHA512:
6
- metadata.gz: d79bfdecf66c1d5896c7f3db0a2faca933cfdeab6025888133ae1e2b999ef2525b0a25224d4295e4d5c4b4b9b0089a0428cee337f2a11d883955626e4214d1ae
7
- data.tar.gz: 4ba20edec0551888d6aa7b13ddbd5fc99bd481794a1771e2c271c6f5c212a328cd028e060d9ddb6f59af56d71e094ff3648ae06100e621069b29186ff3ff4120
6
+ metadata.gz: e4fc9b5b6206da24bf576cc7c9e4a5f1dab28ffa58b53d5d41c41b78092d61ebdf8708a0024efa79c1d593d725237363a45db30a82a2a7de29af6f08ae509cf7
7
+ data.tar.gz: b2096cc388bde3c892b48235e826c3418dba647abde121f42190007015c4102dee95b6949e2d54e9a962d33da17a932721491b0cf623976ce09fc9a23e24ec6c
@@ -22,11 +22,15 @@ module SmplkitGeneratedClient::App
22
22
  # Map of limit key to the cap that applies on this plan. `-1` indicates an unlimited cap.
23
23
  attr_accessor :limits
24
24
 
25
+ # For metered products only: map of metered limit key to the per-unit overage price in micro-USD ($0.000001) charged for each unit beyond the plan's included allotment. A rate of `0` means the plan stops at its allotment with no overage. Omitted for products that are not metered.
26
+ attr_accessor :overage_rates
27
+
25
28
  # Attribute mapping from ruby-style variable name to JSON key.
26
29
  def self.attribute_map
27
30
  {
28
31
  :'price_monthly_cents' => :'price_monthly_cents',
29
- :'limits' => :'limits'
32
+ :'limits' => :'limits',
33
+ :'overage_rates' => :'overage_rates'
30
34
  }
31
35
  end
32
36
 
@@ -44,13 +48,15 @@ module SmplkitGeneratedClient::App
44
48
  def self.openapi_types
45
49
  {
46
50
  :'price_monthly_cents' => :'Integer',
47
- :'limits' => :'Hash<String, Integer>'
51
+ :'limits' => :'Hash<String, Integer>',
52
+ :'overage_rates' => :'Hash<String, Integer>'
48
53
  }
49
54
  end
50
55
 
51
56
  # List of attributes with nullable: true
52
57
  def self.openapi_nullable
53
58
  Set.new([
59
+ :'overage_rates'
54
60
  ])
55
61
  end
56
62
 
@@ -83,6 +89,12 @@ module SmplkitGeneratedClient::App
83
89
  else
84
90
  self.limits = nil
85
91
  end
92
+
93
+ if attributes.key?(:'overage_rates')
94
+ if (value = attributes[:'overage_rates']).is_a?(Hash)
95
+ self.overage_rates = value
96
+ end
97
+ end
86
98
  end
87
99
 
88
100
  # Show invalid properties with the reasons. Usually used together with valid?
@@ -136,7 +148,8 @@ module SmplkitGeneratedClient::App
136
148
  return true if self.equal?(o)
137
149
  self.class == o.class &&
138
150
  price_monthly_cents == o.price_monthly_cents &&
139
- limits == o.limits
151
+ limits == o.limits &&
152
+ overage_rates == o.overage_rates
140
153
  end
141
154
 
142
155
  # @see the `==` method
@@ -148,7 +161,7 @@ module SmplkitGeneratedClient::App
148
161
  # Calculates hash code according to all attributes.
149
162
  # @return [Integer] Hash code
150
163
  def hash
151
- [price_monthly_cents, limits].hash
164
+ [price_monthly_cents, limits, overage_rates].hash
152
165
  end
153
166
 
154
167
  # Builds the object from hash
@@ -34,6 +34,9 @@ module SmplkitGeneratedClient::App
34
34
  # Map of limit key to limit definition for this product.
35
35
  attr_accessor :limits
36
36
 
37
+ # Limit keys on this product that are metered: each includes a monthly allotment in the plan price and bills per unit beyond it at the plan's `overage_rates` rate, rather than capping hard. Empty for products with no metered limits.
38
+ attr_accessor :metered_limits
39
+
37
40
  # Map of plan key to plan definition for this product.
38
41
  attr_accessor :plans
39
42
 
@@ -46,6 +49,7 @@ module SmplkitGeneratedClient::App
46
49
  :'features' => :'features',
47
50
  :'coming_soon' => :'coming_soon',
48
51
  :'limits' => :'limits',
52
+ :'metered_limits' => :'metered_limits',
49
53
  :'plans' => :'plans'
50
54
  }
51
55
  end
@@ -69,6 +73,7 @@ module SmplkitGeneratedClient::App
69
73
  :'features' => :'Array<String>',
70
74
  :'coming_soon' => :'Boolean',
71
75
  :'limits' => :'Hash<String, LimitDefinition>',
76
+ :'metered_limits' => :'Array<String>',
72
77
  :'plans' => :'Hash<String, PlanDefinition>'
73
78
  }
74
79
  end
@@ -132,6 +137,12 @@ module SmplkitGeneratedClient::App
132
137
  self.limits = nil
133
138
  end
134
139
 
140
+ if attributes.key?(:'metered_limits')
141
+ if (value = attributes[:'metered_limits']).is_a?(Array)
142
+ self.metered_limits = value
143
+ end
144
+ end
145
+
135
146
  if attributes.key?(:'plans')
136
147
  if (value = attributes[:'plans']).is_a?(Hash)
137
148
  self.plans = value
@@ -227,6 +238,7 @@ module SmplkitGeneratedClient::App
227
238
  features == o.features &&
228
239
  coming_soon == o.coming_soon &&
229
240
  limits == o.limits &&
241
+ metered_limits == o.metered_limits &&
230
242
  plans == o.plans
231
243
  end
232
244
 
@@ -239,7 +251,7 @@ module SmplkitGeneratedClient::App
239
251
  # Calculates hash code according to all attributes.
240
252
  # @return [Integer] Hash code
241
253
  def hash
242
- [display_name, description, tagline, features, coming_soon, limits, plans].hash
254
+ [display_name, description, tagline, features, coming_soon, limits, metered_limits, plans].hash
243
255
  end
244
256
 
245
257
  # Builds the object from hash
@@ -39,4 +39,10 @@ describe SmplkitGeneratedClient::App::PlanDefinition do
39
39
  end
40
40
  end
41
41
 
42
+ describe 'test attribute "overage_rates"' do
43
+ it 'should work' do
44
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
45
+ end
46
+ end
47
+
42
48
  end
@@ -63,6 +63,12 @@ describe SmplkitGeneratedClient::App::Product do
63
63
  end
64
64
  end
65
65
 
66
+ describe 'test attribute "metered_limits"' do
67
+ it 'should work' do
68
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
69
+ end
70
+ end
71
+
66
72
  describe 'test attribute "plans"' do
67
73
  it 'should work' do
68
74
  # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
@@ -8,16 +8,19 @@ module Smplkit
8
8
  # Response time is independent of how many years of events the account has
9
9
  # accumulated. Sorted alphabetically; offset paginated.
10
10
  class Categories
11
- def initialize(api)
11
+ def initialize(api, environment: nil)
12
12
  @api = api
13
+ @environment = environment
13
14
  end
14
15
 
15
16
  # List the distinct +category+ values seen in the account.
16
17
  #
17
18
  # +environments+ scopes the listing to a set of environments: pass an
18
19
  # array of environment keys and/or the reserved +"smplkit"+ control-plane
19
- # bucket; the values are comma-joined into +filter[environment]+. Omitting
20
- # it (or passing an empty array) leaves the filter off entirely.
20
+ # bucket; the values are comma-joined into +filter[environment]+. Omit it
21
+ # (the default) to scope the listing to the client's configured
22
+ # environment; with no configured environment the filter is left off
23
+ # entirely.
21
24
  #
22
25
  # @param page_number [Integer, nil] 1-based page index. Omit for the first
23
26
  # page.
@@ -28,7 +31,8 @@ module Smplkit
28
31
  # count server-side). Omit to skip it.
29
32
  # @param environments [Array<String>, nil] Environment keys and/or the
30
33
  # reserved +"smplkit"+ control-plane bucket to scope the listing to. Omit
31
- # to leave the filter off entirely.
34
+ # to fall back to the client's configured environment; with no configured
35
+ # environment the filter is left off entirely.
32
36
  # @return [Smplkit::Audit::CategoryListPage] A page of the matching
33
37
  # category values.
34
38
  def list(page_number: nil, page_size: nil, meta_total: nil, environments: nil)
@@ -36,8 +40,8 @@ module Smplkit
36
40
  opts[:page_number] = page_number if page_number
37
41
  opts[:page_size] = page_size if page_size
38
42
  opts[:meta_total] = meta_total unless meta_total.nil?
39
- joined_environments = Smplkit::Audit.join_environments(environments)
40
- opts[:filter_environment] = joined_environments if joined_environments
43
+ resolved_environment = Smplkit::Audit.resolve_environment_filter(environments, @environment)
44
+ opts[:filter_environment] = resolved_environment if resolved_environment
41
45
 
42
46
  resp = Smplkit::Audit.call_api { @api.list_categories(opts) }
43
47
  rows = (resp.data || []).map { |r| Category.from_resource(r) }
@@ -21,9 +21,13 @@ module Smplkit
21
21
  # from +base_domain+/+scheme+; supplied directly by the top-level clients
22
22
  # which have already computed it.
23
23
  # @param environment [String, nil] Deployment environment to scope recording
24
- # and reads to. Optional forwarder CRUD and discovery are
25
- # environment-agnostic, and reads accept an explicit +environments: [...]+
26
- # filter.
24
+ # and reads to. Sent on the event request body when recording and as the
25
+ # default +filter[environment]+ on the read surfaces (events list and the
26
+ # resource_type / event_type / category discovery lists). Optional —
27
+ # forwarder CRUD is environment-agnostic, and reads accept an explicit
28
+ # +environments: [...]+ filter that overrides this default. With no
29
+ # configured environment, recording falls back to the server-side default
30
+ # environment and the read filter is left off.
27
31
  # @param profile [String, nil] Named +~/.smplkit+ profile section.
28
32
  # @param base_domain [String, nil] Base domain for API requests (default
29
33
  # +"smplkit.com"+).
@@ -64,21 +68,26 @@ module Smplkit
64
68
  HttpPool.configure(cfg)
65
69
  api_client = SmplkitGeneratedClient::Audit::ApiClient.new(cfg)
66
70
  api_client.default_headers["User-Agent"] = "smplkit-ruby-sdk/#{Smplkit::VERSION}"
67
- # Runtime audit ops are environment-scoped: record / list / get /
68
- # discovery all resolve their environment from the
69
- # +X-Smplkit-Environment+ request header (ADR-055). We stamp it once
70
- # at the client level from the SDK's configured runtime environment so
71
- # every generated call carries it. It is stamped before +extra_headers+
72
- # is applied so a caller-supplied entry of the same name wins (explicit
73
- # override).
74
- api_client.default_headers["X-Smplkit-Environment"] = environment unless environment.nil?
71
+ # Runtime audit ops are environment-scoped, but the scoping is
72
+ # body-driven (ADR-055): +events.record+ stamps the configured
73
+ # environment onto the event request body, and the read surfaces
74
+ # (events list plus the resource_type / event_type / category discovery
75
+ # lists) default +filter[environment]+ to it. The transport therefore
76
+ # carries only auth plus any caller-supplied +extra_headers+ no
77
+ # environment header. Forwarder CRUD is environment-agnostic.
75
78
  extra_headers&.each do |k, v|
76
79
  api_client.default_headers[k] = v unless SDK_OWNED_HEADERS.include?(k.downcase)
77
80
  end
78
- @events = Events.new(SmplkitGeneratedClient::Audit::EventsApi.new(api_client))
79
- @resource_types = ResourceTypes.new(SmplkitGeneratedClient::Audit::ResourceTypesApi.new(api_client))
80
- @event_types = EventTypes.new(SmplkitGeneratedClient::Audit::EventTypesApi.new(api_client))
81
- @categories = Categories.new(SmplkitGeneratedClient::Audit::CategoriesApi.new(api_client))
81
+ @events = Events.new(SmplkitGeneratedClient::Audit::EventsApi.new(api_client), environment: environment)
82
+ @resource_types = ResourceTypes.new(
83
+ SmplkitGeneratedClient::Audit::ResourceTypesApi.new(api_client), environment: environment
84
+ )
85
+ @event_types = EventTypes.new(
86
+ SmplkitGeneratedClient::Audit::EventTypesApi.new(api_client), environment: environment
87
+ )
88
+ @categories = Categories.new(
89
+ SmplkitGeneratedClient::Audit::CategoriesApi.new(api_client), environment: environment
90
+ )
82
91
  @forwarders = ForwardersClient.new(SmplkitGeneratedClient::Audit::ForwardersApi.new(api_client))
83
92
  end
84
93
 
@@ -13,16 +13,19 @@ module Smplkit
13
13
  #
14
14
  # Sorted alphabetically; offset paginated.
15
15
  class EventTypes
16
- def initialize(api)
16
+ def initialize(api, environment: nil)
17
17
  @api = api
18
+ @environment = environment
18
19
  end
19
20
 
20
21
  # List the distinct +event_type+ slugs seen in the account.
21
22
  #
22
23
  # +environments+ scopes the listing to a set of environments: pass an
23
24
  # array of environment keys and/or the reserved +"smplkit"+ control-plane
24
- # bucket; the values are comma-joined into +filter[environment]+. Omitting
25
- # it (or passing an empty array) leaves the filter off entirely.
25
+ # bucket; the values are comma-joined into +filter[environment]+. Omit it
26
+ # (the default) to scope the listing to the client's configured
27
+ # environment; with no configured environment the filter is left off
28
+ # entirely.
26
29
  #
27
30
  # @param filter_resource_type [String, nil] Restrict the listing to
28
31
  # event_types seen with this +resource_type+. Omit to list every distinct
@@ -36,7 +39,8 @@ module Smplkit
36
39
  # count server-side). Omit to skip it.
37
40
  # @param environments [Array<String>, nil] Environment keys and/or the
38
41
  # reserved +"smplkit"+ control-plane bucket to scope the listing to. Omit
39
- # to leave the filter off entirely.
42
+ # to fall back to the client's configured environment; with no configured
43
+ # environment the filter is left off entirely.
40
44
  # @return [Smplkit::Audit::EventTypeListPage] A page of the matching
41
45
  # event-type slugs.
42
46
  def list(filter_resource_type: nil, page_number: nil, page_size: nil, meta_total: nil, environments: nil)
@@ -45,8 +49,8 @@ module Smplkit
45
49
  opts[:page_number] = page_number if page_number
46
50
  opts[:page_size] = page_size if page_size
47
51
  opts[:meta_total] = meta_total unless meta_total.nil?
48
- joined_environments = Smplkit::Audit.join_environments(environments)
49
- opts[:filter_environment] = joined_environments if joined_environments
52
+ resolved_environment = Smplkit::Audit.resolve_environment_filter(environments, @environment)
53
+ opts[:filter_environment] = resolved_environment if resolved_environment
50
54
 
51
55
  resp = Smplkit::Audit.call_api { @api.list_event_types(opts) }
52
56
  rows = (resp.data || []).map { |r| EventType.from_resource(r) }
@@ -9,8 +9,9 @@ module Smplkit
9
9
  # +flush: true+ to block until the event is durable before continuing.
10
10
  # +#list+ and +#get+ are synchronous reads.
11
11
  class Events
12
- def initialize(api)
12
+ def initialize(api, environment: nil)
13
13
  @api = api
14
+ @environment = environment
14
15
  @buffer = EventBuffer.new(api)
15
16
  end
16
17
 
@@ -105,6 +106,13 @@ module Smplkit
105
106
  data: data || {},
106
107
  do_not_forward: do_not_forward
107
108
  )
109
+ # Stamp the client's configured environment onto the event body — the
110
+ # body-driven replacement for the old +X-Smplkit-Environment+ header
111
+ # (ADR-055). Left off when nil so a single-environment credential
112
+ # resolves it server-side. Assigning conditionally (rather than passing
113
+ # +environment: nil+ through the constructor) keeps the field out of the
114
+ # serialized body entirely when unconfigured.
115
+ attrs.environment = @environment unless @environment.nil?
108
116
  resource = SmplkitGeneratedClient::Audit::EventResource.new(
109
117
  id: "",
110
118
  type: "event",
@@ -141,6 +149,13 @@ module Smplkit
141
149
  # +occurred_at_range+, or with both +resource_type+ and +resource_id+ —
142
150
  # or the request is rejected.
143
151
  #
152
+ # +environments+ scopes the read to a set of environments: pass an array
153
+ # of environment keys and/or the reserved +"smplkit"+ control-plane
154
+ # bucket; the values are sent comma-separated as +filter[environment]+.
155
+ # Omit it (the default) to scope the read to the client's configured
156
+ # environment; with no configured environment the filter is left off
157
+ # entirely.
158
+ #
144
159
  # @param event_type [String, nil] Return only events with this
145
160
  # +event_type+. Omit to match any.
146
161
  # @param resource_type [String, nil] Return only events about this
@@ -160,7 +175,8 @@ module Smplkit
160
175
  # or the request is rejected. Omit to disable text filtering.
161
176
  # @param environments [Array<String>, nil] Environment keys (and/or the
162
177
  # reserved +"smplkit"+ control-plane bucket) to scope the read to. Omit
163
- # to leave the filter off entirely.
178
+ # to fall back to the client's configured environment; with no configured
179
+ # environment the filter is left off entirely.
164
180
  # @param page_size [Integer, nil] Maximum number of events to return in
165
181
  # this page.
166
182
  # @param page_after [String, nil] Opaque cursor from a previous page's
@@ -183,8 +199,8 @@ module Smplkit
183
199
  opts[:filter_actor_id] = actor_id if actor_id
184
200
  opts[:filter_occurred_at] = occurred_at_range if occurred_at_range
185
201
  opts[:filter_search] = search if search
186
- joined_environments = Smplkit::Audit.join_environments(environments)
187
- opts[:filter_environment] = joined_environments if joined_environments
202
+ resolved_environment = Smplkit::Audit.resolve_environment_filter(environments, @environment)
203
+ opts[:filter_environment] = resolved_environment if resolved_environment
188
204
  opts[:page_size] = page_size if page_size
189
205
  opts[:page_after] = page_after if page_after
190
206
 
@@ -79,6 +79,28 @@ module Smplkit
79
79
  values.empty? ? nil : values.join(",")
80
80
  end
81
81
 
82
+ # Resolve the +filter[environment]+ value for a read surface.
83
+ #
84
+ # An explicit, non-empty +environments+ list always wins and is comma-joined
85
+ # via {join_environments}. Otherwise the client's configured +default+
86
+ # environment scopes the read — the body-driven replacement for the old
87
+ # per-request +X-Smplkit-Environment+ header (ADR-055), which previously
88
+ # scoped every read to the client's environment. A client with no configured
89
+ # environment and no explicit list returns +nil+ so the caller omits the
90
+ # query param and the credential's own scoping applies server-side.
91
+ #
92
+ # @param environments [Array<String>, String, nil] Explicit per-call
93
+ # environment filter; an empty/blank value falls through to +default+.
94
+ # @param default [String, nil] The client's configured environment.
95
+ # @return [String, nil] The +filter[environment]+ value, or +nil+ to omit it.
96
+ # @api private
97
+ def self.resolve_environment_filter(environments, default)
98
+ joined = join_environments(environments)
99
+ return joined unless joined.nil?
100
+
101
+ default
102
+ end
103
+
82
104
  # Supported SIEM forwarder destination types.
83
105
  #
84
106
  # Members are declared in alphabetical order. Customers pass these
@@ -204,7 +226,7 @@ module Smplkit
204
226
  # Read-only and always present on reads — the audit service resolves it
205
227
  # when the event is recorded (from a single-environment credential, or
206
228
  # from the runtime SDK's configured environment, which the SDK sends on
207
- # every recording call). Never set on the recording request body.
229
+ # the recording request body).
208
230
  AuditEvent = Struct.new(
209
231
  :id, :event_type, :resource_type, :resource_id,
210
232
  :occurred_at, :created_at,
@@ -8,16 +8,19 @@ module Smplkit
8
8
  # Response time is independent of how many years of events the account has
9
9
  # accumulated. Sorted alphabetically; offset paginated.
10
10
  class ResourceTypes
11
- def initialize(api)
11
+ def initialize(api, environment: nil)
12
12
  @api = api
13
+ @environment = environment
13
14
  end
14
15
 
15
16
  # List the distinct +resource_type+ slugs seen in the account.
16
17
  #
17
18
  # +environments+ scopes the listing to a set of environments: pass an
18
19
  # array of environment keys and/or the reserved +"smplkit"+ control-plane
19
- # bucket; the values are comma-joined into +filter[environment]+. Omitting
20
- # it (or passing an empty array) leaves the filter off entirely.
20
+ # bucket; the values are comma-joined into +filter[environment]+. Omit it
21
+ # (the default) to scope the listing to the client's configured
22
+ # environment; with no configured environment the filter is left off
23
+ # entirely.
21
24
  #
22
25
  # @param page_number [Integer, nil] 1-based page index. Omit for the first
23
26
  # page.
@@ -28,7 +31,8 @@ module Smplkit
28
31
  # count server-side). Omit to skip it.
29
32
  # @param environments [Array<String>, nil] Environment keys and/or the
30
33
  # reserved +"smplkit"+ control-plane bucket to scope the listing to. Omit
31
- # to leave the filter off entirely.
34
+ # to fall back to the client's configured environment; with no configured
35
+ # environment the filter is left off entirely.
32
36
  # @return [Smplkit::Audit::ResourceTypeListPage] A page of the matching
33
37
  # resource-type slugs.
34
38
  def list(page_number: nil, page_size: nil, meta_total: nil, environments: nil)
@@ -36,8 +40,8 @@ module Smplkit
36
40
  opts[:page_number] = page_number if page_number
37
41
  opts[:page_size] = page_size if page_size
38
42
  opts[:meta_total] = meta_total unless meta_total.nil?
39
- joined_environments = Smplkit::Audit.join_environments(environments)
40
- opts[:filter_environment] = joined_environments if joined_environments
43
+ resolved_environment = Smplkit::Audit.resolve_environment_filter(environments, @environment)
44
+ opts[:filter_environment] = resolved_environment if resolved_environment
41
45
 
42
46
  resp = Smplkit::Audit.call_api { @api.list_resource_types(opts) }
43
47
  rows = (resp.data || []).map { |r| ResourceType.from_resource(r) }
@@ -124,9 +124,11 @@ module Smplkit
124
124
  # borrows the shared logging transport and WebSocket. The two management
125
125
  # sub-clients live at client.logging.loggers / client.logging.log_groups.
126
126
  @logging = Logging::LoggingClient.new(parent: self, transport: @transports.logging_http, metrics: @metrics)
127
- # Audit's full surface on one client; this runtime instance carries the
128
- # configured environment as ``X-Smplkit-Environment`` and owns its own
129
- # transport (closed in ``close``).
127
+ # Audit's full surface on one client; this runtime instance scopes audit
128
+ # ops to the configured environment via the body-driven path (ADR-055):
129
+ # ``events.record`` stamps it on the event body and the read surfaces
130
+ # default ``filter[environment]`` to it. Owns its own transport (closed in
131
+ # ``close``).
130
132
  @audit = Audit::AuditClient.new(
131
133
  api_key: cfg.api_key, base_url: audit_url, environment: cfg.environment, extra_headers: extra_headers
132
134
  )
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smplkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.101
4
+ version: 3.0.103
5
5
  platform: ruby
6
6
  authors:
7
7
  - Smpl Solutions LLC