haveapi 0.3.2 → 0.4.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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +12 -0
  3. data/Gemfile +10 -10
  4. data/README.md +19 -12
  5. data/Rakefile +23 -0
  6. data/doc/hooks.erb +35 -0
  7. data/doc/index.md +1 -0
  8. data/doc/json-schema.erb +369 -0
  9. data/doc/protocol.md +178 -38
  10. data/doc/protocol.plantuml +220 -0
  11. data/haveapi.gemspec +6 -10
  12. data/lib/haveapi/action.rb +35 -6
  13. data/lib/haveapi/api.rb +22 -5
  14. data/lib/haveapi/common.rb +7 -0
  15. data/lib/haveapi/exceptions.rb +7 -0
  16. data/lib/haveapi/hooks.rb +19 -8
  17. data/lib/haveapi/model_adapters/active_record.rb +58 -19
  18. data/lib/haveapi/output_formatter.rb +8 -5
  19. data/lib/haveapi/output_formatters/json.rb +6 -1
  20. data/lib/haveapi/params/param.rb +33 -39
  21. data/lib/haveapi/params/resource.rb +20 -0
  22. data/lib/haveapi/params.rb +26 -4
  23. data/lib/haveapi/public/doc/protocol.png +0 -0
  24. data/lib/haveapi/resource.rb +2 -7
  25. data/lib/haveapi/server.rb +87 -26
  26. data/lib/haveapi/tasks/hooks.rb +3 -0
  27. data/lib/haveapi/tasks/yard.rb +12 -0
  28. data/lib/haveapi/validator.rb +134 -0
  29. data/lib/haveapi/validator_chain.rb +99 -0
  30. data/lib/haveapi/validators/acceptance.rb +38 -0
  31. data/lib/haveapi/validators/confirmation.rb +46 -0
  32. data/lib/haveapi/validators/custom.rb +21 -0
  33. data/lib/haveapi/validators/exclusion.rb +38 -0
  34. data/lib/haveapi/validators/format.rb +42 -0
  35. data/lib/haveapi/validators/inclusion.rb +42 -0
  36. data/lib/haveapi/validators/length.rb +71 -0
  37. data/lib/haveapi/validators/numericality.rb +104 -0
  38. data/lib/haveapi/validators/presence.rb +40 -0
  39. data/lib/haveapi/version.rb +2 -1
  40. data/lib/haveapi/views/doc_sidebars/json-schema.erb +7 -0
  41. data/lib/haveapi/views/main_layout.erb +11 -0
  42. data/lib/haveapi/views/version_page.erb +26 -3
  43. data/lib/haveapi.rb +7 -4
  44. metadata +45 -66
