sinatra-browse 0.5 → 0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +53 -5
- data/lib/sinatra/browse.rb +26 -6
- data/lib/sinatra/browse/erb_templates/html.erb +4 -0
- data/lib/sinatra/browse/errors.rb +3 -4
- data/lib/sinatra/browse/parameter_type.rb +29 -19
- data/lib/sinatra/browse/parameter_types/boolean.rb +14 -11
- data/lib/sinatra/browse/parameter_types/date_time.rb +28 -0
- data/lib/sinatra/browse/parameter_types/float.rb +10 -2
- data/lib/sinatra/browse/parameter_types/integer.rb +10 -2
- data/lib/sinatra/browse/parameter_types/min_max.rb +14 -0
- data/lib/sinatra/browse/parameter_types/string.rb +10 -7
- data/lib/sinatra/browse/route.rb +7 -1
- data/lib/sinatra/browse/validators/in.rb +25 -0
- metadata +12 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5bdedea1f30918fa4b4e9e40329b5d36d376e26a
|
4
|
+
data.tar.gz: a3f543ea671453b43857a83971491ebc70469aef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d9ca106f1fc4d51484e5985cfa8f6e66ff18a2fd5deedb325010decb99e1d76dbb86925a436fb1b47e4c1f2cedc0c8f1190d75d92dbba9d39db92c7db378ad9
|
7
|
+
data.tar.gz: 792cb9ccd3f3103046644bc72eb23aa71de835cb7b1b2af7cc0cd5313a8fa9b4a63c0f3cf4fe56ab8af5f63222548fe833b4684dcffce8095a986c80bce3e66e
|
data/README.md
CHANGED
@@ -40,12 +40,10 @@ The syntax is inspired by the [sinatra-param](https://github.com/mattt/sinatra-p
|
|
40
40
|
|
41
41
|
**Browsable API**
|
42
42
|
|
43
|
-
Sinatra-browse
|
43
|
+
Sinatra-browse automatically adds another route simply called `browse`. Surfing to it will display documentation generated from the parameter definitions.
|
44
44
|
|
45
45
|
http://<api_ip_address>:<api_port>/browse
|
46
46
|
|
47
|
-
*Remark:* This is still work in progress. Right now the page only shows some simple documentation.
|
48
|
-
|
49
47
|
## Parameter types
|
50
48
|
|
51
49
|
At the time of writing four parameter types are available.
|
@@ -53,17 +51,43 @@ At the time of writing four parameter types are available.
|
|
53
51
|
* `:String`
|
54
52
|
* `:Integer`
|
55
53
|
* `:Float`
|
56
|
-
* `:Boolean`
|
54
|
+
* `:Boolean`
|
55
|
+
* `:DateTime`
|
56
|
+
|
57
|
+
**Remarks:**
|
58
|
+
|
59
|
+
A `Boolean` parameter will be true for values: `"1"`, `"true"`, `"t"`, `"yes"`, `"y"` and false for values: `"0"`, `"false"`, `"f"`, `"no"`, `"n"`
|
60
|
+
|
61
|
+
A `DateTime` parameter relies on Ruby's [DateTime#parse](http://www.ruby-doc.org/stdlib-2.2.2/libdoc/date/rdoc/DateTime.html#method-c-parse) method and can thus handle all formats this method can.
|
62
|
+
|
63
|
+
Examples:
|
64
|
+
|
65
|
+
'Sat, 03 Feb 2001 04:05:06 GMT'
|
66
|
+
'Sat, 3 Feb 2001 04:05:06 +0700'
|
67
|
+
'2001-02-03T04:05:06+07:00'
|
68
|
+
'H13.02.03T04:05:06+07:00'
|
69
|
+
'2014/02/05'
|
70
|
+
'march 2nd'
|
57
71
|
|
58
72
|
## Default values
|
59
73
|
|
60
|
-
You can set default values in your declarations. These will be used when the parameter in question wasn't provided in the request. You can either set the default value or provide a proc to generate it.
|
74
|
+
You can set default values in your declarations. These will be used when the parameter in question wasn't provided in the request. You can either set the default value or provide a proc/lambda to generate it.
|
61
75
|
|
62
76
|
```ruby
|
63
77
|
param :media_type, :String, default: "book"
|
64
78
|
param :year, :Integer, default: lambda { Time.now.year }
|
65
79
|
```
|
66
80
|
|
81
|
+
## Describing parameters
|
82
|
+
|
83
|
+
Parameters declarations can have an optional arbitrary discription to be included in the generated documentation.
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
# Both of these syntaxes will work.
|
87
|
+
param :name, :Name, description: "What your mother calls you."
|
88
|
+
param :age, :Integer, desc: "The amount of years you've spent on this planet."
|
89
|
+
```
|
90
|
+
|
67
91
|
## Parameter validation
|
68
92
|
|
69
93
|
You can write some quick validation logic directly in the parameter declaration. If the validation fails, either a standard 400 error will be returned or a custom error block will execute if provided.
|
@@ -90,6 +114,30 @@ param :small_prime_number, :Integer, in: Prime.take(10)
|
|
90
114
|
param :order, :String, in: ["ascending", "descending"]
|
91
115
|
```
|
92
116
|
|
117
|
+
### Minimum and maximum validation
|
118
|
+
|
119
|
+
In the case of numeric values like `:Integer`, `:Float` and `:DateTime`, you can specify a minimum and/or maximum value.
|
120
|
+
|
121
|
+
`min` The parameter must be greater than or equal to this.
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
param :min_example, :Integer, min: 128
|
125
|
+
```
|
126
|
+
|
127
|
+
`max` The parameter must be lesser than or equal to this.
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
param :max_example, :Float, max: 66.666
|
131
|
+
```
|
132
|
+
|
133
|
+
In the case of `:DateTime`, min/max validators van be defined as either ruby's DateTime class or a String representation that Ruby's [DateTime#parse](http://www.ruby-doc.org/stdlib-2.1.1/libdoc/date/rdoc/DateTime.html#method-c-parse) method can handle.
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
param :string_min, :DateTime, min: '2014/02/05'
|
137
|
+
param :date_max, :DateTime, max: DateTime.ordinal(2005,34,4,5,6,'+7')
|
138
|
+
```
|
139
|
+
|
140
|
+
|
93
141
|
### String validation
|
94
142
|
|
95
143
|
The following parameter validators can only be used for parameters of type `:String`.
|
data/lib/sinatra/browse.rb
CHANGED
@@ -2,18 +2,38 @@
|
|
2
2
|
|
3
3
|
require 'sinatra/base'
|
4
4
|
|
5
|
-
Dir["#{File.dirname(__FILE__)}/browse/*.rb"].each {|f| require f }
|
6
|
-
Dir["#{File.dirname(__FILE__)}/browse/parameter_types/*.rb"].each do |f|
|
7
|
-
require f
|
8
|
-
end
|
9
|
-
|
10
5
|
module Sinatra::Browse
|
6
|
+
#
|
7
|
+
# Load other files
|
8
|
+
#
|
9
|
+
require_relative 'browse/format'
|
10
|
+
require_relative 'browse/parameter_type'
|
11
|
+
require_relative 'browse/route'
|
12
|
+
require_relative 'browse/validator'
|
13
|
+
|
14
|
+
module Errors
|
15
|
+
require_relative 'browse/errors'
|
16
|
+
end
|
17
|
+
|
18
|
+
module ParameterTypes
|
19
|
+
module MinMax
|
20
|
+
require_relative 'browse/parameter_types/min_max'
|
21
|
+
end
|
22
|
+
|
23
|
+
require_relative 'browse/parameter_types/boolean'
|
24
|
+
require_relative 'browse/parameter_types/date_time'
|
25
|
+
require_relative 'browse/parameter_types/float'
|
26
|
+
require_relative 'browse/parameter_types/integer'
|
27
|
+
require_relative 'browse/parameter_types/string'
|
28
|
+
end
|
29
|
+
|
11
30
|
#
|
12
31
|
# Main DSL methods
|
13
32
|
#
|
14
|
-
def
|
33
|
+
def parameter(name, type, options = {})
|
15
34
|
temp_browse_params[name] = options.merge({ type: type })
|
16
35
|
end
|
36
|
+
alias :param :parameter
|
17
37
|
|
18
38
|
def parameter_options(parameter, options)
|
19
39
|
if temp_browse_params[parameter].nil?
|
@@ -1,19 +1,34 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
module Sinatra::Browse
|
4
|
-
def self.parameter_type(name, &blk)
|
5
|
-
const_set "#{name}Type", Class.new(ParameterType, &blk)
|
6
|
-
end
|
7
|
-
|
8
4
|
class ParameterType
|
9
5
|
attr_reader :name
|
10
6
|
attr_reader :default
|
11
7
|
attr_reader :validators
|
8
|
+
attr_reader :description
|
9
|
+
|
10
|
+
def self.inherited(subclass)
|
11
|
+
subclass.class_eval do
|
12
|
+
# Initialize the validator hash
|
13
|
+
@validator_declarations ||= {}
|
14
|
+
|
15
|
+
#
|
16
|
+
# Global validators
|
17
|
+
#
|
18
|
+
validator(:in) { |possible_values| possible_values.member?(@value) }
|
19
|
+
|
20
|
+
# We need a to_s here because the user should be allowed to define dependencies
|
21
|
+
# using symbols while the actual keys of the params hash are strings
|
22
|
+
validator(:depends_on) { |dep| @params.has_key?(dep.to_s) }
|
23
|
+
end
|
24
|
+
end
|
12
25
|
|
13
26
|
def initialize(name, map)
|
14
27
|
@name = name
|
15
28
|
@default = map.delete(:default)
|
16
29
|
|
30
|
+
@description = map.delete(:description) || map.delete(:desc)
|
31
|
+
|
17
32
|
@transform = map.delete(:transform)
|
18
33
|
@transform = @transform.to_proc if @transform
|
19
34
|
|
@@ -21,8 +36,9 @@ module Sinatra::Browse
|
|
21
36
|
@on_error = map.delete(:on_error)
|
22
37
|
|
23
38
|
@validators = []
|
39
|
+
|
24
40
|
map.each do |key, value|
|
25
|
-
if val_blk =
|
41
|
+
if val_blk = validator_declarations[key]
|
26
42
|
@validators << Validator.new(
|
27
43
|
name: key,
|
28
44
|
criteria: map[key],
|
@@ -68,7 +84,7 @@ module Sinatra::Browse
|
|
68
84
|
|
69
85
|
def type
|
70
86
|
type_string = self.class.to_s.split("::").last
|
71
|
-
type_string
|
87
|
+
type_string.to_sym
|
72
88
|
end
|
73
89
|
|
74
90
|
def to_hash(options = {})
|
@@ -95,23 +111,17 @@ module Sinatra::Browse
|
|
95
111
|
# DSL
|
96
112
|
#
|
97
113
|
|
98
|
-
def self.coerce(&blk)
|
99
|
-
define_method(:coerce) { |value| blk.call(value) }
|
100
|
-
end
|
101
|
-
|
102
114
|
def self.validator(name, &blk)
|
103
|
-
|
115
|
+
@validator_declarations[name] = blk
|
116
|
+
end
|
104
117
|
|
105
|
-
|
118
|
+
def self.validator_declarations
|
119
|
+
@validator_declarations
|
106
120
|
end
|
107
121
|
|
108
|
-
|
109
|
-
|
110
|
-
|
122
|
+
def validator_declarations
|
123
|
+
self.class.validator_declarations
|
124
|
+
end
|
111
125
|
|
112
|
-
# We need a to_s here because the user should be allowed to define dependencies
|
113
|
-
# using symbols while the actual keys of the params hash are strings
|
114
|
-
validator(:depends_on) { |dep| @params.has_key?(dep.to_s) }
|
115
|
-
validator(:in) { |possible_values| possible_values.member?(@value) }
|
116
126
|
end
|
117
127
|
end
|
@@ -1,18 +1,21 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
module Sinatra::Browse
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
4
|
+
module ParameterTypes
|
5
|
+
|
6
|
+
class Boolean < ParameterType
|
7
|
+
def coerce(value)
|
8
|
+
#TODO: Raise error if it's something else
|
9
|
+
# true and false are included here because they can be set as default
|
10
|
+
# values even though only strings will come through http requests
|
11
|
+
case value
|
12
|
+
when "y", "yes", "t", "true", "1", true
|
13
|
+
true
|
14
|
+
when "n", "no", "f", "false", "0", false
|
15
|
+
false
|
16
|
+
end
|
14
17
|
end
|
15
18
|
end
|
16
|
-
end
|
17
19
|
|
20
|
+
end
|
18
21
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require "date"
|
4
|
+
|
5
|
+
module Sinatra::Browse
|
6
|
+
module ParameterTypes
|
7
|
+
|
8
|
+
class DateTime < ParameterType
|
9
|
+
extend MinMax
|
10
|
+
|
11
|
+
def initialize(name, map)
|
12
|
+
# Allow strings for min and max values
|
13
|
+
map[:min] = coerce(map[:min]) if map[:min].is_a?(::String)
|
14
|
+
map[:max] = coerce(map[:max]) if map[:max].is_a?(::String)
|
15
|
+
|
16
|
+
super(name, map)
|
17
|
+
end
|
18
|
+
|
19
|
+
def coerce(value)
|
20
|
+
# We add this line because default values also get coerced.
|
21
|
+
return value if value.is_a?(::DateTime)
|
22
|
+
|
23
|
+
::DateTime.parse(value)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -1,7 +1,15 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
module Sinatra::Browse
|
4
|
-
|
5
|
-
|
4
|
+
module ParameterTypes
|
5
|
+
|
6
|
+
class Float < ParameterType
|
7
|
+
extend MinMax
|
8
|
+
|
9
|
+
def coerce(value)
|
10
|
+
Float(value)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
6
14
|
end
|
7
15
|
end
|
@@ -1,7 +1,15 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
module Sinatra::Browse
|
4
|
-
|
5
|
-
|
4
|
+
module ParameterTypes
|
5
|
+
|
6
|
+
class Integer < ParameterType
|
7
|
+
extend MinMax
|
8
|
+
|
9
|
+
def coerce(value)
|
10
|
+
Integer(value)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
6
14
|
end
|
7
15
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Sinatra::Browse
|
4
|
+
module ParameterTypes
|
5
|
+
# This is a module for parameter types to extend. It will give them the
|
6
|
+
# validators defined here.
|
7
|
+
module MinMax
|
8
|
+
def self.extended(parameter_type)
|
9
|
+
parameter_type.validator(:min) { |min| @value >= min }
|
10
|
+
parameter_type.validator(:max) { |max| @value <= max }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -1,13 +1,16 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
module Sinatra::Browse
|
4
|
+
module ParameterTypes
|
5
|
+
class String < ParameterType
|
6
|
+
def coerce(value)
|
7
|
+
String(value)
|
8
|
+
end
|
4
9
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
validator(:max_length) { |max_len| @value.length <= max_len }
|
10
|
+
#TODO: raise error when declaring a validator that doesn't exist
|
11
|
+
validator(:format) { |regex| !! (@value =~ regex) }
|
12
|
+
validator(:min_length) { |min_len| @value.length >= min_len }
|
13
|
+
validator(:max_length) { |max_len| @value.length <= max_len }
|
14
|
+
end
|
11
15
|
end
|
12
|
-
|
13
16
|
end
|
data/lib/sinatra/browse/route.rb
CHANGED
@@ -77,8 +77,14 @@ module Sinatra::Browse
|
|
77
77
|
|
78
78
|
declaration_maps.each do |name, map|
|
79
79
|
type = map.delete(:type)
|
80
|
+
type_class = Sinatra::Browse::ParameterTypes.const_get(type)
|
80
81
|
|
81
|
-
|
82
|
+
#TODO: Unit test this error
|
83
|
+
unless type_class.is_a?(Class) && type_class.ancestors.member?(ParameterType)
|
84
|
+
raise Errors::UnknownParameterTypeError, type_class
|
85
|
+
end
|
86
|
+
|
87
|
+
@param_declarations[name] = type_class.new(name, map)
|
82
88
|
end
|
83
89
|
end
|
84
90
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Sinatra::Browse
|
4
|
+
module Validators
|
5
|
+
class In < Validator
|
6
|
+
class InvalidFormat < Exception; end
|
7
|
+
class UnableToCoerce < Exception; end
|
8
|
+
|
9
|
+
def intialize(parameter_type, criteria)
|
10
|
+
if ! criteria.respond_to?(:each)
|
11
|
+
raise InvalidFormat, "#{criteria} does not have an .each method. " +
|
12
|
+
"Can't be used for 'in'."
|
13
|
+
end
|
14
|
+
|
15
|
+
criteria.map!
|
16
|
+
|
17
|
+
super(parameter_type, criteria)
|
18
|
+
end
|
19
|
+
|
20
|
+
def _validate
|
21
|
+
@criteria.member?(@value)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sinatra-browse
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.6'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Axsh Co. LTD
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Parameter declaration framework and browsable API for Sinatra
|
14
14
|
email: dev@axsh.net
|
@@ -17,16 +17,19 @@ extensions: []
|
|
17
17
|
extra_rdoc_files: []
|
18
18
|
files:
|
19
19
|
- lib/sinatra/browse.rb
|
20
|
-
- lib/sinatra/browse/
|
21
|
-
- lib/sinatra/browse/errors.rb
|
22
|
-
- lib/sinatra/browse/erb_templates/html.erb
|
20
|
+
- lib/sinatra/browse/format.rb
|
23
21
|
- lib/sinatra/browse/erb_templates/markdown.erb
|
22
|
+
- lib/sinatra/browse/erb_templates/html.erb
|
24
23
|
- lib/sinatra/browse/parameter_type.rb
|
25
|
-
- lib/sinatra/browse/
|
24
|
+
- lib/sinatra/browse/errors.rb
|
25
|
+
- lib/sinatra/browse/validators/in.rb
|
26
|
+
- lib/sinatra/browse/route.rb
|
27
|
+
- lib/sinatra/browse/parameter_types/min_max.rb
|
26
28
|
- lib/sinatra/browse/parameter_types/float.rb
|
27
29
|
- lib/sinatra/browse/parameter_types/string.rb
|
30
|
+
- lib/sinatra/browse/parameter_types/date_time.rb
|
28
31
|
- lib/sinatra/browse/parameter_types/integer.rb
|
29
|
-
- lib/sinatra/browse/
|
32
|
+
- lib/sinatra/browse/parameter_types/boolean.rb
|
30
33
|
- lib/sinatra/browse/validator.rb
|
31
34
|
- LICENSE
|
32
35
|
- README.md
|
@@ -42,7 +45,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
42
45
|
requirements:
|
43
46
|
- - '>='
|
44
47
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
48
|
+
version: 1.9.3
|
46
49
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
50
|
requirements:
|
48
51
|
- - '>='
|
@@ -55,3 +58,4 @@ signing_key:
|
|
55
58
|
specification_version: 4
|
56
59
|
summary: Parameter declaration framework and browsable API for Sinatra
|
57
60
|
test_files: []
|
61
|
+
has_rdoc:
|