apidiesel 0.12 → 0.13

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
  SHA1:
3
- metadata.gz: 08fe77f23044c1ce2a36e5bd94e2c017a0683c9c
4
- data.tar.gz: fb4e57bad12bd7f33791bd7ec5271210543cd047
3
+ metadata.gz: 9da8479808b1cfc506569b246e5dc7901d51d8be
4
+ data.tar.gz: 853d657cf6fbb75d6b0518900aa1375813b5e035
5
5
  SHA512:
6
- metadata.gz: bbff420944f968b9f9a9de1be0db1af02856da7b407e8fbf3a3580f4d914cf9754d621413c05d50eccbbace72e2ed2947eb4e8235bb3a29549eb4fd48db92212
7
- data.tar.gz: 84c5a28bde9e6043a9ad0583e63735bcd7be360e7db8fc315d07ba2bbbf6701e4b2611dc12351ec11fcceb9898f8505769dba7cc9113e765b6a8d57a5400618d
6
+ metadata.gz: bb0cbe4ab97aa00a61c4dba87f93a9238060bc3847a82226cf16ab3aeb5e3cd2dc8b1bdfab89b094e79fe0077553955b5a4e85b6e17d8274adedaca4740bf785
7
+ data.tar.gz: af20d68bf9143dee06a5686f4c7092310e4f09b5a76ce2b10321310a6a97ae1cb79cd97034cf72b6466d795de0ddf1461d263a14bc0c42e0dc2e50bb5961034d
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup=markdown
data/apidiesel.gemspec CHANGED
@@ -25,4 +25,10 @@ Gem::Specification.new do |spec|
25
25
 
26
26
  spec.add_development_dependency "bundler", "~> 1.10"
27
27
  spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "redcarpet", "~> 3.3"
29
+ spec.add_development_dependency "yard", "~> 0.8"
30
+ spec.add_development_dependency "pry", "~> 0.10"
31
+ spec.add_development_dependency 'pry-byebug', '~> 3.2.0'
32
+ spec.add_development_dependency 'pry-rescue', '~> 1.4'
33
+ spec.add_development_dependency 'pry-stack_explorer', '~> 0.4.9'
28
34
  end
data/bin/console CHANGED
@@ -10,5 +10,5 @@ require "apidiesel"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
14
- IRB.start
13
+ require "pry"
14
+ Pry.start
@@ -0,0 +1,102 @@
1
+ module Github
2
+ module Actions
3
+ class GetUserRepos < Apidiesel::Action
4
+ url path: '/users/%{username}/repos'
5
+
6
+ expects do
7
+ string :username, submit: false
8
+ end
9
+
10
+ responds_with do
11
+ array do
12
+ integer :id
13
+ string :name
14
+ string :full_name
15
+ hash :owner do
16
+ string :login
17
+ integer :id
18
+ string :avatar_url
19
+ string :gravatar_id
20
+ string :url
21
+ string :html_url
22
+ string :followers_url
23
+ string :following_url
24
+ string :gists_url
25
+ string :starred_url
26
+ string :subscriptions_url
27
+ string :organizations_url
28
+ string :repos_url
29
+ string :events_url
30
+ string :received_events_url
31
+ string :type
32
+ string :site_admin
33
+ end
34
+ boolean :private
35
+ string :html_url
36
+ string :description
37
+ string :fork
38
+ string :url
39
+ string :forks_url
40
+ string :keys_url
41
+ string :collaborators_url
42
+ string :teams_url
43
+ string :hooks_url
44
+ string :issue_events_url
45
+ string :events_url
46
+ string :assignees_url
47
+ string :branches_url
48
+ string :tags_url
49
+ string :blobs_url
50
+ string :git_tags_url
51
+ string :git_refs_url
52
+ string :trees_url
53
+ string :statuses_url
54
+ string :languages_url
55
+ string :stargazers_url
56
+ string :contributors_url
57
+ string :subscribers_url
58
+ string :subscription_url
59
+ string :commits_url
60
+ string :git_commits_url
61
+ string :comments_url
62
+ string :issue_comment_url
63
+ string :contents_url
64
+ string :compare_url
65
+ string :merges_url
66
+ string :archive_url
67
+ string :downloads_url
68
+ string :issues_url
69
+ string :pulls_url
70
+ string :milestones_url
71
+ string :notifications_url
72
+ string :labels_url
73
+ string :releases_url
74
+ string :deployments_url
75
+ datetime :created_at
76
+ datetime :updated_at
77
+ datetime :pushed_at
78
+ string :git_url
79
+ string :ssh_url
80
+ string :clone_url
81
+ string :svn_url
82
+ string :homepage
83
+ integer :size
84
+ integer :stargazers_count
85
+ integer :watchers_count
86
+ string :language
87
+ boolean :has_issues
88
+ boolean :has_downloads
89
+ boolean :has_wiki
90
+ boolean :has_pages
91
+ integer :forks_count
92
+ string :mirror_url
93
+ integer :open_issues_count
94
+ integer :forks
95
+ integer :open_issues
96
+ integer :watchers
97
+ string :default_branch
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,15 @@
1
+ require "apidiesel"
2
+
3
+ Dir[ File.join(__dir__, 'actions', '*.rb') ].each do |file|
4
+ require file
5
+ end
6
+
7
+ module Github
8
+ class Api < Apidiesel::Api
9
+ use Apidiesel::Handlers::JSON
10
+
11
+ url 'https://api.github.com'
12
+
13
+ register_actions
14
+ end
15
+ end
data/lib/apidiesel.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'uri'
2
2
  require 'httpi'
