ecoportal-api-graphql 0.4.2 → 0.4.4
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 +26 -2
- data/Rakefile +10 -10
- data/ecoportal-api-graphql.gemspec +22 -19
- data/lib/ecoportal/api/common/graphql/auth_service.rb +15 -15
- data/lib/ecoportal/api/common/graphql/class_helpers.rb +6 -3
- data/lib/ecoportal/api/common/graphql/client.rb +1 -1
- data/lib/ecoportal/api/common/graphql/hash_helpers.rb +60 -30
- data/lib/ecoportal/api/common/graphql/http_client.rb +15 -21
- data/lib/ecoportal/api/common/graphql/model/as_input.rb +40 -0
- data/lib/ecoportal/api/common/graphql/model/diffable/hash_diff.rb +60 -0
- data/lib/ecoportal/api/common/graphql/model/diffable.rb +32 -0
- data/lib/ecoportal/api/common/graphql/model.rb +17 -0
- data/lib/ecoportal/api/common/graphql/query_integration.rb +5 -2
- data/lib/ecoportal/api/common/graphql.rb +1 -2
- data/lib/ecoportal/api/graphql/base/action.rb +2 -0
- data/lib/ecoportal/api/graphql/base/action_category.rb +2 -0
- data/lib/ecoportal/api/graphql/base/contractor_entity.rb +2 -0
- data/lib/ecoportal/api/graphql/base/location_classification_type.rb +1 -1
- data/lib/ecoportal/api/graphql/base/location_node.rb +2 -0
- data/lib/ecoportal/api/graphql/base/location_structure.rb +1 -0
- data/lib/ecoportal/api/graphql/base/model.rb +1 -21
- data/lib/ecoportal/api/graphql/base/organization.rb +2 -0
- data/lib/ecoportal/api/graphql/base/page.rb +2 -0
- data/lib/ecoportal/api/graphql/base/person_member.rb +2 -0
- data/lib/ecoportal/api/graphql/error/locations_error.rb +2 -0
- data/lib/ecoportal/api/graphql/error/locations_validation_error.rb +2 -0
- data/lib/ecoportal/api/graphql/error/validation_errors.rb +1 -0
- data/lib/ecoportal/api/graphql/fragment.rb +2 -0
- data/lib/ecoportal/api/graphql/helpers/locations_tree.rb +10 -10
- data/lib/ecoportal/api/graphql/logic/base_query.rb +5 -2
- data/lib/ecoportal/api/graphql/logic/mutation.rb +3 -5
- data/lib/ecoportal/api/graphql/logic/payload.rb +2 -0
- data/lib/ecoportal/api/graphql/logic/query.rb +4 -1
- data/lib/ecoportal/api/graphql/logic/query_array.rb +1 -0
- data/lib/ecoportal/api/graphql/logic/query_connection.rb +2 -0
- data/lib/ecoportal/api/graphql/model/account.rb +2 -0
- data/lib/ecoportal/api/graphql/model/contractor_entity.rb +2 -2
- data/lib/ecoportal/api/graphql/model/location_node.rb +1 -1
- data/lib/ecoportal/api/graphql/model/user.rb +2 -0
- data/lib/ecoportal/api/graphql/payload/location_structure/apply_commands.rb +2 -0
- data/lib/ecoportal/api/graphql/payload/location_structure/command_execution_result.rb +2 -0
- data/lib/ecoportal/api/graphql/query/location_structures.rb +5 -4
- data/lib/ecoportal/api/graphql_version.rb +1 -1
- metadata +31 -28
- data/lib/ecoportal/api/common/graphql/doc_helpers.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e9ec208e89d9a86ad745b0138d3c5ecf3105de642c9fc4ededae17e7a6e278a
|
4
|
+
data.tar.gz: 57d342befa5dd0e2f713bd1a79a9f49ea6367b4fc0da262f0362faaeb21c6195
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d3ea5e64afc249e874d38e4ed1000056c1663ba1b0edd9304b09cf8d999b6a0dd543e47819160742fcc7d73feb4bc7e389c47feba02bc0501a7cc9ff4da62b8
|
7
|
+
data.tar.gz: 76ac28462d5d3dbcb5239a13865f026cd790d1272feec8d9c223b8808309fee14cf8ca59a4bc1992f9aaf6a64df986dc10af21c1c27eddb1d9b9c939d2ac30f8
|
data/CHANGELOG.md
CHANGED
@@ -9,7 +9,7 @@ All notable changes to this project will be documented in this file.
|
|
9
9
|
- Analyse how to "DSL" currentOrganization.action.activities
|
10
10
|
- review `path` tracking
|
11
11
|
|
12
|
-
## [0.4.
|
12
|
+
## [0.4.5] - 2025-02-xx
|
13
13
|
|
14
14
|
### Added
|
15
15
|
|
@@ -17,11 +17,35 @@ All notable changes to this project will be documented in this file.
|
|
17
17
|
|
18
18
|
### Fixed
|
19
19
|
|
20
|
+
## [0.4.4] - 2025-02-23
|
21
|
+
|
22
|
+
### Changed
|
23
|
+
|
24
|
+
- Upgraded `ecoportal-api` gem (maintanance)
|
25
|
+
- Upgraded `ecoportal-api-v2` gem (to provision `root!` class method)
|
26
|
+
- Defined some models that hand on their own as `root!`
|
27
|
+
- Refactored `Base::Model` by moving its loggic to `Common::GraphQL`
|
28
|
+
|
29
|
+
### Fixed
|
30
|
+
|
31
|
+
- `Ecoportal::API::Common::GraphQL::HashHelpers`
|
32
|
+
- Truly make the iterator generic
|
33
|
+
|
34
|
+
## [0.4.3] - 2024-11-21
|
35
|
+
|
36
|
+
### Changed
|
37
|
+
|
38
|
+
- upgrade gems
|
39
|
+
- `ecoportal-api`
|
40
|
+
- `ecoportal-api-v2`
|
41
|
+
- `Ecoportal::API::Common::GraphQL::HttpClient.new` ceased to default `version` to `v1` (now it defaults to `nil`)
|
42
|
+
|
20
43
|
## [0.4.2] - 2024-10-01
|
21
44
|
|
22
45
|
### Changed
|
23
46
|
|
24
|
-
- upgrade
|
47
|
+
- upgrade gems
|
48
|
+
- `ecoportal-api-v2`
|
25
49
|
- add explicit dependency onto `ecoportal-api` gem (client)
|
26
50
|
|
27
51
|
## [0.4.1] - 2024-08-09
|
data/Rakefile
CHANGED
@@ -1,36 +1,36 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
3
|
require 'rubocop/rake_task'
|
4
|
-
require
|
5
|
-
require
|
4
|
+
require 'yard'
|
5
|
+
require 'redcarpet'
|
6
6
|
|
7
|
-
desc
|
7
|
+
desc 'run the specs'
|
8
8
|
RSpec::Core::RakeTask.new(:spec)
|
9
9
|
|
10
|
-
desc
|
10
|
+
desc 'run rspec showing backtrace'
|
11
11
|
RSpec::Core::RakeTask.new(:spec_trace) do |task|
|
12
12
|
task.rspec_opts = ['--backtrace']
|
13
13
|
end
|
14
14
|
task :rspec_trace => :spec_trace
|
15
15
|
|
16
|
-
desc
|
16
|
+
desc 'run rspec stopping on first fail, and show backtrace'
|
17
17
|
RSpec::Core::RakeTask.new(:spec_fast) do |task|
|
18
18
|
task.rspec_opts = ['--fail-fast', '--backtrace']
|
19
19
|
end
|
20
20
|
task :rspec_fast => :spec_fast
|
21
21
|
|
22
|
-
desc
|
22
|
+
desc 'run rubocop diaplying cop names'
|
23
23
|
RuboCop::RakeTask.new(:rubocop) do |t|
|
24
24
|
t.options = ['--display-cop-names']
|
25
25
|
end
|
26
26
|
|
27
27
|
# default task name is yard
|
28
|
-
desc
|
28
|
+
desc 'Yard: generate all the documentation'
|
29
29
|
YARD::Rake::YardocTask.new(:doc) do |t|
|
30
30
|
#t.files = ['lib/**/*.rb']
|
31
31
|
end
|
32
32
|
|
33
|
-
desc
|
33
|
+
desc 'default task: runs rubocop and rspec'
|
34
34
|
task :default do
|
35
35
|
Rake::Task[:rubocop].invoke
|
36
36
|
ensure
|
@@ -1,15 +1,16 @@
|
|
1
|
+
# rubocop:disable Gemspec/DevelopmentDependencies
|
1
2
|
lib = File.expand_path('lib', __dir__)
|
2
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
-
require
|
4
|
+
require 'ecoportal/api/graphql_version'
|
4
5
|
|
5
6
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name =
|
7
|
+
spec.name = 'ecoportal-api-graphql'
|
7
8
|
spec.version = Ecoportal::API::GRAPQL_VERSION
|
8
|
-
spec.authors = [
|
9
|
-
spec.email = [
|
9
|
+
spec.authors = ['Oscar Segura']
|
10
|
+
spec.email = ['oscar@ecoportal.co.nz']
|
10
11
|
|
11
|
-
spec.summary =
|
12
|
-
spec.homepage =
|
12
|
+
spec.summary = 'A collection of helpers for interacting with the ecoPortal GraphQL API'
|
13
|
+
spec.homepage = 'https://www.ecoportal.com'
|
13
14
|
spec.licenses = %w[MIT]
|
14
15
|
|
15
16
|
spec.metadata['rubygems_mfa_required'] = 'true'
|
@@ -19,19 +20,21 @@ Gem::Specification.new do |spec|
|
|
19
20
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
20
21
|
f.match(%r{^(test|spec|features)/})
|
21
22
|
end
|
22
|
-
spec.bindir =
|
23
|
+
spec.bindir = 'exe'
|
23
24
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
|
-
spec.require_paths = [
|
25
|
-
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
29
|
-
spec.add_development_dependency
|
30
|
-
spec.add_development_dependency
|
31
|
-
spec.add_development_dependency
|
32
|
-
spec.add_development_dependency
|
33
|
-
|
34
|
-
spec.add_dependency 'ecoportal-api', '~> 0.10',
|
35
|
-
spec.add_dependency 'ecoportal-api-v2', '~> 2.0',
|
25
|
+
spec.require_paths = ['lib']
|
26
|
+
|
27
|
+
spec.add_development_dependency 'pry', '>= 0.14'
|
28
|
+
spec.add_development_dependency 'rake', '>= 13.0.3', '< 14'
|
29
|
+
spec.add_development_dependency 'redcarpet', '>= 3.6.0', '< 4'
|
30
|
+
spec.add_development_dependency 'rspec', '>= 3.12.0', '< 4'
|
31
|
+
spec.add_development_dependency 'rubocop', '~> 1'
|
32
|
+
spec.add_development_dependency 'rubocop-rake', '~> 0'
|
33
|
+
spec.add_development_dependency 'yard', '>= 0.9.34', '< 1'
|
34
|
+
|
35
|
+
spec.add_dependency 'ecoportal-api', '~> 0.10', '>= 0.10.8'
|
36
|
+
spec.add_dependency 'ecoportal-api-v2', '~> 2.0', '>= 2.0.15'
|
36
37
|
spec.add_dependency 'graphlient', '>= 0.8.0', '< 0.9'
|
37
38
|
end
|
39
|
+
|
40
|
+
# rubocop:enable Gemspec/DevelopmentDependencies
|
@@ -3,7 +3,7 @@ module Ecoportal
|
|
3
3
|
module Common
|
4
4
|
module GraphQL
|
5
5
|
module AuthService
|
6
|
-
DEFAULT_SERVER =
|
6
|
+
DEFAULT_SERVER = 'live.ecoportal.com'.freeze
|
7
7
|
TOKEN_AUTORENEW = 90 # minutes
|
8
8
|
|
9
9
|
module InstanceMethods
|
@@ -11,14 +11,14 @@ module Ecoportal
|
|
11
11
|
session_token_data(host: host, version: version).then do |body|
|
12
12
|
next unless body
|
13
13
|
|
14
|
-
if auto_renew && token_renew?(body[
|
14
|
+
if auto_renew && token_renew?(body['expires_in'])
|
15
15
|
session_token_renewed(
|
16
16
|
host: host,
|
17
17
|
version: version,
|
18
|
-
refresh_token: body[
|
18
|
+
refresh_token: body['refresh_token']
|
19
19
|
)
|
20
20
|
else
|
21
|
-
body[
|
21
|
+
body['access_token']
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -26,7 +26,7 @@ module Ecoportal
|
|
26
26
|
def session_token_renewed(host: server, version: nil, refresh_token: nil)
|
27
27
|
unless refresh_token
|
28
28
|
return unless (body = session_token_data(host: host, version: version))
|
29
|
-
return unless (refresh_token = body[
|
29
|
+
return unless (refresh_token = body['resfresh_token'])
|
30
30
|
end
|
31
31
|
|
32
32
|
session_refresh_token_data(
|
@@ -34,7 +34,7 @@ module Ecoportal
|
|
34
34
|
version: version,
|
35
35
|
refresh_token: refresh_token
|
36
36
|
).then do |bdy|
|
37
|
-
bdy[
|
37
|
+
bdy['access_token'] if bdy
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -42,11 +42,11 @@ module Ecoportal
|
|
42
42
|
|
43
43
|
def session_token_data(host: server, version: nil)
|
44
44
|
http_client(host: host, version: version).post(
|
45
|
-
|
45
|
+
'/oauth/token',
|
46
46
|
data: {
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
'grant_type' => 'password',
|
48
|
+
'email' => user_email,
|
49
|
+
'password' => user_pass
|
50
50
|
}
|
51
51
|
).then do |response|
|
52
52
|
next response.body if response.success?
|
@@ -55,10 +55,10 @@ module Ecoportal
|
|
55
55
|
|
56
56
|
def session_refresh_token_data(refresh_token:, host: server, version: nil)
|
57
57
|
http_client(host: host, version: version).post(
|
58
|
-
|
58
|
+
'/oauth/token',
|
59
59
|
data: {
|
60
|
-
|
61
|
-
|
60
|
+
'grant_type' => 'refresh_token',
|
61
|
+
'refresh_token' => refresh_token
|
62
62
|
}
|
63
63
|
).then do |response|
|
64
64
|
next response.body if response.success?
|
@@ -77,11 +77,11 @@ module Ecoportal
|
|
77
77
|
end
|
78
78
|
|
79
79
|
def user_email
|
80
|
-
@user_email || fetch_env_required(
|
80
|
+
@user_email || fetch_env_required('USER_EMAIL')
|
81
81
|
end
|
82
82
|
|
83
83
|
def user_pass
|
84
|
-
@user_pass || fetch_env_required(
|
84
|
+
@user_pass || fetch_env_required('USER_PASS')
|
85
85
|
end
|
86
86
|
|
87
87
|
def server(default = DEFAULT_SERVER)
|
@@ -7,7 +7,10 @@ module Ecoportal
|
|
7
7
|
def becomes(klass)
|
8
8
|
klass.new.tap do |becoming|
|
9
9
|
instance_variables.each do |var|
|
10
|
-
becoming.instance_variable_set(
|
10
|
+
becoming.instance_variable_set(
|
11
|
+
var,
|
12
|
+
instance_variable_get(var)
|
13
|
+
)
|
11
14
|
end
|
12
15
|
end
|
13
16
|
end
|
@@ -23,11 +26,11 @@ module Ecoportal
|
|
23
26
|
def const?(value)
|
24
27
|
begin
|
25
28
|
const_get(value)
|
26
|
-
rescue NameError
|
29
|
+
rescue NameError
|
27
30
|
return false
|
28
31
|
end
|
29
32
|
true
|
30
|
-
end
|
33
|
+
end
|
31
34
|
end
|
32
35
|
|
33
36
|
class << self
|
@@ -4,48 +4,32 @@ module Ecoportal
|
|
4
4
|
module GraphQL
|
5
5
|
module HashHelpers
|
6
6
|
module InstanceMethods
|
7
|
-
def transform_keys_deep(value, &block)
|
8
|
-
case value
|
9
|
-
when Hash
|
10
|
-
value.dup.each_with_object({}) do |(k, v), out|
|
11
|
-
k_val = block_given?? yield(k) : k
|
12
|
-
out[k_val] = keys_to_sym_deep(v)
|
13
|
-
end
|
14
|
-
when Enumerable
|
15
|
-
value.map {|v| keys_to_sym_deep(v)}
|
16
|
-
else
|
17
|
-
value
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
7
|
def keys_to_sym_deep(value)
|
22
|
-
|
8
|
+
transform_keys_deep(value, &:to_sym)
|
23
9
|
end
|
24
10
|
|
25
11
|
def keys_to_s_deep(value)
|
26
|
-
transform_keys_deep(value
|
12
|
+
transform_keys_deep(value, &:to_s)
|
27
13
|
end
|
28
14
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
value.dup.each_with_object({}) do |(k, v), out|
|
35
|
-
next unless v || !target.include?(k)
|
36
|
-
out[k] = remove_nil_keys_deep(v, target: target)
|
37
|
-
end
|
38
|
-
when Enumerable
|
39
|
-
value.map {|v| remove_nil_keys_deep(v, target: target)}
|
40
|
-
else
|
41
|
-
value
|
15
|
+
def except_keys(value, *keys)
|
16
|
+
return value unless value.is_a?(Hash)
|
17
|
+
|
18
|
+
deep_dup(value).tap do |out|
|
19
|
+
keys.each {|key| out.delete(key)}
|
42
20
|
end
|
43
21
|
end
|
44
22
|
|
23
|
+
# Targetted removal of keys in `target` that are `nil`
|
24
|
+
def remove_nil_keys_deep(value, target: [])
|
25
|
+
remove_keys_deep_if(value, target: target, &:nil?)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Based on Rails support.
|
45
29
|
def deep_dup(data)
|
46
30
|
case data
|
47
31
|
when Hash
|
48
|
-
data.each_with_object({}) do |(k,v), copy|
|
32
|
+
data.each_with_object({}) do |(k, v), copy|
|
49
33
|
if k.is_a?(::String) || k.is_a?(::Symbol)
|
50
34
|
copy[k] = deep_dup(v)
|
51
35
|
else
|
@@ -59,6 +43,52 @@ module Ecoportal
|
|
59
43
|
data.dup
|
60
44
|
end
|
61
45
|
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# Iterator
|
50
|
+
# @param value [Variadic]
|
51
|
+
# @return [value.class]
|
52
|
+
def transform_keys_deep(value, &block)
|
53
|
+
case value
|
54
|
+
when Hash
|
55
|
+
value.dup.each_with_object({}) do |(k, v), out|
|
56
|
+
k_val = block_given?? yield(k) : k
|
57
|
+
out[k_val] = transform_keys_deep(v, &block)
|
58
|
+
end
|
59
|
+
when Enumerable
|
60
|
+
value.map {|v| transform_keys_deep(v, &block)}
|
61
|
+
else
|
62
|
+
value
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Targetted removal of keys in `target` that meet
|
67
|
+
# the `block` condition.
|
68
|
+
# @param value [Variadic]
|
69
|
+
# @param target [Array<String>, Array<Symbol>] the target
|
70
|
+
# `keys` to yield `block` onto.
|
71
|
+
# @return [value.class]
|
72
|
+
def remove_keys_deep_if(value, target: [], &block)
|
73
|
+
msg = 'Expected block. None given.'
|
74
|
+
raise ArgumentError, msg unless block_given?
|
75
|
+
|
76
|
+
target = [target].flatten.compact
|
77
|
+
return value if target.empty?
|
78
|
+
|
79
|
+
case value
|
80
|
+
when Hash
|
81
|
+
value.dup.each_with_object({}) do |(k, v), out|
|
82
|
+
next if yield(v) && target.include?(k) # skip
|
83
|
+
|
84
|
+
out[k] = remove_nil_keys_deep(v, target: target, &block)
|
85
|
+
end
|
86
|
+
when Enumerable
|
87
|
+
value.map {|v| remove_nil_keys_deep(v, target: target, &block)}
|
88
|
+
else
|
89
|
+
value
|
90
|
+
end
|
91
|
+
end
|
62
92
|
end
|
63
93
|
|
64
94
|
module ClassMethods
|
@@ -9,26 +9,20 @@ module Ecoportal
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def protocol(host)
|
12
|
-
host.match(/^localhost|^127\.0\.0\.1/)?
|
12
|
+
host.match(/^localhost|^127\.0\.0\.1/)? 'http' : 'https'
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
attr_reader :host, :version
|
17
17
|
|
18
18
|
def initialize(
|
19
|
-
api_key:
|
20
|
-
version:
|
21
|
-
host:
|
22
|
-
logger:
|
23
|
-
deep_logging:
|
19
|
+
api_key: nil,
|
20
|
+
version: nil,
|
21
|
+
host: 'live.ecoportal.com',
|
22
|
+
logger: ::Logger.new(IO::NULL),
|
23
|
+
deep_logging: false
|
24
24
|
)
|
25
|
-
super
|
26
|
-
api_key: api_key,
|
27
|
-
version: version,
|
28
|
-
host: host,
|
29
|
-
logger: logger,
|
30
|
-
deep_logging: deep_logging
|
31
|
-
)
|
25
|
+
super
|
32
26
|
end
|
33
27
|
|
34
28
|
def refresh_key(value)
|
@@ -43,12 +37,12 @@ module Ecoportal
|
|
43
37
|
case @version
|
44
38
|
when NilClass
|
45
39
|
HTTP.accept(:json)
|
46
|
-
when
|
47
|
-
HTTP.headers(
|
48
|
-
when
|
49
|
-
HTTP.headers(
|
40
|
+
when 'v2'
|
41
|
+
HTTP.headers('X-ECOPORTAL-API-KEY' => key_token).accept(:json)
|
42
|
+
when 'graphql'
|
43
|
+
HTTP.headers('Authorization' => "Bearer #{key_token}").accept(:json)
|
50
44
|
else
|
51
|
-
HTTP.headers(
|
45
|
+
HTTP.headers('X-ApiKey' => key_token).accept(:json)
|
52
46
|
end
|
53
47
|
end
|
54
48
|
|
@@ -79,10 +73,10 @@ module Ecoportal
|
|
79
73
|
|
80
74
|
def key_token
|
81
75
|
if @api_key.nil? || @api_key.match(/\A\W*\z/)
|
82
|
-
if (version ==
|
76
|
+
if (version == 'v0') && (key = ENV['ORG_INT_KEY'])
|
83
77
|
key
|
84
|
-
|
85
|
-
puts
|
78
|
+
elsif !version.nil?
|
79
|
+
puts 'Api-key missing!'
|
86
80
|
end
|
87
81
|
else
|
88
82
|
@api_key
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Ecoportal
|
2
|
+
module API
|
3
|
+
module Common
|
4
|
+
module GraphQL
|
5
|
+
class Model
|
6
|
+
module AsInput
|
7
|
+
class << self
|
8
|
+
def included(base)
|
9
|
+
super
|
10
|
+
base.send(:include, Model::Diffable)
|
11
|
+
base.extend ClassMethods
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
def as_input(hash, clientMutationId: '')
|
17
|
+
hash_input = Ecoportal::API::Common::GraphQL::HashHelpers.
|
18
|
+
keys_to_sym_deep(hash)
|
19
|
+
|
20
|
+
hash_input.merge!(clientMutationId: clientMutationId)
|
21
|
+
|
22
|
+
Ecoportal::API::Common::GraphQL::HashHelpers.
|
23
|
+
remove_nil_keys_deep(hash_input, target: :id)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# INSTANCE METHODS
|
28
|
+
|
29
|
+
def as_input(clientMutationId: '')
|
30
|
+
self.class.as_input(
|
31
|
+
as_update,
|
32
|
+
clientMutationId: clientMutationId
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# rubocop:disable Naming/MethodParameterName
|
2
|
+
|
3
|
+
module Ecoportal
|
4
|
+
module API
|
5
|
+
module Common
|
6
|
+
module GraphQL
|
7
|
+
class Model
|
8
|
+
module Diffable
|
9
|
+
module HashDiff
|
10
|
+
class << self
|
11
|
+
def included(base)
|
12
|
+
super
|
13
|
+
base.extend ClassMethods
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
# @todo: refactor to only reach the current level
|
19
|
+
# @note the aim is to delegate `hash_diff` to the specific classes
|
20
|
+
# of the model... bulding the payload/input_base in a cascaded
|
21
|
+
# way (rather than in a one-off way from the top alone).
|
22
|
+
def hash_diff(a, b, ignore: [])
|
23
|
+
case a
|
24
|
+
when Hash
|
25
|
+
{}.tap do |diffed|
|
26
|
+
a.each do |key, a_value|
|
27
|
+
b_value = b && b[key]
|
28
|
+
no_changes = (a_value == b_value) || ignore.include?(key)
|
29
|
+
next if !ID_KEYS.include?(key) && no_changes
|
30
|
+
|
31
|
+
diffed[key] = diff(a_value, b_value, ignore: ignore)
|
32
|
+
diffed.delete(key) if diffed[key] == {}
|
33
|
+
end
|
34
|
+
|
35
|
+
# All keys are IDs, so it's actually blank
|
36
|
+
return {} if (diffed.keys - ID_KEYS).empty?
|
37
|
+
end
|
38
|
+
when Array
|
39
|
+
return a unless b.is_a?(Array) && a.length == b.length
|
40
|
+
|
41
|
+
a.map.with_index do |a_value, idx|
|
42
|
+
b_value = b[idx]
|
43
|
+
diff(a_value, b_value, ignore: ignore)
|
44
|
+
end.reject do |el|
|
45
|
+
el == {}
|
46
|
+
end
|
47
|
+
else
|
48
|
+
a
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# rubocop:enable Naming/MethodParameterName
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'ecoportal/api/common/graphql/model/diffable/hash_diff'
|
2
|
+
module Ecoportal
|
3
|
+
module API
|
4
|
+
module Common
|
5
|
+
module GraphQL
|
6
|
+
class Model
|
7
|
+
module Diffable
|
8
|
+
class << self
|
9
|
+
def included(base)
|
10
|
+
super
|
11
|
+
base.send(:include, HashDiff)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# INSTANCE METHODS
|
16
|
+
|
17
|
+
def as_update(ref = :last, ignore: [])
|
18
|
+
new_doc = as_json
|
19
|
+
ref_doc = ref == :total ? initial_doc : original_doc
|
20
|
+
|
21
|
+
self.class.hash_diff(
|
22
|
+
new_doc,
|
23
|
+
ref_doc,
|
24
|
+
ignore: ignore
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Ecoportal
|
2
|
+
module API
|
3
|
+
module Common
|
4
|
+
module GraphQL
|
5
|
+
class Model < Ecoportal::API::Common::Content::DoubleModel
|
6
|
+
require 'ecoportal/api/common/graphql/model/diffable'
|
7
|
+
require 'ecoportal/api/common/graphql/model/as_input'
|
8
|
+
|
9
|
+
include Ecoportal::API::Common::GraphQL::ClassHelpers
|
10
|
+
|
11
|
+
include Diffable
|
12
|
+
include AsInput
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -15,7 +15,7 @@ module Ecoportal
|
|
15
15
|
# @return [Connection::$1, $1]
|
16
16
|
def query(method, query_klass:, subpath: [])
|
17
17
|
method = method.to_sym
|
18
|
-
class_method = "#{method}_query_class"
|
18
|
+
class_method = :"#{method}_query_class"
|
19
19
|
|
20
20
|
define_method(method) do |**kargs, &block|
|
21
21
|
if kargs.empty? && !block_given?
|
@@ -27,9 +27,12 @@ module Ecoportal
|
|
27
27
|
|
28
28
|
define_method(class_method) do
|
29
29
|
final_path = path + [subpath].flatten.compact
|
30
|
+
|
30
31
|
resolve_class(query_klass).tap do |klass|
|
31
32
|
unless klass <= Ecoportal::API::GraphQL::Logic::BaseQuery
|
32
|
-
|
33
|
+
msg = "Expected query_klass to be of type Ecoportal::API::GraphQL::Logic::BaseQuery. "
|
34
|
+
msg << "Given: #{klass}"
|
35
|
+
raise msg
|
33
36
|
end
|
34
37
|
end.new(client, base_path: final_path)
|
35
38
|
end
|
@@ -11,7 +11,6 @@ require 'ecoportal/api/common/graphql/http_client'
|
|
11
11
|
require 'ecoportal/api/common/graphql/auth_service'
|
12
12
|
require 'ecoportal/api/common/graphql/client'
|
13
13
|
require 'ecoportal/api/common/graphql/class_helpers'
|
14
|
-
require 'ecoportal/api/common/graphql/doc_helpers'
|
15
14
|
require 'ecoportal/api/common/graphql/hash_helpers'
|
16
|
-
require 'ecoportal/api/common/graphql/
|
15
|
+
require 'ecoportal/api/common/graphql/model'
|
17
16
|
require 'ecoportal/api/common/graphql/query_integration'
|