graphiti-activegraph 0.2.0 → 1.1.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/.github/workflows/specs.yml +17 -3
- data/.gitignore +3 -0
- data/CHANGELOG.md +22 -67
- data/CHANGELOG_PRE_1.0.0.md +70 -0
- data/README.md +81 -0
- data/graphiti-activegraph.gemspec +4 -0
- data/lib/graphiti/active_graph/adapters/active_graph.rb +1 -1
- data/lib/graphiti/active_graph/extensions/context.rb +17 -0
- data/lib/graphiti/active_graph/extensions/resources/authorizationable.rb +29 -0
- data/lib/graphiti/active_graph/extensions/resources/payload_combinable.rb +24 -0
- data/lib/graphiti/active_graph/extensions/resources/preloadable.rb +19 -0
- data/lib/graphiti/active_graph/extensions/resources/rel.rb +19 -0
- data/lib/graphiti/active_graph/jsonapi_ext/include_directive.rb +66 -0
- data/lib/graphiti/active_graph/query.rb +27 -0
- data/lib/graphiti/active_graph/resource.rb +45 -20
- data/lib/graphiti/active_graph/{resource → resources}/interface.rb +1 -1
- data/lib/graphiti/active_graph/{resource → resources}/persistence.rb +1 -1
- data/lib/graphiti/active_graph/scope.rb +28 -0
- data/lib/graphiti/active_graph/scoping/association_eager_load.rb +34 -0
- data/lib/graphiti/active_graph/scoping/include.rb +43 -0
- data/lib/graphiti/active_graph/scoping/internal/include_normalizer.rb +82 -0
- data/lib/graphiti/active_graph/scoping/internal/path_descriptor.rb +94 -0
- data/lib/graphiti/active_graph/scoping/internal/sort_normalizer.rb +54 -0
- data/lib/graphiti/active_graph/scoping/internal/sorting_aliases.rb +25 -0
- data/lib/graphiti/active_graph/scoping/internal/sparse_fields_eagerloading.rb +28 -0
- data/lib/graphiti/active_graph/util/parsers/rel_chain.rb +27 -0
- data/lib/graphiti/active_graph/util/transformers/relation_param.rb +56 -0
- data/lib/graphiti/active_graph/version.rb +1 -1
- data/lib/graphiti/sidepost_configuration.rb +1 -2
- data/lib/graphiti-activegraph.rb +6 -4
- metadata +79 -9
@@ -0,0 +1,28 @@
|
|
1
|
+
module Graphiti
|
2
|
+
module ActiveGraph
|
3
|
+
class Scope < Graphiti::Scope
|
4
|
+
def non_applicable_for_unpaginated
|
5
|
+
%i[association_eagerload]
|
6
|
+
end
|
7
|
+
|
8
|
+
def apply_scoping(scope, opts)
|
9
|
+
opts[:query_obj] = @query
|
10
|
+
super
|
11
|
+
|
12
|
+
append_scopings(opts) unless @resource.remote?
|
13
|
+
@object
|
14
|
+
end
|
15
|
+
|
16
|
+
def append_scopings(opts)
|
17
|
+
add_scoping(:include, Scoping::Include, opts)
|
18
|
+
add_scoping(:association_eagerload, Scoping::AssociationEagerLoad, opts)
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_scoping(key, scoping_class, opts, _ = {})
|
22
|
+
@object = scoping_class.new(@resource, @query.hash, @object, opts).apply
|
23
|
+
return if non_applicable_for_unpaginated.include?(key)
|
24
|
+
@unpaginated_object = scoping_class.new(@resource, @query.hash, @unpaginated_object, opts.merge(unpaginated_query: true)).apply
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Graphiti::ActiveGraph
|
2
|
+
module Scoping
|
3
|
+
class AssociationEagerLoad < Graphiti::Scoping::Base
|
4
|
+
def custom_scope
|
5
|
+
nil
|
6
|
+
end
|
7
|
+
|
8
|
+
def apply_standard_scope
|
9
|
+
return @scope unless eagerload_associations?
|
10
|
+
if (ids = @scope.collect(&:id)).present?
|
11
|
+
@opts[:query_obj].include_hash.each_key do |key|
|
12
|
+
eagerload_association(key, ids)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
@scope
|
16
|
+
end
|
17
|
+
|
18
|
+
def eagerload_associations?
|
19
|
+
@opts[:query_obj].include_hash.present? && @resource.model.include?(ActiveGraph::Node) &&
|
20
|
+
@resource.model.associations_to_eagerload.present?
|
21
|
+
end
|
22
|
+
|
23
|
+
def eagerload_association(key, ids)
|
24
|
+
return unless @resource.model.eagerload_association?(key)
|
25
|
+
nodes = @resource.model.association_nodes(key, ids, @resource.context.send(:association_filter_params))
|
26
|
+
@scope.each { |node| node.send("#{key}=", nodes[node.id] || nil_or_empty(key)) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def nil_or_empty(key)
|
30
|
+
@resource.class.config[:sideloads][key].type == :has_one ? nil : []
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Graphiti::ActiveGraph
|
2
|
+
module Scoping
|
3
|
+
# Handles sideloading via scoping instead of sideloading query as in original jsonapi_suite
|
4
|
+
# This avoids extra queries for fetching sideload
|
5
|
+
class Include < Graphiti::Scoping::Base
|
6
|
+
include Internal::SortingAliases
|
7
|
+
|
8
|
+
def custom_scope
|
9
|
+
nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def apply_standard_scope
|
13
|
+
return scope if normalized_includes.empty?
|
14
|
+
self.scope = resource.handle_includes(scope, normalized_includes, normalized_sorts,
|
15
|
+
with_vars: with_vars_for_sort, paginate: paginate?)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_accessor :scope
|
21
|
+
|
22
|
+
def query
|
23
|
+
@opts[:query_obj]
|
24
|
+
end
|
25
|
+
|
26
|
+
def paginate?
|
27
|
+
Graphiti::Scoping::Paginate.new(@resource, @query_hash, scope, @opts).apply?
|
28
|
+
end
|
29
|
+
|
30
|
+
def normalized_sorts
|
31
|
+
Internal::SortNormalizer.new(scope).normalize(normalized_includes, query.sorts, query.deep_sort)
|
32
|
+
end
|
33
|
+
|
34
|
+
def include_normalizer
|
35
|
+
Internal::IncludeNormalizer
|
36
|
+
end
|
37
|
+
|
38
|
+
def normalized_includes
|
39
|
+
@normalized_includes ||= include_normalizer.new(resource.class, scope, query_hash[:fields]).normalize(query.include_hash)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Graphiti::ActiveGraph
|
2
|
+
module Scoping
|
3
|
+
module Internal
|
4
|
+
class IncludeNormalizer
|
5
|
+
include SparseFieldsEagerloading
|
6
|
+
|
7
|
+
def initialize(resource_class, scope, fields)
|
8
|
+
@scope = scope
|
9
|
+
@resource_class = resource_class
|
10
|
+
@fields = fields
|
11
|
+
end
|
12
|
+
|
13
|
+
def normalize(include_hash)
|
14
|
+
normalize_includes(@scope, include_hash, @resource_class)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def normalize_includes(scope, include_hash, resource_class)
|
20
|
+
includes_array = include_hash.map do |key, value|
|
21
|
+
normalize_include(scope, key, value, resource_class)
|
22
|
+
end
|
23
|
+
add_relationships_from_sparse_fields(scope, includes_array)
|
24
|
+
deep_merge_hashes(includes_array.compact).to_h
|
25
|
+
end
|
26
|
+
|
27
|
+
def deep_merge_hashes(includes_array)
|
28
|
+
includes_array.each_with_object({}) do |(key, value), mapping|
|
29
|
+
mapping[key] = mapping[key] ? mapping[key].deep_merge(value) : value
|
30
|
+
end.to_a
|
31
|
+
end
|
32
|
+
|
33
|
+
def normalize_include(scope, key, value, resource_class)
|
34
|
+
rel_name = rel_name_sym(key)
|
35
|
+
|
36
|
+
if scope.associations.key?(rel_name)
|
37
|
+
[key, normalize_includes(scope.send(rel_name), value, find_resource_class(resource_class, rel_name, scope))]
|
38
|
+
elsif (custom_eagerload = resource_class&.custom_eagerload(rel_name))
|
39
|
+
handle_custom_eagerload(scope, custom_eagerload)
|
40
|
+
else
|
41
|
+
include_for_rel(scope, rel_name, value, resource_class)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def handle_custom_eagerload(_scope, custom_eagerload)
|
46
|
+
JSONAPI::IncludeDirective.new(custom_eagerload).to_hash
|
47
|
+
end
|
48
|
+
|
49
|
+
def include_for_rel(scope, key, value, resource_class)
|
50
|
+
return unless association = PathDescriptor.association_for_relationship(scope.associations, rel_name: key.to_s)
|
51
|
+
|
52
|
+
limit_part = Graphiti::ActiveGraph::Util::Transformers::RelationParam.new(value.keys.first).rel_limit
|
53
|
+
association_name = "#{limit_part}#{association.first}".to_sym
|
54
|
+
normalize_include(scope, association_name, next_non_rel_value(value), resource_class_by_rel(resource_class, association, key, scope))
|
55
|
+
end
|
56
|
+
|
57
|
+
def find_resource_class(resource_class, rel_name, scope)
|
58
|
+
target_class_name = scope.associations[rel_name]&.target_class&.model_name
|
59
|
+
|
60
|
+
resource_class&.sideload_resource_class(rel_name) ||
|
61
|
+
resource_class&.sideload_resource_class(target_class_name&.singular&.to_sym)
|
62
|
+
end
|
63
|
+
|
64
|
+
def resource_class_by_rel(resource_class, association, key, scope)
|
65
|
+
# in case of rel resource, for finding custom_eagerload defination
|
66
|
+
# if current resourceClass defination has direct association defined with opposite node of relResource
|
67
|
+
# then use current resourceClass, (giving direct resourceClass more preference than relResourceClass)
|
68
|
+
# else use relResourceClass
|
69
|
+
find_resource_class(resource_class, association.first, scope) ? resource_class : resource_class&.sideload_resource_class(rel_name_sym(key))
|
70
|
+
end
|
71
|
+
|
72
|
+
def rel_name_sym(key)
|
73
|
+
Graphiti::ActiveGraph::Util::Transformers::RelationParam.new(key).rel_name_sym
|
74
|
+
end
|
75
|
+
|
76
|
+
def next_non_rel_value(value)
|
77
|
+
value.values.first || {}
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Graphiti::ActiveGraph
|
2
|
+
module Scoping
|
3
|
+
module Internal
|
4
|
+
# Determine valid paths specified in filter and sort API params and normalize them for neo4j
|
5
|
+
class PathDescriptor
|
6
|
+
attr_reader :scope, :path, :attribute, :rel
|
7
|
+
delegate :relationship_class, to: :rel, allow_nil: true
|
8
|
+
|
9
|
+
def initialize(scope, rel)
|
10
|
+
self.scope = scope
|
11
|
+
self.path = []
|
12
|
+
self.attribute = :id
|
13
|
+
self.rel = rel
|
14
|
+
@has_next = true
|
15
|
+
end
|
16
|
+
|
17
|
+
def next?
|
18
|
+
@has_next
|
19
|
+
end
|
20
|
+
|
21
|
+
def increment(key)
|
22
|
+
raise Exception, 'no continuation on path possible' unless next?
|
23
|
+
if rel
|
24
|
+
increment_from_cache(key)
|
25
|
+
else
|
26
|
+
increment_from_scope(key)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def declared_property
|
31
|
+
(relationship_class || scope).attributes[attribute]
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.parse(scope, path, rel = nil)
|
35
|
+
path_desc = new(scope, rel)
|
36
|
+
path_desc.increment(path.shift) while path_desc.next? && path.present?
|
37
|
+
path_desc if path.empty?
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.association_for_relationship(associations, key)
|
41
|
+
key_class_name = key[:rel_name].classify
|
42
|
+
key_assoc_name = key[:rel_name].gsub('_rel', '')
|
43
|
+
assocs = associations.find_all { |_, value| value.relationship_class_name == key_class_name || value.name.to_s == key_assoc_name }
|
44
|
+
assocs.size == 1 ? assocs.first : nil
|
45
|
+
end
|
46
|
+
|
47
|
+
def path_relationships
|
48
|
+
path.map { |elm| elm[:rel_name].to_sym }
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
attr_writer :scope, :path, :attribute, :rel
|
54
|
+
|
55
|
+
def increment_from_cache(key)
|
56
|
+
rel_name = key[:rel_name]
|
57
|
+
if rel.target_class_names.map(&:demodulize).map(&:downcase).include?(rel_name)
|
58
|
+
self.rel = nil
|
59
|
+
else
|
60
|
+
final_attribute(rel_name)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def increment_from_scope(key)
|
65
|
+
associations = scope.associations
|
66
|
+
if associations.key?(key[:rel_name].to_sym)
|
67
|
+
advance(key)
|
68
|
+
else
|
69
|
+
increment_from_rel(self.class.association_for_relationship(associations, key), key)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def increment_from_rel(entry, key)
|
74
|
+
if entry
|
75
|
+
advance(rel_name: entry.first.to_s)
|
76
|
+
self.rel = entry.last
|
77
|
+
else
|
78
|
+
final_attribute(key[:rel_name])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def advance(key)
|
83
|
+
path << key
|
84
|
+
self.scope = scope.send(key[:rel_name], rel_length: key[:rel_length])
|
85
|
+
end
|
86
|
+
|
87
|
+
def final_attribute(key)
|
88
|
+
self.attribute = key
|
89
|
+
@has_next = false
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Graphiti::ActiveGraph
|
2
|
+
module Scoping
|
3
|
+
module Internal
|
4
|
+
class SortNormalizer
|
5
|
+
attr_reader :scope
|
6
|
+
|
7
|
+
def initialize(scope)
|
8
|
+
@scope = scope
|
9
|
+
end
|
10
|
+
|
11
|
+
def normalize(includes_hash, sorts, deep_sorts)
|
12
|
+
normalized_deep_sort = normalize_deep_sort(includes_hash, deep_sorts || [])
|
13
|
+
normalized_base_sort = normalize_base_sort(sorts)
|
14
|
+
normalized_deep_sort.merge(normalized_base_sort)
|
15
|
+
end
|
16
|
+
|
17
|
+
def normalize_base_sort(sorts)
|
18
|
+
sorts.present? ? { '' => sorts.map { |sort| "#{sort.keys.first} #{sort.values.first}" } } : {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def normalize_deep_sort(includes_hash, sorts)
|
22
|
+
sorts
|
23
|
+
.map { |sort| sort(includes_hash, sort) }
|
24
|
+
.compact
|
25
|
+
.group_by(&:first)
|
26
|
+
.map { |key, value| combined_order_spec(key, value) }
|
27
|
+
.to_h
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def combined_order_spec(key, value)
|
33
|
+
[key.join('.'), value.map(&:last)]
|
34
|
+
end
|
35
|
+
|
36
|
+
def sort(includes_hash, sort)
|
37
|
+
path = sort.keys.first.map { |key| { rel_name: key.to_s } }
|
38
|
+
return nil unless (descriptor = PathDescriptor.parse(scope, path))
|
39
|
+
|
40
|
+
sort_spec(descriptor, sort.values.first) if valid_sort?(includes_hash.deep_dup, descriptor.path_relationships)
|
41
|
+
end
|
42
|
+
|
43
|
+
def valid_sort?(hash, rels)
|
44
|
+
rels.empty? || rels.all? { |rel| hash = hash[rel] || hash[:"#{rel.to_s + '*'}"] }
|
45
|
+
end
|
46
|
+
|
47
|
+
def sort_spec(descriptor, direction)
|
48
|
+
sort_attr = [descriptor.attribute, direction].join(' ')
|
49
|
+
[descriptor.path_relationships, descriptor.rel.present? ? { rel: sort_attr } : sort_attr]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Graphiti::ActiveGraph
|
2
|
+
module Scoping
|
3
|
+
module Internal
|
4
|
+
# Carrying forward valriables from neo4j procedure call to sort with include
|
5
|
+
module SortingAliases
|
6
|
+
def with_vars_for_sort
|
7
|
+
[] unless add_extra_vars_to_query?
|
8
|
+
(deep_sort_keys + sort_keys) & resource.extra_attributes.keys
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_extra_vars_to_query?
|
12
|
+
resource.extra_attributes.present? && (query.sorts.present? || query.deep_sort.present?)
|
13
|
+
end
|
14
|
+
|
15
|
+
def deep_sort_keys
|
16
|
+
(query.deep_sort || []).collect { |sort| sort.keys.first.first }
|
17
|
+
end
|
18
|
+
|
19
|
+
def sort_keys
|
20
|
+
query.sorts.collect(&:keys).flatten
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Graphiti::ActiveGraph
|
2
|
+
module Scoping
|
3
|
+
module Internal
|
4
|
+
module SparseFieldsEagerloading
|
5
|
+
private
|
6
|
+
|
7
|
+
def add_relationships_from_sparse_fields(scope, includes_array)
|
8
|
+
return if @fields.blank?
|
9
|
+
|
10
|
+
related_fields(scope.model).each { |field_name| includes_array << process_field(field_name, scope) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def process_field(field_name, _scope)
|
14
|
+
field_name
|
15
|
+
end
|
16
|
+
|
17
|
+
def resource_name_of(model)
|
18
|
+
model.model_name.plural.to_sym
|
19
|
+
end
|
20
|
+
|
21
|
+
def related_fields(model)
|
22
|
+
attr_and_rel_fields = @fields[resource_name_of(model)] || []
|
23
|
+
attr_and_rel_fields.select { |field_name| model.associations[field_name] }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Graphiti::ActiveGraph
|
2
|
+
module Util
|
3
|
+
module Parsers
|
4
|
+
class RelChain < Parslet::Parser
|
5
|
+
VAR_CHAR = 'a-z_'
|
6
|
+
|
7
|
+
rule(:asterisk) { str('*') }
|
8
|
+
rule(:range) { str('..') }
|
9
|
+
rule(:dot) { str('.') }
|
10
|
+
rule(:none) { str('') }
|
11
|
+
rule(:number) { match('[\d]').repeat(1) }
|
12
|
+
rule(:number?) { number | none }
|
13
|
+
rule(:identifier) { match("[#{VAR_CHAR}]") >> match("[#{VAR_CHAR}0-9]").repeat(0) }
|
14
|
+
rule(:identifier?) { identifier | none }
|
15
|
+
rule(:rel_name) { identifier?.as(:rel_name) }
|
16
|
+
rule(:length) { asterisk.as(:ast) >> number?.maybe.as(:min) >> range.as(:range).maybe >> number?.maybe.as(:max) }
|
17
|
+
rule(:rel) { rel_name >> length.maybe }
|
18
|
+
|
19
|
+
rule(:rel_chain) { rel >> (dot >> rel).repeat(0) }
|
20
|
+
root(:rel_chain)
|
21
|
+
|
22
|
+
rule(:limit) { number?.as(:limit_digit) >> asterisk.as(:limit_ast) }
|
23
|
+
rule(:rel_param_rule) { limit.maybe.as(:limit_part) >> rel_name >> length.maybe.as(:length_part) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Graphiti::ActiveGraph
|
2
|
+
module Util
|
3
|
+
module Transformers
|
4
|
+
class RelationParam
|
5
|
+
attr_reader :map
|
6
|
+
|
7
|
+
def initialize(relation_param_str)
|
8
|
+
@map = Graphiti::ActiveGraph::Util::Parsers::RelChain.new.rel_param_rule.parse(relation_param_str.to_s)
|
9
|
+
end
|
10
|
+
|
11
|
+
def split_rel_length(retain_rel_limit)
|
12
|
+
rel_name_part = if retain_rel_limit
|
13
|
+
(rel_limit || '') + rel_name
|
14
|
+
else
|
15
|
+
rel_name_sym
|
16
|
+
end
|
17
|
+
[rel_name_part.to_sym, rel_length_number]
|
18
|
+
end
|
19
|
+
|
20
|
+
def rel_name_n_length
|
21
|
+
"#{rel_name}#{rel_length}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def rel_limit(limit_part = nil)
|
25
|
+
join(limit_part || map[:limit_part])
|
26
|
+
end
|
27
|
+
|
28
|
+
def rel_limit_number
|
29
|
+
rel_limit(map[:limit_part]&.except(:limit_ast))
|
30
|
+
end
|
31
|
+
|
32
|
+
def rel_name
|
33
|
+
map[:rel_name].to_s
|
34
|
+
end
|
35
|
+
|
36
|
+
def rel_name_sym
|
37
|
+
rel_name.to_sym
|
38
|
+
end
|
39
|
+
|
40
|
+
def rel_length(length_part = nil)
|
41
|
+
join(length_part || map[:length_part])
|
42
|
+
end
|
43
|
+
|
44
|
+
def rel_length_number
|
45
|
+
rel_length(map[:length_part]&.except(:ast))
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def join(hash)
|
51
|
+
hash&.values&.map(&:to_s)&.join
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/graphiti-activegraph.rb
CHANGED
@@ -20,21 +20,23 @@ loader.ignore(File.expand_path('graphiti-activegraph.rb', __dir__))
|
|
20
20
|
loader.setup
|
21
21
|
|
22
22
|
Graphiti::Scoping::Filterable.prepend Graphiti::ActiveGraph::Scoping::Filterable
|
23
|
-
Graphiti::Resource::Persistence.prepend Graphiti::ActiveGraph::
|
24
|
-
Graphiti::Resource::Interface::ClassMethods.prepend Graphiti::ActiveGraph::
|
23
|
+
Graphiti::Resource::Persistence.prepend Graphiti::ActiveGraph::Resources::Persistence
|
24
|
+
Graphiti::Resource::Interface::ClassMethods.prepend Graphiti::ActiveGraph::Resources::Interface::ClassMethods
|
25
25
|
require 'graphiti'
|
26
26
|
Graphiti::Scoping::Filter.prepend Graphiti::ActiveGraph::Scoping::Filter
|
27
27
|
Graphiti::Util::SerializerRelationship.prepend Graphiti::ActiveGraph::Util::SerializerRelationship
|
28
28
|
Graphiti::Util::SerializerAttribute.prepend Graphiti::ActiveGraph::Util::SerializerAttribute
|
29
29
|
Graphiti::Util::RelationshipPayload.prepend Graphiti::ActiveGraph::Util::RelationshipPayload
|
30
30
|
Graphiti::Query.prepend Graphiti::ActiveGraph::Query
|
31
|
-
Graphiti::Resource.prepend Graphiti::ActiveGraph::ResourceInstanceMethods
|
32
|
-
Graphiti::Resource.extend Graphiti::ActiveGraph::Resource
|
33
31
|
Graphiti::ResourceProxy.prepend Graphiti::ActiveGraph::ResourceProxy
|
34
32
|
Graphiti::Runner.prepend Graphiti::ActiveGraph::Runner
|
35
33
|
Graphiti::Scope.prepend Graphiti::ActiveGraph::SideloadResolve
|
36
34
|
Graphiti::Configuration.include Graphiti::SidepostConfiguration
|
37
35
|
Graphiti::RequestValidators::Validator.prepend Graphiti::ActiveGraph::RequestValidators::Validator
|
38
36
|
|
37
|
+
unless RUBY_PLATFORM == 'java'
|
38
|
+
Graphiti.prepend Graphiti::ActiveGraph::Extensions::Context
|
39
|
+
end
|
40
|
+
|
39
41
|
# JSONAPI extensions
|
40
42
|
JSONAPI::Serializable::Resource.prepend Graphiti::ActiveGraph::JsonapiExt::Serializable::ResourceExt
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphiti-activegraph
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hardik Joshi
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date: 2025-
|
10
|
+
date: 2025-05-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: graphiti
|
@@ -38,6 +37,34 @@ dependencies:
|
|
38
37
|
- - ">="
|
39
38
|
- !ruby/object:Gem::Version
|
40
39
|
version: 12.0.0.beta.5
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: parslet
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 2.0.0
|
47
|
+
type: :runtime
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 2.0.0
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: activegraph-extensions
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 0.1.0
|
61
|
+
type: :runtime
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 0.1.0
|
41
68
|
- !ruby/object:Gem::Dependency
|
42
69
|
name: graphiti_spec_helpers
|
43
70
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +107,34 @@ dependencies:
|
|
80
107
|
- - ">="
|
81
108
|
- !ruby/object:Gem::Version
|
82
109
|
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: ffaker
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
type: :development
|
118
|
+
prerelease: false
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
- !ruby/object:Gem::Dependency
|
125
|
+
name: factory_bot_rails
|
126
|
+
requirement: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
type: :development
|
132
|
+
prerelease: false
|
133
|
+
version_requirements: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
83
138
|
- !ruby/object:Gem::Dependency
|
84
139
|
name: rake
|
85
140
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,7 +163,6 @@ dependencies:
|
|
108
163
|
- - ">="
|
109
164
|
- !ruby/object:Gem::Version
|
110
165
|
version: 3.9.0
|
111
|
-
description:
|
112
166
|
email:
|
113
167
|
- hardikjoshi1991@gmail.com
|
114
168
|
executables: []
|
@@ -119,8 +173,10 @@ files:
|
|
119
173
|
- ".gitignore"
|
120
174
|
- ".rspec"
|
121
175
|
- CHANGELOG.md
|
176
|
+
- CHANGELOG_PRE_1.0.0.md
|
122
177
|
- Gemfile
|
123
178
|
- LICENSE.txt
|
179
|
+
- README.md
|
124
180
|
- graphiti-activegraph.gemspec
|
125
181
|
- lib/graphiti-activegraph.rb
|
126
182
|
- lib/graphiti/active_graph/adapters/active_graph.rb
|
@@ -131,29 +187,44 @@ files:
|
|
131
187
|
- lib/graphiti/active_graph/adapters/active_graph/sideload.rb
|
132
188
|
- lib/graphiti/active_graph/concerns/path_relationships.rb
|
133
189
|
- lib/graphiti/active_graph/deserializer.rb
|
190
|
+
- lib/graphiti/active_graph/extensions/context.rb
|
134
191
|
- lib/graphiti/active_graph/extensions/grouping/params.rb
|
135
192
|
- lib/graphiti/active_graph/extensions/query_params.rb
|
193
|
+
- lib/graphiti/active_graph/extensions/resources/authorizationable.rb
|
194
|
+
- lib/graphiti/active_graph/extensions/resources/payload_combinable.rb
|
195
|
+
- lib/graphiti/active_graph/extensions/resources/preloadable.rb
|
196
|
+
- lib/graphiti/active_graph/extensions/resources/rel.rb
|
197
|
+
- lib/graphiti/active_graph/jsonapi_ext/include_directive.rb
|
136
198
|
- lib/graphiti/active_graph/jsonapi_ext/serializable/resource_ext.rb
|
137
199
|
- lib/graphiti/active_graph/query.rb
|
138
200
|
- lib/graphiti/active_graph/request_validators/validator.rb
|
139
201
|
- lib/graphiti/active_graph/resource.rb
|
140
|
-
- lib/graphiti/active_graph/resource/interface.rb
|
141
|
-
- lib/graphiti/active_graph/resource/persistence.rb
|
142
202
|
- lib/graphiti/active_graph/resource_proxy.rb
|
203
|
+
- lib/graphiti/active_graph/resources/interface.rb
|
204
|
+
- lib/graphiti/active_graph/resources/persistence.rb
|
143
205
|
- lib/graphiti/active_graph/runner.rb
|
206
|
+
- lib/graphiti/active_graph/scope.rb
|
207
|
+
- lib/graphiti/active_graph/scoping/association_eager_load.rb
|
144
208
|
- lib/graphiti/active_graph/scoping/filter.rb
|
145
209
|
- lib/graphiti/active_graph/scoping/filterable.rb
|
210
|
+
- lib/graphiti/active_graph/scoping/include.rb
|
211
|
+
- lib/graphiti/active_graph/scoping/internal/include_normalizer.rb
|
212
|
+
- lib/graphiti/active_graph/scoping/internal/path_descriptor.rb
|
213
|
+
- lib/graphiti/active_graph/scoping/internal/sort_normalizer.rb
|
214
|
+
- lib/graphiti/active_graph/scoping/internal/sorting_aliases.rb
|
215
|
+
- lib/graphiti/active_graph/scoping/internal/sparse_fields_eagerloading.rb
|
146
216
|
- lib/graphiti/active_graph/sideload_resolve.rb
|
217
|
+
- lib/graphiti/active_graph/util/parsers/rel_chain.rb
|
147
218
|
- lib/graphiti/active_graph/util/relationship_payload.rb
|
148
219
|
- lib/graphiti/active_graph/util/serializer_attribute.rb
|
149
220
|
- lib/graphiti/active_graph/util/serializer_relationship.rb
|
221
|
+
- lib/graphiti/active_graph/util/transformers/relation_param.rb
|
150
222
|
- lib/graphiti/active_graph/version.rb
|
151
223
|
- lib/graphiti/sidepost_configuration.rb
|
152
224
|
homepage: https://github.com/mrhardikjoshi/graphiti-activegraph
|
153
225
|
licenses:
|
154
226
|
- MIT
|
155
227
|
metadata: {}
|
156
|
-
post_install_message:
|
157
228
|
rdoc_options: []
|
158
229
|
require_paths:
|
159
230
|
- lib
|
@@ -168,8 +239,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
168
239
|
- !ruby/object:Gem::Version
|
169
240
|
version: '0'
|
170
241
|
requirements: []
|
171
|
-
rubygems_version: 3.
|
172
|
-
signing_key:
|
242
|
+
rubygems_version: 3.6.2
|
173
243
|
specification_version: 4
|
174
244
|
summary: Easily build jsonapi.org-compatible APIs for GraphDB
|
175
245
|
test_files: []
|