3
+ require 'active_support/all'
3
4
 
4
5
  HTTPI.log = false
5
6
 
@@ -13,5 +14,4 @@ require 'apidiesel/request'
13
14
  require 'apidiesel/action'
14
15
  require 'apidiesel/handlers/action_response_processor'
15
16
  require 'apidiesel/handlers/http_request_helper'
16
- require 'apidiesel/handlers/json'
17
-
17
+ require 'apidiesel/handlers/json'
@@ -9,15 +9,20 @@ module Apidiesel
9
9
  class << self
10
10
  include Handlers
11
11
 
12
- attr_reader :url_args
12
+ attr_reader :url_value, :url_args
13
13
 
14
- # Hash for storing validation closures. These closures are called with the request
14
+ # Array for storing parameter validation closures. These closures are called with the request
15
15
  # parameters before the request is made and have the opportunity to check and modify them.
16
16
  def parameter_validations
17
17
  @parameter_validations ||= []
18
18
  end
19
19
 
20
- # Hash for storing filter closures. These closures are called with the received data
20
+ # Array for storing action argument names which are not to be submitted as parameters
21
+ def parameters_to_filter
22
+ @parameters_to_filter ||= []
23
+ end
24
+
25
+ # Array for storing filter closures. These closures are called with the received data
21
26
  # after a request is made and have the opportunity to modify or check it before the
22
27
  # data is returned
23
28
  def response_filters
@@ -47,21 +52,78 @@ module Apidiesel
47
52
  end
48
53
  end
49
54
 
50
- # Combined getter/setter for this actions URL
55
+ # Defines this Actions URL, or modifies the base URL set on `Api`
51
56
  #
52
- # Falls back to the Api setting if blank.
57
+ # Given keyword arguments such as `path:` will be applied to
58
+ # the `URI` object supplied to `Api.url`.
53
59
  #
