ncore 2.3.0 → 3.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +61 -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 -3
- data/lib/ncore/associations.rb +13 -13
- data/lib/ncore/attributes.rb +34 -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 +7 -1
- 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/rails/module_fix.rb +5 -3
- 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 +10 -8
@@ -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,6 +44,8 @@ module NCore
|
|
40
44
|
end
|
41
45
|
|
42
46
|
class BulkActionError < QueryError ; end
|
47
|
+
|
48
|
+
# DEPRECATED; to be removed in v3.1
|
43
49
|
class ValidationError < QueryError ; end
|
44
50
|
INCL
|
45
51
|
end
|
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
|