lhs 2.2.2 → 3.0.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 +4 -4
- data/README.md +296 -30
- data/lhs.gemspec +3 -3
- data/lib/lhs.rb +0 -7
- data/lib/lhs/collection.rb +4 -4
- data/lib/lhs/concerns/item/destroy.rb +2 -2
- data/lib/lhs/concerns/item/save.rb +3 -3
- data/lib/lhs/concerns/item/update.rb +2 -2
- data/lib/lhs/concerns/item/validation.rb +4 -5
- data/lib/lhs/concerns/{service → record}/all.rb +2 -2
- data/lib/lhs/concerns/{service → record}/batch.rb +3 -3
- data/lib/lhs/concerns/{service → record}/create.rb +4 -3
- data/lib/lhs/concerns/{service → record}/endpoints.rb +6 -6
- data/lib/lhs/concerns/{service → record}/find.rb +3 -2
- data/lib/lhs/concerns/{service → record}/find_by.rb +3 -2
- data/lib/lhs/concerns/{service → record}/first.rb +1 -1
- data/lib/lhs/concerns/{service → record}/includes.rb +4 -2
- data/lib/lhs/concerns/{service → record}/mapping.rb +1 -1
- data/lib/lhs/concerns/{service → record}/model.rb +1 -1
- data/lib/lhs/concerns/{service → record}/request.rb +12 -12
- data/lib/lhs/concerns/{service → record}/where.rb +3 -2
- data/lib/lhs/data.rb +25 -53
- data/lib/lhs/endpoint.rb +2 -2
- data/lib/lhs/item.rb +8 -2
- data/lib/lhs/proxy.rb +2 -2
- data/lib/lhs/record.rb +42 -0
- data/lib/lhs/version.rb +1 -1
- data/spec/collection/meta_data_spec.rb +2 -2
- data/spec/collection/without_object_items_spec.rb +1 -1
- data/spec/data/item_spec.rb +2 -14
- data/spec/data/merge_spec.rb +3 -3
- data/spec/data/raw_spec.rb +1 -1
- data/spec/data/respond_to_spec.rb +3 -3
- data/spec/data/root_spec.rb +2 -2
- data/spec/data/to_json_spec.rb +2 -2
- data/spec/endpoint/for_url_spec.rb +1 -1
- data/spec/item/delegate_spec.rb +2 -2
- data/spec/item/destroy_spec.rb +4 -4
- data/spec/item/errors_spec.rb +4 -4
- data/spec/item/getter_spec.rb +2 -2
- data/spec/item/internal_data_structure_spec.rb +1 -1
- data/spec/item/save_spec.rb +3 -4
- data/spec/item/setter_spec.rb +2 -2
- data/spec/item/update_spec.rb +2 -2
- data/spec/item/validation_spec.rb +47 -75
- data/spec/proxy/load_spec.rb +2 -2
- data/spec/{service → record}/all_spec.rb +7 -7
- data/spec/{service → record}/build_spec.rb +5 -4
- data/spec/{service → record}/create_spec.rb +6 -5
- data/spec/{service → record}/creation_failed_spec.rb +6 -5
- data/spec/record/definitions_spec.rb +29 -0
- data/spec/{service → record}/endpoint_misconfiguration_spec.rb +3 -3
- data/spec/{service → record}/endpoint_options_spec.rb +4 -4
- data/spec/{service → record}/endpoints_spec.rb +15 -15
- data/spec/{service → record}/find_by_spec.rb +8 -8
- data/spec/{service → record}/find_each_spec.rb +3 -3
- data/spec/{service → record}/find_in_batches_spec.rb +6 -6
- data/spec/{service → record}/find_spec.rb +10 -9
- data/spec/{service → record}/first_spec.rb +7 -6
- data/spec/{service → record}/includes_spec.rb +7 -7
- data/spec/{service → record}/mapping_spec.rb +27 -16
- data/spec/{service → record}/model_name_spec.rb +2 -2
- data/spec/{service → record}/new_spec.rb +4 -3
- data/spec/{service → record}/request_spec.rb +3 -3
- data/spec/record/where_spec.rb +34 -0
- data/spec/support/cleanup_endpoints.rb +1 -1
- data/spec/support/{cleanup_services.rb → cleanup_records.rb} +2 -2
- metadata +60 -67
- data/docs/collections.md +0 -28
- data/docs/data.md +0 -39
- data/docs/items.md +0 -79
- data/docs/service.jpg +0 -0
- data/docs/service.pdf +2 -650
- data/docs/services.md +0 -266
- data/lib/lhs/concerns/service/build.rb +0 -19
- data/lib/lhs/service.rb +0 -18
- data/spec/data/pagination_spec.rb +0 -60
- data/spec/dummy/README.rdoc +0 -28
- data/spec/service/where_spec.rb +0 -33
@@ -14,9 +14,9 @@ class LHS::Item < LHS::Proxy
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def update!(params)
|
17
|
-
|
17
|
+
record = _data._root._record_class
|
18
18
|
_data.merge_raw!(LHS::Data.new(params))
|
19
|
-
response_data =
|
19
|
+
response_data = record.request(
|
20
20
|
method: :post,
|
21
21
|
url: href,
|
22
22
|
body: _data.to_json,
|
@@ -8,11 +8,10 @@ class LHS::Item < LHS::Proxy
|
|
8
8
|
def valid?
|
9
9
|
self.errors = nil
|
10
10
|
fail 'No validation endpoint found!' unless validation_endpoint
|
11
|
-
|
12
|
-
|
13
|
-
params = validation_endpoint.options.fetch(:params, {}).merge(validation_params)
|
11
|
+
record = LHS::Record.for_url(validation_endpoint.url)
|
12
|
+
params = validation_endpoint.options.fetch(:params, {}).merge(persist: false)
|
14
13
|
begin
|
15
|
-
|
14
|
+
record.request(
|
16
15
|
url: validation_endpoint.url,
|
17
16
|
method: :post,
|
18
17
|
params: params,
|
@@ -30,7 +29,7 @@ class LHS::Item < LHS::Proxy
|
|
30
29
|
private
|
31
30
|
|
32
31
|
def validation_endpoint
|
33
|
-
endpoint = _data.
|
32
|
+
endpoint = _data._record_class.find_endpoint(_data._raw)
|
34
33
|
endpoint ||= LHS::Endpoint.for_url(_data.href) if _data.href
|
35
34
|
validates = endpoint.options && endpoint.options.fetch(:validates, false)
|
36
35
|
fail 'Endpoint does not support validations!' unless validates
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'active_support'
|
2
2
|
|
3
|
-
class LHS::
|
3
|
+
class LHS::Record
|
4
4
|
|
5
5
|
module All
|
6
6
|
extend ActiveSupport::Concern
|
@@ -26,7 +26,7 @@ class LHS::Service
|
|
26
26
|
all.concat request(params: params.merge(limit: limit, offset: offset))._raw[:items]
|
27
27
|
end
|
28
28
|
end
|
29
|
-
LHS::Data.new(all, nil, self)
|
29
|
+
data._record_class.new(LHS::Data.new(all, nil, self))
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'active_support'
|
2
2
|
|
3
|
-
class LHS::
|
3
|
+
class LHS::Record
|
4
4
|
|
5
5
|
module Batch
|
6
6
|
extend ActiveSupport::Concern
|
@@ -12,7 +12,7 @@ class LHS::Service
|
|
12
12
|
find_in_batches(options) do |data|
|
13
13
|
data.each do |record|
|
14
14
|
item = LHS::Item.new(LHS::Data.new(record, data, self))
|
15
|
-
yield LHS::Data.new(item, data, self)
|
15
|
+
yield self.new(LHS::Data.new(item, data, self))
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -27,7 +27,7 @@ class LHS::Service
|
|
27
27
|
data = request(params: params.merge(limit: batch_size, offset: start))
|
28
28
|
batch_size = data._raw[:limit]
|
29
29
|
left = data._raw[:total].to_i - data._raw[:offset].to_i - data._raw[:limit].to_i
|
30
|
-
yield data
|
30
|
+
yield self.new(data)
|
31
31
|
break if left <= 0
|
32
32
|
start += batch_size
|
33
33
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'active_support'
|
2
2
|
|
3
|
-
class LHS::
|
3
|
+
class LHS::Record
|
4
4
|
|
5
5
|
module Create
|
6
6
|
extend ActiveSupport::Concern
|
@@ -14,12 +14,13 @@ class LHS::Service
|
|
14
14
|
data = LHS::Data.new(json, nil, self, e.response.request)
|
15
15
|
item = LHS::Item.new(data)
|
16
16
|
item.errors = LHS::Errors.new(e.response)
|
17
|
-
LHS::Data.new(item, data)
|
17
|
+
data._record_class.new(LHS::Data.new(item, data))
|
18
18
|
end
|
19
19
|
|
20
20
|
def create!(data = {})
|
21
21
|
url = compute_url!(data)
|
22
|
-
request(url: url, method: :post, body: data.to_json, headers: {'Content-Type' => 'application/json'})
|
22
|
+
data = request(url: url, method: :post, body: data.to_json, headers: {'Content-Type' => 'application/json'})
|
23
|
+
data._record_class.new(data)
|
23
24
|
end
|
24
25
|
end
|
25
26
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'active_support'
|
2
2
|
|
3
|
-
class LHS::
|
3
|
+
class LHS::Record
|
4
4
|
|
5
5
|
# An endpoint is an url that leads to a backend resource.
|
6
|
-
# A
|
6
|
+
# A record can contain multiple endpoints.
|
7
7
|
# The endpoint that is used to request data is choosen
|
8
8
|
# based on the provided parameters.
|
9
9
|
module Endpoints
|
@@ -26,16 +26,16 @@ class LHS::Service
|
|
26
26
|
endpoint = LHC::Endpoint.new(url, options)
|
27
27
|
sanity_check(endpoint)
|
28
28
|
endpoints.push(endpoint)
|
29
|
-
LHS::
|
30
|
-
LHS::
|
29
|
+
LHS::Record::Endpoints.all ||= {}
|
30
|
+
LHS::Record::Endpoints.all[url] = self
|
31
31
|
end
|
32
32
|
|
33
33
|
def for_url(url)
|
34
34
|
return unless url
|
35
|
-
template,
|
35
|
+
template, record = LHS::Record::Endpoints.all.detect do |template, _record_class|
|
36
36
|
LHC::Endpoint.match?(url, template)
|
37
37
|
end
|
38
|
-
|
38
|
+
record
|
39
39
|
end
|
40
40
|
|
41
41
|
# Find an endpoint based on the provided parameters.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'active_support'
|
2
2
|
|
3
|
-
class LHS::
|
3
|
+
class LHS::Record
|
4
4
|
|
5
5
|
module Find
|
6
6
|
extend ActiveSupport::Concern
|
@@ -9,11 +9,12 @@ class LHS::Service
|
|
9
9
|
|
10
10
|
# Find a single uniqe record
|
11
11
|
def find(args)
|
12
|
-
if args.is_a? Hash
|
12
|
+
data = if args.is_a? Hash
|
13
13
|
find_with_parameters(args)
|
14
14
|
else
|
15
15
|
find_by_id(args)
|
16
16
|
end
|
17
|
+
data._record_class.new(data)
|
17
18
|
end
|
18
19
|
|
19
20
|
private
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'active_support'
|
2
2
|
|
3
|
-
class LHS::
|
3
|
+
class LHS::Record
|
4
4
|
|
5
5
|
module FindBy
|
6
6
|
extend ActiveSupport::Concern
|
@@ -24,11 +24,12 @@ class LHS::Service
|
|
24
24
|
def _find_by(params)
|
25
25
|
params = params.dup.merge(limit: 1)
|
26
26
|
data = request(params: params)
|
27
|
-
if data._proxy.is_a?(LHS::Collection)
|
27
|
+
data = if data._proxy.is_a?(LHS::Collection)
|
28
28
|
data.first || fail(LHC::NotFound.new('No item was found.', data._request.response))
|
29
29
|
else
|
30
30
|
data
|
31
31
|
end
|
32
|
+
data._record_class.new(data)
|
32
33
|
end
|
33
34
|
end
|
34
35
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'active_support'
|
2
2
|
|
3
|
-
class LHS::
|
3
|
+
class LHS::Record
|
4
4
|
|
5
5
|
module Includes
|
6
6
|
extend ActiveSupport::Concern
|
@@ -16,7 +16,9 @@ class LHS::Service
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def includes(*args)
|
19
|
-
|
19
|
+
name = "#{self}#{args.object_id}"
|
20
|
+
constant = Object.const_set(name, self)
|
21
|
+
class_clone = constant
|
20
22
|
class_clone.endpoints = endpoints
|
21
23
|
class_clone.mapping = mapping
|
22
24
|
class_clone.including = args.size == 1 ? args[0] : args
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'active_support'
|
2
2
|
|
3
|
-
class LHS::
|
3
|
+
class LHS::Record
|
4
4
|
|
5
5
|
module Request
|
6
6
|
extend ActiveSupport::Concern
|
@@ -71,12 +71,12 @@ class LHS::Service
|
|
71
71
|
|
72
72
|
# Load additional resources that are requested with include
|
73
73
|
def load_include(options, data, sub_includes)
|
74
|
-
|
75
|
-
options = convert_options_to_endpoints(options) if
|
74
|
+
record = record_for_options(options) || self
|
75
|
+
options = convert_options_to_endpoints(options) if record_for_options(options)
|
76
76
|
begin
|
77
|
-
|
77
|
+
record.includes(sub_includes).request(options)
|
78
78
|
rescue LHC::NotFound
|
79
|
-
LHS::Data.new({}, data,
|
79
|
+
LHS::Data.new({}, data, record)
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
@@ -116,17 +116,17 @@ class LHS::Service
|
|
116
116
|
options
|
117
117
|
end
|
118
118
|
|
119
|
-
def
|
120
|
-
|
119
|
+
def record_for_options(options)
|
120
|
+
records = []
|
121
121
|
if options.is_a?(Array)
|
122
122
|
options.each do |option|
|
123
|
-
next unless
|
124
|
-
|
123
|
+
next unless record = LHS::Record.for_url(option[:url])
|
124
|
+
records.push(record)
|
125
125
|
end
|
126
|
-
fail 'Found more than one
|
127
|
-
|
126
|
+
fail 'Found more than one record that could be used to do the request' if records.uniq.count > 1
|
127
|
+
records.uniq.first
|
128
128
|
else # Hash
|
129
|
-
LHS::
|
129
|
+
LHS::Record.for_url(options[:url])
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'active_support'
|
2
2
|
|
3
|
-
class LHS::
|
3
|
+
class LHS::Record
|
4
4
|
|
5
5
|
module Where
|
6
6
|
extend ActiveSupport::Concern
|
@@ -9,7 +9,8 @@ class LHS::Service
|
|
9
9
|
|
10
10
|
# Used to query data from the service.
|
11
11
|
def where(params = {})
|
12
|
-
request(params: params)
|
12
|
+
data = request(params: params)
|
13
|
+
data._record_class.new(data)
|
13
14
|
end
|
14
15
|
end
|
15
16
|
end
|
data/lib/lhs/data.rb
CHANGED
@@ -6,12 +6,12 @@ class LHS::Data
|
|
6
6
|
include Json
|
7
7
|
|
8
8
|
# prevent clashing with attributes of underlying data
|
9
|
-
attr_accessor :_proxy, :_raw, :_parent, :
|
9
|
+
attr_accessor :_proxy, :_raw, :_parent, :_record_class, :_request
|
10
10
|
|
11
|
-
def initialize(input, parent = nil,
|
11
|
+
def initialize(input, parent = nil, record = nil, request = nil)
|
12
12
|
self._raw = raw_from_input(input)
|
13
13
|
self._proxy = proxy_from_input(input)
|
14
|
-
self.
|
14
|
+
self._record_class = record
|
15
15
|
self._parent = parent
|
16
16
|
self._request = request
|
17
17
|
end
|
@@ -30,7 +30,7 @@ class LHS::Data
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def class
|
33
|
-
_root.
|
33
|
+
_root._record_class
|
34
34
|
end
|
35
35
|
|
36
36
|
# enforce internal data structure to have deep symbolized keys
|
@@ -39,48 +39,18 @@ class LHS::Data
|
|
39
39
|
@_raw = raw
|
40
40
|
end
|
41
41
|
|
42
|
-
def
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
def first_page
|
47
|
-
1
|
48
|
-
end
|
49
|
-
|
50
|
-
def last_page
|
51
|
-
total_pages
|
52
|
-
end
|
53
|
-
|
54
|
-
def prev_page
|
55
|
-
current_page - 1
|
56
|
-
end
|
57
|
-
|
58
|
-
def next_page
|
59
|
-
current_page + 1
|
60
|
-
end
|
61
|
-
|
62
|
-
def limit_value
|
63
|
-
limit
|
64
|
-
end
|
65
|
-
|
66
|
-
def total_pages
|
67
|
-
total / limit
|
42
|
+
def root_item?
|
43
|
+
root_item == self
|
68
44
|
end
|
69
45
|
|
70
46
|
protected
|
71
47
|
|
72
|
-
# Use existing mapping to provide data
|
73
|
-
# or forward to proxy
|
74
48
|
def method_missing(name, *args, &block)
|
75
|
-
|
76
|
-
self.instance_exec(&mapping)
|
77
|
-
else
|
78
|
-
_proxy.send(name, *args, &block)
|
79
|
-
end
|
49
|
+
_proxy.send(name, *args, &block)
|
80
50
|
end
|
81
51
|
|
82
52
|
def respond_to_missing?(name, include_all = false)
|
83
|
-
(root_item? && _root.
|
53
|
+
(root_item? && _root._record_class.instance_methods.include?(name)) ||
|
84
54
|
_proxy.respond_to?(name, include_all)
|
85
55
|
end
|
86
56
|
|
@@ -90,13 +60,6 @@ class LHS::Data
|
|
90
60
|
!! (input.is_a?(Hash) && input[:items]) || input.is_a?(Array) || _raw.is_a?(Array)
|
91
61
|
end
|
92
62
|
|
93
|
-
def mapping_for(name)
|
94
|
-
service = LHS::Service.for_url(_raw[:href]) if _raw.is_a?(Hash)
|
95
|
-
service ||= _root._service if root_item? && _root._service
|
96
|
-
return unless service
|
97
|
-
service.mapping[name]
|
98
|
-
end
|
99
|
-
|
100
63
|
def root_item
|
101
64
|
return if self._proxy.class != LHS::Item
|
102
65
|
root = root_item = self
|
@@ -111,10 +74,6 @@ class LHS::Data
|
|
111
74
|
root_item
|
112
75
|
end
|
113
76
|
|
114
|
-
def root_item?
|
115
|
-
root_item == self
|
116
|
-
end
|
117
|
-
|
118
77
|
def root?
|
119
78
|
_root == self
|
120
79
|
end
|
@@ -131,15 +90,28 @@ class LHS::Data
|
|
131
90
|
|
132
91
|
def raw_from_input(input)
|
133
92
|
if input.is_a?(String) && input.length > 0
|
134
|
-
|
93
|
+
raw_from_json_string(input)
|
135
94
|
elsif defined?(input._raw)
|
136
95
|
input._raw
|
137
96
|
elsif defined?(input._data)
|
138
97
|
input._data._raw
|
139
98
|
else
|
140
|
-
input
|
141
|
-
input.deep_symbolize_keys! if input.is_a?(Hash)
|
142
|
-
input
|
99
|
+
raw_from_anything_else(input)
|
143
100
|
end
|
144
101
|
end
|
102
|
+
|
103
|
+
def raw_from_json_string(input)
|
104
|
+
json = JSON.parse(input)
|
105
|
+
if json.is_a?(Hash)
|
106
|
+
json.deep_symbolize_keys
|
107
|
+
else
|
108
|
+
json
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def raw_from_anything_else(input)
|
113
|
+
input = input.to_hash if input.class != Hash && input.respond_to?(:to_hash)
|
114
|
+
input.deep_symbolize_keys! if input.is_a?(Hash)
|
115
|
+
input
|
116
|
+
end
|
145
117
|
end
|
data/lib/lhs/endpoint.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
class LHS::Endpoint
|
3
3
|
|
4
4
|
def self.for_url(url)
|
5
|
-
template,
|
5
|
+
template, record = LHS::Record::Endpoints.all.detect do |template, _record_class|
|
6
6
|
LHC::Endpoint.match?(url, template)
|
7
7
|
end
|
8
|
-
|
8
|
+
record.endpoints.detect { |endpoint| endpoint.url == template } if record
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
data/lib/lhs/item.rb
CHANGED
@@ -58,7 +58,13 @@ class LHS::Item < LHS::Proxy
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def handle_hash(value)
|
61
|
-
LHS::
|
61
|
+
record = LHS::Record.for_url(value[:href]) if value[:href]
|
62
|
+
data = LHS::Data.new(value, _data)
|
63
|
+
if record
|
64
|
+
record.new(data)
|
65
|
+
else
|
66
|
+
data
|
67
|
+
end
|
62
68
|
end
|
63
69
|
|
64
70
|
def set(name, value)
|
@@ -81,6 +87,6 @@ class LHS::Item < LHS::Proxy
|
|
81
87
|
end
|
82
88
|
|
83
89
|
def date_time_regex
|
84
|
-
/(?<date>\d{4}-\d{2}-\d{2})?(?<time>T\d{2}:\d{2}:\d{2}
|
90
|
+
/(?<date>\d{4}-\d{2}-\d{2})?(?<time>T\d{2}:\d{2}:\d{2}\.\d*.\d{2}:\d{2})?/
|
85
91
|
end
|
86
92
|
end
|