54
- # @param [String] value
55
- def url(value = nil, **args)
56
- return @url unless value || args.any?
57
-
58
- if value && value.is_a?(Proc)
59
- @url = value
60
- elsif value
61
- @url = URI.parse(value)
62
- else
63
- @url_args = args
60
+ # Accepts a `Proc`, which will be called at request time with
61
+ # the URL constructed so far and the current `Request` object.
62
+ #
63
+ # A string value and all keyword arguments can contain
64
+ # placeholders for all arguments supplied to the action in
65
+ # Rubys standard `String.%` syntax.
66
+ #
67
+ # @example
68
+ # class Api < Apidiesel::Api
69
+ # url 'https://foo.example'
70
+ #
71
+ # register_actions
72
+ # end
73
+ #
74
+ # module Actions
75
+ # # modify the base URL set on `Api`
76
+ # class ActionA < Apidiesel::Action
77
+ # url path: '/action_a'
78
+ # end
79
+ #
80
+ # # replace the base URL set on `Api`
81
+ # class ActionB < Apidiesel::Action
82
+ # url 'https://subdomain.foo.example'
83
+ # end
84
+ #
85
+ # # modify the base URL set on `Api` with a
86
+ # # 'username' argument placeholder
87
+ # class ActionC < Apidiesel::Action
88
+ # url path: '/action_c/%{username}'
89
+ #
90
+ # expects do
91
+ # string :username, submit: false
92
+ # end
93
+ # end
94
+ #
95
+ # # dynamically determine the URL with a
96
+ # # `Proc` object
97
+ # class ActionD < Apidiesel::Action
98
+ # url ->(url, request) {
99
+ # url.path = '/' + request.action_arguments[:username]
100
+ # .downcase
101
+ # url
102
+ # }
103
+ #
104
+ # expects do
105
+ # string :username, submit: false
106
+ # end
107
+ # end
108
+ # end
109
+ #
110
+ # @overload url(value)
111
+ # @param [String, URI] value a complete URL string or `URI`
112
+ #
113
+ # @overload url(**kargs)
114
+ # @option **kargs [String] any method name valid on Rubys `URI::Generic`
115
+ #
116
+ # @overload url(value)
117
+ # @param [Proc] value a callback that returns a URL string at request time.
118
+ # Receives the URL contructed so far and the current
119
+ # `Request` instance.
120
+ def url(value = nil, **kargs)
121
+ if value && kargs.any?
122
+ raise ArgumentError, "you cannot supply both argument and keyword args"
64
123
  end
124
+
125
+ @url_value = value
126
+ @url_args = kargs
65
127
  end
66
128
 
67
129
  # Combined getter/setter for the HTTP method used
@@ -128,42 +190,17 @@ module Apidiesel
128
190
  self.class.endpoint
129
191
  end
130
192
 
131
- def base_url
132
- if self.class.url.nil? || self.class.url.is_a?(Proc)
133
- @api.class.url.dup
134
- else
135
- self.class.url.dup
136
- end
137
- end
138
-
139
- def url
140
- if self.class.url.is_a?(Proc)
141
- url = self.class.url
142
-
143
- elsif self.class.url_args
144
- url = base_url
145
-
146
- self.class.url_args.each do |key, value|
147
- url.send("#{key}=", value)
148
- end
149
- end
150
-
151
- url
152
- end
153
-
154
193
  def http_method
155
- self.class.http_method || @api.class.http_method
194
+ self.class.http_method || @api.class.http_method || :get
156
195
  end
157
196
 
158
197
  # Performs the action-specific input validations on `*args` according to the actions
159
198
  # `expects` block, executes the API request and prepares the data according to the
160
199
  # actions `responds_with` block.
161
200
  #
162
- # @param [Hash] *args see specific, non-abstract `Apidiesel::Action`
201
+ # @option **args see specific, non-abstract `Apidiesel::Action`
163
202
  # @return [Apidiesel::Request]
164
- def build_request(*args)
165
- args = args && args.first.is_a?(Hash) ? args.first : {}
166
-
203
+ def build_request(**args)
167
204
  params = {}
168
205
 
169
206
  self.class.parameter_validations.each do |validation|
@@ -172,9 +209,14 @@ module Apidiesel
172
209
 
173
210
  if self.class.parameter_formatter
174
211
  params = self.class.parameter_formatter.call(params)
212
+ else
213
+ params.except!(*self.class.parameters_to_filter)
175
214
  end
176
215
 
177
- Apidiesel::Request.new action: self, parameters: params
216
+ request = Apidiesel::Request.new(action: self, action_arguments: args, parameters: params)
217
+ request.url = build_url(args, request)
218
+
219
+ request
178
220
  end
179
221
 
180
222
  def process_response(response_data)
@@ -208,6 +250,34 @@ module Apidiesel
208
250
 
209
251
  protected
210
252
 