@@ -0,0 +1,71 @@
1
+ module HaveAPI
2
+ # Checks the length of a string. It does not have a short form.
3
+ #
4
+ # Full form:
5
+ # string :param, length: {
6
+ # min: 3,
7
+ # max: 10
8
+ # message: 'the error message'
9
+ # }
10
+ #
11
+ # string :param, length: {
12
+ # equals: 8
13
+ # }
14
+ class Validators::Length < Validator
15
+ name :length
16
+ takes :length
17
+
18
+ def setup
19
+ @min = take(:min)
20
+ @max = take(:max)
21
+ @equals = take(:equals)
22
+
23
+ if (@min || @max) && @equals
24
+ fail 'cannot mix min/max with equals'
25
+
26
+ elsif !@min && !@max && !@equals
27
+ fail 'must use either min, max or equals'
28
+ end
29
+
30
+ msg = if @equals
31
+ "length has to be #{@equals}"
32
+
33
+ elsif @min && !@max
34
+ "length has to be minimally #{@min}"
35
+
36
+ elsif !@min && @max
37
+ "length has to be maximally #{@max}"
38
+
39
+ else
40
+ "length has to be in range <#{@min}, #{@max}>"
41
+ end
42
+
43
+ @message = take(:message, msg)
44
+ end
45
+
46
+ def describe
47
+ ret = {
48
+ message: @message,
49
+ }
50
+
51
+ if @equals
52
+ ret[:equals] = @equals
53
+
54
+ else
55
+ ret[:min] = @min if @min
56
+ ret[:max] = @max if @max
57
+ end
58
+
59
+ ret
60
+ end
61
+
62
+ def valid?(v)
63
+ len = v.length
64
+
65
+ return len == @equals if @equals
66
+ return len >= @min if @min && !@max
67
+ return len <= @max if !@min && @max
68
+ len >= @min && len <= @max
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,104 @@
1
+ module HaveAPI
2
+ # Checks the value is a number or a string containing only digits.
3
+ #
4
+ # Full form:
5
+ # string :param, number: {
6
+ # min: 3,
7
+ # max: 10,
8
+ # step: 2,
9
+ # message: 'the error message'
10
+ # }
11
+ #
12
+ # Will allow values +3+, +5+, +7+ and +9+.
13
+ #
14
+ # string :param, number: {
15
+ # min: 3,
16
+ # max: 10,
17
+ # mod: 2,
18
+ # }
19
+ #
20
+ # Will allow values +4+, +6+, +8+ and +10+.
21
+ class Validators::Numericality < Validator
22
+ name :number
23
+ takes :number
24
+
25
+ def setup
26
+ @min = take(:min)
27
+ @max = take(:max)
28
+ @step = take(:step)
29
+ @mod = take(:mod)
30
+ @even = take(:even)
31
+ @odd = take(:odd)
32
+
33
+ msg = if @min && !@max
34
+ "has to be minimally #{@min}"
35
+
36
+ elsif !@min && @max
37
+ "has to be maximally #{@max}"
38
+
39
+ elsif @min && @max
40
+ "has to be in range <#{@min}, #{@max}>"
41
+
42
+ else
43
+ 'has to be a number'
44
+ end
45
+
46
+ if @step
47
+ msg += '; ' unless msg.empty?
48
+ msg += "in steps of #{@step}"
49
+ end
50
+
51
+ if @mod
52
+ msg += '; ' unless msg.empty?
53
+ msg += "mod #{@step} must equal zero"
54
+ end
55
+
56
+ if @odd
57
+ msg += '; ' unless msg.empty?
58
+ msg += "odd"
59
+ end
60
+
61
+ if @even
62
+ msg += '; ' unless msg.empty?
63
+ msg += "even"
64
+ end
65
+
66
+ if @odd && @even
67
+ fail 'cannot be both odd and even at the same time'
68
+ end
69
+
70
+ @message = take(:message, msg)
71
+ end
72
+
73
+ def describe
74
+ ret = {
75
+ message: @message,
76
+ }
77
+
78
+ ret[:min] = @min if @min
79
+ ret[:max] = @max if @max
80
+ ret[:step] = @step if @step
81
+ ret[:mod] = @mod if @mod
82
+ ret[:odd] = @odd if @odd
83
+ ret[:even] = @even if @even
84
+
85
+ ret
86
+ end
87
+
88
+ def valid?(v)
89
+ if v.is_a?(::String)
90
+ return false if /\A\d+\z/ !~ v
91
+ v = v.to_i
92
+ end
93
+
94
+ ret = true
95
+ ret = false if @min && v < @min
96
+ ret = false if @max && v > @max
97
+ ret = false if @step && (v - (@min || 0)) % @step != 0
98
+ ret = false if @mod && v % @mod != 0
99
+ ret = false if @odd && v % 2 == 0
100
+ ret = false if @even && v % 2 > 0
101
+ ret
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,40 @@
1
+ module HaveAPI
2
+ # Checks the value is a number or a string containing only digits.
3
+ #
4
+ # Short form:
5
+ # string :param, required: true
6
+ #
7
+ # Full form:
8
+ # string :param, required: {
9
+ # empty: true/false,
10
+ # message: 'the error message'
11
+ # }
12
+ class Validators::Presence < Validator
13
+ name :present
14
+ takes :required, :present
15
+
16
+ def setup
17
+ return useless if simple? && !take
18
+
19
+ @empty = take(:empty, false)
20
+ @message = take(
21
+ :message,
22
+ @empty ? 'must be present' : 'must be present and non-empty'
23
+ )
24
+ end
25
+
26
+ def describe
27
+ {
28
+ empty: @empty,
29
+ message: @message,
30
+ }
31
+ end
32
+
33
+ def valid?(v)
34
+ return false if v.nil?
35
+ return !v.strip.empty? if !@empty && v.is_a?(::String)
36
+ # FIXME: other data types?
37
+ true
38
+ end
39
+ end
40
+ end
@@ -1,3 +1,4 @@
1
1
  module HaveAPI
