lhs 5.7.1 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +20 -5
- data/lhs.gemspec +4 -2
- data/lib/lhs/concerns/record/includes.rb +19 -6
- data/lib/lhs/concerns/record/request.rb +26 -14
- data/lib/lhs/version.rb +1 -1
- data/spec/proxy/load_spec.rb +18 -0
- data/spec/record/includes_spec.rb +30 -0
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1375879a321c15e499ad2871e21ab93cda9b386b
|
4
|
+
data.tar.gz: dfa739b88f8c0f26bd47ce4722a9d145fb479ecd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b457566f62fc9aae5f60287eae881b2a5cf2cf46c2de118a283b301d20b6d98126d93f816d46a70ed4714bb485dd0a2d971f022846864e91eb58764802779232
|
7
|
+
data.tar.gz: da2266a749937a72f6fb2510c054024c1f2171493a7a05c4cdf7321b4e2af45aaf67229adc756d9e4f7da7aedd360d47638a6a2fc56e7dadac947959561018bc
|
data/README.md
CHANGED
@@ -174,6 +174,7 @@ After fetching [single](#find-single-records) or [multiple](#find-multiple-recor
|
|
174
174
|
You can apply options to the request chain. Those options will be forwarded to the request perfomed by the chain/query.
|
175
175
|
|
176
176
|
```ruby
|
177
|
+
# Authenticate with OAuth
|
177
178
|
options = { auth: { bearer: '123456' } }
|
178
179
|
|
179
180
|
AuthenticatedRecord = Record.options(options)
|
@@ -365,22 +366,22 @@ After include:
|
|
365
366
|
|
366
367
|
When including linked resources with `includes`, known/defined services and endpoints are used to make those requests.
|
367
368
|
That also means that options for endpoints of linked resources are applied when requesting those in addition.
|
368
|
-
This allows you to include protected resources (e.g.
|
369
|
+
This allows you to include protected resources (e.g. Basic auth) as endpoint options for oauth authentication get applied.
|
369
370
|
|
370
371
|
The [Auth Inteceptor](https://github.com/local-ch/lhc-core-interceptors#auth-interceptor) from [lhc-core-interceptors](https://github.com/local-ch/lhc-core-interceptors) is used to configure the following endpoints.
|
371
372
|
|
372
373
|
```ruby
|
373
374
|
class Favorite < LHS::Record
|
374
375
|
|
375
|
-
endpoint ':datastore/:user_id/favorites', auth: {
|
376
|
-
endpoint ':datastore/:user_id/favorites/:id', auth: {
|
376
|
+
endpoint ':datastore/:user_id/favorites', auth: { basic: { username: 'steve', password: 'can' } }
|
377
|
+
endpoint ':datastore/:user_id/favorites/:id', auth: { basic: { username: 'steve', password: 'can' } }
|
377
378
|
|
378
379
|
end
|
379
380
|
|
380
381
|
class Place < LHS::Record
|
381
382
|
|
382
|
-
endpoint ':datastore/v2/places', auth: {
|
383
|
-
endpoint ':datastore/v2/places/:id', auth: {
|
383
|
+
endpoint ':datastore/v2/places', auth: { basic: { username: 'steve', password: 'can' } }
|
384
|
+
endpoint ':datastore/v2/places/:id', auth: { basic: { username: 'steve', password: 'can' } }
|
384
385
|
|
385
386
|
end
|
386
387
|
|
@@ -388,6 +389,16 @@ Favorite.includes(:place).where(user_id: current_user.id)
|
|
388
389
|
# Will include places and applies endpoint options to authenticate the request.
|
389
390
|
```
|
390
391
|
|
392
|
+
### Forward options used for request made to include referenced resources
|
393
|
+
|
394
|
+
Provide options to the requests made to include referenced resources:
|
395
|
+
|
396
|
+
```
|
397
|
+
|
398
|
+
Favorite.includes(:place).references(place: { auth: { bearer: '123' }})
|
399
|
+
|
400
|
+
```
|
401
|
+
|
391
402
|
## Map data
|
392
403
|
|
393
404
|
To influence how data is accessed/provied, you can use mappings to either map deep nested data or to manipulate data when its accessed. Simply create methods inside the LHS::Record. They can access underlying data:
|
@@ -629,3 +640,7 @@ The behaviour of `count` and `length` is based on ActiveRecord's behaviour.
|
|
629
640
|
`count` Determine the number of elements by taking the number of total elements that is provided by the endpoint/api.
|
630
641
|
|
631
642
|
`length` This returns the number of elements loaded from an endpoint/api. In case of paginated resources this can be different to count, as it depends on how many pages have been loaded.
|
643
|
+
|
644
|
+
## License
|
645
|
+
|
646
|
+
[GNU Affero General Public License Version 3.](https://www.gnu.org/licenses/agpl-3.0.en.html)
|
data/lhs.gemspec
CHANGED
@@ -17,8 +17,8 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.test_files = `git ls-files -- spec/*`.split("\n")
|
18
18
|
s.require_paths = ['lib']
|
19
19
|
|
20
|
-
s.requirements << 'Ruby >=
|
21
|
-
s.required_ruby_version = '>=
|
20
|
+
s.requirements << 'Ruby >= 2.0.0'
|
21
|
+
s.required_ruby_version = '>= 2.0.0'
|
22
22
|
|
23
23
|
s.add_dependency 'lhc', '>= 3.5.2'
|
24
24
|
s.add_dependency 'lhc-core-interceptors', '>= 2.0.1'
|
@@ -31,4 +31,6 @@ Gem::Specification.new do |s|
|
|
31
31
|
s.add_development_dependency 'pry-byebug'
|
32
32
|
s.add_development_dependency 'ciderizer'
|
33
33
|
s.add_development_dependency 'capybara'
|
34
|
+
|
35
|
+
s.license = 'GPL-3'
|
34
36
|
end
|
@@ -5,22 +5,35 @@ class LHS::Record
|
|
5
5
|
module Includes
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
8
|
+
included do
|
9
|
+
cattr_accessor :including, :referencing
|
10
|
+
end
|
11
|
+
|
8
12
|
module ClassMethods
|
9
|
-
def
|
10
|
-
|
13
|
+
def includes(*args)
|
14
|
+
class_clone_factory(args).tap do |class_clone|
|
15
|
+
class_clone.including = unfold_args(args)
|
16
|
+
end
|
11
17
|
end
|
12
18
|
|
13
|
-
def
|
14
|
-
|
19
|
+
def references(*args)
|
20
|
+
class_clone_factory(args).tap do |class_clone|
|
21
|
+
class_clone.referencing = unfold_args(args)
|
22
|
+
end
|
15
23
|
end
|
16
24
|
|
17
|
-
|
25
|
+
private
|
26
|
+
|
27
|
+
def unfold_args(args)
|
28
|
+
args.size == 1 ? args[0] : args
|
29
|
+
end
|
30
|
+
|
31
|
+
def class_clone_factory(args)
|
18
32
|
name = "#{self}#{args.object_id}"
|
19
33
|
constant = Object.const_set(name.demodulize, self.dup) # rubocop:disable Style/RedundantSelf
|
20
34
|
class_clone = constant
|
21
35
|
class_clone.endpoints = endpoints
|
22
36
|
class_clone.mapping = mapping
|
23
|
-
class_clone.including = args.size == 1 ? args[0] : args
|
24
37
|
class_clone
|
25
38
|
end
|
26
39
|
end
|
@@ -19,20 +19,19 @@ class LHS::Record
|
|
19
19
|
# Convert URLs in options to endpoint templates
|
20
20
|
def convert_options_to_endpoints(options)
|
21
21
|
if options.is_a?(Array)
|
22
|
-
options.map { |
|
22
|
+
options.map { |request_options| convert_options_to_endpoint(request_options) }
|
23
23
|
else
|
24
|
-
|
24
|
+
convert_options_to_endpoint(options)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
29
|
-
return unless
|
30
|
-
|
31
|
-
url = option[:url]
|
28
|
+
def convert_options_to_endpoint(options)
|
29
|
+
return unless options.present?
|
30
|
+
url = options[:url]
|
32
31
|
endpoint = LHS::Endpoint.for_url(url)
|
33
32
|
return unless endpoint
|
34
33
|
template = endpoint.url
|
35
|
-
new_options =
|
34
|
+
new_options = options.deep_merge(params: LHC::Endpoint.values_as_params(template, url))
|
36
35
|
new_options[:url] = template
|
37
36
|
new_options
|
38
37
|
end
|
@@ -80,17 +79,18 @@ class LHS::Record
|
|
80
79
|
end
|
81
80
|
end
|
82
81
|
|
83
|
-
def handle_includes(includes, data)
|
82
|
+
def handle_includes(includes, data, references = {})
|
83
|
+
references ||= {}
|
84
84
|
if includes.is_a? Hash
|
85
|
-
includes.each { |included, sub_includes| handle_include(included, data, sub_includes) }
|
85
|
+
includes.each { |included, sub_includes| handle_include(included, data, sub_includes, references[included]) }
|
86
86
|
elsif includes.is_a? Array
|
87
|
-
includes.each { |included| handle_includes(included, data) }
|
87
|
+
includes.each { |included| handle_includes(included, data, references[included]) }
|
88
88
|
else
|
89
|
-
handle_include(includes, data)
|
89
|
+
handle_include(includes, data, nil, references[includes])
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
-
def handle_include(included, data, sub_includes = nil)
|
93
|
+
def handle_include(included, data, sub_includes = nil, references = nil)
|
94
94
|
return if data.blank? || skip_loading_includes?(data, included)
|
95
95
|
options =
|
96
96
|
if data.collection?
|
@@ -100,10 +100,22 @@ class LHS::Record
|
|
100
100
|
else
|
101
101
|
url_option_for(data, included)
|
102
102
|
end
|
103
|
+
options = extend_with_references(options, references)
|
103
104
|
addition = load_include(options, data, sub_includes)
|
104
105
|
extend_raw_data!(data, addition, included)
|
105
106
|
end
|
106
107
|
|
108
|
+
# Extends request options with options provided for this reference
|
109
|
+
def extend_with_references(options, references)
|
110
|
+
return options unless references
|
111
|
+
options ||= {}
|
112
|
+
if options.is_a?(Array)
|
113
|
+
options.map { |request_options| request_options.merge(references) }
|
114
|
+
else
|
115
|
+
options.merge(references)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
107
119
|
def skip_loading_includes?(data, included)
|
108
120
|
if data.collection?
|
109
121
|
data.to_a.none? { |item| item[included].present? }
|
@@ -140,7 +152,7 @@ class LHS::Record
|
|
140
152
|
data = restore_with_nils(data, locate_nils(options)) # nil objects in data provide location information for mapping
|
141
153
|
unless data.empty?
|
142
154
|
data = LHS::Data.new(data, nil, self)
|
143
|
-
handle_includes(including, data) if including
|
155
|
+
handle_includes(including, data, referencing) if including
|
144
156
|
end
|
145
157
|
data
|
146
158
|
end
|
@@ -200,7 +212,7 @@ class LHS::Record
|
|
200
212
|
endpoint = find_endpoint(options[:params])
|
201
213
|
response = LHC.request(process_options(options, endpoint))
|
202
214
|
data = LHS::Data.new(response.body, nil, self, response.request, endpoint)
|
203
|
-
handle_includes(including, data) if including
|
215
|
+
handle_includes(including, data, referencing) if including
|
204
216
|
data
|
205
217
|
end
|
206
218
|
|
data/lib/lhs/version.rb
CHANGED
data/spec/proxy/load_spec.rb
CHANGED
@@ -42,4 +42,22 @@ describe LHS::Proxy do
|
|
42
42
|
.to raise_error LHC::NotFound
|
43
43
|
end
|
44
44
|
end
|
45
|
+
|
46
|
+
context 'endpoint options' do
|
47
|
+
before(:each) do
|
48
|
+
class AnotherRecord < LHS::Record
|
49
|
+
endpoint ':datastore/v2/feedbacks', params: { color: :blue }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
let(:record) do
|
54
|
+
AnotherRecord.new(href: 'http://datastore/v2/feedbacks')
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'applys endpoint options on load!' do
|
58
|
+
stub_request(:get, 'http://datastore/v2/feedbacks?color=blue')
|
59
|
+
.to_return(body: {}.to_json)
|
60
|
+
record.load!
|
61
|
+
end
|
62
|
+
end
|
45
63
|
end
|
@@ -336,4 +336,34 @@ describe LHS::Record do
|
|
336
336
|
expect(place.contracts.first.products.href).to eq "#{datastore}/place/1/contacts/1/products"
|
337
337
|
end
|
338
338
|
end
|
339
|
+
|
340
|
+
context 'includes with options' do
|
341
|
+
before(:each) do
|
342
|
+
class Customer < LHS::Record
|
343
|
+
endpoint ':datastore/customers/:id'
|
344
|
+
end
|
345
|
+
|
346
|
+
class Place < LHS::Record
|
347
|
+
endpoint ':datastore/places'
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
it 'forwards includes options to requests made for those includes' do
|
352
|
+
stub_request(:get, "#{datastore}/customers/1")
|
353
|
+
.to_return(body: {
|
354
|
+
'places' => {
|
355
|
+
'href' => "#{datastore}/places"
|
356
|
+
}
|
357
|
+
}.to_json)
|
358
|
+
stub_request(:get, "#{datastore}/places?forwarded_params=123")
|
359
|
+
.to_return(body: {
|
360
|
+
'items' => [{ id: 1 }]
|
361
|
+
}.to_json)
|
362
|
+
customer = Customer
|
363
|
+
.includes(:places)
|
364
|
+
.references(places: { params: { forwarded_params: 123 } })
|
365
|
+
.find(1)
|
366
|
+
expect(customer.places.first.id).to eq 1
|
367
|
+
end
|
368
|
+
end
|
339
369
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lhs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 6.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- https://github.com/local-ch/lhs/graphs/contributors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: lhc
|
@@ -328,7 +328,8 @@ files:
|
|
328
328
|
- spec/support/load_json.rb
|
329
329
|
- spec/views/form_for_spec.rb
|
330
330
|
homepage: https://github.com/local-ch/lhs
|
331
|
-
licenses:
|
331
|
+
licenses:
|
332
|
+
- GPL-3
|
332
333
|
metadata: {}
|
333
334
|
post_install_message:
|
334
335
|
rdoc_options: []
|
@@ -338,14 +339,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
338
339
|
requirements:
|
339
340
|
- - ">="
|
340
341
|
- !ruby/object:Gem::Version
|
341
|
-
version:
|
342
|
+
version: 2.0.0
|
342
343
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
343
344
|
requirements:
|
344
345
|
- - ">="
|
345
346
|
- !ruby/object:Gem::Version
|
346
347
|
version: '0'
|
347
348
|
requirements:
|
348
|
-
- Ruby >=
|
349
|
+
- Ruby >= 2.0.0
|
349
350
|
rubyforge_project:
|
350
351
|
rubygems_version: 2.2.2
|
351
352
|
signing_key:
|