253
+ # @return [URI]
254
+ def build_url(action_arguments, request)
255
+ url = case self.class.url_value
256
+ when String
257
+ URI( self.class.url_value % action_arguments )
258
+ when URI
259
+ self.class.url_value
260
+ when Proc
261
+ self.class.url_value.call(base_url, request)
262
+ when nil
263
+ base_url
264
+ end
265
+
266
+ url_args = self.class.url_args.transform_values do |value|
267
+ value % action_arguments
268
+ end
269
+
270
+ url_args.each do |name, value|
271
+ url.send("#{name}=", value)
272
+ end
273
+
274
+ url
275
+ end
276
+
277
+ def base_url
278
+ @api.class.url.nil? ? URI('http://') : @api.class.url.dup
279
+ end
280
+
211
281
  # @return [Hash] Apidiesel configuration options
212
282
  def config
213
283
  Apidiesel::CONFIG[environment]
data/lib/apidiesel/api.rb CHANGED
@@ -42,7 +42,7 @@ module Apidiesel
42
42
  #
43
43
  # Falls back to the Api setting if blank.
44
44
  #
45
- # @param [String] value
45
+ # @param [String] base_url
46
46
  def url(base_url = nil)
47
47
  if base_url
48
48
  config[:url] = URI.parse(base_url)
@@ -68,7 +68,8 @@ module Apidiesel
68
68
  #
69
69
  # Falls back to the Api setting if blank.
70
70
  #
71
- # @param [String] value
71
+ # @param [String] username
72
+ # @param [String] password
72
73
  def http_basic_auth(username = nil, password = nil)
73
74
  if username && password
74
75
  config[:http_basic_username] = username
data/lib/apidiesel/dsl.rb CHANGED
@@ -17,6 +17,7 @@ module Apidiesel
17
17
  builder = ExpectationBuilder.new
18
18
  builder.instance_eval(&block)
19
19
  parameter_validations.concat builder.parameter_validations
20
+ parameters_to_filter.concat builder.parameters_to_filter
20
21
  end
21
22
 
22
23
  # Defines the expected content and format of the response for this API action.
@@ -53,10 +54,13 @@ module Apidiesel
53
54
  # ExpectationBuilder defines the methods available within an `expects` block
54
55
  # when defining an API action.
55
56
  class ExpectationBuilder
56
- attr_accessor :parameter_validations
57
+ # @!visibility private
58
+ attr_accessor :parameter_validations, :parameters_to_filter
57
59
 
60
+ # @!visibility private
58
61
  def initialize
59
62
  @parameter_validations = []
63
+ @parameters_to_filter = []
60
64
  end
61
65
 
62
66
  # Defines a string parameter.
@@ -71,19 +75,23 @@ module Apidiesel
71
75
  # # This action expects to be given an 'email', which is sent to the API as 'username',
72
76
  # # and requires either a 'value1', a 'value2' or both to be present.
73
77
  #
74
- # @param [Symbol] param_name name of the parameter
75
- # @param [Hash] *args
76
- # @option *args [Boolean] :optional (false) defines whether this parameter may be omitted
77
- # @option *args [Symbol] :optional_if_present param_name is optional, if the parameter given here is present instead
78
- # @option *args [Symbol] :required_if_present param_name is required if param_name is also present
79
- # @option *args [Symbol] :submitted_as submit param_name to the API under the name given here
80
- # @option *args [Object] :default a default parameter to be set when no value is specified
81
- # @option *args [Enumerable] :allowed_values only accept the values in this Enumerable.
82
- # If Enumerable is a Hash, use the hash values to define what is actually
83
- # sent to the server. Example: `:allowed_values => {:foo => "f"}` allows
84
- # the value ':foo', but sends it as 'f'
85
- def string(param_name, *args)
86
- validation_builder(:to_s, param_name, *args)
78
+ # @!macro [new] expectation_types
79
+ # @param param_name [Symbol] name of the parameter
80
+ # @option args [Boolean] :optional (false) defines whether this parameter may be omitted
81
+ # @option args [Symbol] :optional_if_present param_name is optional, if the parameter given here is present instead
82
+ # @option args [Symbol] :required_if_present param_name is required if param_name is also present
83
+ # @option args [Symbol] :submitted_as submit param_name to the API under the name given here
84
+ # @option args [Object] :default a default parameter to be set when no value is specified
85
+ # @option args [true, false] :submit (true) set to `false` for arguments that should not be submitted
86
+ # as API parameters
87
+ # @option args [Enumerable] :allowed_values only accept the values in this Enumerable.
88
+ # If Enumerable is a Hash, use the hash values to define what is actually
89
+ # sent to the server. Example: `:allowed_values => {:foo => "f"}` allows
90
+ # the value ':foo', but sends it as 'f'
91
+ # @return [nil]
92
+ def string(param_name, **args)
93
+ validation_builder(:to_s, param_name, **args)
94
+ parameters_to_filter << param_name if args[:submit] == false
87
95
  end
