flipper-ui 0.14.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 287ca4de5728ae295a451e19f1daf54d24caa66c
4
- data.tar.gz: 7ce801bbfb74119adb2fbbdaa951b91365710382
3
+ metadata.gz: 6588ef43bcee1f02024cf32085148eae82ffa9f4
4
+ data.tar.gz: fd986a24960b953f56510bb5b96a18373276f628
5
5
  SHA512:
6
- metadata.gz: e75f14c2b6eb333719a420d95f27ecabe42dce4ad624145538c84545942c3b6b9457a00bd941a4430bddf5a26918a8d74440c6be5792d60d727266cd0aa8d57d
7
- data.tar.gz: 69ed93ab1893bd4fec27656db5dda9728830089c4f4708b318c1d23e584d19ca03e1ce53c2bab4e930fafc653e55fa80dcf5f1c2ea6cfc612ef814c2b776aebd
6
+ metadata.gz: b4f66474ac658466d3a2a87e67f8c4168935457e1a62d9da3cb8d9891ec50864956cb5a800529bc757a1f879ba943da691c62b5565dffbbd2e32ad1e584a1bf6
7
+ data.tar.gz: f0ca4057925cb29dcd2b08116751b71900037cf6319520056a1f5da7a5ef0b559c93e8d84ff36127c0bb8742cd4ee06443f68bea3d47ad52d8bf48de4ca0b2f9
data/lib/flipper/ui.rb CHANGED
@@ -17,27 +17,26 @@ require 'flipper/ui/configuration'
17
17
  module Flipper
18
18
  module UI
19
19
  class << self
20
- # Public: If you set this, the UI will always have a first breadcrumb that
21
- # says "App" which points to this href. The href can be a path (ie: "/")
22
- # or full url ("https://app.example.com/").
23
- attr_accessor :application_breadcrumb_href
20
+ # These three configuration options have been moved to Flipper::UI::Configuration
21
+ deprecated_configuration_options = %w(application_breadcrumb_href
22
+ feature_creation_enabled
23
+ feature_removal_enabled)
24
+ deprecated_configuration_options.each do |attribute_name|
25
+ send(:define_method, "#{attribute_name}=".to_sym) do
26
+ raise ConfigurationDeprecated, "The UI configuration for #{attribute_name} has " \
27
+ "deprecated. This configuration option has moved to Flipper::UI::Configuration"
28
+ end
24
29
 
25
- # Public: Is feature creation allowed from the UI? Defaults to true. If
26
- # set to false, users of the UI cannot create features. All feature
27
- # creation will need to be done through the configured flipper instance.
28
- attr_accessor :feature_creation_enabled
29
-
30
- # Public: Is feature deletion allowed from the UI? Defaults to true. If
31
- # set to false, users won't be able to delete features from the UI.
32
- attr_accessor :feature_removal_enabled
30
+ send(:define_method, attribute_name.to_sym) do
31
+ raise ConfigurationDeprecated, "The UI configuration for #{attribute_name} has " \
32
+ "deprecated. This configuration option has moved to Flipper::UI::Configuration"
33
+ end
34
+ end
33
35
 
34
36
  # Public: Set attributes on this instance to customize UI text
35
37
  attr_reader :configuration
36
38
  end
37
39
 
38
- self.feature_creation_enabled = true
39
- self.feature_removal_enabled = true
40
-
41
40
  def self.root
42
41
  @root ||= Pathname(__FILE__).dirname.expand_path.join('ui')
43
42
  end
@@ -65,8 +65,8 @@ module Flipper
65
65
  @code = 200
66
66
  @headers = { 'Content-Type' => 'text/plain' }
67
67
  @breadcrumbs =
68
- if Flipper::UI.application_breadcrumb_href
69
- [Breadcrumb.new('App', Flipper::UI.application_breadcrumb_href)]
68
+ if Flipper::UI.configuration.application_breadcrumb_href
69
+ [Breadcrumb.new('App', Flipper::UI.configuration.application_breadcrumb_href)]
70
70
  else
71
71
  []
72
72
  end
@@ -8,7 +8,7 @@ module Flipper
8
8
  route %r{features/new/?\Z}
9
9
 
