lighthouse-graphql 0.1.1 → 0.2.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 +154 -1
- data/README.md +42 -2
- data/docs/authorization.md +116 -57
- data/docs/best-practices.md +16 -3
- data/docs/caching.md +161 -0
- data/docs/configuration.md +83 -4
- data/docs/custom-directives.md +5 -1
- data/docs/directives.md +117 -38
- data/docs/getting-started.md +84 -0
- data/docs/mutations.md +260 -0
- data/docs/performance.md +138 -0
- data/docs/relationships.md +80 -33
- data/docs/resolvers.md +179 -0
- data/docs/validation.md +132 -0
- data/lib/generators/lighthouse/builder_generator.rb +30 -0
- data/lib/generators/lighthouse/class_generator.rb +61 -0
- data/lib/generators/lighthouse/install/install_generator.rb +127 -0
- data/lib/generators/lighthouse/install/templates/graphql.config.yml.tt +8 -0
- data/lib/generators/lighthouse/install/templates/graphql_controller.rb.tt +57 -0
- data/lib/generators/lighthouse/install/templates/initializer.rb.tt +67 -0
- data/lib/generators/lighthouse/install/templates/schema.graphql.tt +19 -0
- data/lib/generators/lighthouse/install/templates/schema.rb.tt +10 -0
- data/lib/generators/lighthouse/mutation_generator.rb +30 -0
- data/lib/generators/lighthouse/query_generator.rb +29 -0
- data/lib/generators/lighthouse/validator_generator.rb +36 -0
- data/lib/lighthouse/cache_control.rb +126 -0
- data/lib/lighthouse/caching.rb +68 -0
- data/lib/lighthouse/config.rb +85 -19
- data/lib/lighthouse/contracts/arg_builder.rb +8 -12
- data/lib/lighthouse/contracts/arg_manipulator.rb +8 -12
- data/lib/lighthouse/contracts/directive.rb +10 -14
- data/lib/lighthouse/contracts/field_manipulator.rb +8 -12
- data/lib/lighthouse/contracts/field_middleware.rb +7 -11
- data/lib/lighthouse/contracts/field_resolver.rb +9 -13
- data/lib/lighthouse/dataloader_sources/association_loader.rb +28 -19
- data/lib/lighthouse/dataloader_sources/model_loader.rb +10 -14
- data/lib/lighthouse/dataloader_sources/relation_count_loader.rb +16 -0
- data/lib/lighthouse/dataloader_sources/relation_page_loader.rb +18 -0
- data/lib/lighthouse/directive_resolvers/aggregate_resolver.rb +57 -69
- data/lib/lighthouse/directive_resolvers/all_resolver.rb +26 -57
- data/lib/lighthouse/directive_resolvers/association_resolvers.rb +161 -0
- data/lib/lighthouse/directive_resolvers/auth_resolver.rb +41 -38
- data/lib/lighthouse/directive_resolvers/base.rb +142 -86
- data/lib/lighthouse/directive_resolvers/builder_applier.rb +58 -56
- data/lib/lighthouse/directive_resolvers/cache_resolvers.rb +133 -0
- data/lib/lighthouse/directive_resolvers/can_resolvers.rb +177 -0
- data/lib/lighthouse/directive_resolvers/convention_resolver.rb +70 -0
- data/lib/lighthouse/directive_resolvers/count_resolver.rb +42 -48
- data/lib/lighthouse/directive_resolvers/field_resolver.rb +27 -68
- data/lib/lighthouse/directive_resolvers/find_resolver.rb +42 -52
- data/lib/lighthouse/directive_resolvers/first_resolver.rb +39 -45
- data/lib/lighthouse/directive_resolvers/guard_resolver.rb +16 -22
- data/lib/lighthouse/directive_resolvers/method_resolver.rb +19 -25
- data/lib/lighthouse/directive_resolvers/model_mutation_resolver.rb +219 -0
- data/lib/lighthouse/directive_resolvers/paginate_resolver.rb +70 -128
- data/lib/lighthouse/directive_resolvers/rename_resolver.rb +18 -24
- data/lib/lighthouse/directive_resolvers/resolution.rb +31 -27
- data/lib/lighthouse/directive_resolvers/validator_resolver.rb +193 -0
- data/lib/lighthouse/directive_resolvers/where_conditions_applier.rb +164 -163
- data/lib/lighthouse/directives/arguments/base.rb +23 -31
- data/lib/lighthouse/directives/arguments/filters.rb +113 -93
- data/lib/lighthouse/directives/arguments/order_by.rb +41 -41
- data/lib/lighthouse/directives/pagination_info_types.rb +69 -0
- data/lib/lighthouse/directives/pagination_manipulator.rb +176 -0
- data/lib/lighthouse/directives/registry.rb +210 -141
- data/lib/lighthouse/directives/where_conditions_directive.rb +236 -200
- data/lib/lighthouse/errors.rb +27 -0
- data/lib/lighthouse/federation_directives.rb +53 -0
- data/lib/lighthouse/field_resolver_stack.rb +56 -0
- data/lib/lighthouse/generated_resolvers.rb +82 -0
- data/lib/lighthouse/graphql/version.rb +1 -1
- data/lib/lighthouse/graphql_ruby_patches.rb +18 -0
- data/lib/lighthouse/ide_helper.rb +98 -0
- data/lib/lighthouse/namespaces.rb +21 -0
- data/lib/lighthouse/nested_mutations/belongs_to_operations.rb +50 -0
- data/lib/lighthouse/nested_mutations/executor.rb +149 -0
- data/lib/lighthouse/nested_mutations/has_operations.rb +66 -0
- data/lib/lighthouse/nested_mutations/many_to_many_operations.rb +44 -0
- data/lib/lighthouse/nested_mutations/partitioner.rb +125 -0
- data/lib/lighthouse/nested_mutations.rb +210 -0
- data/lib/lighthouse/pagination.rb +221 -0
- data/lib/lighthouse/persisted_queries.rb +167 -0
- data/lib/lighthouse/railtie.rb +26 -0
- data/lib/lighthouse/rb_lighthouse.rb +50 -29
- data/lib/lighthouse/reference_resolver.rb +13 -15
- data/lib/lighthouse/relation_batch.rb +156 -0
- data/lib/lighthouse/resolver_dispatch.rb +26 -0
- data/lib/lighthouse/schema_cache.rb +120 -0
- data/lib/lighthouse/schema_factory.rb +27 -37
- data/lib/lighthouse/schema_generator.rb +196 -239
- data/lib/lighthouse/schema_implementation.rb +51 -48
- data/lib/lighthouse/sdl_loader.rb +17 -20
- data/lib/lighthouse/support/arguments.rb +119 -0
- data/lib/lighthouse/support/authorization.rb +18 -19
- data/lib/lighthouse/support/batching.rb +16 -0
- data/lib/lighthouse/support/directive_args.rb +26 -24
- data/lib/lighthouse/support/model_resolver.rb +56 -56
- data/lib/lighthouse/support/naming.rb +55 -59
- data/lib/lighthouse/tasks/lighthouse.rake +33 -0
- data/lib/lighthouse/where_conditions/operator_map.rb +25 -29
- metadata +51 -63
- data/lib/lighthouse/directive_resolvers/belongs_to_many_resolver.rb +0 -56
- data/lib/lighthouse/directive_resolvers/belongs_to_resolver.rb +0 -47
- data/lib/lighthouse/directive_resolvers/can_resolver.rb +0 -86
- data/lib/lighthouse/directive_resolvers/has_many_resolver.rb +0 -109
- data/lib/lighthouse/directive_resolvers/has_one_resolver.rb +0 -43
- data/lib/lighthouse/directives/relation_directive.rb +0 -332
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lighthouse-graphql
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vaz Innovation
|
|
@@ -37,62 +37,6 @@ dependencies:
|
|
|
37
37
|
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
39
|
version: '2.5'
|
|
40
|
-
- !ruby/object:Gem::Dependency
|
|
41
|
-
name: rspec
|
|
42
|
-
requirement: !ruby/object:Gem::Requirement
|
|
43
|
-
requirements:
|
|
44
|
-
- - "~>"
|
|
45
|
-
- !ruby/object:Gem::Version
|
|
46
|
-
version: '3.0'
|
|
47
|
-
type: :development
|
|
48
|
-
prerelease: false
|
|
49
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
-
requirements:
|
|
51
|
-
- - "~>"
|
|
52
|
-
- !ruby/object:Gem::Version
|
|
53
|
-
version: '3.0'
|
|
54
|
-
- !ruby/object:Gem::Dependency
|
|
55
|
-
name: activerecord
|
|
56
|
-
requirement: !ruby/object:Gem::Requirement
|
|
57
|
-
requirements:
|
|
58
|
-
- - ">="
|
|
59
|
-
- !ruby/object:Gem::Version
|
|
60
|
-
version: '6.0'
|
|
61
|
-
type: :development
|
|
62
|
-
prerelease: false
|
|
63
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
-
requirements:
|
|
65
|
-
- - ">="
|
|
66
|
-
- !ruby/object:Gem::Version
|
|
67
|
-
version: '6.0'
|
|
68
|
-
- !ruby/object:Gem::Dependency
|
|
69
|
-
name: sqlite3
|
|
70
|
-
requirement: !ruby/object:Gem::Requirement
|
|
71
|
-
requirements:
|
|
72
|
-
- - ">="
|
|
73
|
-
- !ruby/object:Gem::Version
|
|
74
|
-
version: '1.4'
|
|
75
|
-
type: :development
|
|
76
|
-
prerelease: false
|
|
77
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
-
requirements:
|
|
79
|
-
- - ">="
|
|
80
|
-
- !ruby/object:Gem::Version
|
|
81
|
-
version: '1.4'
|
|
82
|
-
- !ruby/object:Gem::Dependency
|
|
83
|
-
name: apollo-federation
|
|
84
|
-
requirement: !ruby/object:Gem::Requirement
|
|
85
|
-
requirements:
|
|
86
|
-
- - "~>"
|
|
87
|
-
- !ruby/object:Gem::Version
|
|
88
|
-
version: '3.0'
|
|
89
|
-
type: :development
|
|
90
|
-
prerelease: false
|
|
91
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
-
requirements:
|
|
93
|
-
- - "~>"
|
|
94
|
-
- !ruby/object:Gem::Version
|
|
95
|
-
version: '3.0'
|
|
96
40
|
description: |
|
|
97
41
|
Lighthouse lets you build a GraphQL API for your Rails app primarily through
|
|
98
42
|
schema (SDL) and server-side directives — @all, @find, @paginate, @hasMany,
|
|
@@ -111,14 +55,32 @@ files:
|
|
|
111
55
|
- README.md
|
|
112
56
|
- docs/authorization.md
|
|
113
57
|
- docs/best-practices.md
|
|
58
|
+
- docs/caching.md
|
|
114
59
|
- docs/configuration.md
|
|
115
60
|
- docs/custom-directives.md
|
|
116
61
|
- docs/directives.md
|
|
117
62
|
- docs/federation.md
|
|
118
63
|
- docs/filtering-and-ordering.md
|
|
119
64
|
- docs/getting-started.md
|
|
65
|
+
- docs/mutations.md
|
|
66
|
+
- docs/performance.md
|
|
120
67
|
- docs/relationships.md
|
|
68
|
+
- docs/resolvers.md
|
|
69
|
+
- docs/validation.md
|
|
70
|
+
- lib/generators/lighthouse/builder_generator.rb
|
|
71
|
+
- lib/generators/lighthouse/class_generator.rb
|
|
72
|
+
- lib/generators/lighthouse/install/install_generator.rb
|
|
73
|
+
- lib/generators/lighthouse/install/templates/graphql.config.yml.tt
|
|
74
|
+
- lib/generators/lighthouse/install/templates/graphql_controller.rb.tt
|
|
75
|
+
- lib/generators/lighthouse/install/templates/initializer.rb.tt
|
|
76
|
+
- lib/generators/lighthouse/install/templates/schema.graphql.tt
|
|
77
|
+
- lib/generators/lighthouse/install/templates/schema.rb.tt
|
|
78
|
+
- lib/generators/lighthouse/mutation_generator.rb
|
|
79
|
+
- lib/generators/lighthouse/query_generator.rb
|
|
80
|
+
- lib/generators/lighthouse/validator_generator.rb
|
|
121
81
|
- lib/lighthouse-graphql.rb
|
|
82
|
+
- lib/lighthouse/cache_control.rb
|
|
83
|
+
- lib/lighthouse/caching.rb
|
|
122
84
|
- lib/lighthouse/config.rb
|
|
123
85
|
- lib/lighthouse/contracts/arg_builder.rb
|
|
124
86
|
- lib/lighthouse/contracts/arg_manipulator.rb
|
|
@@ -128,44 +90,70 @@ files:
|
|
|
128
90
|
- lib/lighthouse/contracts/field_resolver.rb
|
|
129
91
|
- lib/lighthouse/dataloader_sources/association_loader.rb
|
|
130
92
|
- lib/lighthouse/dataloader_sources/model_loader.rb
|
|
93
|
+
- lib/lighthouse/dataloader_sources/relation_count_loader.rb
|
|
94
|
+
- lib/lighthouse/dataloader_sources/relation_page_loader.rb
|
|
131
95
|
- lib/lighthouse/directive_resolvers/aggregate_resolver.rb
|
|
132
96
|
- lib/lighthouse/directive_resolvers/all_resolver.rb
|
|
97
|
+
- lib/lighthouse/directive_resolvers/association_resolvers.rb
|
|
133
98
|
- lib/lighthouse/directive_resolvers/auth_resolver.rb
|
|
134
99
|
- lib/lighthouse/directive_resolvers/base.rb
|
|
135
|
-
- lib/lighthouse/directive_resolvers/belongs_to_many_resolver.rb
|
|
136
|
-
- lib/lighthouse/directive_resolvers/belongs_to_resolver.rb
|
|
137
100
|
- lib/lighthouse/directive_resolvers/builder_applier.rb
|
|
138
|
-
- lib/lighthouse/directive_resolvers/
|
|
101
|
+
- lib/lighthouse/directive_resolvers/cache_resolvers.rb
|
|
102
|
+
- lib/lighthouse/directive_resolvers/can_resolvers.rb
|
|
103
|
+
- lib/lighthouse/directive_resolvers/convention_resolver.rb
|
|
139
104
|
- lib/lighthouse/directive_resolvers/count_resolver.rb
|
|
140
105
|
- lib/lighthouse/directive_resolvers/field_resolver.rb
|
|
141
106
|
- lib/lighthouse/directive_resolvers/find_resolver.rb
|
|
142
107
|
- lib/lighthouse/directive_resolvers/first_resolver.rb
|
|
143
108
|
- lib/lighthouse/directive_resolvers/guard_resolver.rb
|
|
144
|
-
- lib/lighthouse/directive_resolvers/has_many_resolver.rb
|
|
145
|
-
- lib/lighthouse/directive_resolvers/has_one_resolver.rb
|
|
146
109
|
- lib/lighthouse/directive_resolvers/method_resolver.rb
|
|
110
|
+
- lib/lighthouse/directive_resolvers/model_mutation_resolver.rb
|
|
147
111
|
- lib/lighthouse/directive_resolvers/paginate_resolver.rb
|
|
148
112
|
- lib/lighthouse/directive_resolvers/rename_resolver.rb
|
|
149
113
|
- lib/lighthouse/directive_resolvers/resolution.rb
|
|
114
|
+
- lib/lighthouse/directive_resolvers/validator_resolver.rb
|
|
150
115
|
- lib/lighthouse/directive_resolvers/where_conditions_applier.rb
|
|
151
116
|
- lib/lighthouse/directives/arguments/base.rb
|
|
152
117
|
- lib/lighthouse/directives/arguments/filters.rb
|
|
153
118
|
- lib/lighthouse/directives/arguments/order_by.rb
|
|
119
|
+
- lib/lighthouse/directives/pagination_info_types.rb
|
|
120
|
+
- lib/lighthouse/directives/pagination_manipulator.rb
|
|
154
121
|
- lib/lighthouse/directives/registry.rb
|
|
155
|
-
- lib/lighthouse/directives/relation_directive.rb
|
|
156
122
|
- lib/lighthouse/directives/where_conditions_directive.rb
|
|
123
|
+
- lib/lighthouse/errors.rb
|
|
124
|
+
- lib/lighthouse/federation_directives.rb
|
|
125
|
+
- lib/lighthouse/field_resolver_stack.rb
|
|
126
|
+
- lib/lighthouse/generated_resolvers.rb
|
|
157
127
|
- lib/lighthouse/graphql.rb
|
|
158
128
|
- lib/lighthouse/graphql/version.rb
|
|
129
|
+
- lib/lighthouse/graphql_ruby_patches.rb
|
|
130
|
+
- lib/lighthouse/ide_helper.rb
|
|
131
|
+
- lib/lighthouse/namespaces.rb
|
|
132
|
+
- lib/lighthouse/nested_mutations.rb
|
|
133
|
+
- lib/lighthouse/nested_mutations/belongs_to_operations.rb
|
|
134
|
+
- lib/lighthouse/nested_mutations/executor.rb
|
|
135
|
+
- lib/lighthouse/nested_mutations/has_operations.rb
|
|
136
|
+
- lib/lighthouse/nested_mutations/many_to_many_operations.rb
|
|
137
|
+
- lib/lighthouse/nested_mutations/partitioner.rb
|
|
138
|
+
- lib/lighthouse/pagination.rb
|
|
139
|
+
- lib/lighthouse/persisted_queries.rb
|
|
140
|
+
- lib/lighthouse/railtie.rb
|
|
159
141
|
- lib/lighthouse/rb_lighthouse.rb
|
|
160
142
|
- lib/lighthouse/reference_resolver.rb
|
|
143
|
+
- lib/lighthouse/relation_batch.rb
|
|
144
|
+
- lib/lighthouse/resolver_dispatch.rb
|
|
145
|
+
- lib/lighthouse/schema_cache.rb
|
|
161
146
|
- lib/lighthouse/schema_factory.rb
|
|
162
147
|
- lib/lighthouse/schema_generator.rb
|
|
163
148
|
- lib/lighthouse/schema_implementation.rb
|
|
164
149
|
- lib/lighthouse/sdl_loader.rb
|
|
150
|
+
- lib/lighthouse/support/arguments.rb
|
|
165
151
|
- lib/lighthouse/support/authorization.rb
|
|
152
|
+
- lib/lighthouse/support/batching.rb
|
|
166
153
|
- lib/lighthouse/support/directive_args.rb
|
|
167
154
|
- lib/lighthouse/support/model_resolver.rb
|
|
168
155
|
- lib/lighthouse/support/naming.rb
|
|
156
|
+
- lib/lighthouse/tasks/lighthouse.rake
|
|
169
157
|
- lib/lighthouse/where_conditions/operator_map.rb
|
|
170
158
|
homepage: https://github.com/Vaz-Innovation/lighthouse-graphql
|
|
171
159
|
licenses:
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'base'
|
|
4
|
-
|
|
5
|
-
module Lighthouse
|
|
6
|
-
module GraphQL
|
|
7
|
-
module DirectiveResolvers
|
|
8
|
-
class BelongsToManyDirectiveResolver < BaseDirectiveResolver
|
|
9
|
-
def define_resolver(target_type_class)
|
|
10
|
-
field_name = @field_def.name
|
|
11
|
-
assoc_name = extract_relation_name || field_name
|
|
12
|
-
|
|
13
|
-
method_name = "resolve_field_#{field_name}"
|
|
14
|
-
|
|
15
|
-
target_type_class.define_singleton_method(method_name) do |obj, arguments, ctx|
|
|
16
|
-
# Use dataloader when available
|
|
17
|
-
if ctx && ctx.respond_to?(:dataloader) && ctx.dataloader
|
|
18
|
-
loader = ctx.dataloader.with(Lighthouse::GraphQL::DataloaderSources::AssociationLoader, obj.class, assoc_name)
|
|
19
|
-
return loader.load(obj)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# Fallback: call the association directly
|
|
23
|
-
if obj.respond_to?(assoc_name)
|
|
24
|
-
args = arguments.respond_to?(:to_h) ? arguments.to_h : {}
|
|
25
|
-
return obj.public_send(assoc_name)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
nil
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
if @field_def.respond_to?(:resolve_proc=)
|
|
32
|
-
@field_def.resolve_proc = ->(obj, arguments, ctx) do
|
|
33
|
-
if ctx && ctx.respond_to?(:dataloader) && ctx.dataloader
|
|
34
|
-
loader = ctx.dataloader.with(Lighthouse::GraphQL::DataloaderSources::AssociationLoader, obj.class, assoc_name)
|
|
35
|
-
loader.load(obj)
|
|
36
|
-
elsif obj.respond_to?(assoc_name)
|
|
37
|
-
args = arguments.respond_to?(:to_h) ? arguments.to_h : {}
|
|
38
|
-
obj.public_send(assoc_name)
|
|
39
|
-
else
|
|
40
|
-
nil
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
private
|
|
47
|
-
|
|
48
|
-
def extract_relation_name
|
|
49
|
-
arg = @directive_node.arguments&.find { |a| a.name == 'relation' }
|
|
50
|
-
return nil unless arg
|
|
51
|
-
arg.value.respond_to?(:value) ? arg.value.value : arg.value
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'base'
|
|
4
|
-
|
|
5
|
-
module Lighthouse
|
|
6
|
-
module GraphQL
|
|
7
|
-
module DirectiveResolvers
|
|
8
|
-
class BelongsToDirectiveResolver < BaseDirectiveResolver
|
|
9
|
-
def define_resolver(target_type_class)
|
|
10
|
-
field_name = @field_def.name
|
|
11
|
-
assoc_name = extract_relation_name || field_name
|
|
12
|
-
method_name = "resolve_field_#{field_name}"
|
|
13
|
-
|
|
14
|
-
target_type_class.define_singleton_method(method_name) do |obj, _arguments, ctx|
|
|
15
|
-
if ctx && ctx.respond_to?(:dataloader) && ctx.dataloader
|
|
16
|
-
loader = ctx.dataloader.with(Lighthouse::GraphQL::DataloaderSources::AssociationLoader, obj.class, assoc_name)
|
|
17
|
-
return loader.load(obj)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
obj.public_send(assoc_name) if obj.respond_to?(assoc_name)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
if @field_def.respond_to?(:resolve_proc=)
|
|
24
|
-
@field_def.resolve_proc = ->(obj, _arguments, ctx) do
|
|
25
|
-
if ctx && ctx.respond_to?(:dataloader) && ctx.dataloader
|
|
26
|
-
loader = ctx.dataloader.with(Lighthouse::GraphQL::DataloaderSources::AssociationLoader, obj.class, assoc_name)
|
|
27
|
-
loader.load(obj)
|
|
28
|
-
elsif obj.respond_to?(assoc_name)
|
|
29
|
-
obj.public_send(assoc_name)
|
|
30
|
-
else
|
|
31
|
-
nil
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
private
|
|
38
|
-
|
|
39
|
-
def extract_relation_name
|
|
40
|
-
arg = @directive_node.arguments&.find { |a| a.name == 'relation' }
|
|
41
|
-
return nil unless arg
|
|
42
|
-
arg.value.respond_to?(:value) ? arg.value.value : arg.value
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'base'
|
|
4
|
-
|
|
5
|
-
module Lighthouse
|
|
6
|
-
module GraphQL
|
|
7
|
-
module DirectiveResolvers
|
|
8
|
-
# @can — authorize access to a field using a policy ability (Pundit by
|
|
9
|
-
# default; configurable via Config.authorizer). Mirrors PHP Lighthouse's
|
|
10
|
-
# @can* family. Repeatable.
|
|
11
|
-
#
|
|
12
|
-
# contact(id: ID!): Contact @field(resolver: "...") @can(ability: "show")
|
|
13
|
-
#
|
|
14
|
-
# Modes:
|
|
15
|
-
# * default — resolve the field, then authorize the resolved
|
|
16
|
-
# record (skips nil; passes collections through —
|
|
17
|
-
# use scoping for lists).
|
|
18
|
-
# * root: true — authorize the parent object before resolving.
|
|
19
|
-
# * find / model — look the model up by an argument and authorize it
|
|
20
|
-
# before resolving.
|
|
21
|
-
class CanDirectiveResolver < BaseDirectiveResolver
|
|
22
|
-
def self.directive_name = 'can'
|
|
23
|
-
def self.definition
|
|
24
|
-
'directive @can(ability: String!, find: String, model: String, root: Boolean) repeatable on FIELD_DEFINITION'
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def define_resolver(target_type_class)
|
|
28
|
-
field_name = @field_def.name
|
|
29
|
-
method_name = "resolve_field_#{field_name}"
|
|
30
|
-
ability = directive_arg('ability')
|
|
31
|
-
return if ability.nil?
|
|
32
|
-
|
|
33
|
-
find_arg = directive_arg('find')
|
|
34
|
-
model_name = directive_arg('model')
|
|
35
|
-
root = directive_arg('root')
|
|
36
|
-
inner = Resolution.capture(target_type_class, method_name, @field_def, field_name)
|
|
37
|
-
resolver_instance = self
|
|
38
|
-
|
|
39
|
-
wrapper = lambda do |obj, arguments, ctx|
|
|
40
|
-
if root
|
|
41
|
-
resolver_instance.send(:authorize_or_raise, ctx, obj, ability)
|
|
42
|
-
next inner.call(obj, arguments, ctx)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
if find_arg && model_name
|
|
46
|
-
args_h = arguments.respond_to?(:to_h) ? arguments.to_h : {}
|
|
47
|
-
id = Lighthouse::Support::Naming.fetch_arg(args_h, find_arg)
|
|
48
|
-
model_class = resolver_instance.send(:constantize_model, model_name)
|
|
49
|
-
record = model_class&.find_by(id: id)
|
|
50
|
-
resolver_instance.send(:authorize_or_raise, ctx, record, ability)
|
|
51
|
-
next inner.call(obj, arguments, ctx)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
result = inner.call(obj, arguments, ctx)
|
|
55
|
-
resolver_instance.send(:authorize_resolved, ctx, result, ability)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
target_type_class.define_singleton_method(method_name, &wrapper)
|
|
59
|
-
@field_def.resolve_proc = wrapper if @field_def.respond_to?(:resolve_proc=)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
private
|
|
63
|
-
|
|
64
|
-
def directive_arg(name)
|
|
65
|
-
Lighthouse::Support::DirectiveArgs.literal(@directive_node, name)
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def authorize_resolved(ctx, result, ability)
|
|
69
|
-
return result if result.nil?
|
|
70
|
-
# Collections are filtered with scoping, not item-by-item authorization.
|
|
71
|
-
return result if result.respond_to?(:each) && !result.respond_to?(:id)
|
|
72
|
-
|
|
73
|
-
authorize_or_raise(ctx, result, ability)
|
|
74
|
-
result
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def authorize_or_raise(ctx, record, ability)
|
|
78
|
-
return if record.nil?
|
|
79
|
-
|
|
80
|
-
authorized = Lighthouse::Support::Authorization.authorized?(ctx, record, ability)
|
|
81
|
-
raise(::GraphQL::ExecutionError, 'You are not authorized to perform this action.') unless authorized
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'base'
|
|
4
|
-
|
|
5
|
-
module Lighthouse
|
|
6
|
-
module GraphQL
|
|
7
|
-
module DirectiveResolvers
|
|
8
|
-
class HasManyDirectiveResolver < BaseDirectiveResolver
|
|
9
|
-
def define_resolver(target_type_class)
|
|
10
|
-
field_name = @field_def.name
|
|
11
|
-
assoc_name = extract_relation_name || field_name
|
|
12
|
-
is_connection = @field_def.respond_to?(:connection?) ? @field_def.connection? : false
|
|
13
|
-
|
|
14
|
-
resolver_instance = self
|
|
15
|
-
|
|
16
|
-
# Keep compatibility with SchemaImplementation-based resolution by
|
|
17
|
-
# defining a singleton method on the owner type (e.g. Inbox.resolve_field_conversations).
|
|
18
|
-
method_name = "resolve_field_#{field_name}"
|
|
19
|
-
|
|
20
|
-
target_type_class.define_singleton_method(method_name) do |*args|
|
|
21
|
-
# Support both batch and single resolution modes.
|
|
22
|
-
# Batch mode signature: (objects_array, ctx)
|
|
23
|
-
# Single mode signature: (obj, arguments, ctx)
|
|
24
|
-
if args.length == 2 && args[0].is_a?(Array)
|
|
25
|
-
parents, ctx = args
|
|
26
|
-
|
|
27
|
-
if ctx && ctx.respond_to?(:dataloader) && ctx.dataloader
|
|
28
|
-
loader = ctx.dataloader.with(Lighthouse::GraphQL::DataloaderSources::AssociationLoader, parents.first.class, assoc_name)
|
|
29
|
-
parents.map do |p|
|
|
30
|
-
promise = loader.load(p)
|
|
31
|
-
if is_connection
|
|
32
|
-
promise.then { |value| ::GraphQL::Pagination::ArrayConnection.new(value, context: ctx, parent: nil, field: nil, arguments: {}) }
|
|
33
|
-
else
|
|
34
|
-
promise
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
else
|
|
38
|
-
parents.map do |p|
|
|
39
|
-
value = p.respond_to?(assoc_name) ? p.public_send(assoc_name) : nil
|
|
40
|
-
is_connection && value ? ::GraphQL::Pagination::ArrayConnection.new(value, context: ctx, parent: nil, field: nil, arguments: {}) : value
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
else
|
|
44
|
-
obj, arguments, ctx = args
|
|
45
|
-
|
|
46
|
-
# Use dataloader when available
|
|
47
|
-
if ctx && ctx.respond_to?(:dataloader) && ctx.dataloader
|
|
48
|
-
args_h = arguments.respond_to?(:to_h) ? arguments.to_h : {}
|
|
49
|
-
loader = ctx.dataloader.with(Lighthouse::GraphQL::DataloaderSources::AssociationLoader, obj.class, assoc_name)
|
|
50
|
-
value = loader.load(obj)
|
|
51
|
-
if is_connection
|
|
52
|
-
value.then do |v|
|
|
53
|
-
filtered = resolver_instance.apply_where_filters(v, args_h)
|
|
54
|
-
::GraphQL::Pagination::ArrayConnection.new(filtered, context: ctx, parent: nil, field: nil, arguments: {})
|
|
55
|
-
end
|
|
56
|
-
else
|
|
57
|
-
value.then { |v| resolver_instance.apply_where_filters(v, args_h) }
|
|
58
|
-
end
|
|
59
|
-
elsif obj.respond_to?(assoc_name)
|
|
60
|
-
args_h = arguments.respond_to?(:to_h) ? arguments.to_h : {}
|
|
61
|
-
value = obj.public_send(assoc_name)
|
|
62
|
-
value = resolver_instance.apply_where_filters(value, args_h)
|
|
63
|
-
is_connection && value ? ::GraphQL::Pagination::ArrayConnection.new(value, context: ctx, parent: nil, field: nil, arguments: {}) : value
|
|
64
|
-
else
|
|
65
|
-
nil
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
# Also attach a resolve proc where supported by the GraphQL runtime.
|
|
71
|
-
if @field_def.respond_to?(:resolve_proc=)
|
|
72
|
-
@field_def.resolve_proc = ->(obj, arguments, ctx) do
|
|
73
|
-
if ctx && ctx.respond_to?(:dataloader) && ctx.dataloader
|
|
74
|
-
args_h = arguments.respond_to?(:to_h) ? arguments.to_h : {}
|
|
75
|
-
loader = ctx.dataloader.with(Lighthouse::GraphQL::DataloaderSources::AssociationLoader, obj.class, assoc_name)
|
|
76
|
-
result = loader.load(obj)
|
|
77
|
-
if is_connection
|
|
78
|
-
result.then do |value|
|
|
79
|
-
filtered = resolver_instance.apply_where_filters(value, args_h)
|
|
80
|
-
::GraphQL::Pagination::ArrayConnection.new(filtered, context: ctx, parent: nil, field: nil, arguments: {})
|
|
81
|
-
end
|
|
82
|
-
else
|
|
83
|
-
result.then { |value| resolver_instance.apply_where_filters(value, args_h) }
|
|
84
|
-
end
|
|
85
|
-
elsif obj.respond_to?(assoc_name)
|
|
86
|
-
args = arguments.respond_to?(:to_h) ? arguments.to_h : {}
|
|
87
|
-
value = obj.public_send(assoc_name)
|
|
88
|
-
value = resolver_instance.apply_where_filters(value, args)
|
|
89
|
-
is_connection && value ? ::GraphQL::Pagination::ArrayConnection.new(value, context: ctx, parent: nil, field: nil, arguments: {}) : value
|
|
90
|
-
else
|
|
91
|
-
nil
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
private
|
|
98
|
-
|
|
99
|
-
def extract_relation_name
|
|
100
|
-
# directive syntax: @hasMany(relation: "name")
|
|
101
|
-
arg = @directive_node.arguments&.find { |a| a.name == 'relation' }
|
|
102
|
-
return nil unless arg
|
|
103
|
-
# value is AST literal node; use its value method if present
|
|
104
|
-
arg.value.respond_to?(:value) ? arg.value.value : arg.value
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
end
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'base'
|
|
4
|
-
|
|
5
|
-
module Lighthouse
|
|
6
|
-
module GraphQL
|
|
7
|
-
module DirectiveResolvers
|
|
8
|
-
# @hasOne(relation: "name") — resolve a one-to-one association on the parent
|
|
9
|
-
# object. Mirrors @belongsTo (single record) and batch-loads through the
|
|
10
|
-
# AssociationLoader when a dataloader is available.
|
|
11
|
-
class HasOneDirectiveResolver < BaseDirectiveResolver
|
|
12
|
-
def self.directive_name = 'hasOne'
|
|
13
|
-
def self.definition = 'directive @hasOne(relation: String, scopes: [String!]) on FIELD_DEFINITION'
|
|
14
|
-
|
|
15
|
-
def define_resolver(target_type_class)
|
|
16
|
-
field_name = @field_def.name
|
|
17
|
-
assoc_name = directive_arg('relation') || field_name
|
|
18
|
-
method_name = "resolve_field_#{field_name}"
|
|
19
|
-
|
|
20
|
-
resolver = lambda do |obj, _arguments, ctx|
|
|
21
|
-
next nil if obj.nil?
|
|
22
|
-
|
|
23
|
-
if ctx && ctx.respond_to?(:dataloader) && ctx.dataloader
|
|
24
|
-
loader = ctx.dataloader.with(Lighthouse::GraphQL::DataloaderSources::AssociationLoader, obj.class, assoc_name)
|
|
25
|
-
loader.load(obj)
|
|
26
|
-
elsif obj.respond_to?(assoc_name)
|
|
27
|
-
obj.public_send(assoc_name)
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
target_type_class.define_singleton_method(method_name, &resolver)
|
|
32
|
-
@field_def.resolve_proc = resolver if @field_def.respond_to?(:resolve_proc=)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
private
|
|
36
|
-
|
|
37
|
-
def directive_arg(name)
|
|
38
|
-
Lighthouse::Support::DirectiveArgs.literal(@directive_node, name)
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|