shaf_client 0.7.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c4eda6aea2ca9040216f1dee7732b7123e98edfbbec2d3b53dd567f50940d145
4
- data.tar.gz: a1d43989ce6bff97ac6801ef4fcb67f77e01933cbdf796694e6339d57606d9d0
3
+ metadata.gz: 11ccc3070c77ca9f04b3a54599437752022c2de7b6bf51f5d3cf7d6bf25bb147
4
+ data.tar.gz: 73658cc5c27287a677e82a935ced861e8775355ee84df02bc10631e33a13a2e8
5
5
  SHA512:
6
- metadata.gz: d0ca1c6347bf9fb9d15eab004cf7cc83c5f9d571f32cb0fa65c8aaec179c03f9a6f6cd1762951d9904c2eecd537ea0d2b0d04ff347c171099541c7ef1628f9f3
7
- data.tar.gz: 976c5ce8cd4e7868c957c7b4c74696298cb7b262ddb314a359efd28e52b6aa4c1925fe698718eed75472acf646737b12cddedaefb7bb9311026e9599fc934ef3
6
+ metadata.gz: 322b0537cb301169f77dc76b078c11d74d60b156718b9bdef1cf019d3983fb2c6e3aab01750bd309b6e7e672e0fa7f987b74d2ddd6d0edac21ff03088ddb724e
7
+ data.tar.gz: 3d8f6b58ed02af7892425fa39eb1bfb9f52845cba81cff2a8e9204e2dd1780ceafb8bf6b13f2b12f77a7ee6a74ecafcca60a631dacf28dd66e06c7d98a3b4726
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/bin/shaf_client ADDED
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(__dir__, '../lib/')
4
+
5
+ require 'irb'
6
+ require 'optparse'
7
+ require 'shaf_client'
8
+
9
+ url = ARGV.shift || String(ENV['SHAF_CLIENT_URL'])
10
+ options = {
11
+ user: ENV['SHAF_CLIENT_USER'],
12
+ password: ENV['SHAF_CLIENT_PASSWORD']
13
+ }
14
+
15
+ OptionParser.new do |opts|
16
+ opts.banner = "Usage: shaf_client [url]"
17
+
18
+ opts.on("-u", "--user user", "Username used for authentication") do |user|
19
+ options[:user] = user
20
+ end
21
+
22
+ opts.on("-p", "--password password", "Password used for authentication") do |pass|
23
+ options[:password] = pass
24
+ end
25
+ end.parse! ARGV
26
+
27
+ client = ShafClient.new(url, **options) unless url.empty?
28
+ TOPLEVEL_BINDING.local_variable_set(:client, client)
29
+
30
+ IRB.start
data/lib/shaf_client.rb CHANGED
@@ -16,6 +16,7 @@ require 'shaf_client/shaf_form'
16
16
  require 'shaf_client/hal_form'
17
17
  require 'shaf_client/api_error'
18
18
  require 'shaf_client/problem_json'
19
+ require 'shaf_client/alps_json'
19
20
  require 'shaf_client/empty_resource'
20
21
  require 'shaf_client/unknown_resource'
21
22
  require 'shaf_client/hypertext_cache_strategy'
@@ -25,6 +26,12 @@ class ShafClient
25
26
  include MimeTypes
26
27
 
27
28
  DEFAULT_ADAPTER = :net_http
29
+ DEFAULT_ACCEPT_HEADER = [
30
+ MIME_TYPE_HAL,
31
+ MIME_TYPE_PROBLEM_JSON,
32
+ MIME_TYPE_ALPS_JSON,
33
+ '*/*;q=0.8',
34
+ ].join(', ')
28
35
 
29
36
  def initialize(root_uri, **options)
30
37
  @root_uri = root_uri.dup
@@ -55,11 +62,6 @@ class ShafClient
55
62
  end
56
63
  end
57
64
 
58
- def stubs
59
- return unless @adapter == :test
60
- @stubs ||= Faraday::Adapter::Test::Stubs.new
61
- end
62
-
63
65
  private
64
66
 
65
67
  attr_reader :options, :auth_header
@@ -67,7 +69,7 @@ class ShafClient
67
69
  def setup_default_headers
