apidiesel 0.12 → 0.13

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 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: