sinatra-bouncer 1.3.0 → 2.0.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
  SHA256:
3
- metadata.gz: 6b8592539c3824fa1985a4c02b877bd7d53e6ab2635f4227b173325f16484465
4
- data.tar.gz: 1aac0ef35f8584e83cbafd5843172798f8967ad217235f9048e476cf3cc8945f
3
+ metadata.gz: f07c9c87e55563ac21610aecc8813d32ee3322d291382bb1bd5cca0ce0d55a12
4
+ data.tar.gz: fa55400409722c0f0f4ea83c6ee552654d0d8aee128d484f3a42c2c888e9b46b
5
5
  SHA512:
6
- metadata.gz: 83ed25a0acff1d864f978dbbd3667d20f53be0bea36fa5db5abd55eeb4353cad53e29ebeb424f1c462e4a8790444f4a5850cad33c579729aab684ff4f0d482aa
7
- data.tar.gz: a3caa0c02709faa60e5512f73f2b4c4f21066f519999e014ffac2545271198d8a98a7a73d430494a185a00e0ea255170e1693274c7fb8bca51b56c6108fcd8a6
6
+ metadata.gz: 4fc6e73dcb5867a418dea6b555f74fee57f41b58d75ab76657925a71b1b2ff059295135c30646f4de83fe82a00bc816a6d668d54ecd64f035b63f27d68b80ef1
7
+ data.tar.gz: ca808e79a1f59743c17afc6e7475dd03a9a3186d8ed1ec3c6b4412ec96af2c38c0e454a0fada15c513e83c1070eb7b6f72c2a116be9e2ed7135592ce7f04ce70
data/.gitignore CHANGED
@@ -4,9 +4,6 @@
4
4
  # or operating system, you probably want to add a global ignore instead:
5
5
  # git config --global core.excludesfile ~/.gitignore_global
6
6
 
7
- # Ignore bundler config
8
- /.bundle
9
-
10
7
  # Ignore all logfiles and tempfiles.
11
8
  *.log
12
9
  tmp/*
@@ -17,7 +14,5 @@ tmp/*
17
14
  # Ignore all gem files.
18
15
  *.gem
19
16
 
20
- core/config.yml
21
- persist/database.yml
22
-
23
- Gemfile.lock
17
+ # Ignore simplecov results
18
+ .coverage/
data/.rubocop.yml CHANGED
@@ -3,6 +3,7 @@ inherit_from: ~/.config/rubocop/config.yml
3
3
  AllCops:
4
4
  Exclude:
5
5
  - 'bin/*'
6
+ - 'benchmarks/*'
6
7
 
7
8
  Layout/LineLength:
8
9
  Exclude:
@@ -11,12 +12,3 @@ Layout/LineLength:
11
12
  # setting to 6 to match RubyMine autoformat
12
13
  Layout/FirstArrayElementIndentation:
13
14
  IndentationWidth: 6
14
-
15
- # rspec blocks are huge by design
16
- Metrics/BlockLength:
17
- Exclude:
18
- - 'tests/spec/**/*.rb'
19
-
20
- Metrics/ModuleLength:
21
- Exclude:
22
- - 'tests/spec/**/*.rb'
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at robin@tenjin.ca. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile CHANGED
@@ -7,13 +7,14 @@ gemspec
7
7
 
8
8
  group :development do
9
9
  gem 'bundler', '~> 2.4'
10
- gem 'rake', '~> 13.0'
10
+ gem 'rake', '~> 13.1'
11
+ gem 'rubocop', '~> 1.57'
12
+ gem 'rubocop-performance', '~> 1.19'
11
13
  gem 'yard', '~> 0.9'
12
14
  end
13
15
 
14
16
  group :test do
15
- gem 'capybara', '~> 3.39'
16
- gem 'cucumber', '~> 8.0'
17
+ gem 'rack-test', '~> 2.1'
17
18
  gem 'rspec', '~> 3.12'
18
19
  gem 'simplecov', '~> 0.22'
19
20
  end
