sinatra_param_checker 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5e455bde98aa7a56ad0635e5873ed0aca07557dd
4
+ data.tar.gz: 92336035331401f8057986c48dc73c6846b44c6e
5
+ SHA512:
6
+ metadata.gz: f5d20f412ce93c00f7f290e26dce783b479ca423a4d84d59462cebbb6594ce4829991dd2686ee973cdd58213f3e395f22c0032f8d3358def598d17755f4e6257
7
+ data.tar.gz: 6bfd2646ebbb68ab6e70c3b9aa3967bef507201235ac982bbc1041693a69932bf5f08187ee0abebe4b685a0c1e12996d40b5b7a5f74a1ceb4bcb4a4115a1aa1d
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.2.4
5
+ before_install: gem install bundler -v 1.12.5
@@ -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 caojiafeng@sensetime.com. 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 ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sinatra_param_checker.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Cao Jiafeng
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # Sinatra::ParamChecker
2
+
3
+ Sinatra::ParamChecker is an extension of Sinatra.
4
+ The extension add a before filter for your api to do the param
5
+ validation.
6
+ It supports many kinds of type checking, like Integer's range,
7
+ String's regexp, and delimiter of Array, Hash.
8
+
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ ```ruby
15
+ gem 'sinatra_param_checker'
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ Or install it yourself as:
23
+
24
+ $ gem install sinatra_param_checker
25
+
26
+ ## Usage
27
+
28
+ ``` ruby
29
+ require 'sinatra/base'
30
+ class Example < Sinatra::Base
31
+ register Sinatra::ParamChecker
32
+
33
+ api = '/example'
34
+ params api, methods: [:post] do
35
+ required :name, type: String
36
+ optional :gender, type: Boolean, default: false
37
+ end
38
+ post api do
39
+ name = params[:name]
40
+ gender = params[:gender]
41
+ # Do your logic
42
+ 'OK'
43
+ end
44
+ end
45
+ ```
46
+
47
+ ## Supported Options
48
+
49
+ ``` ruby
50
+ OPTIONS = [:type, :default, :values, :min, :max, :range, :regexp, :delimiter, :separator]
51
+ ```
52
+
53
+ - every param validation should contain a `:type` option.
54
+ - `:default` option can only be used with `optional`.
55
+ - `:values` cannot be used with `[Array, Hash, File]`.
56
+ - `:min, :max` can only be used with `[Integer, Float]`.
57
+ - `:range` can only be used with `Integer`.
58
+ - `:regexp` can only be used with `String`.
59
+ - `:delimiter` can only be used with `[Array, Hash]`.
60
+ - `:separator` can only be used with `Hash`.
61
+
62
+ Supported Types:
63
+
64
+ - TrueClass, FalseClass, ParamChecker::Boolean
65
+ - Integer, Float
66
+ - String ,ParamChecker::UUID(32)
67
+ - Date, Time, DateTime
68
+ - File
69
+ - Array, Hash
70
+
71
+ If you has more demands, ping me by issues or pull requests!
72
+
73
+
74
+ ## Development
75
+
76
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
77
+
78
+ ## Contributing
79
+
80
+ Bug reports and pull requests are welcome on GitHub at https://github.com/lerencao/sinatra_param_checker. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
81
+
82
+
83
+ ## License
84
+
85
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
86
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "sinatra/param_checker"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ require "pry"
10
+ Pry.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,22 @@
1
+ require 'json'
2
+ require 'sinatra/base'
3
+ require 'sinatra/param_checker'
4
+
5
+ class BookApp < Sinatra::Base
6
+ register Sinatra::ParamChecker
7
+
8
+ params '/books', methods: [:post] do
9
+ required 'name', type: String
10
+ optional 'author', type: String, default: 'unknown'
11
+ required 'publish_date', type: Date
12
+ end
13
+ post '/books' do
14
+ {
15
+ name: params[:name],
16
+ author: params[:author],
17
+ publish_date: params[:publish_date]
18
+ }.to_json
19
+ end
20
+
21
+ run!
22
+ end
@@ -0,0 +1,242 @@
1
+ require 'sinatra/base'
2
+
3
+ module Sinatra
4
+ module ParamChecker
5
+ Boolean = Class.new
6
+ UUID = Class.new
7
+ class InvalidParameterError < StandardError
8
+ attr_accessor :param, :options
9
+ end
10
+ class ParamScope
11
+ attr_reader :params
12
+ def initialize
13
+ @params = []
14
+ end
15
+
16
+ def required(name, options = {})
17
+ param = [:required, name.to_s, options]
18
+ validate_opts! param
19
+ @params << param
20
+ end
21
+
22
+ def optional(name, options = {})
23
+ param = [:optional, name.to_s, options]
24
+ validate_opts! param
25
+ @params << param
26
+ end
27
+
28
+ def validate!(params)
29
+ validated_params = @params.reduce({}) do |memo, e|
30
+ type, name, opts = e
31
+ begin
32
+ # handle default
33
+ v = if params[name].nil?
34
+ case type
35
+ when :optional
36
+ (opts[:default].call if opts[:default].respond_to?(:call)) || opts[:default]
37
+ when :required
38
+ raise InvalidParameterError, "param #{name} not found"
39
+ end
40
+ else
41
+ params[name]
42
+ end
43
+
44
+ unless v.nil?
45
+ coerced_value = coerce(v, opts[:type], opts)
46
+ validate(coerced_value, opts)
47
+ memo[name] = coerced_value
48
+ end
49
+ memo
50
+ rescue InvalidParameterError => e
51
+ e.param, e.options = name, opts
52
+ raise e
53
+ end
54
+ end
55
+
56
+ validated_params.reduce(params) do |memo, pair|
57
+ k, v = pair
58
+ memo[k] = v
59
+ memo
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def coerce(value, type, options = {})
66
+ return value if value.is_a?(type)
67
+ case type.name.split('::').last.to_sym
68
+ when :Integer
69
+ Integer(value)
70
+ when :Float
71
+ Float(value)
72
+ when :String
73
+ String(value)
74
+ when :UUID
75
+ String(value)
76
+ when :File
77
+ if value.is_a?(Hash) && value[:tempfile].is_a?(::Tempfile)
78
+ value
79
+ else
80
+ raise "cannot coerce value to #{type}"
81
+ end
82
+ when :Date
83
+ Date.parse(value)
84
+ when :Time
85
+ Time.parse(value)
86
+ when :DateTime
87
+ DateTime.parse(value)
88
+ when :Array
89
+ delimiter = options[:delimiter] || ','
90
+ Array(value.split(delimiter))
91
+ when :Hash
92
+ delimiter = options[:delimiter] || ','
93
+ separator = options[:separator] || ':'
94
+ value.split(delimiter).map do |c|
95
+ c.split(separator, 2)
96
+ end.to_h
97
+ when :TrueClass, :FalseClass, :Boolean
98
+ if /(false|f|no|n|0)$/i === value.to_s
99
+ false
100
+ elsif /(true|t|yes|y|1)$/i === value.to_s
101
+ true
102
+ else
103
+ raise "cannot coerce value to Boolean"
104
+ end
105
+ else
106
+ raise "cannot coerce value to #{type}"
107
+ end
108
+ rescue => _e
109
+ raise InvalidParameterError, "#{type} expected"
110
+ end
111
+
112
+
113
+ def validate(v, opts)
114
+ case opts[:type].name.split('::').last.to_sym
115
+ when :String
116
+ if opts[:regexp] && !(v =~ opts[:regexp])
117
+ raise InvalidParameterError, 'wrong format'
118
+ end
119
+ when :UUID
120
+ unless v =~ /\A[a-f0-9]{32}\z/
121
+ raise InvalidParameterError, 'uuid expected'
122
+ end
123
+ when :Integer, :Float
124
+ if opts[:type] == Integer && opts[:range] && !opts[:range].include?(v)
125
+ raise InvalidParameterError, "not in range(#{opts[:range]})"
126
+ end
127
+ if opts[:max] && v > opts[:max]
128
+ raise InvalidParameterError, "greater than #{opts[:max]}"
129
+ end
130
+ if opts[:min] && v < opts[:min]
131
+ raise InvalidParameterError, "smaller than #{opts[:min]}"
132
+ end
133
+ when :File
134
+ tf = v[:tempfile] rescue nil
135
+ raise InvalidParameterError, 'File expected' unless Tempfile === tf
136
+ end
137
+
138
+ unless [Hash, Array, File].include?(opts[:type])
139
+ if opts[:values] && !opts[:values].include?(v)
140
+ raise InvalidParameterError, 'invalid enumeration member'
141
+ end
142
+ end
143
+ end
144
+
145
+ def syntax_err(msg)
146
+ fail SyntaxError, "ParamChecker: #{msg}"
147
+ end
148
+
149
+ def check_type(type, value)
150
+ return value.is_a?(String) if type == UUID
151
+ return [true, false].include?(value) if [TrueClass, FalseClass, Boolean].include?(type)
152
+ return true if (value.is_a?(type) rescue false)
153
+ false
154
+ end
155
+
156
+ OPTIONS = [:type, :default, :values, :min, :max, :range, :regexp, :delimiter, :separator]
157
+ def validate_opts!(param)
158
+ type, name, opts = param
159
+
160
+ syntax_err "#{name}: missing option :type" unless opts[:type]
161
+ unless opts[:type].is_a?(Class)
162
+ syntax_err "#{name}: :type value should be class"
163
+ end
164
+
165
+ prefix = "#{name}(#{opts[:type]})"
166
+ opts.each do |k, v|
167
+ syntax_err "#{prefix}: unsupported option :#{k}" unless OPTIONS.include?(k)
168
+ case k
169
+ when :default
170
+ if type == :required
171
+ syntax_err "#{prefix}: :default can be used only with :optional params"
172
+ end
173
+ if [File, Array, Hash].include?(opts[:type])
174
+ syntax_err "#{prefix}: :default cannot be used with :type File, Array or Hash"
175
+ end
176
+
177
+ unless check_type(opts[:type], v)
178
+ syntax_err "#{prefix}: :default must be #{opts[:type]}"
179
+ end
180
+ when :values
181
+ if [File, Array, Hash].include?(opts[:type])
182
+ syntax_err "#{prefix}: :values cannot be used with :type File, Array or Hash"
183
+ end
184
+ unless Array === v && v.size > 0
185
+ syntax_err "#{prefix}: :values must be Array(size > 0)"
186
+ end
187
+ v.each do |val|
188
+ unless check_type(opts[:type], val)
189
+ syntax_err "#{prefix}: values in :values must be #{opts[:type]}"
190
+ end
191
+ end
192
+ when :min, :max
193
+ unless [Integer, Float].include?(opts[:type])
194
+ syntax_err "#{prefix}: :#{k} can be used only with :type Integer and Float"
195
+ end
196
+ unless check_type(opts[:type], v)
197
+ syntax_err "#{prefix}: :#{k} must be #{opts[:type]}"
198
+ end
199
+ when :range
200
+ unless opts[:type] == Integer
201
+ syntax_err "#{prefix}: :range can be used only with :type Integer"
202
+ end
203
+ unless Range === v && Integer === v.begin
204
+ syntax_err "#{prefix}: :range must be Range of Integer"
205
+ end
206
+ when :regexp
207
+ unless opts[:type] == String
208
+ syntax_err "#{prefix}: :regexp can be used only with :type String"
209
+ end
210
+ unless Regexp === v
211
+ syntax_err "#{prefix}: :regexp must be Regexp"
212
+ end
213
+ when :delimiter
214
+ unless [Array, Hash].include?(opts[:type])
215
+ syntax_err "#{prefix}: :delimiter can be used only with :type Array and Hash"
216
+ end
217
+ when :separator
218
+ unless opts[:type] == Hash
219
+ syntax_err "#{prefix}: :separator can be used only with :type Hash"
220
+ end
221
+ end
222
+ end
223
+ end
224
+ end
225
+
226
+ def params(path = nil, options = {}, &block)
227
+ ps = ParamScope.new
228
+ ps.instance_eval(&block)
229
+ methods = options.delete(:methods)
230
+ if methods.nil?
231
+ methods = [:post]
232
+ end
233
+ before path, options do
234
+ if methods.include?(self.request.request_method.downcase.to_sym)
235
+ ps.validate!(self.params)
236
+ end
237
+ end
238
+ end
239
+ end
240
+
241
+ register ParamChecker
242
+ end
@@ -0,0 +1,5 @@
1
+ module Sinatra
2
+ module ParamChecker
3
+ VERSION = "0.1.0".freeze
4
+ end
5
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sinatra/param_checker/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "sinatra_param_checker"
8
+ spec.version = Sinatra::ParamChecker::VERSION
9
+ spec.authors = ["Cao Jiafeng"]
10
+ spec.email = ["funfriendcjf@gmail.com"]
11
+
12
+ spec.summary = %q{Param checker extension of sinatra framework}
13
+ spec.description = %q{Param checker adds a before filter for each api to do the validation}
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_runtime_dependency 'sinatra', '>= 1.4.7'
20
+ spec.add_development_dependency "bundler", "~> 1.12"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "minitest", "~> 5.0"
23
+ spec.add_development_dependency 'pry', '>= 0.10'
24
+ spec.add_development_dependency 'thin', '>= 1.7.0'
25
+ end
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sinatra_param_checker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Cao Jiafeng
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-08-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sinatra
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.4.7
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.4.7
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.12'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.12'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0.10'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0.10'
83
+ - !ruby/object:Gem::Dependency
84
+ name: thin
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 1.7.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 1.7.0
97
+ description: Param checker adds a before filter for each api to do the validation
98
+ email:
99
+ - funfriendcjf@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".travis.yml"
106
+ - CODE_OF_CONDUCT.md
107
+ - Gemfile
108
+ - LICENSE.txt
109
+ - README.md
110
+ - Rakefile
111
+ - bin/console
112
+ - bin/setup
113
+ - examples/book_app.rb
114
+ - lib/sinatra/param_checker.rb
115
+ - lib/sinatra/param_checker/version.rb
116
+ - sinatra_param_checker.gemspec
117
+ homepage:
118
+ licenses:
119
+ - MIT
120
+ metadata: {}
121
+ post_install_message:
122
+ rdoc_options: []
123
+ require_paths:
124
+ - lib
125
+ required_ruby_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ requirements: []
136
+ rubyforge_project:
137
+ rubygems_version: 2.5.1
138
+ signing_key:
139
+ specification_version: 4
140
+ summary: Param checker extension of sinatra framework
141
+ test_files: []
142
+ has_rdoc: