klient 0.0.1
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 +7 -0
- data/lib/klient.rb +12 -0
- data/lib/klient/hash_methods.rb +32 -0
- data/lib/klient/klient.rb +77 -0
- data/lib/klient/resource.rb +203 -0
- data/lib/klient/resource_collection.rb +17 -0
- data/lib/klient/resource_methods.rb +82 -0
- data/lib/klient/response.rb +59 -0
- data/lib/klient/response_data.rb +31 -0
- data/lib/klient/version.rb +3 -0
- metadata +178 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 05be7e8bf426e334012023a497e378cbede55ec3b6ea3f1f7c0f912798744f3c
|
4
|
+
data.tar.gz: 46406b31960577c079ea06bfcd4532e5f175a5a1330d68f26ecac50f999850ba
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 06c7b1ed4383baf74ab9ccd24e471671cc2cbb2f208ce14c56d42962b7e951594210e2a3c082c9478ce275ca7d3058f612933fc6ac748e9beb88b5b60e4bcc70
|
7
|
+
data.tar.gz: 411da5be1600da3008f9fb0b3d7bf4804292297984bb78fa8446fd1cb38f72499608ece66c899ac83915c4565f83dfb5b1be1e28843594c6d96df661b183e487
|
data/lib/klient.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
require 'addressable'
|
4
|
+
require 'nokogiri'
|
5
|
+
# require 'parsed_data'
|
6
|
+
|
7
|
+
require_relative "klient/hash_methods.rb"
|
8
|
+
require_relative "klient/klient.rb"
|
9
|
+
require_relative "klient/resource.rb"
|
10
|
+
require_relative "klient/response.rb"
|
11
|
+
require_relative "klient/response_data.rb"
|
12
|
+
require_relative "klient/version.rb"
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Hash
|
2
|
+
def deep_get(key, obj, found = nil)
|
3
|
+
if obj.respond_to?(:key?) && obj.key?(key)
|
4
|
+
return obj[key]
|
5
|
+
elsif obj.respond_to?(:each)
|
6
|
+
obj.find { |*a| found = deep_get(key, a.last) }
|
7
|
+
return found
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def deep_set(key, obj, value, found = nil)
|
12
|
+
if obj.respond_to?(:key?) && obj.key?(key)
|
13
|
+
obj[key] = value
|
14
|
+
return value
|
15
|
+
elsif obj.respond_to?(:each)
|
16
|
+
obj.find { |*a| found = deep_set(key, a.last, value) }
|
17
|
+
return found
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def method_missing(mth, *args, &block)
|
22
|
+
m = mth.to_s
|
23
|
+
|
24
|
+
if keys.include?(m)
|
25
|
+
self[m]
|
26
|
+
elsif m =~ /\S+=/
|
27
|
+
deep_set(m.gsub(/=/, ''), self, args[0])
|
28
|
+
else
|
29
|
+
deep_get(m, self)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
require_relative "resource"
|
3
|
+
require_relative "resource_methods"
|
4
|
+
|
5
|
+
module Klient
|
6
|
+
attr_reader :base_url, :header_proc, :collection_accessor, :headers, :collection_key, :url_template, :root
|
7
|
+
|
8
|
+
module KlientClassMethods
|
9
|
+
attr_reader :header_proc, :resource_map
|
10
|
+
|
11
|
+
include ResourceMethods
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.included(klass)
|
15
|
+
klass.extend(KlientClassMethods)
|
16
|
+
klass.send(:attr_reader, :header_proc)
|
17
|
+
klass.send(:attr_reader, :resource_map)
|
18
|
+
klass.send(:attr_reader, :identifier_map)
|
19
|
+
klass.instance_variable_set(:@resource_map, {})
|
20
|
+
klass.instance_variable_set(:@identifier_map, {})
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(base_url)
|
24
|
+
@root = self
|
25
|
+
@header_proc = self.class.header_proc
|
26
|
+
@collection_accessor = self.class.instance_variable_get(:@collection_accessor)
|
27
|
+
@base_url = base_url
|
28
|
+
@headers = headers
|
29
|
+
@url_template = Addressable::Template.new(base_url)
|
30
|
+
|
31
|
+
rmap = {}
|
32
|
+
self.class::Resource.descendants
|
33
|
+
.select { |x| x.name.split('::').length == 2 }
|
34
|
+
.sort { |x, y| x.name.demodulize <=> y.name.demodulize }
|
35
|
+
.each do |klass|
|
36
|
+
next unless klass.id
|
37
|
+
cname = klass.name.demodulize.underscore.singularize.to_sym
|
38
|
+
cname_plural = klass.name.demodulize.underscore.pluralize.to_sym
|
39
|
+
|
40
|
+
if rmap.include?(cname)
|
41
|
+
next
|
42
|
+
else
|
43
|
+
rmap[cname_plural] = klass
|
44
|
+
rmap[cname] = klass
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
imap = {}
|
49
|
+
rmap.values.each do |klass|
|
50
|
+
next unless klass.id
|
51
|
+
imap[klass.id] = klass
|
52
|
+
end
|
53
|
+
|
54
|
+
@resource_map = rmap
|
55
|
+
@identifier_map = imap
|
56
|
+
|
57
|
+
self.class::Resource.descendants.each do |rklass|
|
58
|
+
cname = rklass.name.demodulize.underscore.to_sym
|
59
|
+
|
60
|
+
if rklass && rklass.arguments && rklass.arguments[:type]
|
61
|
+
rklass.resource_type = @resource_map[rklass.arguments[:type]]
|
62
|
+
elsif @resource_map[rklass.arguments[:type]] && @identifier_map.key(rklass)
|
63
|
+
rklass.resource_type = @resource_map[@identifier_map.key(rklass)]
|
64
|
+
elsif @resource_map.values.include?(rklass)
|
65
|
+
rklass.resource_type = rklass
|
66
|
+
elsif @resource_map[cname]
|
67
|
+
rklass.resource_type = @resource_map[cname]
|
68
|
+
elsif @identifier_map[rklass.id]
|
69
|
+
rklass.resource_type = rklass.id
|
70
|
+
else
|
71
|
+
rklass.resource_type = rklass
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
alias url base_url
|
77
|
+
end
|
@@ -0,0 +1,203 @@
|
|
1
|
+
require_relative "resource_methods"
|
2
|
+
require_relative "resource_collection"
|
3
|
+
require 'pry'
|
4
|
+
module Klient
|
5
|
+
class Resource
|
6
|
+
attr_reader :collection_accessor, :header_proc, :headers, :id, :last_response, :parent, :status, :url, :url_arguments, :url_template,:root
|
7
|
+
|
8
|
+
class << self
|
9
|
+
attr_reader :collection_accessor, :id, :identifier, :mapping, :url_template
|
10
|
+
attr_accessor :arguments, :resource_type, :type
|
11
|
+
end
|
12
|
+
|
13
|
+
extend ResourceMethods
|
14
|
+
|
15
|
+
def initialize(parent)
|
16
|
+
@root = parent.root
|
17
|
+
@header_proc = parent.header_proc
|
18
|
+
@regexp = /#{self.class.name.demodulize.underscore.gsub(/(_|-|\s+)/, "(_|-|\s*)")}/i
|
19
|
+
@id = self.class.try(:id)
|
20
|
+
@collection_accessor = @identifier = self.class.try(:identifier)
|
21
|
+
|
22
|
+
if @id
|
23
|
+
@url_arguments = {@id => @identifier}
|
24
|
+
else
|
25
|
+
@url_arguments = {}
|
26
|
+
end
|
27
|
+
|
28
|
+
@parent = parent
|
29
|
+
@headers = {}
|
30
|
+
|
31
|
+
@url_template = Addressable::Template.new(
|
32
|
+
@parent.url + self.class.url_template.pattern
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
def inspect
|
37
|
+
"#<#{self.class.name}:#{object_id} @url=#{self.url.inspect} @status_code=#{self.last_response.try(:status) || 'nil'}>"
|
38
|
+
end
|
39
|
+
|
40
|
+
%i(delete get head).each do |mth|
|
41
|
+
define_method(mth) do |identifier = nil, **params|
|
42
|
+
|
43
|
+
if params.empty?
|
44
|
+
@headers = @header_proc.call
|
45
|
+
else
|
46
|
+
@headers = @header_proc.call.merge(params: params)
|
47
|
+
end
|
48
|
+
|
49
|
+
if identifier
|
50
|
+
out = process_response(
|
51
|
+
RestClient.send(
|
52
|
+
mth,
|
53
|
+
@url_template.expand(@id => identifier).to_s,
|
54
|
+
@headers
|
55
|
+
)
|
56
|
+
)
|
57
|
+
else
|
58
|
+
out = process_response(RestClient.send(mth, url, @headers))
|
59
|
+
end
|
60
|
+
|
61
|
+
if respond_to?(:last_response) && out.respond_to?(:last_response)
|
62
|
+
@last_response = out.last_response
|
63
|
+
end
|
64
|
+
|
65
|
+
out.instance_variable_set(:@identifier, identifier)
|
66
|
+
out
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
%i(post put).each do |mth|
|
71
|
+
define_method(mth) do |identifier = nil, doc, **params|
|
72
|
+
if params.empty?
|
73
|
+
@headers = @header_proc.call
|
74
|
+
else
|
75
|
+
@headers = @header_proc.call.merge(params: params)
|
76
|
+
end
|
77
|
+
out = process_response(
|
78
|
+
RestClient.send(mth, url, doc, @headers)
|
79
|
+
)
|
80
|
+
|
81
|
+
if respond_to?(:last_response) && out.respond_to?(:last_response)
|
82
|
+
@last_response = out.last_response
|
83
|
+
end
|
84
|
+
|
85
|
+
out.instance_variable_set(:@identifier, identifier)
|
86
|
+
out
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def url
|
91
|
+
@url_template.expand(@url_arguments).to_s
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
# Assumes JSON for the moment.
|
96
|
+
def process_doc(doc)
|
97
|
+
if doc.is_a?(Hash)
|
98
|
+
doc.to_json
|
99
|
+
elsif doc.empty?
|
100
|
+
{}.to_json
|
101
|
+
else
|
102
|
+
doc
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def method_missing(mth, *args, &block)
|
107
|
+
if @parsed_body.respond_to?(mth)
|
108
|
+
@parsed_body.send(mth, *args, &block)
|
109
|
+
else
|
110
|
+
@last_response.send(mth, *args, &block)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# EXPERIMENTAL (USING HASH MODS)
|
115
|
+
def process_response(resp)
|
116
|
+
parsed = JSON.parse(resp.body)#.to_data
|
117
|
+
|
118
|
+
klass_type = self.class.resource_type
|
119
|
+
|
120
|
+
if klass_type == self.class
|
121
|
+
klass = self.class.new(parent)
|
122
|
+
else
|
123
|
+
klass = self.class.resource_type.new(@root)
|
124
|
+
end
|
125
|
+
|
126
|
+
if klass_type != self.class
|
127
|
+
if match = klass.url_template.match(resp.request.args[:url])
|
128
|
+
klass.url_arguments[klass.id] = match.mapping.with_indifferent_access[klass.id]
|
129
|
+
end
|
130
|
+
else
|
131
|
+
if match = self.url_template.match(resp.request.args[:url])
|
132
|
+
klass.url_arguments[klass.id] = match.mapping.with_indifferent_access[klass.id]
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
if klass.url_arguments[klass.id]
|
137
|
+
klass.url_arguments[klass.id]= parsed[klass.id]
|
138
|
+
klass.instance_variable_set(:@last_response, Response.new(resp))
|
139
|
+
return klass
|
140
|
+
# elsif parsed.is_a?(Hash) && parsed.keys.any? { |k| k.to_sym == @root.collection_accessor }
|
141
|
+
# klass.url_arguments[klass.id]= parsed[klass.id]
|
142
|
+
# klass.instance_variable_set(:@last_response, Response.new(resp))
|
143
|
+
# return klass
|
144
|
+
elsif key = parsed.keys.find { |k| k.to_s =~ @regexp }
|
145
|
+
if parsed[key].is_a?(Array)
|
146
|
+
arr = parsed[key].map! do |res|
|
147
|
+
tmp = klass_type.new(@root)
|
148
|
+
# TODO: Ugly. Revisit after recursive lookup.
|
149
|
+
tmp.url_arguments[klass.id]= res.send(klass.id) || res.send(klass.collection_accessor).try(klass.id)
|
150
|
+
|
151
|
+
processed = Response.new(resp, res)
|
152
|
+
tmp.instance_variable_set(:@last_response, processed)
|
153
|
+
|
154
|
+
tmp.instance_variable_set(:@parsed_body, processed.parsed_body)
|
155
|
+
tmp.instance_variable_set(:@status, processed.status)
|
156
|
+
tmp
|
157
|
+
end
|
158
|
+
return Klient::ResourceCollection.new(arr)
|
159
|
+
else
|
160
|
+
klass.url_arguments[klass.id]= parsed.send(klass.id) if klass.id
|
161
|
+
klass.instance_variable_set(:@last_response, Response.new(resp))
|
162
|
+
return klass
|
163
|
+
end
|
164
|
+
elsif self.class.type == :resource
|
165
|
+
klass.url_arguments[klass.id]= parsed.send(klass.id) if klass.id
|
166
|
+
klass.instance_variable_set(:@last_response, Response.new(resp))
|
167
|
+
return klass
|
168
|
+
elsif klass.url_arguments[klass.id]
|
169
|
+
klass.url_arguments[klass.id]= parsed.send(klass.id)
|
170
|
+
klass.instance_variable_set(:@last_response, Response.new(resp))
|
171
|
+
return klass
|
172
|
+
else
|
173
|
+
if parsed.is_a?(Array)
|
174
|
+
arr = parsed
|
175
|
+
elsif parsed.keys.length == 1 && parsed[parsed.keys.first].is_a?(Array)
|
176
|
+
arr = parsed[parsed.keys.first]
|
177
|
+
else
|
178
|
+
parsed.keys.each do |k|
|
179
|
+
if parsed[k].is_a?(Array) && parsed[k].first && parsed[k].first.send(klass.id.to_sym)
|
180
|
+
arr = parsed[k]
|
181
|
+
break
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
arr.map! do |res|
|
187
|
+
tmp = klass_type.new(@root)
|
188
|
+
# TODO: Ugly. Revisit after recursive lookup.
|
189
|
+
tmp.url_arguments[klass.id]= res.send(klass.id) || res.send(klass.collection_accessor).try(klass.id)
|
190
|
+
|
191
|
+
processed = Response.new(resp, res)
|
192
|
+
tmp.instance_variable_set(:@last_response, processed)
|
193
|
+
|
194
|
+
tmp.instance_variable_set(:@parsed_body, processed.parsed_body)
|
195
|
+
tmp.instance_variable_set(:@status, processed.status)
|
196
|
+
tmp
|
197
|
+
end
|
198
|
+
|
199
|
+
return Klient::ResourceCollection.new(arr)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Klient
|
2
|
+
class ResourceCollection
|
3
|
+
attr_reader :members, :last_response
|
4
|
+
|
5
|
+
def initialize(arr)
|
6
|
+
@members = arr
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_missing(mth, *args, &block)
|
10
|
+
@members.send(mth, *args, &block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def respond_to?(mth, *args, &block)
|
14
|
+
super || @members.respond_to?(mth)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module ResourceMethods
|
2
|
+
def default_collection_accessor(sym)
|
3
|
+
@collection_accessor = sym
|
4
|
+
end
|
5
|
+
|
6
|
+
def headers(&block)
|
7
|
+
@header_proc = block
|
8
|
+
end
|
9
|
+
|
10
|
+
def collection(name, template = nil, **hash_args, &block)
|
11
|
+
klass_name = name.to_s.camelcase
|
12
|
+
|
13
|
+
klass = Class.new(Klient::Resource) do
|
14
|
+
@arguments = hash_args
|
15
|
+
@type = :collection
|
16
|
+
|
17
|
+
# Obtain the collection's resource identifier. Don't allow hash arg AND block
|
18
|
+
# param for same thing -- it has to be either one or the other.
|
19
|
+
if block_given? && block.arity > 0 && hash_args[:identifier]
|
20
|
+
raise ArgumentError, "Collection identifier for :#{name} can be specified as a " \
|
21
|
+
"hash argument OR a block parameter (You can't use both simultaneously.)"
|
22
|
+
elsif block_given? && block.arity > 0
|
23
|
+
@id = block.parameters[0][1]
|
24
|
+
elsif hash_args[:identifier]
|
25
|
+
@id = hash_args[:identifier]
|
26
|
+
else
|
27
|
+
# raise ArgumentError, "#{name} collection definition does not specify a resource identifier."
|
28
|
+
end
|
29
|
+
|
30
|
+
# Don't allow templates with variables.
|
31
|
+
if template && template =~ /[\{\}]/
|
32
|
+
raise ArgumentError, "URL template variables not supported."
|
33
|
+
end
|
34
|
+
|
35
|
+
# Build a URL template if the template arg was provided.
|
36
|
+
if template && id
|
37
|
+
@url_template = Addressable::Template.new(template.to_s + "{/#{id}}")
|
38
|
+
elsif id
|
39
|
+
@identifier = nil
|
40
|
+
@url_template = Addressable::Template.new("/#{name}{/#{id}}")
|
41
|
+
else
|
42
|
+
@identifier = nil
|
43
|
+
@url_template = Addressable::Template.new("/#{name}")
|
44
|
+
end
|
45
|
+
|
46
|
+
class_eval(&block) if block
|
47
|
+
end
|
48
|
+
const_set(klass_name, klass)
|
49
|
+
|
50
|
+
define_method(name) do
|
51
|
+
klass.new(self)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def resource(name, template = nil, **hash_args, &block)
|
56
|
+
klass_name = name.to_s.camelcase
|
57
|
+
|
58
|
+
klass = Class.new(Klient::Resource) do
|
59
|
+
@arguments = hash_args
|
60
|
+
@type = :resource
|
61
|
+
|
62
|
+
# TODO: Avoid identifier conflicts between hash and URL template.
|
63
|
+
if template
|
64
|
+
@url_template = Addressable::Template.new(template)
|
65
|
+
else
|
66
|
+
@identifier = nil
|
67
|
+
@url_template = Addressable::Template.new("/#{name}")
|
68
|
+
end
|
69
|
+
|
70
|
+
class_eval(&block) if block
|
71
|
+
end
|
72
|
+
const_set(klass_name, klass)
|
73
|
+
|
74
|
+
define_method(name) do
|
75
|
+
klass.new(self)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def resources(*resource_names)
|
80
|
+
resource_names.each { |rname| resource rname }
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'json'
|
2
|
+
module Klient
|
3
|
+
class Response
|
4
|
+
attr_reader :original_response, :parsed_body, :parsed_headers, :status
|
5
|
+
|
6
|
+
def body
|
7
|
+
@original_response.body
|
8
|
+
end
|
9
|
+
|
10
|
+
def ok?
|
11
|
+
(200..299).include?(status_code)
|
12
|
+
end
|
13
|
+
|
14
|
+
def status_code
|
15
|
+
@original_response.code
|
16
|
+
end
|
17
|
+
|
18
|
+
def headers
|
19
|
+
@parsed_headers
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(original_response, data = nil)
|
23
|
+
@status = original_response.code
|
24
|
+
|
25
|
+
# If data arg is provided then it's a collection resource and the original
|
26
|
+
# response is for the entire collection. We don't want that -- this is an
|
27
|
+
# individual resource FOR the collection -- so the data arg is used in place
|
28
|
+
# of the parsed body for the collection response.
|
29
|
+
if data
|
30
|
+
@original_response = nil
|
31
|
+
@parsed_body = data
|
32
|
+
@parsed_headers = nil
|
33
|
+
else
|
34
|
+
@original_response = original_response
|
35
|
+
@body = @original_response.body
|
36
|
+
@parsed_headers = @original_response.headers
|
37
|
+
|
38
|
+
if @original_response.body.blank?
|
39
|
+
@parsed_body = {}
|
40
|
+
else
|
41
|
+
@parsed_body = JSON.parse(@original_response.body)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# TODO: This is dangerously wrong. It's just a shortcut to get something working.
|
47
|
+
def method_missing(mth, *args, &block)
|
48
|
+
if mth.to_s =~ /http_(\d+)\?/
|
49
|
+
status_code == $1.to_i
|
50
|
+
else
|
51
|
+
@parsed_body.send(mth)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def respond_to_missing?(mth, *args)
|
56
|
+
mth.to_s =~ /http_(\d+)\?/ || @parsed_body.respond_to?(mth) || super
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Klient
|
2
|
+
class ResponseData
|
3
|
+
attr_reader :original_response, :parsed_body, :parsed_headers, :status_code
|
4
|
+
|
5
|
+
def body
|
6
|
+
nil
|
7
|
+
end
|
8
|
+
|
9
|
+
def headers
|
10
|
+
nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(status_code, parsed_body)
|
14
|
+
@status_code = status_code
|
15
|
+
@parsed_body = parsed_body.freeze
|
16
|
+
end
|
17
|
+
|
18
|
+
def ok?
|
19
|
+
(200..299).include?(status_code)
|
20
|
+
end
|
21
|
+
|
22
|
+
# TODO: Bandaid.
|
23
|
+
def method_missing(mth, *args, &block)
|
24
|
+
@parsed_body.send(mth, *args, &block)
|
25
|
+
end
|
26
|
+
|
27
|
+
def respond_to_missing?(mth, *args)
|
28
|
+
mth.to_s =~ /http_(\d+)\?/ || @parsed_body.respond_to?(mth) || super
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: klient
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- John Fitisoff
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-01-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.2.5
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.2.5
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: addressable
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.5.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.5.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: nokogiri
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.7.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.7.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rest-client
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.0.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 2.0.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: coveralls
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.8.21
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.8.21
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.16.1
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.16.1
|
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.11.3
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.11.3
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rake
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 12.3.1
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 12.3.1
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rspec
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 3.7.0
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 3.7.0
|
139
|
+
description: Experimental REST API client library.
|
140
|
+
email: jfitisoff@yahoo.com
|
141
|
+
executables: []
|
142
|
+
extensions: []
|
143
|
+
extra_rdoc_files: []
|
144
|
+
files:
|
145
|
+
- lib/klient.rb
|
146
|
+
- lib/klient/hash_methods.rb
|
147
|
+
- lib/klient/klient.rb
|
148
|
+
- lib/klient/resource.rb
|
149
|
+
- lib/klient/resource_collection.rb
|
150
|
+
- lib/klient/resource_methods.rb
|
151
|
+
- lib/klient/response.rb
|
152
|
+
- lib/klient/response_data.rb
|
153
|
+
- lib/klient/version.rb
|
154
|
+
homepage: https://github.com/jfitisoff/klient
|
155
|
+
licenses:
|
156
|
+
- MIT
|
157
|
+
metadata: {}
|
158
|
+
post_install_message:
|
159
|
+
rdoc_options: []
|
160
|
+
require_paths:
|
161
|
+
- lib
|
162
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 2.3.0
|
167
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
168
|
+
requirements:
|
169
|
+
- - ">="
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: '0'
|
172
|
+
requirements: []
|
173
|
+
rubyforge_project:
|
174
|
+
rubygems_version: 2.7.6
|
175
|
+
signing_key:
|
176
|
+
specification_version: 4
|
177
|
+
summary: Experimental REST API client library.
|
178
|
+
test_files: []
|