2
- VERSION = '0.3.2'
2
+ PROTOCOL_VERSION = '1.0'
3
+ VERSION = '0.4.0'
3
4
  end
@@ -0,0 +1,7 @@
1
+ <h1>Contents</h1>
2
+ <ul class="top-level">
3
+ <li><a href="#envelope">Envelope</a></li>
4
+ <li><a href="#all">OPTIONS /</a></li>
5
+ <li><a href="#versions">OPTIONS /?describe=versions</a></li>
6
+ <li><a href="#default">OPTIONS /?describe=default</a></li>
7
+ </ul>
@@ -34,6 +34,17 @@
34
34
  .table-of-contents li.active > a {
35
35
  font-weight: bold;
36
36
  }
37
+ dl {
38
+ border: 1px solid #ccc;
39
+ }
40
+ dl dt {
41
+ background: #ddd none repeat scroll 0% 0%;
42
+ padding-left: 5px;
43
+ }
44
+ dl dd {
45
+ padding: 5px 0px;
46
+ margin-left: 18px;
47
+ }
37
48
  </style>
38
49
  </head>
39
50
  <body data-spy="scroll" data-target=".table-of-contents">
@@ -1,3 +1,26 @@
1
+ <%
2
+ def format_param_type(param)
3
+ return param[:type] if param[:type] != 'Resource'
4
+ "<a href=\"#root-#{param[:resource].join('-')}-show\">#{param[:type]}</a>"
5
+ end
6
+
7
+ def format_validators(validators)
8
+ ret = ''
9
+ return ret if validators.nil?
10
+
11
+ validators.each do |name, opts|
12
+ ret += "<h5>#{name.to_s.capitalize}</h5>"
13
+ ret += '<dl>'
14
+ opts.each do |k, v|
15
+ ret += "<dt>#{k}</dt><dd>#{v}</dd>"
16
+ end
17
+ ret += '</dl>'
18
+ end
19
+
20
+ ret
21
+ end
22
+ %>
23
+
1
24
  <% def render_resource_body(resource, info, prefix='root', name=nil) %>
2
25
  <% name ||= resource.humanize %>
3
26
  <h2 class="resource" id="<%= "#{prefix}-#{resource}" %>"><%= resource.humanize %></h2>
@@ -46,8 +69,8 @@
46
69
  <td><%= info[:label] %></td>
47
70
  <td><%= param %></td>
48
71
  <td><%= info[:required] ? 'yes' : 'no' %></td>
49
- <td><%= info[:type] %></td>
50
- <td><%= info[:validators] %></td>
72
+ <td><%= format_param_type(info) %></td>
73
+ <td><%= format_validators(info[:validators]) %></td>
51
74
  <td><%= info[:default] == :_nil ? '' : info[:default] %></td>
52
75
  <td><%= info[:description] %></td>
53
76
  </tr>
@@ -79,7 +102,7 @@
79
102
  <tr>
80
103
  <td><%= info[:label] %></td>
81
104
  <td><%= param %></td>
82
- <td><%= info[:type] %></td>
105
+ <td><%= format_param_type(info) %></td>
83
106
  <td><%= info[:description] %></td>
84
107
  </tr>
85
108
  <% end %>
data/lib/haveapi.rb CHANGED
@@ -1,7 +1,9 @@
1
+ ar = defined?(:ActiveRecord)
2
+
1
3
  require 'require_all'