68
70
  @default_headers = {
69
71
  'Content-Type' => options.fetch(:content_type, MIME_TYPE_JSON),
70
- 'Accept' => options.fetch(:accept, MIME_TYPE_HAL)
72
+ 'Accept' => options.fetch(:accept, DEFAULT_ACCEPT_HEADER)
71
73
  }
72
74
  return unless token = options[:auth_token]
73
75
 
@@ -105,9 +107,11 @@ class ShafClient
105
107
  end
106
108
 
107
109
  def connect_adapter(connection)
108
- args = [@adapter]
109
- args << stubs if @adapter == :test
110
- connection.adapter(*args)
110
+ connection.adapter(*adapter_args)
111
+ end
112
+
113
+ def adapter_args
114
+ [@adapter]
111
115
  end
112
116
 
113
117
  def request(method:, uri:, payload: nil, opts: {})
@@ -0,0 +1,60 @@
1
+ require 'shaf_client/alps/extension'
2
+
3
+ class ShafClient
4
+ module Alps
5
+ class Descriptor
6
+ attr_reader :id, :href, :name, :type, :doc, :ext
7
+
8
+ def initialize(id:, **kwargs)
9
+ @id = id.to_sym
10
+ @href = kwargs[:href]
11
+ @name = kwargs[:name]
12
+ @type = kwargs[:type]
13
+ @doc = kwargs[:doc]
14
+ @ext = parse_extentions(kwargs[:ext])
15
+ end
16
+
17
+ alias extensions ext
18
+
19
+ def to_h
20
+ {
21
+ id: id,
22
+ href: href,
23
+ name: name,
24
+ type: type,
25
+ doc: doc,
26
+ ext: extensions.map(&:to_h),
27
+ }
28
+ end
29
+
30
+ def semantic?
31
+ type == 'semantic'
32
+ end
33
+
34
+ def safe?
35
+ type == 'safe'
36
+ end
37
+
38
+ def idempotent?
39
+ type == 'idempotent'
40
+ end
41
+
42
+ def unsafe?
43
+ type == 'unsafe'
44
+ end
45
+
46
+ def extension(id)
47
+ extensions.find { |ext| ext.id == id.to_sym }
48
+ end
49
+
50
+ private
51
+
52
+ def parse_extentions(extensions)
53
+ extensions ||= []
54
+ extensions = [extensions] unless extensions.is_a? Array
55
+ extensions.map { |ext| Extension.new(**ext.transform_keys(&:to_sym)) }
56
+ end
57
+ end
58
+ end
59
+ end
60
+
@@ -0,0 +1,35 @@
1
+ class ShafClient
2
+ module Alps
3
+ class Extension
4
+ attr_reader :id, :href, :value
5
+
6
+ def initialize(id:, href: nil, value: nil)
7
+ @id = id.to_sym
8
+ @href = href
9
+ @value = value
10
+ end
11
+
12
+ def to_h
13
+ {
14
+ id: id,
15
+ href: href,
16
+ value: value,
17
+ }
18
+ end
19
+
20
+ private
21
+
22
+ def method_missing(method_name, *args, &block)
23
+ name = method_name.to_s
24
+ return super unless name.end_with? '?'
25
+
26
+ id.to_s == name[0..-2]
27
+ end
28
+
29
+ def respond_to_missing?(method_name, include_private = false)
30
+ return true if method_name.to_s.end_with? '?'
31
+ super
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,44 @@
1
+ require 'shaf_client/alps/descriptor'
2
+
3
+ class ShafClient
4
+ class AlpsJson < Resource
5
+ content_type MIME_TYPE_ALPS_JSON
6
+
7
+ attr_reader :descriptors
8
+
9
+ def initialize(_client, payload, status = nil, headers = {})
10
+ super
11
+
12
+ @links = {}.freeze
13
+ @curies = {}.freeze
14
+ @embedded_resources = {}.freeze
15
+ end
16
+
17
+ def to_h
18
+ attributes.merge(
19
+ descriptors: descriptors.map(&:to_h)
20
+ )
21
+ end
22
+
23
+ def descriptor(id)
24
+ descriptors.find { |desc| desc.id == id.to_sym }
25
+ end
26
+
27
+ def each_descriptor(&block)
28
+ descriptors.each(&block)
29
+ end
30
+
31
+ private
32
+
33
+ def parse
34
+ alps = payload&.dig('alps') || {}
35
+ @attributes = {
36
+ version: alps['version'],
37
+ doc: alps['doc'],
38
+ }
39
+ @descriptors = alps.fetch('descriptor', []).map do |desc|
40
+ Alps::Descriptor.new(**desc.transform_keys(&:to_sym))
41
+ end
42
+ end
43
+ end
44
+ end
@@ -154,13 +154,17 @@ class ShafClient
154
154
  embedded.each do |key, value|
155
155
  @embedded_resources[key.to_sym] =
156
156
  if value.is_a? Array
157
- value.map { |d| BaseResource.new(d) }
157
+ value.map { |d| build_embedded_resource(d) }
158
158
  else
159
- BaseResource.new(value)
159
+ build_embedded_resource(value)
160
160
  end
161
161
  end
162
162
  end
163
163
 
164
+ def build_embedded_resource(payload)
165
+ BaseResource.new(payload)
166
+ end
167
+
164
168
  def method_missing(method_name, *args, &block)
165
169
  return super unless attributes.key?(method_name)
166
170
  attribute(method_name)
@@ -0,0 +1,53 @@
1
+ require 'forwardable'
2
+
3
+ class ShafClient
4
+ class ContentTypeMap
5
+ extend Forwardable
6
+
7
+ def_delegators :@map, :default, :default=, :keys, :values, :each
8
+
9
+ def initialize
10
+ @map = {}
11
+ end
12
+
13
+ def [](content_type, profile = nil)
14
+ key = key_for(content_type, profile)
15
+ map.fetch(key) do
16
+ key = key_for(content_type, nil)
17
+ map[key]
18
+ end
19
+ end
20
+
21
+ def []=(content_type, profile = nil, value)
22
+ key = key_for(content_type, profile)
23
+ map[key] = value
24
+ end
25
+
26
+ def key?(content_type, profile = nil)
27
+ key = key_for(content_type, profile)
28
+ map.key? key
29
+ end
30
+
31
+ def delete(content_type, profile = nil)
32
+ key = key_for(content_type, profile)
33
+ map.delete(key)
34
+ end
35
+
36
+ def key_for(content_type, profile)
37
+ return unless content_type
38
+
39
+ key = content_type.to_s.downcase
40
+ key = strip_parameters(key)
41
+ key << "_#{profile.to_s.downcase}" if profile
42
+ key
43
+ end
44
+
45
+ private
46
+
47
+ attr_reader :map
48
+
49
+ def strip_parameters(content_type)
50
+ content_type&.sub(/;.*/, '')
51
+ end
52
+ end
53
+ end
@@ -24,7 +24,7 @@ class ShafClient
24
24
 
25
25
  def fields
26
26
  template[:properties].map do |values|
27
- Field.new(values.transform_keys(&:to_sym))
27
+ Field.new(**values.transform_keys(&:to_sym))
28
28
  end
29
29
  end
30
30
 
@@ -18,10 +18,6 @@ class ShafClient
18
18
  def default_http_status
19
19
  203
20
20
  end
21
-
22
- def default_headers
23
- {'content-type' => 'application/hal+json'}
24
- end
25
21
  end
26
22
 
27
23
  def default_hypertext_cache_strategy
@@ -27,8 +27,8 @@ class ShafClient
27
27
  return href unless templated?
28
28
 
29
29
  href
30
- .then { |href| resolve_required(href, **args) }
31
- .then { |href| resolve_optional(href, **args) }
30
+ .yield_self { |href| resolve_required(href, **args) }
31
+ .yield_self { |href| resolve_optional(href, **args) }
32
32
  end
33
33
 
34
34
  def to_h
@@ -2,5 +2,7 @@ class ShafClient
2
2
  module MimeTypes
3
3
  MIME_TYPE_JSON = 'application/json'
4
4
  MIME_TYPE_HAL = 'application/hal+json'
5
+ MIME_TYPE_PROBLEM_JSON = 'application/problem+json'
6
+ MIME_TYPE_ALPS_JSON = 'application/alps+json'
5
7
  end
6
8
  end
@@ -5,7 +5,7 @@ class ShafClient
5
5
  class ProblemJson < Resource
6
6
  include StatusCodes
7
7
 
8
- content_type 'application/problem+json'
8
+ content_type MIME_TYPE_PROBLEM_JSON
9
9
 
10
10
  def type
11
11
  attribute(:type) { 'about:blank' }
@@ -10,17 +10,28 @@ class ShafClient
10
10
 
11
11
  ResourceMapper.register(MIME_TYPE_HAL, self)
12
12
 
13
- def self.content_type(type)
14
- ResourceMapper.register(type, self)
13
+ def self.content_type(type, profile: nil)
14
+ ResourceMapper.register(type, profile, self)
15
15
  end
16
16
 
17
17
  def self.profile(name)
18
- content_type "#{MIME_TYPE_HAL};profile=#{name}"
18
+ content_type MIME_TYPE_HAL, profile: name
19
19
  end
20
20
 
21
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
+ resource_class, extensions = ResourceMapper.for(
23
+ content_type: content_type,
24
+ headers: headers,
25
+ payload: payload,
26
+ client: client,
27
+ )
28
+ resrc = resource_class.new(client, payload, status, headers)
29
+ extensions.compact.each { |extension| resrc.extend extension }
30
+ resrc
31
+ end
32
+
33
+ def self.default_resource_class!
34
+ ResourceMapper.default = self
24
35
  end
25
36
 
26
37
  def initialize(client, payload, status = nil, headers = {})
@@ -63,7 +74,7 @@ class ShafClient
63
74
 
64
75
  curie = curie(curie_name)
65
76
  uri = curie.resolve_templated(rel: rel)
66
- client.get(uri, options)
77
+ client.get(uri, **options)
67
78
  end
68
79
 
69
80
  def get_hal_form(rel)
@@ -96,6 +107,7 @@ class ShafClient
96
107
  protected
97
108
 
98
109
  def <<(other)
110
+ @client = other.client
99
111
  @http_status = other.http_status.dup
100
112
  @headers = other.headers.dup
101
113
  super
@@ -105,6 +117,16 @@ class ShafClient
105
117
 
106
118
  attr_reader :client
107
119
 
120
+ def build_embedded_resource(payload)
121
+ self.class.build(
122
+ client,
123
+ payload,
124
+ headers['content-type'],
125
+ http_status,
126
+ headers
127
+ )
128
+ end
129
+
108
130
  def hypertext_cache_strategy(options)
109
131
  options.fetch(:hypertext_cache_strategy) do
110
132
  ShafClient.default_hypertext_cache_strategy
@@ -122,13 +144,13 @@ class ShafClient
122
144
  return unless HypertextCacheStrategy.cacheable? cache_strategy
123
145
 
124
146
  if HypertextCacheStrategy.fetch_headers? cache_strategy
125
- resource = client.head(href, options)
147
+ resource = client.head(href, **options)
126
148
  status = resource.http_status
127
149
  headers = resource.headers
128
150
  embedded_resource = embedded_resource.payload
129
151
  else
130
152
  status = HypertextCacheStrategy.default_http_status
131
- headers = HypertextCacheStrategy.default_headers
153
+ headers = embedded_resource.headers
132
154
  end
133
155
 
134
156
  self.class.build(client, embedded_resource, headers['content-type'], status, headers)
@@ -0,0 +1,36 @@
1
+ require 'set'
2
+
3
+ class ShafClient
4
+ module ResourceExtension
5
+ class << self
6
+ def register(extender)
7
+ extenders << extender
8
+ end
9
+
10
+ def unregister(extender)
11
+ extenders.delete(extender)
12
+ end
13
+
14
+ def for(profile, base, link_relations, client)
15
+ link_relations = remove_curies(link_relations)
16
+ extenders.map { |extender| extender.call(profile, base, link_relations, client) }
17
+ .compact
18
+ end
19
+
20
+ private
21
+
22
+ def extenders
23
+ @extenders ||= Set.new
24
+ end
25
+
26
+ def remove_curies(link_relations)
27
+ Array(link_relations).map do |rel|
28
+ rel.to_s.sub(/[^:]*:/, '').to_sym
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ require 'shaf_client/resource_extension/base'
36
+ require 'shaf_client/resource_extension/alps_http_method'
@@ -0,0 +1,67 @@
1
+ class ShafClient
2
+ module ResourceExtension
3
+ class AlpsHttpMethod < Base
4
+ class << self
5
+ def call(profile, base, link_relations, _client)
6
+ return unless profile.is_a? AlpsJson
7
+ return unless base <= Resource
8
+
9
+ link_relations = Array(link_relations).compact
10
+ descriptors = descriptors_with_http_method(profile)
11
+ descriptors.keep_if do |descriptor|
12
+ link_relations.include? identifier_for(descriptor)&.to_sym
13
+ end
14
+
15
+ extension_for(descriptors)
16
+ end
17
+
18
+ private
19
+
20
+ def descriptors_with_http_method(profile)
21
+ profile.each_descriptor.each_with_object([]) do |descriptor, descriptors|
22
+ next unless descriptor.extension(:http_method)
23
+ descriptors << descriptor
24
+ end
25
+ end
26
+
27
+ def extension_for(descriptors)
28
+ return if descriptors.empty?
29
+
30
+ Module.new.tap do |mod|
31
+ descriptors.each do |descriptor|
32
+ add_method(mod, descriptor, methods.first)
33
+ end
34
+ end
35
+ end
36
+
37
+ def add_method(mod, descriptor, method)
38
+ rel = identifier_for(descriptor)
39
+ return unless rel
40
+
41
+ ext = descriptor.extension(:http_method)
42
+ methods = Array(ext&.value)
43
+
44
+ # We only know what method to use when size is 1
45
+ return unless methods.size == 1
46
+
47
+ http_method = methods.first.downcase.to_sym
48
+ name = method_name_from(rel)
49
+
50
+ mod.define_method(name) do |payload: nil, **options|
51
+ href = link(rel).href
52
+ client.send(http_method, href, payload: payload, **options)
53
+ end
54
+ end
55
+
56
+ def method_name_from(rel)
57
+ "#{rel.to_s.downcase.tr('-', '_')}!"
58
+ end
59
+
60
+ def identifier_for(descriptor)
61
+ # Currently we only support `id` (i.e no support for descriptors with `href`)
62
+ descriptor.id
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,13 @@
1
+ class ShafClient
2
+ module ResourceExtension
3
+ class Base
4
+ def self.inherited(mod)
5
+ ResourceExtension.register(mod)
6
+ end
7
+
8
+ def self.call(*args)
9
+ raise NotImplementedError, "Class '#{self}' must respond to `call`"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,22 +1,26 @@
1
1
  require 'shaf_client/error'
2
+ require 'shaf_client/content_type_map'
3
+ require 'shaf_client/resource_extension'
2
4
 
3
5
  class ShafClient
4
- class ResourceMapper
6
+ module ResourceMapper
5
7
  class << self
6
- def for(content_type)
7
- mapping[content_type&.to_sym].tap do |clazz|
8
- next if clazz
9
- raise UnSupportedContentType,
10
- "Can't handle Content-Type: #{content_type}"
11
- end
8
+ def for(content_type:, headers: {}, payload: nil, client: nil)
9
+ content_type = content_type&.to_sym
10
+ profile = profile_from(content_type, headers, payload)
11
+ clazz, extensions = result_for(content_type, payload, profile, client)
12
+
13
+ raise_unsupported_error(content_type) unless clazz
14
+
15
+ [clazz, extensions]
12
16
  end
13
17
 
14
- def register(content_type, clazz)
15
- mapping[content_type&.to_sym] = clazz
18
+ def register(content_type, profile = nil, clazz)
19
+ mapping[content_type&.to_sym, profile] = clazz
16
20
  end
17
21
 
18
- def unregister(content_type)
19
- mapping.delete(content_type.to_sym)
22
+ def unregister(content_type, profile = nil)
23
+ mapping.delete(content_type.to_sym, profile)
20
24
  end
21
25
 
22
26
  def default=(clazz)
@@ -26,7 +30,75 @@ class ShafClient
26
30
  private
27
31
 
28
32
  def mapping
29
- @mapping ||= {}
33
+ @mapping ||= ContentTypeMap.new
34
+ end
35
+
36
+ def result_for(content_type, payload, profile, client)
37
+ clazz = nil
38
+ extensions = []
39
+
40
+ # Note: mapping typically has a default value, so we need to check that the key really exist
41
+ if mapping.key? content_type, profile
42
+ # Registered classes with profile takes precedence over linked profiles
43
+ clazz = mapping[content_type, profile]
44
+ else
45
+ clazz = mapping[content_type]
46
+ extensions = extensions_for(clazz, profile, payload, client) if profile
47
+ end
48
+
49
+ [clazz, extensions]
50
+ end
51
+
52
+ def profile_from(content_type, headers, payload)
53
+ profile_from_content_type(content_type) ||
54
+ profile_from_link_header(headers) ||
55
+ profile_from_payload_link(content_type, payload)
56
+ rescue StandardError => err
57
+ warn "Exception while looking up profile link relation: #{err}"
58
+ end
59
+
60
+ def profile_from_content_type(content_type)
61
+ return unless content_type
62
+
63
+ content_type[/profile="?([^"\s;]*)/, 1]
64
+ end
65
+
66
+ def profile_from_link_header(headers)
67
+ links = String(headers["link"] || headers["Link"]).split(',')
68
+ profile_link = links.find { |link| link.match?(/rel="?profile"?/) }
69
+ profile_link[/<(.*)>/, 1] if profile_link
70
+ end
71
+
72
+ def profile_from_payload_link(content_type, payload)
73
+ clazz = mapping[content_type]
74
+ resource = clazz&.new(nil, payload)
75
+ return unless resource.respond_to? :link
76
+
77
+ link = resource.link(:profile) { nil }
78
+ link&.href
79
+ end
80
+
81
+ def extensions_for(clazz, profile, payload, client)
82
+ return [] unless clazz && profile && client
83
+
84
+ profile_resource = fetch_profile(profile, client)
85
+ link_relations = clazz.new(nil, payload).actions if payload
86
+
87
+ ResourceExtension.for(profile_resource, clazz, link_relations, client)
88
+ rescue StandardError => err
89
+ warn "Exception while resolving extensions for profile " \
90
+ "#{profile_resource&.name || profile}: #{err}"
91
+ []
92
+ end
93
+
94
+ def fetch_profile(profile, client)
95
+ return unless profile&.start_with? %r{https?://}
96
+
97
+ client.get(profile)
98
+ end
99
+
100
+ def raise_unsupported_error(content_type)
101
+ raise UnSupportedContentType, "Can't handle Content-Type: #{content_type}"
30
102
  end
31
103
  end
32
104
  end
@@ -27,7 +27,7 @@ class ShafClient
27
27
 
28
28
  def fields
29
29
  attribute(:fields).map do |values|
30
- Field.new(values.transform_keys(&:to_sym))
30
+ Field.new(**values.transform_keys(&:to_sym))
31
31
  end
32
32
  end
33
33
  end
@@ -0,0 +1,16 @@
1
+ class ShafClient
2
+ module Test
3
+ module Stubbing
4
+ def stubs
5
+ return unless @adapter == :test
6
+ @stubs ||= Faraday::Adapter::Test::Stubs.new
7
+ end
8
+
9
+ def adapter_args
10
+ args = super
11
+ args << stubs if @adapter == :test
12
+ args
13
+ end
14
+ end
15
+ end
16
+ end
@@ -2,9 +2,9 @@ require 'shaf_client/resource'
2
2
 
3
3
  class ShafClient
4
4
  class UnknownResource < Resource
5
- attr_reader :http_status, :headers, :body
5
+ default_resource_class!
6
6
 
7
- ResourceMapper.default = self
7
+ attr_reader :http_status, :headers, :body
8
8
 
9
9
  def initialize(_client, payload, status = nil, headers = {})
10
10
  @body = payload.freeze
@@ -1,3 +1,3 @@
1
1
  class ShafClient
2
- VERSION = "0.7.1"
2
+ VERSION = "1.0.0"
3
3
  end
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.7.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sammy Henningsson
@@ -10,27 +10,26 @@ bindir: bin
10
10
  cert_chain:
11
11
  - |
12
12
  -----BEGIN CERTIFICATE-----
13
- MIIDXjCCAkagAwIBAgIBATANBgkqhkiG9w0BAQsFADAsMSowKAYDVQQDDCFzYW1t
14
- eS5oZW5uaW5nc3Nvbi9EQz1nbWFpbC9EQz1jb20wHhcNMTgwNzE2MTYzNTMzWhcN
15
- MjAwNzE2MTYzNTMzWjAsMSowKAYDVQQDDCFzYW1teS5oZW5uaW5nc3Nvbi9EQz1n
16
- bWFpbC9EQz1jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvkgwt
17
- Zn8obnCelWttayB1BrHBLUK3b8gasRRtbNk4DzAL+EW6sHSVT2u5I7Wws7JQA5VB
18
- NaK7tgvq3CbDLVRl9NrpDCDx09To08stPxDKi6kst1nkSPAD8g0sQlW3voeQTH98
19
- 2Z2H3XUegHhu5Z9PU9T/7V/vZUzHPiPg1tX1JUIGOPAjVGsr7SUetbL171zK4S4Y
20
- tvUkIoNaph+maHttvyYB/ptiZLD53WORKd4Knw3OiJsLtrxr5hhKyQ+txQdF0P8G
21
- +FlR+Je7B0Ek3yg6fEiJgrdcajYCMo8Oe/GRtoHhi6J3LsYA620P1BSCddZQ2XeL
22
- y3rzIZyMU0iaT69nAgMBAAGjgYowgYcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw
23
- HQYDVR0OBBYEFLpI49QndnmuiDhwy2XtMps7No1pMCYGA1UdEQQfMB2BG3NhbW15
24
- Lmhlbm5pbmdzc29uQGdtYWlsLmNvbTAmBgNVHRIEHzAdgRtzYW1teS5oZW5uaW5n
25
- c3NvbkBnbWFpbC5jb20wDQYJKoZIhvcNAQELBQADggEBAFJZqH6sgeiTLvMLpxaK
26
- K1GaYSCyZbMutf5C3tIAgkmU5UD6B8R0bw6gTM1deM5NJ60LjzqY7rlK3YKDIbTn
27
- iXMCe9vd4yE/jb5Zi8Wk//9n8CMG68dQpBvmcQ58/M4gTtgsx+lIgXuI5dPQMmRi
28
- bhWQqqWqxT9X6njjfXFk4xn3z6mfFQNPAYqRVeTHUpXBQZPt+bYXRwHPFZGWkx4l
29
- BnuuhYKt3CR7YIgvnsQWlTAcU1Ipdayj6UfYqUtlc6cF3CL96NOx7mgZXV8URFiX
30
- ZMhjYR7sRczGJx+GxGU2EaR0bjRsPVlC4ywtFxoOfRG3WaJcpWGEoAoMJX6Z0bRv
31
- M40=
13
+ MIIDVjCCAj6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAqMSgwJgYDVQQDDB9zYW1t
14
+ eS5oZW5uaW5nc3Nvbi9EQz1oZXkvREM9Y29tMB4XDTIxMDIwMjEzNTY1OFoXDTIy
15
+ MDIwMjEzNTY1OFowKjEoMCYGA1UEAwwfc2FtbXkuaGVubmluZ3Nzb24vREM9aGV5
16
+ L0RDPWNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK+SDC1mfyhu
17
+ cJ6Va21rIHUGscEtQrdvyBqxFG1s2TgPMAv4RbqwdJVPa7kjtbCzslADlUE1oru2
18
+ C+rcJsMtVGX02ukMIPHT1OjTyy0/EMqLqSy3WeRI8APyDSxCVbe+h5BMf3zZnYfd
19
+ dR6AeG7ln09T1P/tX+9lTMc+I+DW1fUlQgY48CNUayvtJR61svXvXMrhLhi29SQi
20
+ g1qmH6Zoe22/JgH+m2JksPndY5Ep3gqfDc6Imwu2vGvmGErJD63FB0XQ/wb4WVH4
21
+ l7sHQSTfKDp8SImCt1xqNgIyjw578ZG2geGLoncuxgDrbQ/UFIJ11lDZd4vLevMh
22
+ nIxTSJpPr2cCAwEAAaOBhjCBgzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNV
23
+ HQ4EFgQUukjj1Cd2ea6IOHDLZe0ymzs2jWkwJAYDVR0RBB0wG4EZc2FtbXkuaGVu
24
+ bmluZ3Nzb25AaGV5LmNvbTAkBgNVHRIEHTAbgRlzYW1teS5oZW5uaW5nc3NvbkBo
25
+ ZXkuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQBt310FZ56E/fp/y5Wym1xb4C0owfnI
26
+ LzUqOjXWZTO7RezlBJV/qIwqt6bEjYDQR56zULJFSp4YdoDsratmQ+/kwtbHF7xf
27
+ WYkSE36mhLP2ggQFH9fXtX6XdyIlwFqwEfNW73ZrkBXGjMxLVKIS9uHdN7PoNhbS
28
+ 0YjOZZD/rq1Jf+klwl/G7bBDPjn58DWlUmwzoj49goGS/UBG37RssQxRwPelKHZh
29
+ 5ZlcHq9h5CxVt380OKaU6wMg95RJBd/kUJqmPxxlxMH8QDQinTwZmmFA9wW7PJdy
30
+ wAx8px9LkSjTs0GVLH7VtVRWAELllsswCJktz63Adelx9fmIMgrTYgZM
32
31
  -----END CERTIFICATE-----
33
- date: 2020-05-16 00:00:00.000000000 Z
32
+ date: 2021-03-12 00:00:00.000000000 Z
34
33
  dependencies:
35
34
  - !ruby/object:Gem::Dependency
36
35
  name: faraday
@@ -83,7 +82,7 @@ dependencies:
83
82
  version: '5'
84
83
  - - ">="
85
84
  - !ruby/object:Gem::Version
86
- version: '5.14'
85
+ version: 5.14.3
87
86
  type: :development
88
87
  prerelease: false
89
88
  version_requirements: !ruby/object:Gem::Requirement
@@ -93,17 +92,37 @@ dependencies:
93
92
  version: '5'
94
93
  - - ">="
95
94
  - !ruby/object:Gem::Version
96
- version: '5.14'
95
+ version: 5.14.3
96
+ - !ruby/object:Gem::Dependency
97
+ name: minitest-hooks
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '1'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '1'
97
110
  description: A HAL client customized for Shaf APIs
98
111
  email: sammy.henningsson@gmail.com
99
- executables: []
112
+ executables:
113
+ - shaf_client
100
114
  extensions: []
101
115
  extra_rdoc_files: []
102
116
  files:
117
+ - bin/shaf_client
103
118
  - lib/faraday_http_cache_patch.rb
104
119
  - lib/shaf_client.rb
120
+ - lib/shaf_client/alps/descriptor.rb
121
+ - lib/shaf_client/alps/extension.rb
122
+ - lib/shaf_client/alps_json.rb
105
123
  - lib/shaf_client/api_error.rb
106
124
  - lib/shaf_client/base_resource.rb
125
+ - lib/shaf_client/content_type_map.rb
107
126
  - lib/shaf_client/curie.rb
108
127
  - lib/shaf_client/empty_resource.rb
109
128
  - lib/shaf_client/error.rb
@@ -116,9 +135,13 @@ files:
116
135
  - lib/shaf_client/mime_types.rb
117
136
  - lib/shaf_client/problem_json.rb
118
137
  - lib/shaf_client/resource.rb
138
+ - lib/shaf_client/resource_extension.rb
139
+ - lib/shaf_client/resource_extension/alps_http_method.rb
140
+ - lib/shaf_client/resource_extension/base.rb
119
141
  - lib/shaf_client/resource_mapper.rb
120
142
  - lib/shaf_client/shaf_form.rb
121
143
  - lib/shaf_client/status_codes.rb
144
+ - lib/shaf_client/test/stubbing.rb
122
145
  - lib/shaf_client/unknown_resource.rb
123
146
  - lib/shaf_client/version.rb
124
147
  homepage: https://github.com/sammyhenningsson/shaf_client
metadata.gz.sig CHANGED
Binary file