hyperresource 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/hyper_resource.rb +154 -0
- data/lib/hyper_resource/attributes.rb +24 -0
- data/lib/hyper_resource/link.rb +51 -0
- data/lib/hyper_resource/links.rb +26 -0
- data/lib/hyper_resource/modules/bless.rb +57 -0
- data/lib/hyper_resource/modules/http.rb +39 -0
- data/lib/hyper_resource/modules/utils.rb +29 -0
- data/lib/hyper_resource/objects.rb +31 -0
- data/lib/hyper_resource/response.rb +2 -0
- data/lib/hyper_resource/version.rb +4 -0
- metadata +128 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2fd8d70a1aa3c15bde69a7a26ca532232c1795cd
|
4
|
+
data.tar.gz: 87cf162990ed41accbb7fdf7b3bcc2abded565f7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3b6b9a4e0a3e19f78af2d68ac3b9fe208b1db41b0dc413f393d9a7b20a66ea853f95e2836f9524406573251d42cb5cbaab642b6489c7d7f5a1ee216ffadf426a
|
7
|
+
data.tar.gz: 62fc3bf454b4b54427c9d481c4556039119ba48ddcddbda4aee3c14f68f1b2d3288a7ccebbf2ef38b1b3fbe2914ef4b83f06c93a6bc70c082a4875f1985d396d
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'hyper_resource/version'
|
2
|
+
require 'hyper_resource/attributes'
|
3
|
+
require 'hyper_resource/links'
|
4
|
+
require 'hyper_resource/link'
|
5
|
+
require 'hyper_resource/objects'
|
6
|
+
require 'hyper_resource/response'
|
7
|
+
|
8
|
+
require 'hyper_resource/modules/utils'
|
9
|
+
require 'hyper_resource/modules/http'
|
10
|
+
require 'hyper_resource/modules/bless'
|
11
|
+
|
12
|
+
require 'pp'
|
13
|
+
|
14
|
+
class HyperResource
|
15
|
+
include HyperResource::Modules::Utils
|
16
|
+
include HyperResource::Modules::HTTP
|
17
|
+
include HyperResource::Modules::Bless
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def self._hr_class_attributes
|
22
|
+
%w( root auth headers namespace ).map(&:to_sym)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self._hr_attributes
|
26
|
+
%w( root href auth headers namespace
|
27
|
+
request response response_body
|
28
|
+
attributes links objects loaded).map(&:to_sym)
|
29
|
+
end
|
30
|
+
|
31
|
+
public
|
32
|
+
|
33
|
+
_hr_class_attributes.each {|attr| class_attribute attr}
|
34
|
+
_hr_attributes.each {|attr| attr_accessor attr}
|
35
|
+
|
36
|
+
# :nodoc:
|
37
|
+
DEFAULT_HEADERS = {
|
38
|
+
'Accept' => 'application/json'
|
39
|
+
}
|
40
|
+
|
41
|
+
## Create a new HyperResource, given a hash of options. These options
|
42
|
+
## include:
|
43
|
+
##
|
44
|
+
## [root] The root URL of the resource.
|
45
|
+
##
|
46
|
+
## [auth] Authentication information. Currently only +{basic:
|
47
|
+
## ['key', 'secret']}+ is supported.
|
48
|
+
##
|
49
|
+
## [namespace] Class or class name, into which resources should be
|
50
|
+
## instantiated.
|
51
|
+
##
|
52
|
+
## [headers] Headers to send along with requests for this resource (as
|
53
|
+
## well as its eventual child resources, if any).
|
54
|
+
def initialize(opts={})
|
55
|
+
if opts.is_a?(HyperResource)
|
56
|
+
self.class._hr_attributes.each {|attr| self.send("#{attr}=".to_sym, opts.send(attr))}
|
57
|
+
return
|
58
|
+
end
|
59
|
+
|
60
|
+
self.root = opts[:root] || self.class.root
|
61
|
+
self.href = opts[:href] || ''
|
62
|
+
self.auth = (self.class.auth || {}).merge(opts[:auth] || {})
|
63
|
+
self.namespace = opts[:namespace] || self.class.namespace
|
64
|
+
self.headers = DEFAULT_HEADERS.merge(self.class.headers || {}).
|
65
|
+
merge(opts[:headers] || {})
|
66
|
+
|
67
|
+
self.attributes = Attributes.new(self)
|
68
|
+
self.links = Links.new(self)
|
69
|
+
self.objects = Objects.new(self)
|
70
|
+
self.loaded = false
|
71
|
+
end
|
72
|
+
|
73
|
+
## Returns a new HyperResource based on the given HyperResource object.
|
74
|
+
def new_from_resource(rsrc); self.class.new_from_resource(rsrc) end
|
75
|
+
def self.new_from_resource(rsrc)
|
76
|
+
new_rsrc = self.new
|
77
|
+
_hr_attributes.each do |attr|
|
78
|
+
new_rsrc.send("#{attr}=".to_sym, rsrc.send(attr))
|
79
|
+
end
|
80
|
+
new_rsrc
|
81
|
+
end
|
82
|
+
|
83
|
+
## Returns a new HyperResource based on the given HAL document.
|
84
|
+
def new_from_hal(obj)
|
85
|
+
rsrc = self.class.new(:root => self.root,
|
86
|
+
:auth => self.auth,
|
87
|
+
:headers => self.headers,
|
88
|
+
:namespace => self.namespace,
|
89
|
+
:href => obj['_links']['self']['href'])
|
90
|
+
rsrc.response_body = Response[obj]
|
91
|
+
rsrc.init_from_response_body!
|
92
|
+
rsrc
|
93
|
+
end
|
94
|
+
|
95
|
+
## Returns a new HyperResource based on the given link href.
|
96
|
+
def new_from_link(href)
|
97
|
+
rsrc = self.class.new(:root => self.root,
|
98
|
+
:auth => self.auth,
|
99
|
+
:headers => self.headers,
|
100
|
+
:namespace => self.namespace,
|
101
|
+
:href => href)
|
102
|
+
end
|
103
|
+
|
104
|
+
## Populates +attributes+, +links+, and +objects+ from the contents of
|
105
|
+
## +response+. Sets +loaded = true+.
|
106
|
+
def init_from_response_body!
|
107
|
+
return unless self.response_body
|
108
|
+
self.objects. init_from_hal(self.response_body);
|
109
|
+
self.links. init_from_hal(self.response_body);
|
110
|
+
self.attributes.init_from_hal(self.response_body);
|
111
|
+
self.loaded = true
|
112
|
+
self
|
113
|
+
end
|
114
|
+
|
115
|
+
## Returns the first object in the first collection of objects embedded
|
116
|
+
## in this resource. Equivalent to +self.objects.first+.
|
117
|
+
def first; self.objects.first end
|
118
|
+
|
119
|
+
## Returns the *i*th object in the first collection of objects embedded
|
120
|
+
## in this resource. Equivalent to +self.objects[i]+.
|
121
|
+
def [](i); self.objects[i] end
|
122
|
+
|
123
|
+
|
124
|
+
## method_missing will load this resource if not yet loaded, then
|
125
|
+
## attempt to delegate to +attributes+, then +objects+,
|
126
|
+
## then +links+. When it finds a match, it will define a method class-wide
|
127
|
+
## if self.class != HyperResource, instance-wide otherwise.
|
128
|
+
def method_missing(method, *args)
|
129
|
+
self.get unless self.loaded
|
130
|
+
[:attributes, :objects, :links].each do |field|
|
131
|
+
if self.send(field).respond_to?(method)
|
132
|
+
if self.class == HyperResource
|
133
|
+
define_singleton_method(method) do |*args|
|
134
|
+
self.send(field).send(method, *args)
|
135
|
+
end
|
136
|
+
else
|
137
|
+
self.class.send(:define_method, method) do |*args|
|
138
|
+
self.send(field).send(method, *args)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
return self.send(field).send(method, *args)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
super
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
def inspect # :nodoc:
|
149
|
+
"#<#{self.class}:0x#{"%x" % self.object_id} @root=#{self.root.inspect} "+
|
150
|
+
"@href=#{self.href.inspect} @loaded=#{self.loaded} "+
|
151
|
+
"@namespace=#{self.namespace.inspect} ...>"
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class HyperResource::Attributes < Hash
|
2
|
+
attr_accessor :parent_resource
|
3
|
+
def initialize(resource=nil)
|
4
|
+
self.parent_resource = resource || HyperResource.new
|
5
|
+
end
|
6
|
+
# Initialize attributes from a HAL response.
|
7
|
+
def init_from_hal(hal_resp)
|
8
|
+
(hal_resp.keys - ['_links', '_embedded']).map(&:to_s).each do |attr|
|
9
|
+
self[attr] = hal_resp[attr]
|
10
|
+
|
11
|
+
unless self.respond_to?(attr.to_sym)
|
12
|
+
define_singleton_method(attr.to_sym) { self[attr] }
|
13
|
+
define_singleton_method("#{attr}=".to_sym) {|v| self[attr]=v}
|
14
|
+
end
|
15
|
+
|
16
|
+
unless self.parent_resource.respond_to?(attr.to_sym)
|
17
|
+
self.parent_resource.define_singleton_method(attr.to_sym) {self[attr]}
|
18
|
+
self.parent_resource.define_singleton_method("#{attr}=".to_sym) do |v|
|
19
|
+
self[attr] = v
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'uri_template'
|
2
|
+
|
3
|
+
class HyperResource::Link
|
4
|
+
attr_accessor :base_href,
|
5
|
+
:templated,
|
6
|
+
:params,
|
7
|
+
:parent_resource
|
8
|
+
|
9
|
+
def templated?; templated end
|
10
|
+
|
11
|
+
def initialize(resource=nil, link_spec={})
|
12
|
+
self.parent_resource = resource || HyperResource.new
|
13
|
+
self.base_href = link_spec['href']
|
14
|
+
self.templated = !!link_spec['templated']
|
15
|
+
self.params = link_spec['params'] || {}
|
16
|
+
end
|
17
|
+
|
18
|
+
## Returns this link's href, applying any URI template params.
|
19
|
+
def href
|
20
|
+
if self.templated?
|
21
|
+
URITemplate.new(self.base_href).expand(params)
|
22
|
+
else
|
23
|
+
self.base_href
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
## Returns a new scope with the given params; that is, returns a copy of
|
28
|
+
## itself with the given params applied.
|
29
|
+
def where(params)
|
30
|
+
self.class.new(self.parent_resource,
|
31
|
+
'href' => self.base_href,
|
32
|
+
'templated' => self.templated,
|
33
|
+
'params' => self.params.merge(params))
|
34
|
+
end
|
35
|
+
|
36
|
+
## Returns a HyperResource representing this link
|
37
|
+
def resource
|
38
|
+
parent_resource.new_from_link(self.href)
|
39
|
+
end
|
40
|
+
|
41
|
+
## Returns a HyperResource representing this link, and fetches it.
|
42
|
+
def get
|
43
|
+
self.resource.get
|
44
|
+
end
|
45
|
+
|
46
|
+
## If we were called with a method we don't know, load this resource
|
47
|
+
## and pass the message along. This achieves implicit loading.
|
48
|
+
def method_missing(method, *args)
|
49
|
+
self.get.send(method, *args)
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class HyperResource
|
2
|
+
class Links < Hash
|
3
|
+
attr_accessor :resource
|
4
|
+
|
5
|
+
def initialize(resource=nil)
|
6
|
+
self.resource = resource || HyperResource.new
|
7
|
+
end
|
8
|
+
|
9
|
+
# Initialize links from a HAL response.
|
10
|
+
def init_from_hal(hal_resp)
|
11
|
+
return unless hal_resp['_links']
|
12
|
+
hal_resp['_links'].each do |rel, link_spec|
|
13
|
+
self[rel] = HyperResource::Link.new(resource, link_spec)
|
14
|
+
unless self.respond_to?(rel.to_sym)
|
15
|
+
define_singleton_method(rel.to_sym) { self[rel] }
|
16
|
+
end
|
17
|
+
unless self.resource.respond_to?(rel.to_sym)
|
18
|
+
self.resource.define_singleton_method(rel.to_sym) {self.links[rel]}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module HyperResource::Modules::Bless
|
2
|
+
|
3
|
+
## Returns this resource as an instance of +self.resource_class+.
|
4
|
+
## The returned object will share structure with the source object;
|
5
|
+
## beware.
|
6
|
+
def blessed
|
7
|
+
return self unless self.namespace
|
8
|
+
self.resource_class.new(self)
|
9
|
+
end
|
10
|
+
|
11
|
+
## Returns the class into which this resource should be cast.
|
12
|
+
## If the object is not loaded yet, or if +self.namespace+ is
|
13
|
+
## not set, returns +self.class+.
|
14
|
+
##
|
15
|
+
## Otherwise, +resource_class+ looks at the returned content-type, and
|
16
|
+
## attempts to match a 'type=...' modifier. Given a namespace of
|
17
|
+
## +FooAPI+ and a response content-type of
|
18
|
+
## "application/vnd.foocorp.fooapi.v1+json;type=User", this should
|
19
|
+
## return +FooAPI::User+ (even if +FooAPI::User+ hadn't existed yet).
|
20
|
+
def resource_class
|
21
|
+
return self.class unless self.namespace
|
22
|
+
return self.class unless type_name = self.data_type_name
|
23
|
+
class_name = "#{self.namespace}::#{type_name}".
|
24
|
+
gsub(/[^_0-9A-Za-z:]/, '')
|
25
|
+
|
26
|
+
## Return data type class if it exists
|
27
|
+
klass = eval(class_name) rescue :sorry_dude
|
28
|
+
return klass if klass.is_a?(Class)
|
29
|
+
|
30
|
+
## Data type class didn't exist -- create namespace (if necessary),
|
31
|
+
## then the data type class
|
32
|
+
if self.namespace != ''
|
33
|
+
nsc = eval(self.namespace) rescue :bzzzzzt
|
34
|
+
unless nsc.is_a?(Class)
|
35
|
+
Object.module_eval "class #{self.namespace} < #{self.class}; end"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
Object.module_eval "class #{class_name} < #{self.namespace}; end"
|
39
|
+
eval(class_name)
|
40
|
+
end
|
41
|
+
|
42
|
+
## Inspects the response, and returns a string describing this
|
43
|
+
## resource's data type.
|
44
|
+
##
|
45
|
+
## By default, this method looks for a +type=...+ modifier in the
|
46
|
+
## response's +Content-type+. Override this method in a
|
47
|
+
## HyperResource subclass in order to implement different data type
|
48
|
+
## detection.
|
49
|
+
def data_type_name
|
50
|
+
return nil unless self.response
|
51
|
+
return nil unless content_type = self.response['content-type']
|
52
|
+
return nil unless m=content_type.match(/;\s* type=(?<type> [0-9A-Za-z:]+)/x)
|
53
|
+
m[:type][0].upcase + m[:type][1..-1]
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'uri'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
|
6
|
+
module HyperResource::Modules::HTTP
|
7
|
+
|
8
|
+
## Loads and returns the resource pointed to by +href+. The returned
|
9
|
+
## resource will be blessed into its "proper" class, if
|
10
|
+
## +self.class.namespace != nil+.
|
11
|
+
def get
|
12
|
+
self.response = faraday_connection.get(self.href || '')
|
13
|
+
finish_up
|
14
|
+
end
|
15
|
+
|
16
|
+
## Returns a per-thread Faraday connection for this object.
|
17
|
+
def faraday_connection(url=nil)
|
18
|
+
url ||= self.root
|
19
|
+
key = "faraday_connection_#{url}"
|
20
|
+
return Thread.current[key] if Thread.current[key]
|
21
|
+
|
22
|
+
fc = Faraday.new(:url => url)
|
23
|
+
fc.headers.merge!('User-Agent' => "HyperResource #{HyperResource::VERSION}")
|
24
|
+
fc.headers.merge!(self.headers || {})
|
25
|
+
if ba=self.auth[:basic]
|
26
|
+
fc.basic_auth(*ba)
|
27
|
+
end
|
28
|
+
Thread.current[key] = fc
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def finish_up
|
34
|
+
self.response_body = JSON.parse(self.response.body)
|
35
|
+
self.init_from_response_body!
|
36
|
+
self.blessed
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module HyperResource::Modules
|
2
|
+
module Utils
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
|
10
|
+
## Inheritable class attribute, kinda like in Rails.
|
11
|
+
def class_attribute(*names)
|
12
|
+
names.map(&:to_sym).each do |name|
|
13
|
+
instance_eval <<-EOT
|
14
|
+
def #{name}=(val)
|
15
|
+
@#{name} = val
|
16
|
+
end
|
17
|
+
def #{name}
|
18
|
+
return @#{name} if defined?(@#{name})
|
19
|
+
return superclass.#{name} if superclass.respond_to?(:#{name})
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
EOT
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end # module ClassMethods
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class HyperResource::Objects < Hash
|
2
|
+
attr_accessor :parent_resource
|
3
|
+
def initialize(parent_resource=nil)
|
4
|
+
self.parent_resource = parent_resource || HyperResource.new
|
5
|
+
end
|
6
|
+
def init_from_hal(hal_resp)
|
7
|
+
return unless hal_resp['_embedded']
|
8
|
+
hal_resp['_embedded'].each do |name, collection|
|
9
|
+
self[name] = collection.map do |obj|
|
10
|
+
self.parent_resource.new_from_hal(obj)
|
11
|
+
end
|
12
|
+
unless self.respond_to?(name.to_sym)
|
13
|
+
define_singleton_method(name.to_sym) { self[name] }
|
14
|
+
end
|
15
|
+
unless self.parent_resource.respond_to?(name.to_sym)
|
16
|
+
self.parent_resource.define_singleton_method(name.to_sym) {self[name]}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
## Returns the first item in the first collection in +self+.
|
22
|
+
alias_method :first_orig, :first
|
23
|
+
def first
|
24
|
+
self.first_orig[1][0]
|
25
|
+
end
|
26
|
+
|
27
|
+
## Returns the ith item in the first collection in +self+.
|
28
|
+
def [](i)
|
29
|
+
self.first_orig[1][i]
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hyperresource
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Pete Gamache
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-04-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: uri_template
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.5.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.5.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.8.6
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.8.6
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 10.0.4
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 10.0.4
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 4.7.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 4.7.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: mocha
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.13.3
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.13.3
|
83
|
+
description: |2
|
84
|
+
HyperResource is a hypermedia client library for Ruby. Its goals are to
|
85
|
+
interface directly with well-behaved hypermedia APIs, to allow the data
|
86
|
+
returned from these APIs to optionally be extended by client-side code,
|
87
|
+
and to present a modern replacement for ActiveResource.
|
88
|
+
email: pete@gamache.org
|
89
|
+
executables: []
|
90
|
+
extensions: []
|
91
|
+
extra_rdoc_files: []
|
92
|
+
files:
|
93
|
+
- lib/hyper_resource/attributes.rb
|
94
|
+
- lib/hyper_resource/link.rb
|
95
|
+
- lib/hyper_resource/links.rb
|
96
|
+
- lib/hyper_resource/modules/bless.rb
|
97
|
+
- lib/hyper_resource/modules/http.rb
|
98
|
+
- lib/hyper_resource/modules/utils.rb
|
99
|
+
- lib/hyper_resource/objects.rb
|
100
|
+
- lib/hyper_resource/response.rb
|
101
|
+
- lib/hyper_resource/version.rb
|
102
|
+
- lib/hyper_resource.rb
|
103
|
+
homepage: https://github.com/gamache/hyperresource
|
104
|
+
licenses:
|
105
|
+
- MIT
|
106
|
+
metadata: {}
|
107
|
+
post_install_message:
|
108
|
+
rdoc_options: []
|
109
|
+
require_paths:
|
110
|
+
- lib
|
111
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - '>='
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: 1.8.7
|
116
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - '>='
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
requirements: []
|
122
|
+
rubyforge_project:
|
123
|
+
rubygems_version: 2.0.2
|
124
|
+
signing_key:
|
125
|
+
specification_version: 4
|
126
|
+
summary: Extensible hypermedia client for Ruby
|
127
|
+
test_files: []
|
128
|
+
has_rdoc: true
|