2
- require 'active_record'
4
+ require 'active_record' if ar
3
5
  require 'sinatra/base'
4
- require 'sinatra/activerecord'
6
+ require 'sinatra/activerecord' if ar
5
7
  require 'pp'
6
8
  require 'github/markdown'
7
9
 
@@ -13,10 +15,11 @@ end
13
15
  require_relative 'haveapi/params'
14
16
  require_rel 'haveapi/params/'
15
17
  require_rel 'haveapi/*.rb'
16
- require_rel 'haveapi/model_adapters/'
18
+ require_rel 'haveapi/model_adapters/hash'
19
+ require_rel 'haveapi/model_adapters/active_record' if ar
17
20
  require_rel 'haveapi/authentication'
18
21
  require_rel 'haveapi/actions/*.rb'
19
22
  require_rel 'haveapi/output_formatters/base.rb'
20
23
  require_rel 'haveapi/output_formatters/'
24
+ require_rel 'haveapi/validators/'
21
25
  require_rel 'haveapi/extensions'
22
-
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haveapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jakub Skokan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-13 00:00:00.000000000 Z
11
+ date: 2016-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: activerecord
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ~>
18
- - !ruby/object:Gem::Version
19
- version: 4.1.6
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ~>
25
- - !ruby/object:Gem::Version
26
- version: 4.1.6
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: require_all
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -56,44 +42,44 @@ dependencies:
56
42
  name: sinatra
57
43
  requirement: !ruby/object:Gem::Requirement
58
44
  requirements:
59
- - - '>='
45
+ - - ~>
60
46
  - !ruby/object:Gem::Version
61
- version: '0'
47
+ version: 1.4.6
62
48
  type: :runtime
63
49
  prerelease: false
64
50
  version_requirements: !ruby/object:Gem::Requirement
65
51
  requirements:
66
- - - '>='
52
+ - - ~>
67
53
  - !ruby/object:Gem::Version
68
- version: '0'
54
+ version: 1.4.6
69
55
  - !ruby/object:Gem::Dependency
70
- name: mysql
56
+ name: tilt
71
57
  requirement: !ruby/object:Gem::Requirement
72
58
  requirements:
73
- - - '>='
59
+ - - ~>
74
60
  - !ruby/object:Gem::Version
75
- version: '0'
61
+ version: 1.4.1
76
62
  type: :runtime
77
63
  prerelease: false
78
64
  version_requirements: !ruby/object:Gem::Requirement
79
65
  requirements:
80
- - - '>='
66
+ - - ~>
81
67
  - !ruby/object:Gem::Version
82
- version: '0'
68
+ version: 1.4.1
83
69
  - !ruby/object:Gem::Dependency
84
- name: sinatra-activerecord
70
+ name: redcarpet
85
71
  requirement: !ruby/object:Gem::Requirement
86
72
  requirements:
87
- - - '>='
73
+ - - ~>
88
74
  - !ruby/object:Gem::Version
89
- version: '0'
75
+ version: 3.3.4
90
76
  type: :runtime
91
77
  prerelease: false
92
78
  version_requirements: !ruby/object:Gem::Requirement
93
79
  requirements:
94
- - - '>='
80
+ - - ~>
95
81
  - !ruby/object:Gem::Version
96
- version: '0'
82
+ version: 3.3.4
97
83
  - !ruby/object:Gem::Dependency
98
84
  name: rake
99
85
  requirement: !ruby/object:Gem::Requirement
@@ -114,56 +100,28 @@ dependencies:
114
100
  requirements:
115
101
  - - ~>
116
102
  - !ruby/object:Gem::Version
117
- version: 0.6.6
103
+ version: 0.6.9
118
104
  type: :runtime
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
107
  requirements:
122
108
  - - ~>
123
109
  - !ruby/object:Gem::Version
124
- version: 0.6.6
125
- - !ruby/object:Gem::Dependency
126
- name: rspec
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - '>='
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - '>='
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: railties
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - '>='
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - '>='
151
- - !ruby/object:Gem::Version
152
- version: '0'
110
+ version: 0.6.9
153
111
  - !ruby/object:Gem::Dependency
154
- name: rack-test
112
+ name: nesty
155
113
  requirement: !ruby/object:Gem::Requirement
156
114
  requirements:
157
- - - '>='
115
+ - - ~>
158
116
  - !ruby/object:Gem::Version
159
- version: '0'
160
- type: :development
117
+ version: 1.0.2
118
+ type: :runtime
161
119
  prerelease: false
162
120
  version_requirements: !ruby/object:Gem::Requirement
163
121
  requirements:
164
- - - '>='
122
+ - - ~>
165
123
  - !ruby/object:Gem::Version
166
- version: '0'
124
+ version: 1.0.2
167
125
  description: Framework for creating self-describing APIs
168
126
  email: jakub.skokan@vpsfree.cz
169
127
  executables: []
@@ -171,13 +129,17 @@ extensions: []
171
129
  extra_rdoc_files: []
172
130
  files:
173
131
  - .gitignore
132
+ - CHANGELOG
174
133
  - Gemfile
175
134
  - LICENSE.txt
176
135
  - README.md
177
136
  - Rakefile
178
137
  - doc/create-client.md
138
+ - doc/hooks.erb
179
139
  - doc/index.md
140
+ - doc/json-schema.erb
180
141
  - doc/protocol.md
142
+ - doc/protocol.plantuml
181
143
  - haveapi.gemspec
182
144
  - lib/haveapi.rb
183
145
  - lib/haveapi/action.rb
@@ -193,6 +155,7 @@ files:
193
155
  - lib/haveapi/common.rb
194
156
  - lib/haveapi/context.rb
195
157
  - lib/haveapi/example.rb
158
+ - lib/haveapi/exceptions.rb
196
159
  - lib/haveapi/extensions/action_exceptions.rb
197
160
  - lib/haveapi/extensions/base.rb
198
161
  - lib/haveapi/hooks.rb
@@ -208,16 +171,31 @@ files:
208
171
  - lib/haveapi/params/resource.rb
209
172
  - lib/haveapi/public/css/bootstrap-theme.min.css
210
173
  - lib/haveapi/public/css/bootstrap.min.css
174
+ - lib/haveapi/public/doc/protocol.png
211
175
  - lib/haveapi/public/js/bootstrap.min.js
212
176
  - lib/haveapi/public/js/jquery-1.11.1.min.js
213
177
  - lib/haveapi/resource.rb
214
178
  - lib/haveapi/route.rb
215
179
  - lib/haveapi/server.rb
216
180
  - lib/haveapi/spec/helpers.rb
181
+ - lib/haveapi/tasks/hooks.rb
182
+ - lib/haveapi/tasks/yard.rb
217
183
  - lib/haveapi/types.rb
184
+ - lib/haveapi/validator.rb
185
+ - lib/haveapi/validator_chain.rb
186
+ - lib/haveapi/validators/acceptance.rb
187
+ - lib/haveapi/validators/confirmation.rb
188
+ - lib/haveapi/validators/custom.rb
189
+ - lib/haveapi/validators/exclusion.rb
190
+ - lib/haveapi/validators/format.rb
191
+ - lib/haveapi/validators/inclusion.rb
192
+ - lib/haveapi/validators/length.rb
193
+ - lib/haveapi/validators/numericality.rb
194
+ - lib/haveapi/validators/presence.rb
218
195
  - lib/haveapi/version.rb
219
196
  - lib/haveapi/views/doc_layout.erb
220
197
  - lib/haveapi/views/doc_sidebars/create-client.erb
198
+ - lib/haveapi/views/doc_sidebars/json-schema.erb
221
199
  - lib/haveapi/views/doc_sidebars/protocol.erb
222
200
  - lib/haveapi/views/index.erb
223
201
  - lib/haveapi/views/main_layout.erb
@@ -248,3 +226,4 @@ signing_key:
248
226
  specification_version: 4
249
227
  summary: Framework for creating self-describing APIs
250
228
  test_files: []
229
+ has_rdoc: