shaf_client 0.6.3 → 0.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8d368622457d097eda4375008f44dabd5f2757e860e777347fee28679eb517a3
4
- data.tar.gz: 4f59085a13b589b01f3e4dec49c08410f3bc7617e54fa64f8d16fab260bb3a22
3
+ metadata.gz: de51f879d8fd9a032434411bbe29df1b1dd6629c39277c1373384ae10615e2ff
4
+ data.tar.gz: fa37f60def169a85f3910d6c4dd36faa3155b299f42725606682500e722c504e
5
5
  SHA512:
6
- metadata.gz: e9e353931db9365e43038a6bfbf89ec19a1bd5e1e96031821517e582261c730e7c2e4c860ee3e937951c042c454f5176e627d3b3fd3b3126bd7c696361aa5ee8
7
- data.tar.gz: 7f23e71a7ccab43837f152ed5285118f1cbbff0aafdf439d18a58fba44ef736ceb00d260b3b4612638c5dc54b1338eedec3bece80c88a05ac5b7bd9d29f779e2
6
+ metadata.gz: 6e11dd7e17aa9052606440cbb16c06e8bec99933b0d1033c803116e14c18591795eb26304277288f249c8812a3991d8a2a3bca6deedd1e0c59ea0a1a529abd85
7
+ data.tar.gz: 4db2d441198e463dc8f590638d2017baab472d4d00a205b0694c6b9aef74f6952d5fb715e408f81da70959bbf9d7aeb02970ecc78a1853859dbcb595c0c43432
checksums.yaml.gz.sig CHANGED
Binary file
@@ -10,8 +10,13 @@ class ShafClient
10
10
  @payload =
11
11
  if payload&.is_a? String
12
12
  JSON.parse(payload)
13
+ elsif payload.respond_to? :to_h
14
+ payload.to_h
13
15
  else
14
- payload
16
+ raise Error, <<~ERR
17
+ Trying to create an instance of #{self.class} with a payload that
18
+ cannot be coerced into a Hash
19
+ ERR
15
20
  end
16
21
 
17
22
  parse
@@ -19,8 +24,9 @@ class ShafClient
19
24
 
20
25
  def to_h
21
26
  attributes.dup.tap do |hash|
22
- hash[:_links] = transform_values_to_s(links)
23
- embedded = transform_values_to_s(embedded_resources)
27
+ hash[:_links] = transform_values_to_h(links)
28
+ hash[:_links].merge!(curies: curies.values.map(&:to_h)) unless curies.empty?
29
+ embedded = transform_values_to_h(embedded_resources)
24
30
  hash[:_embedded] = embedded unless embedded.empty?
25
31
  end
26
32
  end
@@ -34,31 +40,23 @@ class ShafClient
34
40
  end
35
41
 
36
42
  def attribute(key)
37
- raise Error, "No attribute for key: #{key}" unless attributes.key? key
38
- attributes.fetch(key.to_sym)
43
+ _attribute(key) or raise Error, "No attribute for key: #{key}"
39
44
  end
40
45
 
41
46
  def link(rel)
42
- rewritten_rel = best_match(links.keys, rel)
43
- raise Error, "No link with rel: #{rel}" unless links.key? rewritten_rel
44
- links[rewritten_rel]
47
+ _link(rel) or raise Error, "No link with rel: #{rel}"
45
48
  end
46
49
 
47
50
  def curie(rel)
48
- raise Error, "No curie with rel: #{rel}" unless curies.key? rel.to_sym
49
- curies[rel.to_sym]
51
+ _curie(rel) or raise Error, "No curie with rel: #{rel}"
50
52
  end
51
53
 
52
54
  def embedded(rel)
53
- rewritten_rel = best_match(embedded_resources.keys, rel)
54
- unless embedded_resources.key? rewritten_rel
55
- raise Error, "No embedded resources with rel: #{rel}"
56
- end
57
- embedded_resources[rewritten_rel]
55
+ _embedded(rel) or raise Error, "No embedded resources with rel: #{rel}"
58
56
  end
59
57
 
60
58
  def rel?(rel)
61
- !link(rel).nil?
59
+ !link(rel).nil? || !embedded(rel).nil?
62
60
  rescue StandardError
63
61
  false
64
62
  end
@@ -77,6 +75,24 @@ class ShafClient
77
75
  @payload ||= {}
78
76
  end
79
77
 
78
+ def _attribute(key)
79
+ attributes[key.to_sym]
80
+ end
81
+
82
+ def _link(rel)
83
+ rewritten_rel = best_match(links.keys, rel)
84
+ links[rewritten_rel]
85
+ end
86
+
87
+ def _curie(rel)
88
+ curies[rel.to_sym]
89
+ end
90
+
91
+ def _embedded(rel)
92
+ rewritten_rel = best_match(embedded_resources.keys, rel)
93
+ embedded_resources[rewritten_rel]
94
+ end
95
+
80
96
  def <<(other)
81
97
  @payload = other.payload.dup
82
98
  @attributes = other.attributes.dup
@@ -148,7 +164,7 @@ class ShafClient
148
164
  best_match(rels, rel.to_s.tr('_', '-')) if rel.to_s.include? '_'
149
165
  end
150
166
 
151
- def transform_values_to_s(hash)
167
+ def transform_values_to_h(hash)
152
168
  hash.transform_values do |value|
153
169
  if value.is_a? Array
154
170
  value.map(&:to_h)
@@ -26,5 +26,9 @@ class ShafClient
26
26
  args[:rel] &&= args[:rel].to_s.sub(/#{name}:/, '')
27
27
  super(**args)
28
28
  end
29
+
30
+ def to_h
31
+ {name: name}.merge(super)
32
+ end
29
33
  end
30
34
  end
@@ -21,7 +21,7 @@ class ShafClient
21
21
 
22
22
  %i[get put post delete patch, get_doc, reload!].each do |method|
23
23
  define_method(method) do |*_args|
24
- raise "EmptyResource: #{method} not available"
24
+ raise Error, "EmptyResource: #{method} not available"
25
25
  end
26
26
  end
27
27
  end
@@ -0,0 +1,47 @@
1
+ class ShafClient
2
+ module HypertextCacheStrategy
3
+ AVAILABLE_CACHE_STRATEGIES = [
4
+ CACHE_STRATEGY_NO_CACHE = :no_cache,
5
+ CACHE_STRATEGY_EMBEDDED = :use_embedded,
6
+ CACHE_STRATEGY_FETCH_HEADERS = :fetch_headers
7
+ ]
8
+
9
+ class << self
10
+ def cacheable?(strategy)
11
+ [CACHE_STRATEGY_EMBEDDED, CACHE_STRATEGY_FETCH_HEADERS].include? strategy
12
+ end
13
+
14
+ def fetch_headers?(strategy)
15
+ CACHE_STRATEGY_FETCH_HEADERS == strategy
16
+ end
17
+
18
+ def default_http_status
19
+ 203
20
+ end
21
+
22
+ def default_headers
23
+ {'content-type' => 'application/hal+json'}
24
+ end
25
+ end
26
+
27
+ def default_hypertext_cache_strategy
28
+ @__default_hypertext_cache_strategy ||= CACHE_STRATEGY_EMBEDDED
29
+ end
30
+
31
+ def default_hypertext_cache_strategy=(strategy)
32
+ unless __valid_cache? strategy
33
+ raise Error, <<~ERR
34
+ Unsupported hypertext cache strategy: #{strategy}
35
+ Possible strategies are: #{AVAILABLE_CACHE_STRATEGIES.join(', ')}
36
+ ERR
37
+ end
38
+ @__default_hypertext_cache_strategy = value
39
+ end
40
+
41
+ private
42
+
43
+ def __valid_cache?(strategy)
44
+ AVAILABLE_CACHE_STRATEGIES.include? strategy
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,7 @@
1
+ class ShafClient
2
+ module MimeTypes
3
+ MIME_TYPE_JSON = 'application/json'
4
+ MIME_TYPE_HAL = 'application/hal+json'
5
+ DEFAULT_ADAPTER = :net_http
6
+ end
7
+ end
@@ -4,21 +4,23 @@ require 'shaf_client/base_resource'
4
4
 
5
5
  class ShafClient
6
6
  class Resource < BaseResource
7
+ include MimeTypes
8
+
7
9
  attr_reader :http_status, :headers
8
10
 
9
- ResourceMapper.register("application/hal+json", self)
11
+ ResourceMapper.register(MIME_TYPE_HAL, self)
10
12
 
11
13
  def self.content_type(type)
12
14
  ResourceMapper.register(type, self)
13
15
  end
14
16
 
15
17
  def self.profile(name)
16
- content_type "application/hal+json;profile=#{name}"
18
+ content_type "#{MIME_TYPE_HAL};profile=#{name}"
17
19
  end
18
20
 
19
- def self.build(client, payload, status = nil, headers = {})
20
- content_type = headers.fetch('content-type', '')
21
- ResourceMapper.for(content_type).new(client, payload, status, headers)
21
+ def self.build(client, payload, content_type = MIME_TYPE_HAL, status = nil, headers = {})
22
+ ResourceMapper.for(content_type)
23
+ .new(client, payload, status, headers)
22
24
  end
23
25
 
24
26
  def initialize(client, payload, status = nil, headers = {})
@@ -36,14 +38,21 @@ class ShafClient
36
38
  RESOURCE
37
39
  end
38
40
 
39
- %i[get put post delete patch].each do |method|
41
+ %i[put post delete patch].each do |method|
40
42
  define_method(method) do |rel, payload = nil, **options|
41
43
  href = link(rel).href
42
44
  client.send(method, href, payload: payload, **options)
43
45
  end
44
46
  end
45
47
 
46
- def get_doc(rel)
48
+ def get(rel, **options)
49
+ href = link(rel).href
50
+ embedded_resource = _embedded(rel)
51
+ cached_resource = hypertext_cache_resource(href, embedded_resource, options)
52
+ cached_resource || client.get(href, **options)
53
+ end
54
+
55
+ def get_doc(rel, **options)
47
56
  rel = rel.to_s
48
57
  curie_name, rel =
49
58
  if rel.include? ':'
@@ -54,7 +63,7 @@ class ShafClient
54
63
 
55
64
  curie = curie(curie_name)
56
65
  uri = curie.resolve_templated(rel: rel)
57
- client.get_doc(uri)
66
+ client.get(uri, options)
58
67
  end
59
68
 
60
69
  def get_hal_form(rel)
@@ -91,5 +100,34 @@ class ShafClient
91
100
  private
92
101
 
93
102
  attr_reader :client
103
+
104
+ def hypertext_cache_strategy(options)
105
+ options.fetch(:hypertext_cache_strategy) do
106
+ ShafClient.default_hypertext_cache_strategy
107
+ end
108
+ end
109
+
110
+ def hypertext_cache?(options)
111
+ HypertextCacheStrategy.cacheable? hypertext_cache_strategy(options)
112
+ end
113
+
114
+ def hypertext_cache_resource(href, embedded_resource, options)
115
+ return unless embedded_resource
116
+
117
+ cache_strategy = hypertext_cache_strategy(options)
118
+ return unless HypertextCacheStrategy.cacheable? cache_strategy
119
+
120
+ if HypertextCacheStrategy.fetch_headers? cache_strategy
121
+ resource = client.head(href, options)
122
+ status = resource.http_status
123
+ headers = resource.headers
124
+ embedded_resource = embedded_resource.payload
125
+ else
126
+ status = HypertextCacheStrategy.default_http_status
127
+ headers = HypertextCacheStrategy.default_headers
128
+ end
129
+
130
+ self.class.build(client, embedded_resource, headers['content-type'], status, headers)
131
+ end
94
132
  end
95
133
  end
@@ -15,6 +15,10 @@ class ShafClient
15
15
  mapping[content_type&.to_sym] = clazz
16
16
  end
17
17
 
18
+ def unregister(content_type)
19
+ mapping.delete(content_type.to_sym)
20
+ end
21
+
18
22
  def default=(clazz)
19
23
  mapping.default = clazz
20
24
  end
@@ -22,7 +22,7 @@ class ShafClient
22
22
 
23
23
  %i[get put post delete patch, get_doc, reload!].each do |method|
24
24
  define_method(method) do |*_args|
25
- raise "UnknownResource: #{method} not available"
25
+ raise Error, "UnknownResource: #{method} not available"
26
26
  end
27
27
  end
28
28
  end
@@ -0,0 +1,3 @@
1
+ class ShafClient
2
+ VERSION = "0.7.0"
3
+ end
data/lib/shaf_client.rb CHANGED
@@ -9,6 +9,7 @@ require 'faraday_http_cache_patch'
9
9
 
10
10
  require 'json'
11
11
  require 'shaf_client/error'
12
+ require 'shaf_client/mime_types'
12
13
  require 'shaf_client/middleware/redirect'
13
14
  require 'shaf_client/resource'
14
15
  require 'shaf_client/shaf_form'
@@ -16,10 +17,12 @@ require 'shaf_client/hal_form'
16
17
  require 'shaf_client/api_error'
17
18
  require 'shaf_client/empty_resource'
18
19
  require 'shaf_client/unknown_resource'
20
+ require 'shaf_client/hypertext_cache_strategy'
19
21
 
20
22
  class ShafClient
21
- MIME_TYPE_JSON = 'application/json'
22
- MIME_TYPE_HAL = 'application/hal+json'
23
+ extend HypertextCacheStrategy
24
+ include MimeTypes
25
+
23
26
  DEFAULT_ADAPTER = :net_http
24
27
 
25
28
  def initialize(root_uri, **options)
@@ -35,12 +38,7 @@ class ShafClient
35
38
  get(@root_uri, **options)
36
39
  end
37
40
 
38
- def get_doc(uri, **options)
39
- response = request(method: :get, uri: uri, opts: options)
40
- response&.body || ''
41
- end
42
-
43
- %i[get put post delete patch].each do |method|
41
+ %i[head get put post delete patch].each do |method|
44
42
  define_method(method) do |uri, payload: nil, **options|
45
43
  response = request(
46
44
  method: method,
@@ -50,9 +48,9 @@ class ShafClient
50
48
  )
51
49
 
52
50
  body = String(response.body)
53
- response.headers['content-type'] = nil if body.empty?
51
+ content_type = response.headers['content-type'] unless body.empty?
54
52
 
55
- Resource.build(self, body, response.status, response.headers)
53
+ Resource.build(self, body, content_type, response.status, response.headers)
56
54
  end
57
55
  end
58
56
 
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shaf_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.3
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sammy Henningsson
@@ -30,7 +30,7 @@ cert_chain:
30
30
  ZMhjYR7sRczGJx+GxGU2EaR0bjRsPVlC4ywtFxoOfRG3WaJcpWGEoAoMJX6Z0bRv
31
31
  M40=
32
32
  -----END CERTIFICATE-----
33
- date: 2019-10-07 00:00:00.000000000 Z
33
+ date: 2019-11-01 00:00:00.000000000 Z
34
34
  dependencies:
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: faraday
@@ -110,12 +110,15 @@ files:
110
110
  - lib/shaf_client/field.rb
111
111
  - lib/shaf_client/form.rb
112
112
  - lib/shaf_client/hal_form.rb
113
+ - lib/shaf_client/hypertext_cache_strategy.rb
113
114
  - lib/shaf_client/link.rb
114
115
  - lib/shaf_client/middleware/redirect.rb
116
+ - lib/shaf_client/mime_types.rb
115
117
  - lib/shaf_client/resource.rb
116
118
  - lib/shaf_client/resource_mapper.rb
117
119
  - lib/shaf_client/shaf_form.rb
118
120
  - lib/shaf_client/unknown_resource.rb
121
+ - lib/shaf_client/version.rb
119
122
  homepage: https://github.com/sammyhenningsson/shaf_client
120
123
  licenses:
121
124
  - MIT
metadata.gz.sig CHANGED
@@ -1,2 +1,2 @@
1
- p�b�WQ�l%�f����;b�YjÛys��C��bC)(�rjlP:�����l�OP�����5�J��� � �mzU3�-"��䤌�ӂ�Ex#����h;aU�tK����Z�=�;�gq� ݑ��$�ܧ|�CYv� � �>I�"��/���5E�A����d[��ML^t�J������h1l�2� ��,‡���nȐ*��
2
- v��O���3�����}Y|&Y5Hk��*�֭ %$U���}5iKe6��
1
+ ��^���!�j��k\�
2
+ ,�P������\?�z��[+�mbsE�\Y�Ԧ�&��7M?��ZXv����u����CH]*܋�i��v��l��f�o�a G�_V�0/(� �=!w����ht-3`�N