10
10
  def get
11
- unless Flipper::UI.feature_creation_enabled
11
+ unless Flipper::UI.configuration.feature_creation_enabled
12
12
  status 403
13
13
 
14
14
  breadcrumb 'Home', '/'
@@ -21,7 +21,7 @@ module Flipper
21
21
  end
22
22
 
23
23
  def delete
24
- unless Flipper::UI.feature_removal_enabled
24
+ unless Flipper::UI.configuration.feature_removal_enabled
25
25
  status 403
26
26
 
27
27
  breadcrumb 'Home', '/'
@@ -23,7 +23,7 @@ module Flipper
23
23
  end
24
24
 
25
25
  def post
26
- unless Flipper::UI.feature_creation_enabled
26
+ unless Flipper::UI.configuration.feature_creation_enabled
27
27
  status 403
28
28
 
29
29
  breadcrumb 'Home', '/'
@@ -12,6 +12,20 @@ module Flipper
12
12
  attr_accessor :banner_text,
13
13
  :banner_class
14
14
 
15
+ # Public: If you set this, the UI will always have a first breadcrumb that
16
+ # says "App" which points to this href. The href can be a path (ie: "/")
17
+ # or full url ("https://app.example.com/").
18
+ attr_accessor :application_breadcrumb_href
19
+
20
+ # Public: Is feature creation allowed from the UI? Defaults to true. If
21
+ # set to false, users of the UI cannot create features. All feature
22
+ # creation will need to be done through the configured flipper instance.
23
+ attr_accessor :feature_creation_enabled
24
+
25
+ # Public: Is feature deletion allowed from the UI? Defaults to true. If
26
+ # set to false, users won't be able to delete features from the UI.
27
+ attr_accessor :feature_removal_enabled
28
+
15
29
  VALID_BANNER_CLASS_VALUES = %w(
16
30
  danger
17
31
  dark
@@ -31,6 +45,8 @@ module Flipper
31
45
  @delete = Option.new("Danger Zone", "Deleting a feature removes it from the list of features and disables it for everyone.") # rubocop:disable Metrics/LineLength
32
46
  @banner_text = nil
33
47
  @banner_class = 'danger'
48
+ @feature_creation_enabled = true
49
+ @feature_removal_enabled = true
34
50
  end
35
51
 
36
52
  def banner_class=(value)
@@ -16,7 +16,6 @@ module Flipper
16
16
  @action_collection = ActionCollection.new
17
17
 
18
18
  # UI
19
- @action_collection.add UI::Actions::Features
20
19
  @action_collection.add UI::Actions::AddFeature
21
20
  @action_collection.add UI::Actions::Feature
22
21
  @action_collection.add UI::Actions::ActorsGate
@@ -25,6 +24,7 @@ module Flipper
25
24
  @action_collection.add UI::Actions::PercentageOfTimeGate
26
25
  @action_collection.add UI::Actions::PercentageOfActorsGate
27
26
  @action_collection.add UI::Actions::Gate
27
+ @action_collection.add UI::Actions::Features
28
28
 
29
29
  # Static Assets/Files
30
30
  @action_collection.add UI::Actions::File
@@ -229,7 +229,7 @@
229
229
  </div>
230
230
  </div>
231
231
 
232
- <% if Flipper::UI.feature_removal_enabled %>
232
+ <% if Flipper::UI.configuration.feature_removal_enabled %>
233
233
  <div class="row">
234
234
  <div class="col">
235
235
  <div class="card border-danger">
@@ -1,3 +1,3 @@
1
1
  <div class="alert alert-danger">
2
- Feature creation is disabled. To enable, you'll need to set <code>Flipper::UI.feature_creation_enabled = true</code> wherever flipper is running from.
2
+ Feature creation is disabled. To enable, you'll need to set <code>Flipper::UI.configuration.feature_creation_enabled = true</code> wherever flipper is running from.
3
3
  </div>
@@ -1,3 +1,3 @@
1
1
  <div class="alert alert-danger">
2
- Feature removal from the UI is disabled. To enable, you'll need to set <code>Flipper::UI.feature_removal_enabled = true</code> wherever flipper is running from.
2
+ Feature removal from the UI is disabled. To enable, you'll need to set <code>Flipper::UI.configuration.feature_removal_enabled = true</code> wherever flipper is running from.
3
3
  </div>
@@ -35,7 +35,7 @@
35
35
  </li>
36
36
  <% end %>
37
37
  <li class="ml-auto">
38
- <%- if Flipper::UI.feature_creation_enabled -%>
38
+ <%- if Flipper::UI.configuration.feature_creation_enabled -%>
39
39
  <a class="btn btn-sm btn-light" href="<%= script_name %>/features/new">Add Feature</a>
40
40
  <%- end -%>
41
41
  </li>
@@ -1,3 +1,3 @@
1
1
  module Flipper
2
- VERSION = '0.14.0'.freeze
2
+ VERSION = '0.15.0'.freeze
3
3
  end
@@ -3,13 +3,13 @@ require 'helper'
3
3
  RSpec.describe Flipper::UI::Actions::AddFeature do
4
4
  describe 'GET /features/new with feature_creation_enabled set to true' do
5
5
  before do
6
- @original_feature_creation_enabled = Flipper::UI.feature_creation_enabled
7
- Flipper::UI.feature_creation_enabled = true
6
+ @original_feature_creation_enabled = Flipper::UI.configuration.feature_creation_enabled
7
+ Flipper::UI.configuration.feature_creation_enabled = true
8
8
  get '/features/new'
9
9
  end
10
10
 
11
11
  after do
12
- Flipper::UI.feature_creation_enabled = @original_feature_creation_enabled
12
+ Flipper::UI.configuration.feature_creation_enabled = @original_feature_creation_enabled
13
13
  end
14
14
 
15
15
  it 'responds with success' do
@@ -24,13 +24,13 @@ RSpec.describe Flipper::UI::Actions::AddFeature do
24
24
 
25
25
  describe 'GET /features/new with feature_creation_enabled set to false' do
26
26
  before do
27
- @original_feature_creation_enabled = Flipper::UI.feature_creation_enabled
28
- Flipper::UI.feature_creation_enabled = false
27
+ @original_feature_creation_enabled = Flipper::UI.configuration.feature_creation_enabled
28
+ Flipper::UI.configuration.feature_creation_enabled = false
29
29
  get '/features/new'
30
30
  end
31
31
 
32
32
  after do
33
- Flipper::UI.feature_creation_enabled = @original_feature_creation_enabled
33
+ Flipper::UI.configuration.feature_creation_enabled = @original_feature_creation_enabled
34
34
  end
35
35
 
36
36
  it 'returns 403' do
@@ -32,11 +32,11 @@ RSpec.describe Flipper::UI::Actions::Feature do
32
32
  context 'when feature_removal_enabled is set to false' do
33
33
  around do |example|
34
34
  begin
35
- @original_feature_removal_enabled = Flipper::UI.feature_removal_enabled
36
- Flipper::UI.feature_removal_enabled = false
35
+ @original_feature_removal_enabled = Flipper::UI.configuration.feature_removal_enabled
36
+ Flipper::UI.configuration.feature_removal_enabled = false
37
37
  example.run
38
38
  ensure
39
- Flipper::UI.feature_removal_enabled = @original_feature_removal_enabled
39
+ Flipper::UI.configuration.feature_removal_enabled = @original_feature_removal_enabled
40
40
  end
41
41
  end
42
42
 
@@ -87,4 +87,24 @@ RSpec.describe Flipper::UI::Actions::Feature do
87
87
  expect(last_response.body).to include('Percentage of Actors')
88
88
  end
89
89
  end
90
+
91
+ describe 'GET /features/:feature with _features in feature name' do
92
+ before do
93
+ get '/features/search_features'
94
+ end
95
+
96
+ it 'responds with success' do
97
+ expect(last_response.status).to be(200)
98
+ end
99
+
100
+ it 'renders template' do
101
+ expect(last_response.body).to include('search_features')
102
+ expect(last_response.body).to include('Enable')
103
+ expect(last_response.body).to include('Disable')
104
+ expect(last_response.body).to include('Actors')
105
+ expect(last_response.body).to include('Groups')
106
+ expect(last_response.body).to include('Percentage of Time')
107
+ expect(last_response.body).to include('Percentage of Actors')
108
+ end
109
+ end
90
110
  end
@@ -33,15 +33,15 @@ RSpec.describe Flipper::UI::Actions::Features do
33
33
  let(:feature_name) { 'notifications_next' }
34
34
 
35
35
  before do
36
- @original_feature_creation_enabled = Flipper::UI.feature_creation_enabled
37
- Flipper::UI.feature_creation_enabled = feature_creation_enabled
36
+ @original_feature_creation_enabled = Flipper::UI.configuration.feature_creation_enabled
37
+ Flipper::UI.configuration.feature_creation_enabled = feature_creation_enabled
38
38
  post '/features',
39
39
  { 'value' => feature_name, 'authenticity_token' => token },
40
40
  'rack.session' => session
41
41
  end
42
42
 
43
43
  after do
44
- Flipper::UI.feature_creation_enabled = @original_feature_creation_enabled
44
+ Flipper::UI.configuration.feature_creation_enabled = @original_feature_creation_enabled
45
45
  end
46
46
 
47
47
  context 'feature_creation_enabled set to true' do
@@ -69,4 +69,37 @@ RSpec.describe Flipper::UI::Configuration do
69
69
  .to raise_error(Flipper::InvalidConfigurationValue)
70
70
  end
71
71
  end
72
+
73
+ describe "#application_breadcrumb_href" do
74
+ it "has default value" do
75
+ expect(configuration.application_breadcrumb_href).to eq(nil)
76
+ end
77
+
78
+ it "can be updated" do
79
+ configuration.application_breadcrumb_href = 'http://www.myapp.com'
80
+ expect(configuration.application_breadcrumb_href).to eq('http://www.myapp.com')
81
+ end
82
+ end
83
+
84
+ describe "#feature_creation_enabled" do
85
+ it "has default value" do
86
+ expect(configuration.feature_creation_enabled).to eq(true)
87
+ end
88
+
89
+ it "can be updated" do
90
+ configuration.feature_creation_enabled = false
91
+ expect(configuration.feature_creation_enabled).to eq(false)
92
+ end
93
+ end
94
+
95
+ describe "#feature_removal_enabled" do
96
+ it "has default value" do
97
+ expect(configuration.feature_removal_enabled).to eq(true)
98
+ end
99
+
100
+ it "can be updated" do
101
+ configuration.feature_removal_enabled = false
102
+ expect(configuration.feature_removal_enabled).to eq(false)
103
+ end
104
+ end
72
105
  end
@@ -11,6 +11,7 @@ RSpec.describe Flipper::UI do
11
11
  let(:session) do
12
12
  { :csrf => token, 'csrf' => token, '_csrf_token' => token }
13
13
  end
14
+ let(:configuration) { described_class.configuration }
14
15
 
15
16
  describe 'Initializing middleware with flipper instance' do
16
17
  let(:app) { build_app(flipper) }
@@ -59,91 +60,24 @@ RSpec.describe Flipper::UI do
59
60
  expect(last_response.headers['Location']).to eq('/features/refactor-images')
60
61
  end
61
62
 
62
- it 'does not have an application_breadcrumb_href by default' do
63
- expect(described_class.application_breadcrumb_href).to be(nil)
64
- end
65
-
66
- context 'with application_breadcrumb_href not set' do
67
- before do
68
- @original_application_breadcrumb_href = described_class.application_breadcrumb_href
69
- described_class.application_breadcrumb_href = nil
70
- end
71
-
72
- after do
73
- described_class.application_breadcrumb_href = @original_application_breadcrumb_href
74
- end
75
-
76
- it 'does not add App breadcrumb' do
77
- get '/features'
78
- expect(last_response.body).not_to include('<a href="/myapp">App</a>')
63
+ describe "application_breadcrumb_href" do
64
+ it "raises an exception since it is deprecated" do
65
+ expect { described_class.application_breadcrumb_href }
66
+ .to raise_error(Flipper::ConfigurationDeprecated)
79
67
  end
80
68
  end
81
69
 
82
- context 'with application_breadcrumb_href set' do
83
- before do
84
- @original_application_breadcrumb_href = described_class.application_breadcrumb_href
85
- described_class.application_breadcrumb_href = '/myapp'
86
- end
87
-
88
- after do
89
- described_class.application_breadcrumb_href = @original_application_breadcrumb_href
90
- end
91
-
92
- it 'does add App breadcrumb' do
93
- get '/features'
94
- expect(last_response.body).to include('<a href="/myapp">App</a>')
70
+ describe "feature_creation_enabled" do
71
+ it "raises an exception since it is deprecated" do
72
+ expect { described_class.feature_creation_enabled }
73
+ .to raise_error(Flipper::ConfigurationDeprecated)
95
74
  end
96
75
  end
97
76
 
98
- context 'with application_breadcrumb_href set to full url' do
99
- before do
100
- @original_application_breadcrumb_href = described_class.application_breadcrumb_href
101
- described_class.application_breadcrumb_href = 'https://myapp.com/'
102
- end
103
-
104
- after do
105
- described_class.application_breadcrumb_href = @original_application_breadcrumb_href
106
- end
107
-
108
- it 'does add App breadcrumb' do
109
- get '/features'
110
- expect(last_response.body).to include('<a href="https://myapp.com/">App</a>')
111
- end
112
- end
113
-
114
- it 'sets feature_creation_enabled to true by default' do
115
- expect(described_class.feature_creation_enabled).to be(true)
116
- end
117
-
118
- context 'with feature_creation_enabled set to true' do
119
- before do
120
- @original_feature_creation_enabled = described_class.feature_creation_enabled
121
- described_class.feature_creation_enabled = true
122
- end
123
-
124
- it 'has the add_feature button' do
125
- get '/features'
126
- expect(last_response.body).to include('Add Feature')
127
- end
128
-
129
- after do
130
- described_class.feature_creation_enabled = @original_feature_creation_enabled
131
- end
132
- end
133
-
134
- context 'with feature_creation_enabled set to false' do
135
- before do
136
- @original_feature_creation_enabled = described_class.feature_creation_enabled
137
- described_class.feature_creation_enabled = false
138
- end
139
-
140
- it 'does not have the add_feature button' do
141
- get '/features'
142
- expect(last_response.body).not_to include('Add Feature')
143
- end
144
-
145
- after do
146
- described_class.feature_creation_enabled = @original_feature_creation_enabled
77
+ describe "feature_removal_enabled" do
78
+ it "raises an exception since it is deprecated" do
79
+ expect { described_class.feature_removal_enabled }
80
+ .to raise_error(Flipper::ConfigurationDeprecated)
147
81
  end
148
82
  end
149
83
 
@@ -177,5 +111,135 @@ RSpec.describe Flipper::UI do
177
111
  end
178
112
  end
179
113
  end
114
+
115
+ describe "application_breadcrumb_href" do
116
+ it 'does not have an application_breadcrumb_href by default' do
117
+ expect(configuration.application_breadcrumb_href).to be(nil)
118
+ end
119
+
120
+ context 'with application_breadcrumb_href not set' do
121
+ before do
122
+ @original_application_breadcrumb_href = configuration.application_breadcrumb_href
123
+ configuration.application_breadcrumb_href = nil
124
+ end
125
+
126
+ after do
127
+ configuration.application_breadcrumb_href = @original_application_breadcrumb_href
128
+ end
129
+
130
+ it 'does not add App breadcrumb' do
131
+ get '/features'
132
+ expect(last_response.body).not_to include('<a href="/myapp">App</a>')
133
+ end
134
+ end
135
+
136
+ context 'with application_breadcrumb_href set' do
137
+ before do
138
+ @original_application_breadcrumb_href = configuration.application_breadcrumb_href
139
+ configuration.application_breadcrumb_href = '/myapp'
140
+ end
141
+
142
+ after do
143
+ configuration.application_breadcrumb_href = @original_application_breadcrumb_href
144
+ end
145
+
146
+ it 'does add App breadcrumb' do
147
+ get '/features'
148
+ expect(last_response.body).to include('<a href="/myapp">App</a>')
149
+ end
150
+ end
151
+
152
+ context 'with application_breadcrumb_href set to full url' do
153
+ before do
154
+ @original_application_breadcrumb_href = configuration.application_breadcrumb_href
155
+ configuration.application_breadcrumb_href = 'https://myapp.com/'
156
+ end
157
+
158
+ after do
159
+ configuration.application_breadcrumb_href = @original_application_breadcrumb_href
160
+ end
161
+
162
+ it 'does add App breadcrumb' do
163
+ get '/features'
164
+ expect(last_response.body).to include('<a href="https://myapp.com/">App</a>')
165
+ end
166
+ end
167
+ end
168
+
169
+ describe "feature_creation_enabled" do
170
+ it 'sets feature_creation_enabled to true by default' do
171
+ expect(configuration.feature_creation_enabled).to be(true)
172
+ end
173
+
174
+ context 'with feature_creation_enabled set to true' do
175
+ before do
176
+ @original_feature_creation_enabled = configuration.feature_creation_enabled
177
+ configuration.feature_creation_enabled = true
178
+ end
179
+
180
+ it 'has the add_feature button' do
181
+ get '/features'
182
+ expect(last_response.body).to include('Add Feature')
183
+ end
184
+
185
+ after do
186
+ configuration.feature_creation_enabled = @original_feature_creation_enabled
187
+ end
188
+ end
189
+
190
+ context 'with feature_creation_enabled set to false' do
191
+ before do
192
+ @original_feature_creation_enabled = configuration.feature_creation_enabled
193
+ configuration.feature_creation_enabled = false
194
+ end
195
+
196
+ it 'does not have the add_feature button' do
197
+ get '/features'
198
+ expect(last_response.body).not_to include('Add Feature')
199
+ end
200
+
201
+ after do
202
+ configuration.feature_creation_enabled = @original_feature_creation_enabled
203
+ end
204
+ end
205
+ end
206
+
207
+ describe "feature_removal_enabled" do
208
+ it 'sets feature_removal_enabled to true by default' do
209
+ expect(configuration.feature_removal_enabled).to be(true)
210
+ end
211
+
212
+ context 'with feature_removal_enabled set to true' do
213
+ before do
214
+ @original_feature_removal_enabled = configuration.feature_removal_enabled
215
+ configuration.feature_removal_enabled = true
216
+ end
217
+
218
+ it 'has the add_feature button' do
219
+ get '/features/test'
220
+ expect(last_response.body).to include('Delete')
221
+ end
222
+
223
+ after do
224
+ configuration.feature_removal_enabled = @original_feature_removal_enabled
225
+ end
226
+ end
227
+
228
+ context 'with feature_removal_enabled set to false' do
229
+ before do
230
+ @original_feature_removal_enabled = configuration.feature_removal_enabled
231
+ configuration.feature_removal_enabled = false
232
+ end
233
+
234
+ it 'does not have the add_feature button' do
235
+ get '/features/test'
236
+ expect(last_response.body).not_to include('Delete')
237
+ end
238
+
239
+ after do
240
+ configuration.feature_removal_enabled = @original_feature_removal_enabled
241
+ end
242
+ end
243
+ end
180
244
  end
181
245
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flipper-ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.0
4
+ version: 0.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-27 00:00:00.000000000 Z
11
+ date: 2018-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -56,14 +56,14 @@ dependencies:
56
56
  requirements:
57
57
  - - "~>"
58
58
  - !ruby/object:Gem::Version
59
- version: 0.14.0
59
+ version: 0.15.0
60
60
  type: :runtime
61
61
  prerelease: false
62
62
  version_requirements: !ruby/object:Gem::Requirement
63
63
  requirements:
64
64
  - - "~>"
65
65
  - !ruby/object:Gem::Version
66
- version: 0.14.0
66
+ version: 0.15.0
67
67
  - !ruby/object:Gem::Dependency
68
68
  name: erubis
69
69
  requirement: !ruby/object:Gem::Requirement
@@ -289,7 +289,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
289
289
  version: '0'
290
290
  requirements: []
291
291
  rubyforge_project:
292
- rubygems_version: 2.6.14
292
+ rubygems_version: 2.4.5.4
293
293
  signing_key:
294
294
  specification_version: 4
295
295
  summary: UI for the Flipper gem