88
96
 
89
97
  # Defines an integer parameter.
@@ -93,10 +101,10 @@ module Apidiesel
93
101
  # integer :per_page, :optional => true
94
102
  # end
95
103
  #
96
- # @param (see #string)
97
- # @option (see #string)
98
- def integer(param_name, *args)
99
- validation_builder(:to_i, param_name, *args)
104
+ # @!macro expectation_types
105
+ def integer(param_name, **args)
106
+ validation_builder(:to_i, param_name, **args)
107
+ parameters_to_filter << param_name if args[:submit] == false
100
108
  end
101
109
 
102
110
  # Defines a boolean parameter.
@@ -108,10 +116,10 @@ module Apidiesel
108
116
  # boolean :per_page, :optional => true
109
117
  # end
110
118
  #
111
- # @param (see #string)
112
- # @option (see #string)
113
- def boolean(param_name, *args)
114
- validation_builder(:to_s, param_name, *args)
119
+ # @!macro expectation_types
120
+ def boolean(param_name, **args)
121
+ validation_builder(:to_s, param_name, **args)
122
+ parameters_to_filter << param_name if args[:submit] == false
115
123
  end
116
124
 
117
125
  # Defines a date, time or datetime parameter.
@@ -122,15 +130,15 @@ module Apidiesel
122
130
  # datetime :starts_at, format: '%d-%m-%Y'
123
131
  # end
124
132
  #
125
- # @param (see #string)
126
- # @option *args [String] :format strftime format string
127
- # @option (see #string)
133
+ # @!macro expectation_types
134
+ # @option args [String] :format a format string as supported by Rubys `#strftime`
128
135
  def datetime(param_name, **args)
129
136
  if args[:format]
130
137
  args[:processor] = ->(value) { value.try(:strftime, args[:format]) }
131
138
  end
132
139
 
133
140
  validation_builder(:strftime, param_name, **args)
141
+ parameters_to_filter << param_name if args[:submit] == false
134
142
  end
135
143
 
136
144
  alias_method :time, :datetime
@@ -144,9 +152,8 @@ module Apidiesel
144
152
  # object :contract, klass: Contract
145
153
  # end
146
154
  #
147
- # @param (see #string)
148
- # @option *args [Class] :klass
149
- # @option (see #string)
155
+ # @!macro expectation_types
156
+ # @option args [Class] :klass the expected class of the value
150
157
  def object(param_name, **args)
151
158
  type_check = ->(value, param_name) {
152
159
  unless value.is_a?(args[:klass])
@@ -155,12 +162,13 @@ module Apidiesel
155
162
  }
156
163
 
157
164
  validation_builder(type_check, param_name, **args)
165
+ parameters_to_filter << param_name if args[:submit] == false
158
166
  end
159
167
 
160
168
  protected
161
169
 
162
- def validation_builder(duck_typing_check, param_name, *args)
163
- options = args.extract_options!
170
+ def validation_builder(duck_typing_check, param_name, **args)
171
+ options = args
164
172
 
165
173
  parameter_validations << lambda do |given_params, processed_params|
166
174
  if options[:default]
@@ -211,13 +219,38 @@ module Apidiesel
211
219
  # FilterBuilder defines the methods available within an `responds_with` block
212
220
  # when defining an API action.
213
221
  class FilterBuilder
222
+ # @!visibility private
214
223
  attr_accessor :response_filters, :response_formatters
215
224
 
225
+ # @!visibility private
216
226
  def initialize
217
227
  @response_filters = []
218
228
  @response_formatters = []
219
229
  end
220
230
 
231
+ # @!macro [new] filter_types
232
+ # Returns a $0 from the API response hash
233
+ #
234
+ # @overload $0(key, **kargs)
235
+ # Get the $0 named `key` from the response hash and name it `key` in the result hash
236
+ #
237
+ # @param key [String, Symbol]
238
+ # @option kargs [Proc] :prefilter callback for modifying the value before typecasting
239
+ # @option kargs [Proc] :postfilter callback for modifying the value after typecasting
240
+ # @option kargs [Proc] :filter alias for :postfilter
241
+ # @option kargs [Hash] :map a hash map for replacing the value
242
+ #
243
+ # @overload $0(at:, as:, **kargs)
244
+ # Get the $0 named `at:` from the response hash and name it `as:` in the result hash
245
+ #
246
+ # @param at [String, Symbol, Array<Symbol>] response hash key name or key path to lookup
247
+ # @param as [String, Symbol] result hash key name to return the value as
248
+ # @option kargs [Proc] :prefilter callback for modifying the value before typecasting
249
+ # @option kargs [Proc] :postfilter callback for modifying the value after typecasting
250
+ # @option kargs [Proc] :filter alias for :postfilter
251
+ # @option kargs [Hash] :map a hash map for replacing the value
252
+ #
253
+ # @return [nil]
221
254
  def value(*args, **kargs)
222
255
  args = normalize_arguments(args, kargs)
223
256
 
@@ -236,43 +269,65 @@ module Apidiesel
236
269
  end
237
270
  end
238
271
 
239
- # Returns `key` from the API response as a string.
272
+ # @!macro filter_types
240
273
  #
241
- # @param [Symbol] key the key name to be returned as a string
242
- # @param [Hash] *args
243
- # @option *args [Symbol] :within look up the key in a namespace (nested hash)
274
+ # Please note that response value is typecasted to `String` for comparison, so that
275
+ # for absent values to be considered false, you have to include an empty string.
276
+ #
277
+ # @option kargs [Array<#to_s>, #to_s] :truthy ('true') values to be considered true
278
+ # @option kargs [Array<#to_s>, #to_s] :falsy ('false') values to be considered false
279
+ def boolean(*args, **kargs)
280
+ args = normalize_arguments(args, kargs)
281
+
282
+ args.reverse_merge!(truthy: 'true', falsy: 'false')
283
+
284
+ args[:truthy] = Array(args[:truthy]).map(&:to_s)
285
+ args[:falsy] = Array(args[:falsy]).map(&:to_s)
286
+
287
+ response_formatters << lambda do |data, processed_data|
288
+ value = get_value(data, args[:at])
289
+
290
+ value = apply_filter(args[:prefilter], value)
291
+
292
+ value = if args[:truthy].include?(value.to_s)
293
+ true
294
+ elsif args[:falsy].include?(value.to_s)
295
+ false
296
+ else
297
+ nil
298
+ end
299
+
300
+ value = apply_filter(args[:postfilter] || args[:filter], value)
301
+
302
+ value = args[:map][value] if args[:map]
303
+
304
+ processed_data[ args[:as] ] = value
305
+
306
+ processed_data
307
+ end
308
+ end
309
+
310
+ # @!macro filter_types
244
311
  def string(*args, **kargs)
245
312
  create_primitive_formatter(:to_s, *args, **kargs)
246
313
  end
247
314
 
248
- # Returns `key` from the API response as an integer.
249
- #
250
- # @param (see #string)
251
- # @option (see #string)
315
+ # @!macro filter_types
252
316
  def integer(*args, **kargs)
253
317
  create_primitive_formatter(:to_i, *args, **kargs)
254
318
  end
255
319
 
256
- # Returns `key` from the API response as a float.
257
- #
258
- # @param (see #string)
259
- # @option (see #string)
320
+ # @!macro filter_types
260
321
  def float(*args, **kargs)
261
322
  create_primitive_formatter(:to_f, *args, **kargs)
262
323
  end
263
324
 