data/Gemfile.lock ADDED
@@ -0,0 +1,92 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ sinatra-bouncer (2.0.0)
5
+ sinatra (>= 2.2)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ ast (2.4.2)
11
+ diff-lcs (1.5.0)
12
+ docile (1.4.0)
13
+ json (2.6.3)
14
+ language_server-protocol (3.17.0.3)
15
+ mustermann (3.0.0)
16
+ ruby2_keywords (~> 0.0.1)
17
+ parallel (1.23.0)
18
+ parser (3.2.2.4)
19
+ ast (~> 2.4.1)
20
+ racc
21
+ racc (1.7.3)
22
+ rack (2.2.8)
23
+ rack-protection (3.1.0)
24
+ rack (~> 2.2, >= 2.2.4)
25
+ rack-test (2.1.0)
26
+ rack (>= 1.3)
27
+ rainbow (3.1.1)
28
+ rake (13.1.0)
29
+ regexp_parser (2.8.2)
30
+ rexml (3.2.6)
31
+ rspec (3.12.0)
32
+ rspec-core (~> 3.12.0)
33
+ rspec-expectations (~> 3.12.0)
34
+ rspec-mocks (~> 3.12.0)
35
+ rspec-core (3.12.2)
36
+ rspec-support (~> 3.12.0)
37
+ rspec-expectations (3.12.3)
38
+ diff-lcs (>= 1.2.0, < 2.0)
39
+ rspec-support (~> 3.12.0)
40
+ rspec-mocks (3.12.6)
41
+ diff-lcs (>= 1.2.0, < 2.0)
42
+ rspec-support (~> 3.12.0)
43
+ rspec-support (3.12.1)
44
+ rubocop (1.57.2)
45
+ json (~> 2.3)
46
+ language_server-protocol (>= 3.17.0)
47
+ parallel (~> 1.10)
48
+ parser (>= 3.2.2.4)
49
+ rainbow (>= 2.2.2, < 4.0)
50
+ regexp_parser (>= 1.8, < 3.0)
51
+ rexml (>= 3.2.5, < 4.0)
52
+ rubocop-ast (>= 1.28.1, < 2.0)
53
+ ruby-progressbar (~> 1.7)
54
+ unicode-display_width (>= 2.4.0, < 3.0)
55
+ rubocop-ast (1.30.0)
56
+ parser (>= 3.2.1.0)
57
+ rubocop-performance (1.19.1)
58
+ rubocop (>= 1.7.0, < 2.0)
59
+ rubocop-ast (>= 0.4.0)
60
+ ruby-progressbar (1.13.0)
61
+ ruby2_keywords (0.0.5)
62
+ simplecov (0.22.0)
63
+ docile (~> 1.1)
64
+ simplecov-html (~> 0.11)
65
+ simplecov_json_formatter (~> 0.1)
66
+ simplecov-html (0.12.3)
67
+ simplecov_json_formatter (0.1.4)
68
+ sinatra (3.1.0)
69
+ mustermann (~> 3.0)
70
+ rack (~> 2.2, >= 2.2.4)
71
+ rack-protection (= 3.1.0)
72
+ tilt (~> 2.0)
73
+ tilt (2.2.0)
74
+ unicode-display_width (2.5.0)
75
+ yard (0.9.34)
76
+
77
+ PLATFORMS
78
+ x86_64-linux
79
+
80
+ DEPENDENCIES
81
+ bundler (~> 2.4)
82
+ rack-test (~> 2.1)
83
+ rake (~> 13.1)
84
+ rspec (~> 3.12)
85
+ rubocop (~> 1.57)
86
+ rubocop-performance (~> 1.19)
87
+ simplecov (~> 0.22)
88
+ sinatra-bouncer!
89
+ yard (~> 0.9)
90
+
91
+ BUNDLED WITH
92
+ 2.4.19
data/README.md CHANGED
@@ -1,108 +1,268 @@
1
- #Sinatra-Bouncer
2
- Simple authorization permissions extension for [Sinatra](http://www.sinatrarb.com/). Require the gem, then declare which routes are permitted based on your own logic.
1
+ # Sinatra-Bouncer
2
+
3
+ Simple permissions extension for [Sinatra](http://www.sinatrarb.com/). Require the gem, then declare which
4
+ routes are permitted based on your own logic.
5
+
6
+ ## Big Picture
7
+
8
+ Bouncer rules look like:
3
9
 
4
- **Gemfile**
5
10
  ```ruby
6
- gem 'sinatra-bouncer'
7
- ```
11
+ rules do
12
+ # Routes match based on one or more strings.
13
+ can get: '/',
14
+ post: %w[/user/sign-in
15
+ /user/sign-out]
16
+
17
+ # Wildcards match anything directly under that path
18
+ can get: '/lib/js/*'
19
+
20
+ # Use a conditional rule block for additional logic
21
+ can_sometimes get: '/admin/*',
22
+ post: '/admin/actions/*' do
23
+ current_user.admin?
24
+ end
25
+
26
+ # ... etc ...
27
+ end
8
28
 
9
- **Terminal**
10
- ```sh
11
- gem install sinatra-bouncer
12
29
  ```
13
30
 
14
- ##Quickstart
15
- ###Step 1: Require/Register Bouncer
31
+ ## Features
16
32
 
17
- After registration, Bouncer will reject any request that either:
18
- * has no rule associated with it, or
19
- * has no associated rule that returns `true`
33
+ Here's what this Gem provides:
34
+
35
+ * **Block-by-default**
36
+ * Any route must be explicitly allowed
37
+ * **Declarative Syntax**
38
+ * Straightforward syntax reduces complexity of layered permissions
39
+ * Keeps permissions together for clarity
40
+ * **Conditional Logic Via Blocks**
41
+ * Often additional checks must be performed to know if a route is allowed.
42
+ * **Grouping**
43
+ * Routes can be matched by wildcard
44
+ * **Forced Boolean Affirmation**
45
+ * Condition blocks must explicitly return `true`, avoiding accidental truthy values
46
+
47
+ ## Anti-Features
48
+
49
+ Bouncer intentionally does not support some concepts.
50
+
51
+ * **No User Identification** *(aka Authentication)*
52
+ * Bouncer is not a user identification gem. It assumes you already have an existing solution
53
+ like [Warden](https://github.com/wardencommunity/warden). Knowing *who* someone is is already a complex enough
54
+ problem and should be separate from what they may do.
55
+ * **No Rails Integration**
56
+ * Bouncer is not intended to work with Rails. Use one of the Rails-based permissions gems for these situations.
57
+ * **No Negation**
58
+ * There is intentionally no negation (eg. `cannot`) to preserve the default-deny frame of mind
59
+
60
+ ## Installation
61
+
62
+ Add this to your gemfile:
20
63
 
21
- **Sinatra Classic**
22
64
  ```ruby
23
- require 'sinatra'
24
- require 'sinatra/bouncer'
65
+ gem 'sinatra-bouncer'
66
+ ```
25
67
 
26
- # ... routes and other config
68
+ Then run:
69
+
70
+ ```shell
71
+ bundle install
27
72
  ```
28
73
 
29
- **Modular**
74
+ **Sinatra Modular Style**
75
+
30
76
  ```ruby
31
77
  require 'sinatra/base'
32
78
  require 'sinatra/bouncer'
33
79
 
34
80
  class MyApp < Sinatra::Base
35
- register Sinatra::Bouncer
36
-
37
- # ... routes and other config
81
+ register Sinatra::Bouncer
82
+
83
+ rules do
84
+ # ... can statements ...
85
+ end
86
+
87
+ # ... routes and other config
38
88
  end
39
89
  ```
40
90
 
41
- ###Step 2: Declare Bouncer Rules
42
- Call `rules` with a block that uses `can` and `can_sometimes` to declare which paths are legalduring this request. The rules block is run in the context of the request, which means you will have access to sinatra helpers,
43
- the `request` object, and `params`.
91
+ **Sinatra Classic Style**
44
92
 
45
93
  ```ruby
46
94
  require 'sinatra'
47
95
  require 'sinatra/bouncer'
48
96
 
49
97
  rules do
50
- # example: allow any GET request
51
- can(:get, :all)
52
-
53
- # example: logged in users can edit their account
54
- if(current_user)
55
- can(:post, '/user_edits_account')
56
- end
98
+ # ... can statements ...
57
99
  end
58
100
 
59
- # ... route declarations as normal below
101
+ # ... routes and other config
60
102
  ```
61
103
 
62
- ## API
63
- #### can
64
- Any route declared with #can will be accepted without further challenge.
104
+ ## Usage
105
+
106
+ Call `rules` with a block that uses the `#can` and `#can_sometimes` DSL methods to declare rules for paths.
107
+
108
+ The rules block is run once as part of the configuration phase but the condition blocks are evaluated in the context of
109
+ the
110
+ request, which means you will have access to Sinatra helpers,
111
+ the `request` object, and `params`.
65
112
 
66
113
  ```ruby
114
+ require 'sinatra'
115
+ require 'sinatra/bouncer'
116
+
67
117
  rules do
68
- can(:post, '/user_posts_blog')
118
+ # example: always allow GET requests to root path or /sign-in
119
+ can get: %w[/
120
+ /sign-in]
121
+
122
+ # example: logged in users can view (GET) member restricted paths and edit their account (POST)
123
+ can_sometimes get: '/members/*',
124
+ post: '/members/edit-account' do
125
+ !current_user.nil?
126
+ end
127
+
128
+ # example: check an arbitrary request header is present
129
+ can_sometimes get: '/bots/*' do
130
+ !request.get_header('X-CUSTOM_PROP').nil?
131
+ end
69
132
  end
133
+
134
+ # ... Sinatra route declarations as normal ...
70
135
  ```
71
136
 
72
- ####can_sometimes
73
- `can_sometimes` is for occasions that you to check further, but want to defer that choice until the path is actually attempted.
74
- `can_sometimes` takes a block that will be run once the path is attempted. This block **must return an explicit boolean**
75
- (ie. `true` or `false`) to avoid any accidental truthy values creating unwanted access.
137
+ ### HTTP Method and Route Matching
138
+
139
+ Both `#can` and `#can_sometimes` accept multiple
140
+ [HTTP methods](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) as symbols
141
+ and each key is paired with one or more path strings.
142
+
143
+ ```ruby
144
+ # example: single method, single route
145
+ can get: '/'
146
+
147
+ # example: multiple methods, single route each
148
+ can get: '/',
149
+ post: '/blog/action/save'
150
+
151
+ # example: multiple methods, multiple routes (using string array syntax)
152
+ can get: %w[/
153
+ /sign-in
154
+ /blog/editor],
155
+ post: %w[/blog/action/save
156
+ /blog/action/delete]
157
+ ```
158
+
159
+ > **Note** Allowing GET implies allowing HEAD, since HEAD is by spec a GET without a response body. The reverse is not
160
+ > true, however; allowing HEAD will not also allow GET.
161
+
162
+ #### Wildcards and Special Symbols
163
+
164
+ > **Warning** Always be cautious when using wildcards and special symbols to not accidentally open up pathways that
165
+ > should remain private.
166
+
167
+ Provide a wildcard `*` to match any string excluding slash. There is intentionally no syntax for matching wildcards
168
+ recursively, so nested paths will also need to be declared.
169
+
170
+ ```ruby
171
+ # example: match anything directly under the /members/ path
172
+ can get: '/members/*'
173
+ ```
174
+
175
+ There are also 2 special symbols:
176
+
177
+ 1. `:any` will match any HTTP method.
178
+ 2. `:all` will match all paths.
179
+
180
+ ```ruby
181
+ # this allows any method type on the / path
182
+ can any: '/'
183
+
184
+ # this allows GET on all paths
185
+ can get: :all
186
+ ```
187
+
188
+ ### Always Allow: `can`
189
+
190
+ Any route declared with `#can` will be accepted without further challenge.
76
191
 
77
192
  ```ruby
78
193
  rules do
79
- can_sometimes('/login') # Anyone can access this path
194
+ # Anyone can access this path over GET
195
+ can get: '/login'
80
196
  end
81
197
  ```
82
198
 
83
- #### :any and :all special parameters
84
- Passing `can` or `can_sometimes`:
85
- * `:any` to the first parameter will match any HTTP method.
86
- * `:all` to the second parameter will match any path.
199
+ ### Conditionally Allow: `can_sometimes`
200
+
201
+ `can_sometimes` is for occasions that you to check further, but want to defer that choice until the path is actually
202
+ attempted.
203
+ `can_sometimes` takes a block that will be run once the path is attempted. This block **must return an explicit boolean
204
+ **
205
+ (ie. `true` or `false`) to avoid any accidental truthy values creating unwanted access.
87
206
 
88
207
  ```ruby
89
- # this allows get on all paths
90
- can(:get, :all)
208
+ rules do
209
+ can_sometimes get: '/login' # Anyone can access this path over GET
91
210
 
92
- # this allows any method type to run on the /login path
93
- can(:any, '/login')
211
+ can_sometimes post: '/user/blog/actions/save' do
212
+ !current_user.nil?
213
+ end
214
+ end
94
215
  ```
95
216
 
96
217
  ### Custom Bounce Behaviour
97
- The default bounce action is to `halt 403`. Call `bounce_with` with a block to specify your own behaviour. The block is also run in a sinatra request context, so you can use helpers here as well.
218
+
219
+ The default bounce action is to `halt 403`. Call `bounce_with` with a block to specify your own behaviour. The block is
220
+ also run in a sinatra request context, so you can use helpers here as well.
98
221
 
99
222
  ```ruby
100
223
  require 'sinatra'
101
224
  require 'sinatra/bouncer'
102
225
 
103
- bounce_with do
104
- redirect '/login'
226
+ bounce_with do
227
+ redirect '/login'
105
228
  end
106
229
 
107
230
  # bouncer rules, routes, etc...
108
231
  ```
232
+
233
+ ## Alternatives
234
+
235
+ The syntax for Bouncer is largely influenced by the now-deprecated [CanCan](https://github.com/ryanb/cancan) gem.
236
+
237
+ ## Contributing
238
+
239
+ Bug reports and pull requests are welcome on GitHub at https://github.com/TenjinInc/Sinatra-Bouncer.
240
+
241
+ Valued topics:
242
+
243
+ * Error messages (clarity, hinting)
244
+ * Documentation
245
+ * API
246
+ * Security correctness
247
+
248
+ This project is intended to be a friendly space for collaboration, and contributors are expected to adhere to the
249
+ [Contributor Covenant](https://www.contributor-covenant.org/) code of conduct. Play nice.
250
+
251
+ ### Core Developers
252
+
253
+ After checking out the repo, run `bundle install` to install dependencies. Then, run `rake spec` to run the tests. You
254
+ can also run `bin/console` for an interactive prompt that will allow you to experiment.
255
+
256
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the
257
+ version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version,
258
+ push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
259
+
260
+ Documentation is produced by Yard. Run `bundle exec rake yard`. The goal is to have 100% documentation coverage and 100%
261
+ test coverage.
262
+
263
+ Release notes are provided in `RELEASE_NOTES.md`, and should vaguely
264
+ follow [Keep A Changelog](https://keepachangelog.com/en/1.0.0/) recommendations.
265
+
266
+ ## License
267
+
268
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/license/mit/).
data/RELEASE_NOTES.md ADDED
@@ -0,0 +1,153 @@
1
+ # Release Notes
2
+
3
+ All notable changes to this project will be documented below.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project loosely follows
6
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Major Changes
11
+
12
+ * none
13
+
14
+ ### Minor Changes
15
+
16
+ * none
17
+
18
+ ### Bugfixes
19
+
20
+ * none
21
+
22
+ ## [2.0.0] - 2023-11-13
23
+
24
+ ### Major Changes
25
+
26
+ * Converted to hash syntax in `can` and `can_sometimes` statements
27
+
28
+ ### Minor Changes
29
+
30
+ * Converted Cucumber tests to Rspec integration tests for consistency
31
+ * HEAD requests are evaluated like GET requests due to semantic equivalence
32
+ * Falsey values are now acceptable rule block results
33
+
34
+ ### Bugfixes
35
+
36
+ * none
37
+
38
+ ## [1.3.0] - 2023-09-13
39
+
40
+ ### Major Changes
41
+
42
+ * none
43
+
44
+ ### Minor Changes
45
+
46
+ * Increased minimum Ruby to 3.1
47
+ * Cleaned up development dependencies
48
+ * Rubocop cleanups
49
+ * Installed Simplecov
50
+ * Created Rakefile
51
+
52
+ ### Bugfixes
53
+
54
+ * none
55
+
56
+ ## [1.2.0] - 2016-10-02
57
+
58
+ ### Major Changes
59
+
60
+ * none
61
+
62
+ ### Minor Changes
63
+
64
+ * Supports wildcard matches in route strings
65
+
66
+ ### Bugfixes
67
+
68
+ * none
69
+
70
+ ## [1.1.1] - 2015-06-02
71
+
72
+ ### Major Changes
73
+
74
+ * none
75
+
76
+ ### Minor Changes
77
+
78
+ * none
79
+
80
+ ### Bugfixes
81
+
82
+ * Runs `bounce_with` in context of web request
83
+
84
+ ## [1.1.0] - 2015-05-28
85
+
86
+ ### Major Changes
87
+
88
+ * none
89
+
90
+ ### Minor Changes
91
+
92
+ * none
93
+
94
+ ### Bugfixes
95
+
96
+ * Correctly forgets rules between routes
97
+
98
+ ## [1.0.2] - 2015-05-24
99
+
100
+ ### Major Changes
101
+
102
+ * none
103
+
104
+ ### Minor Changes
105
+
106
+ * Changed default halt to 403
107
+ * Application available in rule block
108
+
109
+ ### Bugfixes
110
+
111
+ * Fixed sinatra module registration
112
+
113
+ ## [1.0.1] - 2015-05-21
114
+
115
+ ### Major Changes
116
+
117
+ * none
118
+
119
+ ### Minor Changes
120
+
121
+ * none
122
+
123
+ ### Bugfixes
124
+
125
+ * none
126
+
127
+ ## [1.0.0] - Unreleased Prototype
128
+
129
+ ### Major Changes
130
+
131
+ * none
132
+
133
+ ### Minor Changes
134
+
135
+ * none
136
+
137
+ ### Bugfixes
138
+
139
+ * none
140
+
141
+ ## [0.1.0] - Unreleased Prototype
142
+
143
+ ### Major Changes
144
+
145
+ * Initial prototype
146
+
147
+ ### Minor Changes
148
+
149
+ * none
150
+
151
+ ### Bugfixes
152
+
153
+ * none