seahorse 0.1.0 → 1.0.0.pre1
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 +5 -5
- data/CHANGELOG.md +12 -0
- data/VERSION +1 -0
- data/lib/seahorse/api_error.rb +15 -0
- data/lib/seahorse/block_io.rb +24 -0
- data/lib/seahorse/context.rb +34 -0
- data/lib/seahorse/http/api_error.rb +29 -0
- data/lib/seahorse/http/client.rb +152 -0
- data/lib/seahorse/http/error_parser.rb +105 -0
- data/lib/seahorse/http/headers.rb +70 -0
- data/lib/seahorse/http/middleware/content_length.rb +28 -0
- data/lib/seahorse/http/networking_error.rb +20 -0
- data/lib/seahorse/http/request.rb +132 -0
- data/lib/seahorse/http/response.rb +29 -0
- data/lib/seahorse/http.rb +36 -0
- data/lib/seahorse/json/parse_error.rb +18 -0
- data/lib/seahorse/json.rb +30 -0
- data/lib/seahorse/middleware/around_handler.rb +24 -0
- data/lib/seahorse/middleware/build.rb +26 -0
- data/lib/seahorse/middleware/host_prefix.rb +48 -0
- data/lib/seahorse/middleware/parse.rb +42 -0
- data/lib/seahorse/middleware/request_handler.rb +24 -0
- data/lib/seahorse/middleware/response_handler.rb +25 -0
- data/lib/seahorse/middleware/retry.rb +43 -0
- data/lib/seahorse/middleware/send.rb +62 -0
- data/lib/seahorse/middleware/validate.rb +29 -0
- data/lib/seahorse/middleware.rb +16 -0
- data/lib/seahorse/middleware_builder.rb +246 -0
- data/lib/seahorse/middleware_stack.rb +73 -0
- data/lib/seahorse/output.rb +20 -0
- data/lib/seahorse/structure.rb +40 -0
- data/lib/seahorse/stubbing/client_stubs.rb +115 -0
- data/lib/seahorse/stubbing/stubs.rb +32 -0
- data/lib/seahorse/time_helper.rb +35 -0
- data/lib/seahorse/union.rb +10 -0
- data/lib/seahorse/validator.rb +20 -0
- data/lib/seahorse/waiters/errors.rb +15 -0
- data/lib/seahorse/waiters/poller.rb +132 -0
- data/lib/seahorse/waiters/waiter.rb +79 -0
- data/lib/seahorse/xml/formatter.rb +68 -0
- data/lib/seahorse/xml/node.rb +123 -0
- data/lib/seahorse/xml/parse_error.rb +18 -0
- data/lib/seahorse/xml.rb +58 -0
- data/lib/seahorse.rb +23 -13
- data/sig/lib/seahorse/api_error.rbs +10 -0
- data/sig/lib/seahorse/document.rbs +2 -0
- data/sig/lib/seahorse/http/api_error.rbs +21 -0
- data/sig/lib/seahorse/http/headers.rbs +47 -0
- data/sig/lib/seahorse/http/response.rbs +21 -0
- data/sig/lib/seahorse/simple_delegator.rbs +3 -0
- data/sig/lib/seahorse/structure.rbs +18 -0
- data/sig/lib/seahorse/stubbing/client_stubs.rbs +103 -0
- data/sig/lib/seahorse/stubbing/stubs.rbs +14 -0
- data/sig/lib/seahorse/union.rbs +6 -0
- metadata +73 -54
- data/LICENSE +0 -12
- data/README.md +0 -3
- data/Rakefile +0 -7
- data/lib/seahorse/api_translator/inflector.rb +0 -37
- data/lib/seahorse/api_translator/operation.rb +0 -150
- data/lib/seahorse/api_translator/shape.rb +0 -235
- data/lib/seahorse/controller.rb +0 -87
- data/lib/seahorse/model.rb +0 -82
- data/lib/seahorse/operation.rb +0 -66
- data/lib/seahorse/param_validator.rb +0 -158
- data/lib/seahorse/railtie.rb +0 -7
- data/lib/seahorse/router.rb +0 -20
- data/lib/seahorse/shape_builder.rb +0 -84
- data/lib/seahorse/type.rb +0 -220
- data/lib/seahorse/version.rb +0 -3
- data/lib/tasks/seahorse_tasks.rake +0 -24
data/Rakefile
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
# Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
-
# may not use this file except in compliance with the License. A copy of
|
5
|
-
# the License is located at
|
6
|
-
#
|
7
|
-
# http://aws.amazon.com/apache2.0/
|
8
|
-
#
|
9
|
-
# or in the "license" file accompanying this file. This file is
|
10
|
-
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
11
|
-
# ANY KIND, either express or implied. See the License for the specific
|
12
|
-
# language governing permissions and limitations under the License.
|
13
|
-
|
14
|
-
module Seahorse
|
15
|
-
class ApiTranslator
|
16
|
-
|
17
|
-
# @private
|
18
|
-
module Inflector
|
19
|
-
|
20
|
-
# Performs a very simple inflection on on the words as they are
|
21
|
-
# formatted in the source API configurations. These are *not*
|
22
|
-
# general case inflectors.
|
23
|
-
# @param [String] string The string to inflect.
|
24
|
-
# @param [String,nil] format Valid formats include 'snake_case',
|
25
|
-
# 'camelCase' and `nil` (leave as is).
|
26
|
-
# @return [String]
|
27
|
-
def inflect string, format = nil
|
28
|
-
case format
|
29
|
-
when 'camelCase' then string.camelize
|
30
|
-
when 'snake_case' then string.underscore
|
31
|
-
else string
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
end
|
@@ -1,150 +0,0 @@
|
|
1
|
-
# Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
-
# may not use this file except in compliance with the License. A copy of
|
5
|
-
# the License is located at
|
6
|
-
#
|
7
|
-
# http://aws.amazon.com/apache2.0/
|
8
|
-
#
|
9
|
-
# or in the "license" file accompanying this file. This file is
|
10
|
-
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
11
|
-
# ANY KIND, either express or implied. See the License for the specific
|
12
|
-
# language governing permissions and limitations under the License.
|
13
|
-
|
14
|
-
require_relative './inflector'
|
15
|
-
require_relative './shape'
|
16
|
-
|
17
|
-
module Seahorse
|
18
|
-
class ApiTranslator
|
19
|
-
|
20
|
-
# @private
|
21
|
-
class Operation
|
22
|
-
|
23
|
-
include Inflector
|
24
|
-
|
25
|
-
def initialize rules, options = {}
|
26
|
-
@options = options
|
27
|
-
|
28
|
-
@method_name = rules['name'].sub(/\d{4}_\d{2}_\d{2}$/, '')
|
29
|
-
@method_name = inflect(@method_name, @options[:inflect_method_names])
|
30
|
-
|
31
|
-
@rules = rules
|
32
|
-
|
33
|
-
if @rules['http']
|
34
|
-
@rules['http'].delete('response_code')
|
35
|
-
end
|
36
|
-
|
37
|
-
translate_input
|
38
|
-
translate_output
|
39
|
-
|
40
|
-
if @options[:documentation]
|
41
|
-
@rules['errors'] = @rules['errors'].map {|e| e['shape_name'] }
|
42
|
-
else
|
43
|
-
@rules.delete('errors')
|
44
|
-
@rules.delete('documentation')
|
45
|
-
@rules.delete('documentation_url')
|
46
|
-
@rules.delete('response_code')
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# @return [String]
|
51
|
-
attr_reader :method_name
|
52
|
-
|
53
|
-
# @return [Hash]
|
54
|
-
attr_reader :rules
|
55
|
-
|
56
|
-
private
|
57
|
-
|
58
|
-
def translate_input
|
59
|
-
if @rules['input']
|
60
|
-
rules = InputShape.new(@rules['input'], @options).rules
|
61
|
-
rules['members'] ||= {}
|
62
|
-
rules = normalize_inputs(rules)
|
63
|
-
else
|
64
|
-
rules = {
|
65
|
-
'type' => 'structure',
|
66
|
-
'members' => {},
|
67
|
-
}
|
68
|
-
end
|
69
|
-
@rules['input'] = rules
|
70
|
-
end
|
71
|
-
|
72
|
-
def translate_output
|
73
|
-
if @rules['output']
|
74
|
-
rules = OutputShape.new(@rules['output'], @options).rules
|
75
|
-
move_up_outputs(rules)
|
76
|
-
cache_payload(rules)
|
77
|
-
else
|
78
|
-
rules = {
|
79
|
-
'type' => 'structure',
|
80
|
-
'members' => {},
|
81
|
-
}
|
82
|
-
end
|
83
|
-
@rules['output'] = rules
|
84
|
-
end
|
85
|
-
|
86
|
-
def normalize_inputs rules
|
87
|
-
return rules unless @options[:type].match(/rest/)
|
88
|
-
|
89
|
-
xml = @options[:type].match(/xml/)
|
90
|
-
payload = false
|
91
|
-
wrapper = false
|
92
|
-
|
93
|
-
if rules['members'].any?{|name,rule| rule['payload'] }
|
94
|
-
|
95
|
-
# exactly one member has the payload trait
|
96
|
-
payload, rule = rules['members'].find{|name,rule| rule['payload'] }
|
97
|
-
rule.delete('payload')
|
98
|
-
|
99
|
-
#if rule['type'] == 'structure'
|
100
|
-
# wrapper = payload
|
101
|
-
# payload = [payload]
|
102
|
-
#end
|
103
|
-
|
104
|
-
else
|
105
|
-
|
106
|
-
# no members marked themselves as the payload, collect everything
|
107
|
-
# without a location
|
108
|
-
payload = rules['members'].inject([]) do |list,(name,rule)|
|
109
|
-
list << name if !rule['location']
|
110
|
-
list
|
111
|
-
end
|
112
|
-
|
113
|
-
if payload.empty?
|
114
|
-
payload = false
|
115
|
-
elsif xml
|
116
|
-
wrapper = @rules['input']['shape_name']
|
117
|
-
end
|
118
|
-
|
119
|
-
end
|
120
|
-
|
121
|
-
rules = { 'wrapper' => wrapper }.merge(rules) if wrapper
|
122
|
-
rules = { 'payload' => payload }.merge(rules) if payload
|
123
|
-
rules
|
124
|
-
|
125
|
-
end
|
126
|
-
|
127
|
-
def move_up_outputs output
|
128
|
-
move_up = nil
|
129
|
-
(output['members'] || {}).each_pair do |member_name, rules|
|
130
|
-
if rules['payload'] and rules['type'] == 'structure'
|
131
|
-
rules.delete('payload')
|
132
|
-
move_up = member_name
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
if move_up
|
137
|
-
output['members'].merge!(output['members'].delete(move_up)['members'])
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
def cache_payload rules
|
142
|
-
(rules['members'] || {}).each_pair do |member_name, rule|
|
143
|
-
rules['payload'] = member_name if rule['payload'] || rule['streaming']
|
144
|
-
rule.delete('payload')
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
@@ -1,235 +0,0 @@
|
|
1
|
-
# Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
-
# may not use this file except in compliance with the License. A copy of
|
5
|
-
# the License is located at
|
6
|
-
#
|
7
|
-
# http://aws.amazon.com/apache2.0/
|
8
|
-
#
|
9
|
-
# or in the "license" file accompanying this file. This file is
|
10
|
-
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
11
|
-
# ANY KIND, either express or implied. See the License for the specific
|
12
|
-
# language governing permissions and limitations under the License.
|
13
|
-
|
14
|
-
require_relative './inflector'
|
15
|
-
|
16
|
-
module Seahorse
|
17
|
-
class ApiTranslator
|
18
|
-
|
19
|
-
# @private
|
20
|
-
class Shape
|
21
|
-
|
22
|
-
include Inflector
|
23
|
-
|
24
|
-
def initialize rules, options = {}
|
25
|
-
@options = options
|
26
|
-
@rules = {}
|
27
|
-
@rules['name'] = options['name'] if options.key?('name')
|
28
|
-
set_type(rules.delete('type'))
|
29
|
-
rules.each_pair do |method,arg|
|
30
|
-
send("set_#{method}", *[arg])
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def rules
|
35
|
-
if @rules['type'] != 'blob'
|
36
|
-
@rules
|
37
|
-
elsif @rules['payload'] or @rules['streaming']
|
38
|
-
@rules.merge('type' => 'binary')
|
39
|
-
else
|
40
|
-
@rules.merge('type' => 'base64')
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def xmlname
|
45
|
-
if @rules['flattened']
|
46
|
-
(@rules['members'] || {})['name'] || @xmlname
|
47
|
-
else
|
48
|
-
@xmlname
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
protected
|
53
|
-
|
54
|
-
def set_timestamp_format format
|
55
|
-
@rules['format'] = format
|
56
|
-
end
|
57
|
-
|
58
|
-
def set_type name
|
59
|
-
types = {
|
60
|
-
'structure' => 'structure',
|
61
|
-
'list' => 'list',
|
62
|
-
'map' => 'map',
|
63
|
-
'boolean' => 'boolean',
|
64
|
-
'timestamp' => 'timestamp',
|
65
|
-
'character' => 'string',
|
66
|
-
'double' => 'float',
|
67
|
-
'float' => 'float',
|
68
|
-
'integer' => 'integer',
|
69
|
-
'long' => 'integer',
|
70
|
-
'short' => 'integer',
|
71
|
-
'string' => 'string',
|
72
|
-
'blob' => 'blob',
|
73
|
-
'biginteger' => 'integer',
|
74
|
-
'bigdecimal' => 'float',
|
75
|
-
}
|
76
|
-
if name == 'string'
|
77
|
-
# Purposefully omitting type when string (to reduce size of the api
|
78
|
-
# configuration). The parsers use string as the default when
|
79
|
-
# 'type' is omitted.
|
80
|
-
#@rules['type'] = 'string'
|
81
|
-
elsif type = types[name]
|
82
|
-
@rules['type'] = type
|
83
|
-
else
|
84
|
-
raise "unhandled shape type: #{name}"
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
def set_members members
|
89
|
-
case @rules['type']
|
90
|
-
when 'structure'
|
91
|
-
@rules['members'] = {}
|
92
|
-
members.each_pair do |member_name,member_rules|
|
93
|
-
|
94
|
-
member_shape = new_shape(member_rules)
|
95
|
-
|
96
|
-
member_key = inflect(member_name, @options[:inflect_member_names])
|
97
|
-
member_rules = member_shape.rules
|
98
|
-
|
99
|
-
if member_name != member_key
|
100
|
-
member_rules = { 'name' => member_name }.merge(member_rules)
|
101
|
-
end
|
102
|
-
|
103
|
-
if swap_names?(member_shape)
|
104
|
-
member_rules['name'] = member_key
|
105
|
-
member_key = member_shape.xmlname
|
106
|
-
end
|
107
|
-
|
108
|
-
@rules['members'][member_key] = member_rules
|
109
|
-
|
110
|
-
end
|
111
|
-
when 'list'
|
112
|
-
@rules['members'] = new_shape(members).rules
|
113
|
-
when 'map'
|
114
|
-
@rules['members'] = new_shape(members).rules
|
115
|
-
else
|
116
|
-
raise "unhandled complex shape `#{@rules['type']}'"
|
117
|
-
end
|
118
|
-
@rules.delete('members') if @rules['members'].empty?
|
119
|
-
end
|
120
|
-
|
121
|
-
def set_keys rules
|
122
|
-
shape = new_shape(rules)
|
123
|
-
@rules['keys'] = shape.rules
|
124
|
-
@rules.delete('keys') if @rules['keys'].empty?
|
125
|
-
end
|
126
|
-
|
127
|
-
def set_xmlname name
|
128
|
-
@xmlname = name
|
129
|
-
@rules['name'] = name
|
130
|
-
end
|
131
|
-
|
132
|
-
def set_location location
|
133
|
-
@rules['location'] = (location == 'http_status' ? 'status' : location)
|
134
|
-
end
|
135
|
-
|
136
|
-
def set_location_name header_name
|
137
|
-
@rules['name'] = header_name
|
138
|
-
end
|
139
|
-
|
140
|
-
def set_payload state
|
141
|
-
@rules['payload'] = true if state
|
142
|
-
end
|
143
|
-
|
144
|
-
def set_flattened state
|
145
|
-
@rules['flattened'] = true if state
|
146
|
-
end
|
147
|
-
|
148
|
-
def set_streaming state
|
149
|
-
@rules['streaming'] = true if state
|
150
|
-
end
|
151
|
-
|
152
|
-
def set_xmlnamespace ns
|
153
|
-
@rules['xmlns'] = ns
|
154
|
-
end
|
155
|
-
|
156
|
-
def set_xmlattribute state
|
157
|
-
@rules['attribute'] = true if state
|
158
|
-
end
|
159
|
-
|
160
|
-
def set_documentation docs
|
161
|
-
@rules['documentation'] = docs if @options[:documentation]
|
162
|
-
end
|
163
|
-
|
164
|
-
def set_enum values
|
165
|
-
@rules['enum'] = values if @options[:documentation]
|
166
|
-
end
|
167
|
-
|
168
|
-
def set_wrapper state
|
169
|
-
@rules['wrapper'] = true if state
|
170
|
-
end
|
171
|
-
|
172
|
-
# we purposefully drop these, not useful unless you want to create
|
173
|
-
# static classes
|
174
|
-
def set_shape_name *args; end
|
175
|
-
def set_box *args; end
|
176
|
-
|
177
|
-
# @param [Hash] rules
|
178
|
-
# @option options [String] :name The name this shape has as a structure member.
|
179
|
-
def new_shape rules
|
180
|
-
self.class.new(rules, @options)
|
181
|
-
end
|
182
|
-
|
183
|
-
end
|
184
|
-
|
185
|
-
# @private
|
186
|
-
class InputShape < Shape
|
187
|
-
|
188
|
-
def set_required *args
|
189
|
-
@rules['required'] = true;
|
190
|
-
end
|
191
|
-
|
192
|
-
def set_member_order order
|
193
|
-
@rules['order'] = order
|
194
|
-
end
|
195
|
-
|
196
|
-
def set_min_length min
|
197
|
-
@rules['min_length'] = min if @options[:documentation]
|
198
|
-
end
|
199
|
-
|
200
|
-
def set_max_length max
|
201
|
-
@rules['max_length'] = max if @options[:documentation]
|
202
|
-
end
|
203
|
-
|
204
|
-
def set_pattern pattern
|
205
|
-
@rules['pattern'] = pattern if @options[:documentation]
|
206
|
-
end
|
207
|
-
|
208
|
-
def swap_names? shape
|
209
|
-
false
|
210
|
-
end
|
211
|
-
|
212
|
-
end
|
213
|
-
|
214
|
-
# @private
|
215
|
-
class OutputShape < Shape
|
216
|
-
|
217
|
-
# these traits are ignored for output shapes
|
218
|
-
def set_required *args; end
|
219
|
-
def set_member_order *args; end
|
220
|
-
def set_min_length *args; end
|
221
|
-
def set_max_length *args; end
|
222
|
-
def set_pattern *args; end
|
223
|
-
|
224
|
-
def swap_names? shape
|
225
|
-
if @options[:documentation]
|
226
|
-
false
|
227
|
-
else
|
228
|
-
!!(%w(query rest-xml).include?(@options[:type]) and shape.xmlname)
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
end
|
233
|
-
|
234
|
-
end
|
235
|
-
end
|
data/lib/seahorse/controller.rb
DELETED
@@ -1,87 +0,0 @@
|
|
1
|
-
require_relative './param_validator'
|
2
|
-
|
3
|
-
module Seahorse
|
4
|
-
module Controller
|
5
|
-
extend ActiveSupport::Concern
|
6
|
-
|
7
|
-
included do
|
8
|
-
respond_to :json, :xml
|
9
|
-
|
10
|
-
rescue_from Exception, :with => :render_error
|
11
|
-
|
12
|
-
wrap_parameters false
|
13
|
-
|
14
|
-
before_filter do
|
15
|
-
@params = params
|
16
|
-
@params = operation.input.from_input(params, false)
|
17
|
-
@params.update(operation.input.from_input(map_headers, false))
|
18
|
-
|
19
|
-
begin
|
20
|
-
input_rules = operation.to_hash['input']
|
21
|
-
%w(action controller format).each {|v| params.delete(v) }
|
22
|
-
validator = Seahorse::ParamValidator.new(input_rules)
|
23
|
-
validator.validate!(params)
|
24
|
-
rescue ArgumentError => error
|
25
|
-
if request.headers['HTTP_USER_AGENT'] =~ /sdk|cli/
|
26
|
-
service_error(error, 'ValidationError')
|
27
|
-
else
|
28
|
-
raise(error)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
@params = operation.input.from_input(@params)
|
33
|
-
@params = params.permit(*operation.input.to_strong_params)
|
34
|
-
|
35
|
-
true
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def render_error(exception)
|
42
|
-
service_error(exception, exception.class.name)
|
43
|
-
end
|
44
|
-
|
45
|
-
def params
|
46
|
-
@params || super
|
47
|
-
end
|
48
|
-
|
49
|
-
def respond_with(model, opts = {})
|
50
|
-
opts[:location] = nil
|
51
|
-
if opts[:error]
|
52
|
-
opts[:status] = opts[:error]
|
53
|
-
super
|
54
|
-
else
|
55
|
-
super(operation.output.to_output(model), opts)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def operation
|
60
|
-
return @operation if @operation
|
61
|
-
@operation = api_model.operation_from_action(action_name)
|
62
|
-
end
|
63
|
-
|
64
|
-
def api_model
|
65
|
-
return @api_model if @api_model
|
66
|
-
@api_model = ('Api::' + controller_name.singularize.camelcase).constantize
|
67
|
-
end
|
68
|
-
|
69
|
-
def service_error(error, code = 'ServiceError', status = 400)
|
70
|
-
respond_with({ code: code, message: error.message }, error: status)
|
71
|
-
end
|
72
|
-
|
73
|
-
def map_headers
|
74
|
-
return @map_headers if @map_headers
|
75
|
-
@map_headers = {}
|
76
|
-
return @map_headers unless operation.input.default_type == 'structure'
|
77
|
-
operation.input.members.each do |name, member|
|
78
|
-
if member.header
|
79
|
-
hdr_name = member.header == true ? name : member.header
|
80
|
-
hdr_name = "HTTP_" + hdr_name.upcase.gsub('-', '_')
|
81
|
-
@map_headers[name] = request.headers[hdr_name]
|
82
|
-
end
|
83
|
-
end
|
84
|
-
@map_headers
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
data/lib/seahorse/model.rb
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
module Seahorse
|
2
|
-
module Model
|
3
|
-
@@apis ||= {}
|
4
|
-
|
5
|
-
class << self
|
6
|
-
def apis; @@apis end
|
7
|
-
|
8
|
-
def add_all_routes(router)
|
9
|
-
Dir.glob("#{Rails.root}/app/models/api/*.rb").each {|f| load f }
|
10
|
-
@@apis.values.each {|api| api.add_routes(router) }
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
extend ActiveSupport::Concern
|
15
|
-
|
16
|
-
included do
|
17
|
-
@@apis[name.underscore.gsub(/_api$|^api\//, '')] = self
|
18
|
-
end
|
19
|
-
|
20
|
-
module ClassMethods
|
21
|
-
attr_reader :operations
|
22
|
-
|
23
|
-
def model_name
|
24
|
-
name.underscore.gsub(/_api$|^api\//, '')
|
25
|
-
end
|
26
|
-
|
27
|
-
def add_routes(router)
|
28
|
-
Seahorse::Router.new(self).add_routes(router)
|
29
|
-
end
|
30
|
-
|
31
|
-
def desc(text)
|
32
|
-
@desc = text
|
33
|
-
end
|
34
|
-
|
35
|
-
def operation(name, &block)
|
36
|
-
name, action = *operation_name_and_action(name)
|
37
|
-
@actions ||= {}
|
38
|
-
@operations ||= {}
|
39
|
-
@operations[name] = Operation.new(self, name, action, &block)
|
40
|
-
@operations[name].documentation = @desc
|
41
|
-
@actions[action] = @operations[name]
|
42
|
-
@desc = nil
|
43
|
-
end
|
44
|
-
|
45
|
-
def operation_from_action(action)
|
46
|
-
@actions ||= {}
|
47
|
-
@actions[action]
|
48
|
-
end
|
49
|
-
|
50
|
-
def type(name, &block)
|
51
|
-
supertype = 'structure'
|
52
|
-
name, supertype = *name.map {|k,v| [k, v] }.flatten if Hash === name
|
53
|
-
ShapeBuilder.type(name, supertype, &block)
|
54
|
-
end
|
55
|
-
|
56
|
-
def to_hash
|
57
|
-
ops = @operations.inject({}) do |hash, (name, operation)|
|
58
|
-
hash[name.camelcase(:lower)] = operation.to_hash
|
59
|
-
hash
|
60
|
-
end
|
61
|
-
{'operations' => ops}
|
62
|
-
end
|
63
|
-
|
64
|
-
private
|
65
|
-
|
66
|
-
def operation_name_and_action(name)
|
67
|
-
if Hash === name
|
68
|
-
name.to_a.first.map(&:to_s).reverse
|
69
|
-
else
|
70
|
-
case name.to_s
|
71
|
-
when 'index', 'list'
|
72
|
-
["list_#{model_name.pluralize}", 'index']
|
73
|
-
when 'show'
|
74
|
-
["get_#{model_name}", name.to_s]
|
75
|
-
else
|
76
|
-
["#{name}_#{model_name}", name.to_s]
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
data/lib/seahorse/operation.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
module Seahorse
|
2
|
-
class Operation
|
3
|
-
attr_reader :name, :verb, :action
|
4
|
-
attr_accessor :documentation
|
5
|
-
|
6
|
-
def initialize(controller, name, action = nil, &block)
|
7
|
-
@name = name.to_s
|
8
|
-
@action = action.to_s
|
9
|
-
@controller = controller
|
10
|
-
url_prefix = "/" + controller.model_name.pluralize
|
11
|
-
url_extra = nil
|
12
|
-
|
13
|
-
case action.to_s
|
14
|
-
when 'index'
|
15
|
-
@verb = 'get'
|
16
|
-
when 'show'
|
17
|
-
@verb = 'get'
|
18
|
-
url_extra = ':id'
|
19
|
-
when 'destroy', 'delete'
|
20
|
-
@verb = 'delete'
|
21
|
-
url_extra = ':id'
|
22
|
-
when 'create'
|
23
|
-
@verb = 'post'
|
24
|
-
when 'update'
|
25
|
-
@verb = 'put'
|
26
|
-
else
|
27
|
-
@verb = 'get'
|
28
|
-
url_extra = name.to_s
|
29
|
-
end
|
30
|
-
@url = url_prefix + (url_extra ? "/#{url_extra}" : "")
|
31
|
-
|
32
|
-
instance_eval(&block)
|
33
|
-
end
|
34
|
-
|
35
|
-
def verb(verb = nil)
|
36
|
-
verb ? (@verb = verb) : @verb
|
37
|
-
end
|
38
|
-
|
39
|
-
def url(url = nil)
|
40
|
-
url ? (@url = url) : @url
|
41
|
-
end
|
42
|
-
|
43
|
-
def input(type = nil, &block)
|
44
|
-
@input ||= ShapeBuilder.type_class_for(type || 'structure').new
|
45
|
-
type || block ? ShapeBuilder.new(@input).build(&block) : @input
|
46
|
-
end
|
47
|
-
|
48
|
-
def output(type = nil, &block)
|
49
|
-
@output ||= ShapeBuilder.type_class_for(type || 'structure').new
|
50
|
-
type || block ? ShapeBuilder.new(@output).build(&block) : @output
|
51
|
-
end
|
52
|
-
|
53
|
-
def to_hash
|
54
|
-
{
|
55
|
-
'name' => name.camelcase,
|
56
|
-
'http' => {
|
57
|
-
'uri' => url.gsub(/:(\w+)/, '{\1}'),
|
58
|
-
'method' => verb.upcase
|
59
|
-
},
|
60
|
-
'input' => input.to_hash,
|
61
|
-
'output' => output.to_hash,
|
62
|
-
'documentation' => documentation
|
63
|
-
}
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|