264
- # Returns `key` from the API response as a symbol.
265
- #
266
- # @param (see #string)
267
- # @option (see #string)
325
+ # @!macro filter_types
268
326
  def symbol(*args, **kargs)
269
327
  create_primitive_formatter(:to_sym, *args, **kargs)
270
328
  end
271
329
 
272
- # Returns `key` from the API response as DateTime.
273
- #
274
- # @param (see #string)
275
- # @option (see #string)
330
+ # @!macro filter_types
276
331
  def datetime(*args, **kargs)
277
332
  args = normalize_arguments(args, kargs)
278
333
  args.reverse_merge!(format: '%Y-%m-%d')
@@ -296,10 +351,7 @@ module Apidiesel
296
351
  end
297
352
  end
298
353
 
299
- # Returns `key` from the API response as Date.
300
- #
301
- # @param (see #string)
302
- # @option (see #string)
354
+ # @!macro filter_types
303
355
  def date(*args, **kargs)
304
356
  args = normalize_arguments(args, kargs)
305
357
  args.reverse_merge!(format: '%Y-%m-%d')
@@ -323,10 +375,7 @@ module Apidiesel
323
375
  end
324
376
  end
325
377
 
326
- # Returns `key` from the API response as Time.
327
- #
328
- # @param (see #string)
329
- # @option (see #string)
378
+ # @!macro filter_types
330
379
  def time(*args, **kargs)
331
380
  args = normalize_arguments(args, kargs)
332
381
  args.reverse_merge!(format: '%Y-%m-%d')
@@ -350,8 +399,7 @@ module Apidiesel
350
399
  end
351
400
  end
352
401
 
353
- # Returns an array of subhashes
354
- #
402
+ # @!macro filter_types
355
403
  # @example
356
404
  #
357
405
  # # Given an API response:
@@ -375,6 +423,7 @@ module Apidiesel
375
423
  # end
376
424
  # end
377
425
  #
426
+ # @example
378
427
  # # Given an API response:
379
428
  # #
380
429
  # # [
@@ -388,19 +437,12 @@ module Apidiesel
388
437
  # # },
389
438
  # # ]
390
439
  #
391
- # @example
392
440
  # expects do
393
441
  # array do
394
442
  # string :name
395
443
  # integer :order_id
396
444
  # end
397
445
  # end
398
- #
399
- # @option *args [Symbol] the key for finding and returning the array
400
- # (sets both :as and :at)
401
- # @option **kargs [Symbol] :at which key to find the hash at in the
402
- # response
403
- # @option **kargs [Symbol] :as which key to return the result under
404
446
  def array(*args, **kargs, &block)
405
447
  unless block.present?
406
448
  create_primitive_formatter(:to_a, *args, **kargs)
@@ -447,10 +489,7 @@ module Apidiesel
447
489
  end
448
490
  end
449
491
 
450
- # Returns `key` from the API response as a hash.
451
- #
452
- # @param (see #string)
453
- # @option (see #string)
492
+ # @!macro filter_types
454
493
  def hash(*args, **kargs, &block)
455
494
  unless block.present?
456
495
  create_primitive_formatter(:to_hash, *args, **kargs)
@@ -483,24 +522,24 @@ module Apidiesel
483
522
  end
484
523
  end
485
524
 
486
- # Returns the API response processed or wrapped in wrapper objects.
487
- #
488
525
  # @example
489
526
  # responds_with do
490
- # object :issues, :processed_with => lambda { |data| data.delete_if { |k,v| k == 'www_id' } }
527
+ # object :issues,
528
+ # processed_with: ->(data) {
529
+ # data.delete_if { |k,v| k == 'www_id' }
530
+ # }
491
531
  # end
492
532
  #
493
533
  # @example
494
534
  #
495
535
  # responds_with do
496
- # object :issues, :wrapped_in => Apidiesel::ResponseObjects::Topic
536
+ # object :issues,
537
+ # wrapped_in: Apidiesel::ResponseObjects::Topic
497
538
  # end
498
539
  #
