ncore 2.3.1 → 3.3.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/CHANGELOG.md +63 -1
- data/LICENSE +1 -1
- data/README.md +1 -1
- data/example/lib/my_api/api_config.rb +10 -0
- data/example/lib/my_api/rails/railtie.rb +4 -0
- data/lib/ncore.rb +31 -4
- data/lib/ncore/associations.rb +13 -13
- data/lib/ncore/attributes.rb +36 -15
- data/lib/ncore/base.rb +6 -3
- data/lib/ncore/client.rb +29 -27
- data/lib/ncore/client_cache.rb +48 -0
- data/lib/ncore/configuration.rb +16 -3
- data/lib/ncore/exceptions.rb +5 -2
- data/lib/ncore/identity.rb +27 -0
- data/lib/ncore/lifecycle.rb +3 -3
- data/lib/ncore/methods/all.rb +3 -7
- data/lib/ncore/methods/build.rb +2 -2
- data/lib/ncore/methods/count.rb +1 -1
- data/lib/ncore/methods/create.rb +4 -5
- data/lib/ncore/methods/delete.rb +6 -7
- data/lib/ncore/methods/delete_bulk.rb +4 -4
- data/lib/ncore/methods/delete_single.rb +4 -5
- data/lib/ncore/methods/find.rb +5 -6
- data/lib/ncore/methods/find_single.rb +5 -9
- data/lib/ncore/methods/update.rb +6 -7
- data/lib/ncore/methods/update_bulk.rb +26 -0
- data/lib/ncore/rails/active_model.rb +24 -14
- data/lib/ncore/singleton_base.rb +4 -3
- data/lib/ncore/util.rb +10 -2
- data/lib/ncore/version.rb +1 -1
- data/ncore.gemspec +1 -1
- metadata +7 -6
- data/lib/ncore/rails/module_fix.rb +0 -17
@@ -0,0 +1,48 @@
|
|
1
|
+
module NCore
|
2
|
+
module Client::Cache
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
# cache_opts: true
|
10
|
+
# use *::Api.cache_store
|
11
|
+
# cache_opts: {...}
|
12
|
+
# use: *::Api.cache_store, with options: {...}
|
13
|
+
# hint: add force: true execute the query and rewrite the cache
|
14
|
+
# cache_opts: Store.new
|
15
|
+
# use Store.new as-is
|
16
|
+
def execute_request(req, cache_opts=nil)
|
17
|
+
case cache_opts
|
18
|
+
when true
|
19
|
+
store, cache_opts = cache_store, {}
|
20
|
+
when Hash
|
21
|
+
store, cache_opts = cache_store, cache_opts.symbolize_keys
|
22
|
+
when nil, false
|
23
|
+
store = false
|
24
|
+
else
|
25
|
+
store, cache_opts = cache_opts, {}
|
26
|
+
end
|
27
|
+
|
28
|
+
if store && req[:method] == :get
|
29
|
+
store.fetch request_cache_key(req.slice(:url, :headers)), cache_opts do
|
30
|
+
super
|
31
|
+
end
|
32
|
+
else
|
33
|
+
super
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def request_cache_key(url:, headers:)
|
39
|
+
[ 'ncore',
|
40
|
+
url.gsub(/[^a-zA-Z0-9]+/,'-'),
|
41
|
+
Digest::MD5.hexdigest(headers.sort.to_s)
|
42
|
+
].join ':'
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
data/lib/ncore/configuration.rb
CHANGED
@@ -28,6 +28,9 @@ module NCore
|
|
28
28
|
mattr_accessor :strict_attributes
|
29
29
|
self.strict_attributes = true
|
30
30
|
|
31
|
+
mattr_accessor :i18n_scope
|
32
|
+
self.i18n_scope = :ncore
|
33
|
+
|
31
34
|
mattr_accessor :instrument_key
|
32
35
|
self.instrument_key = 'request.ncore'
|
33
36
|
|
@@ -37,10 +40,18 @@ module NCore
|
|
37
40
|
mattr_accessor :auth_header_prefix
|
38
41
|
self.auth_header_prefix = 'X-Api'
|
39
42
|
|
40
|
-
|
43
|
+
mattr_reader :bearer_credential_key
|
44
|
+
class_eval <<-MTH
|
45
|
+
def self.bearer_credential_key=(v)
|
46
|
+
@@bearer_credential_key = v&.to_s
|
47
|
+
end
|
48
|
+
def bearer_credential_key=(v)
|
49
|
+
@@bearer_credential_key = v&.to_s
|
50
|
+
end
|
51
|
+
MTH
|
41
52
|
|
42
53
|
mattr_accessor :credentials_error_message
|
43
|
-
self.credentials_error_message = %Q{Missing API credentials. Set default credentials using "#{self.
|
54
|
+
self.credentials_error_message = %Q{Missing API credentials. Set default credentials using "#{self.module_parent.name}.credentials = {api_user: YOUR_API_USER, api_key: YOUR_API_KEY}"}
|
44
55
|
|
45
56
|
mattr_accessor :verify_ssl
|
46
57
|
self.verify_ssl = true
|
@@ -57,6 +68,8 @@ module NCore
|
|
57
68
|
end
|
58
69
|
MTH
|
59
70
|
|
71
|
+
mattr_accessor :cache_store
|
72
|
+
|
60
73
|
mattr_accessor :logger
|
61
74
|
self.logger = Logger.new(STDOUT)
|
62
75
|
end
|
@@ -69,7 +82,7 @@ module NCore
|
|
69
82
|
if b
|
70
83
|
b.freeze
|
71
84
|
else
|
72
|
-
raise
|
85
|
+
raise module_parent::CertificateError, 'Failed to locate CA cert bundle from excon. Specify a full path instead.'
|
73
86
|
end
|
74
87
|
end
|
75
88
|
|
data/lib/ncore/exceptions.rb
CHANGED
@@ -24,9 +24,13 @@ module NCore
|
|
24
24
|
cl_name ||= object.class.class_name if object.class.respond_to?(:class_name)
|
25
25
|
cl_name ||= object.name if object.respond_to?(:name)
|
26
26
|
cl_name ||= object.class.name
|
27
|
-
msg = "\#{cl_name} Invalid: \#{
|
27
|
+
msg = "\#{cl_name} Invalid: \#{object.errors.to_a.join(' ')}"
|
28
28
|
super msg
|
29
29
|
end
|
30
|
+
|
31
|
+
def errors
|
32
|
+
object&.errors
|
33
|
+
end
|
30
34
|
end
|
31
35
|
|
32
36
|
class QueryError < Error
|
@@ -40,7 +44,6 @@ module NCore
|
|
40
44
|
end
|
41
45
|
|
42
46
|
class BulkActionError < QueryError ; end
|
43
|
-
class ValidationError < QueryError ; end
|
44
47
|
INCL
|
45
48
|
end
|
46
49
|
|
data/lib/ncore/identity.rb
CHANGED
@@ -15,9 +15,36 @@ module NCore
|
|
15
15
|
class_name.underscore
|
16
16
|
end
|
17
17
|
alias :json_root :attrib_name
|
18
|
+
|
19
|
+
def i18n_scope
|
20
|
+
module_parent::Api.i18n_scope
|
21
|
+
end
|
22
|
+
|
23
|
+
# make NCore::SomeResource.model_name do the right thing
|
24
|
+
def model_name
|
25
|
+
::ActiveModel::Name.new(self, nil, ::ActiveSupport::Inflector.demodulize(self))
|
26
|
+
end
|
27
|
+
|
18
28
|
end
|
19
29
|
|
20
30
|
|
31
|
+
# from ActiveRecord::Core
|
32
|
+
def ==(comparison_object)
|
33
|
+
super ||
|
34
|
+
comparison_object.instance_of?(self.class) &&
|
35
|
+
!id.nil? &&
|
36
|
+
comparison_object.id == id
|
37
|
+
end
|
38
|
+
alias :eql? :==
|
39
|
+
|
40
|
+
def hash
|
41
|
+
if id
|
42
|
+
self.class.hash ^ id.hash
|
43
|
+
else
|
44
|
+
super
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
21
48
|
def json_root
|
22
49
|
self.class.json_root
|
23
50
|
end
|
data/lib/ncore/lifecycle.rb
CHANGED
@@ -15,20 +15,20 @@ module NCore
|
|
15
15
|
if respond_to? :update, true
|
16
16
|
update(update_params)
|
17
17
|
else
|
18
|
-
raise self.class.
|
18
|
+
raise self.class.module_parent::Error, "Updating #{self.class.name} objects is not supported."
|
19
19
|
end
|
20
20
|
else
|
21
21
|
if respond_to? :create, true
|
22
22
|
create(update_params)
|
23
23
|
else
|
24
|
-
raise self.class.
|
24
|
+
raise self.class.module_parent::Error, "Creating #{self.class.name} objects is not supported."
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
28
|
alias :update_attributes :save
|
29
29
|
|
30
30
|
def save!(update_params={})
|
31
|
-
save(update_params) || raise(self.class.
|
31
|
+
save(update_params) || raise(self.class.module_parent::RecordInvalid, self)
|
32
32
|
end
|
33
33
|
alias :update_attributes! :save!
|
34
34
|
|
data/lib/ncore/methods/all.rb
CHANGED
@@ -5,18 +5,14 @@ module NCore
|
|
5
5
|
module ClassMethods
|
6
6
|
def all(params={})
|
7
7
|
params = parse_request_params(params)
|
8
|
-
parsed, creds = request(:get,
|
8
|
+
parsed, creds = request(:get, resource_path, params)
|
9
9
|
if parsed[:errors].any?
|
10
|
-
raise
|
10
|
+
raise module_parent::QueryError, parsed[:errors]
|
11
11
|
end
|
12
12
|
Collection.new.tap do |coll|
|
13
13
|
coll.metadata = parsed[:metadata]
|
14
14
|
parsed[:data].each do |hash|
|
15
|
-
|
16
|
-
coll << discover_class(key, self).new(hash.merge(metadata: parsed[:metadata]), creds)
|
17
|
-
else
|
18
|
-
coll << new(hash.merge(metadata: parsed[:metadata]), creds)
|
19
|
-
end
|
15
|
+
coll << factory(hash.merge(metadata: parsed[:metadata]), creds)
|
20
16
|
end
|
21
17
|
end
|
22
18
|
end
|
data/lib/ncore/methods/build.rb
CHANGED
@@ -5,9 +5,9 @@ module NCore
|
|
5
5
|
module ClassMethods
|
6
6
|
def build(params={})
|
7
7
|
params = parse_request_params(params)
|
8
|
-
parsed, creds = request(:get,
|
8
|
+
parsed, creds = request(:get, "#{resource_path}/new", params)
|
9
9
|
if parsed[:errors].any?
|
10
|
-
raise
|
10
|
+
raise module_parent::QueryError, parsed[:errors]
|
11
11
|
end
|
12
12
|
new(parsed, creds)
|
13
13
|
end
|
data/lib/ncore/methods/count.rb
CHANGED
data/lib/ncore/methods/create.rb
CHANGED
@@ -6,16 +6,15 @@ module NCore
|
|
6
6
|
def create!(attribs={})
|
7
7
|
obj = create(attribs)
|
8
8
|
if obj.errors?
|
9
|
-
raise
|
9
|
+
raise module_parent::RecordInvalid, obj
|
10
10
|
end
|
11
11
|
obj
|
12
12
|
end
|
13
13
|
|
14
14
|
# always returns a new object; check .errors? or .valid? to see how it went
|
15
15
|
def create(attribs={})
|
16
|
-
|
17
|
-
obj
|
18
|
-
obj.send :create, params
|
16
|
+
obj = new
|
17
|
+
obj.send :create, attribs
|
19
18
|
obj
|
20
19
|
end
|
21
20
|
end
|
@@ -24,7 +23,7 @@ module NCore
|
|
24
23
|
|
25
24
|
def create(attribs={})
|
26
25
|
params = parse_request_params(attribs, json_root: json_root).reverse_merge credentials: api_creds
|
27
|
-
parsed, @api_creds = request(:post, self.class.
|
26
|
+
parsed, @api_creds = request(:post, self.class.resource_path, params)
|
28
27
|
load(data: params[json_root]) if parsed[:errors].any?
|
29
28
|
load(parsed)
|
30
29
|
errors.empty? ? self : false
|
data/lib/ncore/methods/delete.rb
CHANGED
@@ -4,18 +4,17 @@ module NCore
|
|
4
4
|
|
5
5
|
module ClassMethods
|
6
6
|
def delete!(id, params={})
|
7
|
-
obj = delete(id,
|
7
|
+
obj = delete(id, params)
|
8
8
|
if obj.errors?
|
9
|
-
raise
|
9
|
+
raise module_parent::RecordInvalid, obj
|
10
10
|
end
|
11
11
|
obj
|
12
12
|
end
|
13
13
|
|
14
14
|
# always returns a new object; check .errors? or .valid? to see how it went
|
15
15
|
def delete(id, params={})
|
16
|
-
raise(
|
17
|
-
|
18
|
-
obj = new({id: id}, params[:credentials])
|
16
|
+
raise(module_parent::RecordNotFound, "Cannot delete id=nil") if id.blank?
|
17
|
+
obj = new(id: id)
|
19
18
|
obj.delete(params)
|
20
19
|
obj
|
21
20
|
end
|
@@ -23,13 +22,13 @@ module NCore
|
|
23
22
|
|
24
23
|
def delete(params={})
|
25
24
|
params = parse_request_params(params).reverse_merge credentials: api_creds
|
26
|
-
parsed, @api_creds = request(:delete,
|
25
|
+
parsed, @api_creds = request(:delete, resource_path, params)
|
27
26
|
load(parsed)
|
28
27
|
errors.empty? ? self : false
|
29
28
|
end
|
30
29
|
|
31
30
|
def delete!(params={})
|
32
|
-
delete(params) || raise(self.class.
|
31
|
+
delete(params) || raise(self.class.module_parent::RecordInvalid, self)
|
33
32
|
end
|
34
33
|
|
35
34
|
end
|
@@ -4,12 +4,12 @@ module NCore
|
|
4
4
|
|
5
5
|
module ClassMethods
|
6
6
|
def bulk_delete!(ids, params={})
|
7
|
-
raise(
|
7
|
+
raise(module_parent::RecordNotFound, "ids must not be empty") if ids.blank?
|
8
8
|
params[:ids] = ids
|
9
9
|
params = parse_request_params(params)
|
10
|
-
parsed, creds = request(:delete,
|
10
|
+
parsed, creds = request(:delete, resource_path, params)
|
11
11
|
if parsed[:errors].any?
|
12
|
-
raise
|
12
|
+
raise module_parent::BulkActionError, parsed[:errors]
|
13
13
|
else
|
14
14
|
parsed[:metadata]
|
15
15
|
end
|
@@ -17,7 +17,7 @@ module NCore
|
|
17
17
|
|
18
18
|
def bulk_delete(ids, params={})
|
19
19
|
bulk_delete!(ids, params)
|
20
|
-
rescue
|
20
|
+
rescue module_parent::RecordNotFound, module_parent::BulkActionError
|
21
21
|
false
|
22
22
|
end
|
23
23
|
end
|
@@ -4,21 +4,20 @@ module NCore
|
|
4
4
|
|
5
5
|
module ClassMethods
|
6
6
|
def delete(params={})
|
7
|
-
|
8
|
-
obj
|
9
|
-
obj.delete(params) || raise(parent::RecordInvalid, obj)
|
7
|
+
obj = new
|
8
|
+
obj.delete!(params)
|
10
9
|
end
|
11
10
|
end
|
12
11
|
|
13
12
|
def delete(params={})
|
14
13
|
params = parse_request_params(params).reverse_merge credentials: api_creds
|
15
|
-
parsed, @api_creds = request(:delete,
|
14
|
+
parsed, @api_creds = request(:delete, resource_path, params)
|
16
15
|
load(parsed)
|
17
16
|
errors.empty? ? self : false
|
18
17
|
end
|
19
18
|
|
20
19
|
def delete!(params={})
|
21
|
-
delete(params) || raise(self.class.
|
20
|
+
delete(params) || raise(self.class.module_parent::RecordInvalid, self)
|
22
21
|
end
|
23
22
|
|
24
23
|
end
|
data/lib/ncore/methods/find.rb
CHANGED
@@ -4,23 +4,22 @@ module NCore
|
|
4
4
|
|
5
5
|
module ClassMethods
|
6
6
|
def find(id, params={})
|
7
|
-
raise(
|
8
|
-
|
9
|
-
o = new({id: id}, params[:credentials])
|
7
|
+
raise(module_parent::RecordNotFound, "Cannot find id=nil") if id.blank?
|
8
|
+
o = new(id: id)
|
10
9
|
o.reload(params)
|
11
10
|
end
|
12
11
|
|
13
12
|
def retrieve(id, params={})
|
14
13
|
find id, params
|
15
|
-
rescue
|
16
|
-
|
14
|
+
rescue module_parent::RecordNotFound
|
15
|
+
nil
|
17
16
|
end
|
18
17
|
end
|
19
18
|
|
20
19
|
def reload(find_params={})
|
21
20
|
return if id.blank?
|
22
21
|
params = parse_request_params(find_params).reverse_merge credentials: api_creds
|
23
|
-
parsed, @api_creds = request(:get,
|
22
|
+
parsed, @api_creds = request(:get, resource_path, params)
|
24
23
|
@attribs = {}.with_indifferent_access
|
25
24
|
load(parsed)
|
26
25
|
end
|
@@ -4,18 +4,14 @@ module NCore
|
|
4
4
|
|
5
5
|
module ClassMethods
|
6
6
|
def find(params={})
|
7
|
-
|
8
|
-
|
9
|
-
if parsed[:errors].any?
|
10
|
-
raise parent::QueryError, parsed[:errors]
|
11
|
-
end
|
12
|
-
new(parsed, creds)
|
7
|
+
obj = new
|
8
|
+
obj.reload(params)
|
13
9
|
end
|
14
10
|
|
15
11
|
def retrieve(params={})
|
16
12
|
find params
|
17
|
-
rescue
|
18
|
-
|
13
|
+
rescue module_parent::RecordNotFound
|
14
|
+
nil
|
19
15
|
end
|
20
16
|
end
|
21
17
|
|
@@ -27,7 +23,7 @@ module NCore
|
|
27
23
|
|
28
24
|
def reload(find_params={})
|
29
25
|
params = parse_request_params(find_params).reverse_merge credentials: api_creds
|
30
|
-
parsed, @api_creds = request(:get,
|
26
|
+
parsed, @api_creds = request(:get, resource_path, params)
|
31
27
|
@attribs = {}.with_indifferent_access
|
32
28
|
load(parsed)
|
33
29
|
end
|
data/lib/ncore/methods/update.rb
CHANGED
@@ -6,31 +6,30 @@ module NCore
|
|
6
6
|
def update!(id, attribs)
|
7
7
|
obj = update(id, attribs)
|
8
8
|
if obj.errors?
|
9
|
-
raise
|
9
|
+
raise module_parent::RecordInvalid, obj
|
10
10
|
end
|
11
11
|
obj
|
12
12
|
end
|
13
13
|
|
14
14
|
# always returns a new object; check .errors? or .valid? to see how it went
|
15
15
|
def update(id, attribs)
|
16
|
-
raise(
|
17
|
-
|
18
|
-
obj
|
19
|
-
obj.update params
|
16
|
+
raise(module_parent::RecordNotFound, "Cannot update id=nil") if id.blank?
|
17
|
+
obj = new(id: id)
|
18
|
+
obj.update attribs
|
20
19
|
obj
|
21
20
|
end
|
22
21
|
end
|
23
22
|
|
24
23
|
def update(attribs={})
|
25
24
|
params = parse_request_params(attribs, json_root: json_root).reverse_merge credentials: api_creds
|
26
|
-
parsed, @api_creds = request(:put,
|
25
|
+
parsed, @api_creds = request(:put, resource_path, params)
|
27
26
|
load(data: params[json_root]) if parsed[:errors].any?
|
28
27
|
load(parsed)
|
29
28
|
errors.empty? ? self : false
|
30
29
|
end
|
31
30
|
|
32
31
|
def update!(params={})
|
33
|
-
update(params) || raise(self.class.
|
32
|
+
update(params) || raise(self.class.module_parent::RecordInvalid, self)
|
34
33
|
end
|
35
34
|
|
36
35
|
end
|