leadlight 0.0.2 → 0.0.3
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.
- data/Gemfile.lock +5 -7
- data/README.md +82 -0
- data/default.gems +1 -0
- data/leadlight.gemspec +16 -7
- data/lib/leadlight.rb +18 -62
- data/lib/leadlight/basic_converter.rb +18 -0
- data/lib/leadlight/codec.rb +2 -0
- data/lib/leadlight/entity.rb +1 -0
- data/lib/leadlight/errors.rb +10 -2
- data/lib/leadlight/header_helpers.rb +11 -0
- data/lib/leadlight/hyperlinkable.rb +1 -1
- data/lib/leadlight/representation.rb +19 -1
- data/lib/leadlight/request.rb +44 -11
- data/lib/leadlight/service.rb +4 -9
- data/lib/leadlight/service_class_methods.rb +69 -0
- data/lib/leadlight/service_middleware.rb +2 -14
- data/lib/leadlight/tint.rb +6 -2
- data/lib/leadlight/tint_helper.rb +27 -4
- data/lib/leadlight/type_map.rb +101 -0
- data/spec/cassettes/Leadlight/authorized_GitHub_example/_user/has_the_expected_content.yml +8 -8
- data/spec/cassettes/Leadlight/authorized_GitHub_example/_user/indicates_the_expected_oath_scopes.yml +8 -8
- data/spec/cassettes/Leadlight/authorized_GitHub_example/adding_and_removing_team_members.yml +273 -284
- data/spec/cassettes/Leadlight/authorized_GitHub_example/{adding_and_removing_team_members/.yml → adding_and_removing_teams.yml} +57 -84
- data/spec/cassettes/Leadlight/authorized_GitHub_example/test_team/.yml +111 -117
- data/spec/cassettes/Leadlight/basic_GitHub_example/_root/.yml +58 -25
- data/spec/cassettes/Leadlight/basic_GitHub_example/_root/__location__/.yml +58 -25
- data/spec/cassettes/Leadlight/basic_GitHub_example/_root/should_be_a_204_no_content.yml +58 -25
- data/spec/cassettes/Leadlight/tinted_GitHub_example/_root/.yml +58 -25
- data/spec/cassettes/Leadlight/tinted_GitHub_example/_root/__location__/.yml +58 -25
- data/spec/cassettes/Leadlight/tinted_GitHub_example/_root/should_be_a_204_no_content.yml +58 -25
- data/spec/cassettes/Leadlight/tinted_GitHub_example/_user/has_the_expected_content.yml +122 -50
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/.yml +190 -77
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/should_be_able_to_follow_next_link.yml +260 -104
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/should_be_enumerable.yml +616 -212
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/should_be_enumerable_over_page_boundaries.yml +331 -131
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_followers/should_have_next_and_last_links.yml +190 -77
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_link/exists.yml +58 -25
- data/spec/cassettes/Leadlight/tinted_GitHub_example/user_link/links_to_the_expected_URL.yml +58 -25
- data/spec/leadlight/hyperlinkable_spec.rb +3 -1
- data/spec/leadlight/link_template_spec.rb +2 -1
- data/spec/leadlight/request_spec.rb +44 -21
- data/spec/leadlight/service_middleware_spec.rb +9 -46
- data/spec/leadlight/service_spec.rb +30 -24
- data/spec/leadlight/tint_helper_spec.rb +67 -1
- data/spec/leadlight/tint_spec.rb +69 -0
- data/spec/leadlight/type_map_spec.rb +127 -0
- data/spec/leadlight_spec.rb +102 -51
- data/spec/support/credentials.rb +10 -2
- data/spec/support/vcr.rb +1 -1
- metadata +61 -32
- data/lib/leadlight/type.rb +0 -71
- data/spec/leadlight/type_spec.rb +0 -137
data/Gemfile.lock
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
leadlight (0.0.
|
4
|
+
leadlight (0.0.2)
|
5
|
+
addressable
|
5
6
|
faraday
|
6
7
|
fattr
|
7
8
|
hookr
|
@@ -20,7 +21,7 @@ GEM
|
|
20
21
|
faraday (0.7.5)
|
21
22
|
addressable (~> 2.2.6)
|
22
23
|
multipart-post (~> 1.1.3)
|
23
|
-
rack (
|
24
|
+
rack (>= 1.1.0, < 2)
|
24
25
|
fattr (2.2.0)
|
25
26
|
ffi (1.0.11)
|
26
27
|
guard (0.10.0)
|
@@ -33,7 +34,6 @@ GEM
|
|
33
34
|
guard (>= 0.10.0)
|
34
35
|
hookr (1.1.1)
|
35
36
|
fail-fast (= 1.0.0)
|
36
|
-
libnotify (0.7.1)
|
37
37
|
linecache19 (0.5.12)
|
38
38
|
ruby_core_source (>= 0.1.4)
|
39
39
|
link_header (0.0.5)
|
@@ -41,8 +41,7 @@ GEM
|
|
41
41
|
multi_json (1.0.4)
|
42
42
|
multipart-post (1.1.4)
|
43
43
|
rack (1.4.0)
|
44
|
-
|
45
|
-
ffi (>= 0.5.0)
|
44
|
+
rake (0.9.2.2)
|
46
45
|
rspec (2.7.0)
|
47
46
|
rspec-core (~> 2.7.0)
|
48
47
|
rspec-expectations (~> 2.7.0)
|
@@ -72,8 +71,7 @@ DEPENDENCIES
|
|
72
71
|
guard-bundler
|
73
72
|
guard-rspec
|
74
73
|
leadlight!
|
75
|
-
|
76
|
-
rb-inotify
|
74
|
+
rake
|
77
75
|
rspec
|
78
76
|
ruby-debug19
|
79
77
|
vcr (~> 2.0.0.rc1)
|
data/README.md
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
# Leadlight [](http://travis-ci.org/avdi/leadlight)
|
2
|
+
|
3
|
+
Rose colored stained glass windows for HTTP.
|
4
|
+
|
5
|
+
|
6
|
+
## Goals
|
7
|
+
|
8
|
+
### Progressive enhancement for HTTP APIs
|
9
|
+
|
10
|
+
Don't cover up the web; just fill in the gaps here and there. Make it easy to
|
11
|
+
add links and other affordances API publishers might have forgotten.
|
12
|
+
|
13
|
+
### Model RESTful APIs as a web of links
|
14
|
+
|
15
|
+
Don't try to make the web look like a database.
|
16
|
+
|
17
|
+
### Representations over resources
|
18
|
+
|
19
|
+
Resources are the server's job to worry about. The things we get back from a
|
20
|
+
server are representations. Take representations at face value and interpret
|
21
|
+
them sensibly, rather than trying to fit them into a client-side model of an
|
22
|
+
imaginary server-side object graph.
|
23
|
+
|
24
|
+
### Support current and emerging standards
|
25
|
+
|
26
|
+
Such as the [Link header][], [URI templates][], [PATCH][], [ETags][], and
|
27
|
+
[JSON-schema][].
|
28
|
+
|
29
|
+
### Sensible defaults
|
30
|
+
|
31
|
+
Always try to convert representations returned by the server into a form that is
|
32
|
+
useful to the programmer--whether that is a Hash parsed from JSON data, a
|
33
|
+
Nokogiri document, or a text string.
|
34
|
+
|
35
|
+
### Backend agnostic
|
36
|
+
|
37
|
+
Using the power of [Faraday][].
|
38
|
+
|
39
|
+
### Exception-free
|
40
|
+
|
41
|
+
Only raise exceptions in API calls which explicitly request them. Provide ample
|
42
|
+
information to explain the cause of a failure.
|
43
|
+
|
44
|
+
### Async-ready
|
45
|
+
|
46
|
+
Architected from the ground up with asynchrony in mind. It's easier to build a
|
47
|
+
synchronous API on top of an async one than vice-versa.
|
48
|
+
|
49
|
+
### Controlled abstraction leakage
|
50
|
+
|
51
|
+
All abstractions are leaky. Provide ample and convenient access points into the
|
52
|
+
guts of the request lifecycle for situations when the defaults are not
|
53
|
+
sufficient.
|
54
|
+
|
55
|
+
### Quality
|
56
|
+
|
57
|
+
Code quality is important. [Code Climate][] keeps a
|
58
|
+
[close eye on Leadlight][leadlight_climate] instilling confidence and showing
|
59
|
+
how any technical debt can be paid down.
|
60
|
+
|
61
|
+
|
62
|
+
[link header]: http://tools.ietf.org/html/draft-nottingham-http-link-header
|
63
|
+
[uri templates]: http://tools.ietf.org/html/draft-gregorio-uritemplate
|
64
|
+
[patch]: http://tools.ietf.org/html/rfc5789
|
65
|
+
[etags]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.19
|
66
|
+
[json-schema]: http://tools.ietf.org/html/draft-zyp-json-schema
|
67
|
+
[faraday]: https://github.com/technoweenie/faraday
|
68
|
+
[code climate]: https://codeclimate.com
|
69
|
+
[leadlight_climate]: https://codeclimate.com/github/avdi/leadlight
|
70
|
+
|
71
|
+
|
72
|
+
## Installation
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
gem 'leadlight'
|
76
|
+
```
|
77
|
+
|
78
|
+
## Usage
|
79
|
+
|
80
|
+
_See
|
81
|
+
[leadlight_spec.rb](https://github.com/avdi/leadlight/blob/master/spec/leadlight_spec.rb)
|
82
|
+
for now._
|
data/default.gems
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
bundler -v1.0.21
|
data/leadlight.gemspec
CHANGED
@@ -13,14 +13,14 @@ Gem::Specification.new do |s|
|
|
13
13
|
## If your rubyforge_project name is different, then edit it and comment out
|
14
14
|
## the sub! line in the Rakefile
|
15
15
|
s.name = 'leadlight'
|
16
|
-
s.version = '0.0.
|
17
|
-
s.date = '2012-
|
16
|
+
s.version = '0.0.3'
|
17
|
+
s.date = '2012-02-05'
|
18
18
|
s.rubyforge_project = 'leadlight'
|
19
19
|
|
20
20
|
## Make sure your summary is short. The description may be as long
|
21
21
|
## as you like.
|
22
|
-
s.summary = "
|
23
|
-
s.description = "
|
22
|
+
s.summary = "Rose colored stained glass windows for HTTP."
|
23
|
+
s.description = "Rose colored stained glass windows for HTTP."
|
24
24
|
|
25
25
|
## List the primary authors. If there are a bunch of authors, it's probably
|
26
26
|
## better to set the email to an email list or something. If you don't have
|
@@ -41,6 +41,7 @@ Gem::Specification.new do |s|
|
|
41
41
|
## List your runtime dependencies here. Runtime dependencies are those
|
42
42
|
## that are needed for an end user to actually USE your code.
|
43
43
|
## s.add_dependency('DEPNAME', [">= 1.1.0", "< 2.0.0"])
|
44
|
+
s.add_dependency 'addressable'
|
44
45
|
s.add_dependency 'faraday'
|
45
46
|
s.add_dependency 'fattr'
|
46
47
|
s.add_dependency 'link_header'
|
@@ -51,6 +52,7 @@ Gem::Specification.new do |s|
|
|
51
52
|
## List your development dependencies here. Development dependencies are
|
52
53
|
## those that are only needed during development
|
53
54
|
## s.add_development_dependency('DEVDEPNAME', [">= 1.1.0", "< 2.0.0"])
|
55
|
+
s.add_development_dependency 'rake'
|
54
56
|
s.add_development_dependency 'rspec'
|
55
57
|
s.add_development_dependency 'vcr', '~> 2.0.0.rc1'
|
56
58
|
s.add_development_dependency 'guard'
|
@@ -66,27 +68,33 @@ Gem::Specification.new do |s|
|
|
66
68
|
Gemfile
|
67
69
|
Gemfile.lock
|
68
70
|
Guardfile
|
71
|
+
README.md
|
69
72
|
Rakefile
|
73
|
+
default.gems
|
70
74
|
leadlight.gemspec
|
71
75
|
lib/leadlight.rb
|
76
|
+
lib/leadlight/basic_converter.rb
|
72
77
|
lib/leadlight/blank.rb
|
73
78
|
lib/leadlight/codec.rb
|
79
|
+
lib/leadlight/entity.rb
|
74
80
|
lib/leadlight/enumerable_representation.rb
|
75
81
|
lib/leadlight/errors.rb
|
82
|
+
lib/leadlight/header_helpers.rb
|
76
83
|
lib/leadlight/hyperlinkable.rb
|
77
84
|
lib/leadlight/link.rb
|
78
85
|
lib/leadlight/link_template.rb
|
79
86
|
lib/leadlight/representation.rb
|
80
87
|
lib/leadlight/request.rb
|
81
88
|
lib/leadlight/service.rb
|
89
|
+
lib/leadlight/service_class_methods.rb
|
82
90
|
lib/leadlight/service_middleware.rb
|
83
91
|
lib/leadlight/tint.rb
|
84
92
|
lib/leadlight/tint_helper.rb
|
85
|
-
lib/leadlight/
|
93
|
+
lib/leadlight/type_map.rb
|
86
94
|
spec/cassettes/Leadlight/authorized_GitHub_example/_user/has_the_expected_content.yml
|
87
95
|
spec/cassettes/Leadlight/authorized_GitHub_example/_user/indicates_the_expected_oath_scopes.yml
|
88
96
|
spec/cassettes/Leadlight/authorized_GitHub_example/adding_and_removing_team_members.yml
|
89
|
-
spec/cassettes/Leadlight/authorized_GitHub_example/
|
97
|
+
spec/cassettes/Leadlight/authorized_GitHub_example/adding_and_removing_teams.yml
|
90
98
|
spec/cassettes/Leadlight/authorized_GitHub_example/test_team/.yml
|
91
99
|
spec/cassettes/Leadlight/basic_GitHub_example/_root/.yml
|
92
100
|
spec/cassettes/Leadlight/basic_GitHub_example/_root/__location__/.yml
|
@@ -111,7 +119,8 @@ Gem::Specification.new do |s|
|
|
111
119
|
spec/leadlight/service_middleware_spec.rb
|
112
120
|
spec/leadlight/service_spec.rb
|
113
121
|
spec/leadlight/tint_helper_spec.rb
|
114
|
-
spec/leadlight/
|
122
|
+
spec/leadlight/tint_spec.rb
|
123
|
+
spec/leadlight/type_map_spec.rb
|
115
124
|
spec/leadlight_spec.rb
|
116
125
|
spec/spec_helper_lite.rb
|
117
126
|
spec/support/credentials.rb
|
data/lib/leadlight.rb
CHANGED
@@ -1,27 +1,37 @@
|
|
1
1
|
require 'faraday'
|
2
2
|
require 'fattr'
|
3
3
|
require 'logger'
|
4
|
+
require 'hookr'
|
4
5
|
require 'leadlight/errors'
|
5
6
|
require 'leadlight/link'
|
6
7
|
require 'leadlight/hyperlinkable'
|
7
8
|
require 'leadlight/service_middleware'
|
8
9
|
require 'leadlight/representation'
|
9
10
|
require 'leadlight/tint'
|
10
|
-
require 'leadlight/type'
|
11
11
|
require 'leadlight/service'
|
12
|
+
require 'leadlight/service_class_methods'
|
12
13
|
require 'leadlight/enumerable_representation'
|
14
|
+
require 'leadlight/basic_converter'
|
13
15
|
|
14
16
|
|
15
17
|
module Leadlight
|
16
18
|
|
17
|
-
VERSION = '0.0.
|
18
|
-
|
19
|
-
def self.build_service(target, &block)
|
20
|
-
target.
|
21
|
-
|
22
|
-
|
19
|
+
VERSION = '0.0.3'
|
20
|
+
|
21
|
+
def self.build_service(target=Class.new, &block)
|
22
|
+
target.tap do
|
23
|
+
target.module_eval do
|
24
|
+
extend ServiceClassMethods
|
25
|
+
include Service
|
26
|
+
include HookR::Hooks
|
27
|
+
extend SingleForwardable
|
28
|
+
|
29
|
+
request_events = request_class.hooks.map(&:name)
|
30
|
+
def_delegators :request_class, *request_events
|
31
|
+
define_hook :on_init, :service
|
32
|
+
end
|
33
|
+
target.module_eval(&block)
|
23
34
|
end
|
24
|
-
target.module_eval(&block)
|
25
35
|
end
|
26
36
|
|
27
37
|
def self.build_connection_common(&common_connection_stack)
|
@@ -34,59 +44,5 @@ module Leadlight
|
|
34
44
|
}
|
35
45
|
end
|
36
46
|
|
37
|
-
module ServiceClassMethods
|
38
|
-
fattr(:tints) { default_tints }
|
39
|
-
fattr(:types) { [] }
|
40
|
-
|
41
|
-
def url(new_url=:none)
|
42
|
-
if new_url == :none
|
43
|
-
@url ||= Addressable::URI.parse('http://example.com')
|
44
|
-
else
|
45
|
-
@url = Addressable::URI.parse(new_url)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def session(options={})
|
50
|
-
sessions[options]
|
51
|
-
end
|
52
|
-
|
53
|
-
def sessions
|
54
|
-
@sessions ||= Hash.new{|h,k|
|
55
|
-
h[k] = new(k)
|
56
|
-
}
|
57
|
-
end
|
58
|
-
|
59
|
-
def connection_stack
|
60
|
-
@connection_stack ||= ->(builder){}
|
61
|
-
end
|
62
|
-
|
63
|
-
def default_tints
|
64
|
-
[
|
65
|
-
EnumerableRepresentation::Tint
|
66
|
-
]
|
67
|
-
end
|
68
|
-
|
69
|
-
private
|
70
|
-
|
71
|
-
def tint(name, &block)
|
72
|
-
self.tints << Tint.new(name, &block)
|
73
|
-
end
|
74
|
-
|
75
|
-
def type(name, &block)
|
76
|
-
self.types << Type.new(name, self, &block)
|
77
|
-
end
|
78
|
-
|
79
|
-
def type_for_name(name)
|
80
|
-
raise_on_missing = -> do
|
81
|
-
raise KeyError, "Type not found: #{name}"
|
82
|
-
end
|
83
|
-
types.detect(raise_on_missing){|type| type.name.to_s == name.to_s}
|
84
|
-
end
|
85
|
-
|
86
|
-
def build_connection(&block)
|
87
|
-
@connection_stack = block
|
88
|
-
end
|
89
|
-
|
90
|
-
end
|
91
47
|
|
92
48
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Leadlight
|
2
|
+
module BasicConverter
|
3
|
+
fattr(:codec) { Codec.new }
|
4
|
+
|
5
|
+
def initialize(codec)
|
6
|
+
@codec = codec
|
7
|
+
end
|
8
|
+
|
9
|
+
def decode_with_type(content_type, entity_body, options={})
|
10
|
+
codec.decode(content_type, entity_body, options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def encode_with_type(content_type, object, options={})
|
14
|
+
body = codec.encode(content_type, object, options)
|
15
|
+
Entity.new(content_type, body)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/leadlight/codec.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
Entity ||= Struct.new(:content_type, :body)
|
data/lib/leadlight/errors.rb
CHANGED
@@ -1,14 +1,22 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
1
3
|
module Leadlight
|
2
4
|
class Error < StandardError; end
|
3
5
|
class CredentialsRequiredError < Error; end
|
4
6
|
class HttpError < Error
|
7
|
+
extend Forwardable
|
8
|
+
|
5
9
|
attr_reader :response
|
6
|
-
|
10
|
+
|
11
|
+
def_delegator :response, :status
|
12
|
+
|
13
|
+
def initialize(response, message=response.status.to_s)
|
7
14
|
@response = response
|
8
|
-
super(
|
15
|
+
super(message)
|
9
16
|
end
|
10
17
|
end
|
11
18
|
class ClientError < HttpError; end
|
12
19
|
class ResourceNotFound < ClientError; end
|
13
20
|
class ServerError < HttpError; end
|
21
|
+
class TypeError < Error; end
|
14
22
|
end
|
@@ -10,7 +10,7 @@ module Leadlight
|
|
10
10
|
module Hyperlinkable
|
11
11
|
def self.extended(representation)
|
12
12
|
super(representation)
|
13
|
-
representation.add_link(representation.
|
13
|
+
representation.add_link(representation.__location__,
|
14
14
|
'self', 'self', rev: 'self')
|
15
15
|
representation.add_links_from_headers
|
16
16
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'addressable/uri'
|
2
2
|
require 'leadlight/link'
|
3
|
+
require 'leadlight/errors'
|
3
4
|
|
4
5
|
module Leadlight
|
5
6
|
module Representation
|
6
7
|
attr_accessor :__service__
|
7
8
|
attr_accessor :__location__
|
8
9
|
attr_accessor :__response__
|
9
|
-
attr_accessor :__type__
|
10
10
|
|
11
11
|
def initialize_representation(service, location, response)
|
12
12
|
self.__service__ = service
|
@@ -21,6 +21,24 @@ module Leadlight
|
|
21
21
|
self
|
22
22
|
end
|
23
23
|
|
24
|
+
def exception(message=exception_message)
|
25
|
+
return super if defined?(super)
|
26
|
+
case __response__.status.to_i
|
27
|
+
when 404 then ResourceNotFound
|
28
|
+
when (400..499) then ClientError
|
29
|
+
when (500..599) then ServerError
|
30
|
+
end.new(__response__, exception_message)
|
31
|
+
end
|
32
|
+
|
33
|
+
def exception_message
|
34
|
+
http_status_message
|
35
|
+
end
|
36
|
+
|
37
|
+
def http_status_message
|
38
|
+
__response__.env.fetch(:response_headers).fetch('status'){
|
39
|
+
status.to_s
|
40
|
+
}
|
41
|
+
end
|
24
42
|
|
25
43
|
private
|
26
44
|
|
data/lib/leadlight/request.rb
CHANGED
@@ -1,35 +1,49 @@
|
|
1
1
|
require 'monitor'
|
2
2
|
require 'fattr'
|
3
|
+
require 'forwardable'
|
3
4
|
require 'hookr'
|
4
5
|
require 'leadlight/errors'
|
6
|
+
require 'leadlight/blank'
|
7
|
+
require 'leadlight/hyperlinkable'
|
8
|
+
require 'leadlight/representation'
|
9
|
+
require 'leadlight/type_map'
|
10
|
+
require 'leadlight/header_helpers'
|
5
11
|
|
6
12
|
module Leadlight
|
7
13
|
class Request
|
8
14
|
include HookR::Hooks
|
9
15
|
include MonitorMixin
|
16
|
+
extend Forwardable
|
17
|
+
include HeaderHelpers
|
10
18
|
|
11
19
|
fattr(:http_method)
|
12
20
|
fattr(:url)
|
13
21
|
fattr(:connection)
|
14
22
|
fattr(:body)
|
15
23
|
fattr(:params)
|
24
|
+
fattr(:service)
|
25
|
+
fattr(:codec)
|
26
|
+
fattr(:type_map) { service.type_map || TypeMap.new }
|
16
27
|
|
17
28
|
attr_reader :response
|
18
29
|
|
19
30
|
define_hook :on_prepare_request, :request
|
20
31
|
define_hook :on_complete, :response
|
21
32
|
|
22
|
-
|
33
|
+
def_delegator :service, :service_options
|
34
|
+
|
35
|
+
def initialize(service, connection, url, method, params={}, body=nil)
|
23
36
|
self.connection = connection
|
24
37
|
self.url = url
|
25
38
|
self.http_method = method
|
26
39
|
self.body = body
|
27
40
|
self.params = params
|
41
|
+
self.service = service
|
28
42
|
@completed = new_cond
|
29
43
|
@state = :initialized
|
30
44
|
@env = nil
|
31
45
|
@response = nil
|
32
|
-
super
|
46
|
+
super()
|
33
47
|
end
|
34
48
|
|
35
49
|
def completed?
|
@@ -37,11 +51,16 @@ module Leadlight
|
|
37
51
|
end
|
38
52
|
|
39
53
|
def submit
|
40
|
-
|
54
|
+
entity = type_map.to_entity_body(body)
|
55
|
+
entity_body = entity.body
|
56
|
+
content_type = entity.content_type
|
57
|
+
connection.run_request(http_method, url, entity_body, {}) do |request|
|
58
|
+
request.headers['Content-Type'] = content_type if content_type
|
59
|
+
request.options[:leadlight_request] = self
|
41
60
|
execute_hook(:on_prepare_request, request)
|
42
61
|
end.on_complete do |env|
|
43
62
|
synchronize do
|
44
|
-
@response =
|
63
|
+
@response = env.fetch(:response)
|
45
64
|
execute_hook :on_complete, @response
|
46
65
|
@env = env
|
47
66
|
@state = :completed
|
@@ -66,13 +85,8 @@ module Leadlight
|
|
66
85
|
|
67
86
|
def raise_on_error
|
68
87
|
on_or_after_complete do |response|
|
69
|
-
|
70
|
-
|
71
|
-
raise ResourceNotFound, response
|
72
|
-
when (400..499)
|
73
|
-
raise ClientError, response
|
74
|
-
when (500..599)
|
75
|
-
raise ServerError, response
|
88
|
+
unless response.success?
|
89
|
+
raise response.env.fetch(:leadlight_representation)
|
76
90
|
end
|
77
91
|
end
|
78
92
|
self
|
@@ -87,5 +101,24 @@ module Leadlight
|
|
87
101
|
end
|
88
102
|
end
|
89
103
|
end
|
104
|
+
|
105
|
+
def represent(env)
|
106
|
+
content_type = env[:response_headers]['Content-Type']
|
107
|
+
content_type = clean_content_type(content_type)
|
108
|
+
representation = type_map.to_native(content_type, env[:body])
|
109
|
+
location = Addressable::URI.parse(env[:response_headers].fetch('location'){ env[:url] })
|
110
|
+
representation.
|
111
|
+
extend(Representation).
|
112
|
+
initialize_representation(env[:leadlight_service], location, env[:response]).
|
113
|
+
extend(Hyperlinkable).
|
114
|
+
apply_all_tints
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
def representation
|
120
|
+
raise "No representation until complete" unless completed?
|
121
|
+
@env.fetch(:leadlight_representation)
|
122
|
+
end
|
90
123
|
end
|
91
124
|
end
|