499
- # @param [Symbol] key the key name to be wrapped or processed
500
- # @option *args [Symbol] :within look up the key in a namespace (nested hash)
501
- # @option *args [Proc] :processed_with yield the data to this Proc for processing
502
- # @option *args [Class] :wrapped_in wrapper object, will be called as `Object.create(data)`
503
- # @option *args [Symbol] :as key name to save the result as
540
+ # @!macro filter_types
541
+ # @option kargs [Proc] :processed_with yield the data to this Proc for processing
542
+ # @option kargs [Class] :wrapped_in wrapper object, will be called as `Object.create(data)`
504
543
  def objects(*args, **kargs)
505
544
  args = normalize_arguments(args, kargs)
506
545
 
@@ -530,7 +569,7 @@ module Apidiesel
530
569
  # @param [Symbol, Array] key
531
570
  def set_scope(key)
532
571
  response_filters << lambda do |data|
533
- begin; fetch_path(data, *key); rescue => e; binding.pry; end
572
+ fetch_path(data, *key)
534
573
  end
535
574
  end
536
575
 
@@ -543,7 +582,7 @@ module Apidiesel
543
582
  #
544
583
  # @param [Lambda, Proc] callable
545
584
  # @param [String, Lambda, Proc] message
546
- # @raises [Apidiesel::ResponseError]
585
+ # @raise [Apidiesel::ResponseError]
547
586
  def response_error_if(callable, message:)
548
587
  response_formatters << lambda do |data, processed_data|
549
588
  return processed_data unless callable.call(data)
@@ -2,25 +2,17 @@ module Apidiesel
2
2
 
3
3
  # Wrapper for API requests
4
4
  class Request
5
- attr_accessor :action, :parameters, :response_body, :http_request, :http_response, :metadata, :result
5
+ attr_accessor :action, :action_arguments, :parameters, :url, :response_body, :http_request, :http_response, :metadata, :result
6
6
 
7
7
  # @param [Apidiesel::Action] action
8
+ # @param [Hash] action_arguments
8
9
  # @param [Hash] parameters
9
10
  # @param [Hash] metadata
10
- def initialize(action:, parameters:, metadata: {})
11
- @action = action
12
- @parameters = parameters
13
- @metadata = metadata
14
- end
15
-
16
- def url
17
- @url ||=
18
- case action.url
19
- when Proc
20
- action.url.call(action.base_url, self)
21
- when URI
22
- action.url
23
- end
11
+ def initialize(action:, action_arguments:, parameters:, metadata: {})
12
+ @action = action
13
+ @action_arguments = action_arguments
14
+ @parameters = parameters
15
+ @metadata = metadata
24
16
  end
25
17
 
26
18
  def response_body
@@ -1,3 +1,3 @@
1
1
  module Apidiesel
2
- VERSION = "0.12"
2
+ VERSION = "0.13"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apidiesel
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.12'
4
+ version: '0.13'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan-Christian Foeh
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-02-29 00:00:00.000000000 Z
11
+ date: 2016-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -66,6 +66,90 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: redcarpet
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.3'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: yard
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.8'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.8'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.10'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.10'
111
+ - !ruby/object:Gem::Dependency
112
+ name: pry-byebug
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 3.2.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 3.2.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: pry-rescue
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.4'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.4'
139
+ - !ruby/object:Gem::Dependency
140
+ name: pry-stack_explorer
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 0.4.9
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 0.4.9
69
153
  description:
70
154
  email:
71
155
  - jan@programmanstalt.de
@@ -76,6 +160,7 @@ files:
76
160
  - ".gitignore"
77
161
  - ".ruby-gemset"
78
162
  - ".ruby-version"
163
+ - ".yardopts"
79
164
  - Gemfile
80
165
  - LICENSE
81
166
  - README.md
@@ -83,6 +168,8 @@ files:
83
168
  - apidiesel.gemspec
84
169
  - bin/console
85
170
  - bin/setup
171
+ - examples/github/actions/get_user_repos.rb
172
+ - examples/github/api.rb
86
173
  - lib/apidiesel.rb
87
174
  - lib/apidiesel/action.rb
88
175
  - lib/apidiesel/api.rb
@@ -120,3 +207,4 @@ signing_key:
120
207
  specification_version: 4
121
208
  summary: Build API clients through an expressive DSL
122
209
  test_files: []
210
+ has_rdoc: