lighthouse-graphql 0.3.0 → 0.4.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 +44 -1
- data/README.md +11 -3
- data/docs/best-practices.md +16 -6
- data/docs/configuration.md +7 -6
- data/docs/directives.md +31 -6
- data/docs/events.md +3 -1
- data/docs/federation.md +3 -2
- data/docs/getting-started.md +52 -14
- data/docs/motivation.md +3 -2
- data/docs/resolvers.md +93 -19
- data/docs/security.md +210 -0
- data/docs/subscriptions.md +60 -37
- data/lib/generators/lighthouse/base_classes.rb +87 -0
- data/lib/generators/lighthouse/class_generator.rb +19 -8
- data/lib/generators/lighthouse/install/install_generator.rb +23 -6
- data/lib/generators/lighthouse/install/templates/initializer.rb.tt +7 -6
- data/lib/generators/lighthouse/install/templates/schema.rb.tt +14 -2
- data/lib/generators/lighthouse/mutation_generator.rb +5 -4
- data/lib/generators/lighthouse/query_generator.rb +5 -4
- data/lib/generators/lighthouse/subscription_generator.rb +21 -16
- data/lib/lighthouse/complexity.rb +174 -0
- data/lib/lighthouse/complexity_analyzer.rb +56 -0
- data/lib/lighthouse/config.rb +4 -3
- data/lib/lighthouse/directive_resolvers/convention_resolver.rb +14 -4
- data/lib/lighthouse/directive_resolvers/convert_empty_strings_resolver.rb +1 -1
- data/lib/lighthouse/directive_resolvers/subscription_resolver.rb +12 -4
- data/lib/lighthouse/directives/registry.rb +1 -0
- data/lib/lighthouse/events/execution_trace.rb +2 -1
- data/lib/lighthouse/events/lifecycle.rb +3 -1
- data/lib/lighthouse/field_resolver_stack.rb +8 -7
- data/lib/lighthouse/graphql/version.rb +1 -1
- data/lib/lighthouse/rb_lighthouse.rb +3 -0
- data/lib/lighthouse/resolver_bases.rb +61 -0
- data/lib/lighthouse/schema_factory.rb +0 -1
- data/lib/lighthouse/schema_generator.rb +15 -7
- data/lib/lighthouse/sdl_loader.rb +0 -2
- data/lib/lighthouse/support/model_resolver.rb +1 -1
- data/sig/lighthouse/graphql.rbs +29 -0
- metadata +6 -1
|
@@ -30,7 +30,6 @@ module Lighthouse::GraphQL::SchemaFactory
|
|
|
30
30
|
folder = sdl_folder || (Lighthouse::GraphQL::Config.sdl_folder if defined?(Lighthouse::GraphQL::Config))
|
|
31
31
|
return Lighthouse::GraphQL::SDLLoader.load_from_folder(folder) if folder && Dir.exist?(folder)
|
|
32
32
|
|
|
33
|
-
# fallback to apps/chatwoot/schema.graphql
|
|
34
33
|
File.read(File.expand_path('../../schema.graphql', __dir__))
|
|
35
34
|
end
|
|
36
35
|
end
|
|
@@ -45,17 +45,21 @@ module Lighthouse::GraphQL::SchemaGenerator
|
|
|
45
45
|
# and fresh (see SchemaCache), else built now.
|
|
46
46
|
document = build_document(sdl_string)
|
|
47
47
|
impl = default_implementation
|
|
48
|
+
# base_types' resolver / mutation / subscription are Lighthouse's, not graphql-ruby's.
|
|
49
|
+
bases = Lighthouse::GraphQL::ResolverBases.extract!(opts)
|
|
48
50
|
schema = from_document(document, impl, opts)
|
|
49
51
|
|
|
50
52
|
delegate_to_federation_sdl(schema)
|
|
51
53
|
Lighthouse::GraphQL::GeneratedResolvers.install_dispatcher(schema)
|
|
52
54
|
attach_schema(impl, schema)
|
|
53
|
-
post_process(schema, impl, **opts)
|
|
55
|
+
post_process(schema, impl, bases: bases, **opts)
|
|
54
56
|
schema.trace_with(Lighthouse::Events::ExecutionTrace)
|
|
55
57
|
|
|
56
58
|
# @cacheControl hints become the response's Cache-Control header,
|
|
57
59
|
# computed per query from the fields it selects.
|
|
58
60
|
schema.query_analyzer(Lighthouse::GraphQL::CacheControl::Analyzer) if uses_cache_control
|
|
61
|
+
# The score graphql-ruby checks against max_complexity, for BuildExtensionsResponse.
|
|
62
|
+
schema.query_analyzer(Lighthouse::GraphQL::Complexity::Analyzer)
|
|
59
63
|
|
|
60
64
|
schema
|
|
61
65
|
end
|
|
@@ -124,7 +128,8 @@ module Lighthouse::GraphQL::SchemaGenerator
|
|
|
124
128
|
augment_sdl_with_connections(inject_directive_definitions(sdl))
|
|
125
129
|
end
|
|
126
130
|
|
|
127
|
-
|
|
131
|
+
# `bases`: { root kind => the base class its fields' classes inherit from } (ResolverBases).
|
|
132
|
+
def post_process(schema, _impl, bases: {}, **_opts)
|
|
128
133
|
root_kinds = root_kinds(schema)
|
|
129
134
|
|
|
130
135
|
# Inspect types and fields for directives and attach generated resolvers
|
|
@@ -134,9 +139,12 @@ module Lighthouse::GraphQL::SchemaGenerator
|
|
|
134
139
|
# Apply object-level federation directives to generated types so the
|
|
135
140
|
# Apollo Federation helper can detect entities and add _entities.
|
|
136
141
|
Lighthouse::GraphQL::FederationDirectives.apply(type)
|
|
137
|
-
type.fields.each_value { |field_def| process_field(type, field_def, root_kinds[type.graphql_name]) }
|
|
142
|
+
type.fields.each_value { |field_def| process_field(type, field_def, root_kinds[type.graphql_name], bases) }
|
|
138
143
|
end
|
|
139
144
|
|
|
145
|
+
# @complexity, and paginated fields, give graphql-ruby's complexity analysis their cost.
|
|
146
|
+
Lighthouse::GraphQL::Complexity.apply(schema, root_kinds)
|
|
147
|
+
|
|
140
148
|
# @feature hides a field or type per query, through graphql-ruby's visibility.
|
|
141
149
|
Lighthouse::GraphQL::FeatureDirective.apply(schema)
|
|
142
150
|
|
|
@@ -155,10 +163,10 @@ module Lighthouse::GraphQL::SchemaGenerator
|
|
|
155
163
|
|
|
156
164
|
# A field's generated resolvers, then the runtime hooks that make
|
|
157
165
|
# graphql-ruby reach them.
|
|
158
|
-
def process_field(type, field_def, root_kind)
|
|
166
|
+
def process_field(type, field_def, root_kind, bases = {})
|
|
159
167
|
return unless field_def.ast_node
|
|
160
168
|
|
|
161
|
-
apply_field_resolvers(type, field_def, field_def.ast_node.directives || [], root_kind)
|
|
169
|
+
apply_field_resolvers(type, field_def, field_def.ast_node.directives || [], root_kind, bases)
|
|
162
170
|
Lighthouse::GraphQL::GeneratedResolvers.route_runtime_resolver(type, field_def)
|
|
163
171
|
ensure_connection_extension(field_def)
|
|
164
172
|
end
|
|
@@ -180,8 +188,8 @@ module Lighthouse::GraphQL::SchemaGenerator
|
|
|
180
188
|
end
|
|
181
189
|
|
|
182
190
|
# A field's resolvers, installed in resolution order (see FieldResolverStack).
|
|
183
|
-
def apply_field_resolvers(type, field_def, directives, root_kind)
|
|
184
|
-
Lighthouse::GraphQL::FieldResolverStack.apply(type, field_def, directives, root_kind)
|
|
191
|
+
def apply_field_resolvers(type, field_def, directives, root_kind, bases = {})
|
|
192
|
+
Lighthouse::GraphQL::FieldResolverStack.apply(type, field_def, directives, root_kind, bases: bases)
|
|
185
193
|
end
|
|
186
194
|
|
|
187
195
|
# Scan SDL string for list-typed fields that carry relationship directives
|
|
@@ -6,8 +6,6 @@ module Lighthouse::GraphQL::SDLLoader
|
|
|
6
6
|
def load_from_folder(folder)
|
|
7
7
|
files = Dir[File.join(folder, '**', '*.graphql')]
|
|
8
8
|
if files.empty?
|
|
9
|
-
# fallback to the monolithic schema.graphql in apps/chatwoot
|
|
10
|
-
# schema.graphql is located at apps/chatwoot/schema.graphql
|
|
11
9
|
default = File.expand_path('../../..//schema.graphql', __dir__)
|
|
12
10
|
return File.read(default) if File.exist?(default)
|
|
13
11
|
|
|
@@ -25,7 +25,7 @@ module Lighthouse::Support::ModelResolver
|
|
|
25
25
|
|
|
26
26
|
# `namespaces:` overrides the configured resolver_namespaces, e.g. with
|
|
27
27
|
# Config.namespaces[:builders] to look a builder class up.
|
|
28
|
-
# `fallback: false` skips the bare name, so `
|
|
28
|
+
# `fallback: false` skips the bare name, so `Resolvers::User` is never
|
|
29
29
|
# mistaken for the `User` model.
|
|
30
30
|
def constantize(name, namespaces: self.namespaces, fallback: true)
|
|
31
31
|
return nil unless name
|
data/sig/lighthouse/graphql.rbs
CHANGED
|
@@ -97,6 +97,35 @@ module Lighthouse
|
|
|
97
97
|
def self?.apply: (untyped response, untyped result) -> String?
|
|
98
98
|
end
|
|
99
99
|
|
|
100
|
+
# What fields cost in graphql-ruby's complexity analysis (@complexity, and
|
|
101
|
+
# paginated fields scaled by `first`).
|
|
102
|
+
module Complexity
|
|
103
|
+
DEFINITION: String
|
|
104
|
+
CONTEXT_KEY: Symbol
|
|
105
|
+
|
|
106
|
+
# Give the schema's fields their cost; `root_kinds` maps root type names to
|
|
107
|
+
# :queries / :mutations / :subscriptions.
|
|
108
|
+
def self?.apply: (untyped schema, ?Hash[String, Symbol] root_kinds) -> untyped
|
|
109
|
+
# A query's score, once scored for BuildExtensionsResponse; nil otherwise.
|
|
110
|
+
def self?.query_complexity: (untyped query) -> Integer?
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# A concern for a GraphQL::Analysis::Analyzer that @complexity(resolver:)
|
|
114
|
+
# names (graphql-ruby ships no RBS, so the class it is included in is not
|
|
115
|
+
# declared): its `complexity` is the cost of the fields naming the class.
|
|
116
|
+
module ComplexityAnalyzer
|
|
117
|
+
# Only when the class has a `result` of its own.
|
|
118
|
+
def analyze?: () -> bool
|
|
119
|
+
def result: () -> nil
|
|
120
|
+
|
|
121
|
+
# The class methods the concern adds to its includer.
|
|
122
|
+
module ClassMethods
|
|
123
|
+
# A number (added to the selection's cost) or a proc of
|
|
124
|
+
# (context, args, child_complexity); nil when never set.
|
|
125
|
+
def complexity: (?(Numeric | ^(context, arguments, Integer) -> Integer)? new_complexity) -> (Numeric | ^(context, arguments, Integer) -> Integer)?
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
100
129
|
# The opt-in cache of the manipulated schema document, in tmp/cache.
|
|
101
130
|
module SchemaCache
|
|
102
131
|
PREFIX: String
|
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.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vaz Innovation
|
|
@@ -68,8 +68,10 @@ files:
|
|
|
68
68
|
- docs/performance.md
|
|
69
69
|
- docs/relationships.md
|
|
70
70
|
- docs/resolvers.md
|
|
71
|
+
- docs/security.md
|
|
71
72
|
- docs/subscriptions.md
|
|
72
73
|
- docs/validation.md
|
|
74
|
+
- lib/generators/lighthouse/base_classes.rb
|
|
73
75
|
- lib/generators/lighthouse/builder_generator.rb
|
|
74
76
|
- lib/generators/lighthouse/class_generator.rb
|
|
75
77
|
- lib/generators/lighthouse/install/install_generator.rb
|
|
@@ -87,6 +89,8 @@ files:
|
|
|
87
89
|
- lib/lighthouse/broadcasting.rb
|
|
88
90
|
- lib/lighthouse/cache_control.rb
|
|
89
91
|
- lib/lighthouse/caching.rb
|
|
92
|
+
- lib/lighthouse/complexity.rb
|
|
93
|
+
- lib/lighthouse/complexity_analyzer.rb
|
|
90
94
|
- lib/lighthouse/config.rb
|
|
91
95
|
- lib/lighthouse/contracts/arg_builder.rb
|
|
92
96
|
- lib/lighthouse/contracts/arg_manipulator.rb
|
|
@@ -161,6 +165,7 @@ files:
|
|
|
161
165
|
- lib/lighthouse/rb_lighthouse.rb
|
|
162
166
|
- lib/lighthouse/reference_resolver.rb
|
|
163
167
|
- lib/lighthouse/relation_batch.rb
|
|
168
|
+
- lib/lighthouse/resolver_bases.rb
|
|
164
169
|
- lib/lighthouse/resolver_dispatch.rb
|
|
165
170
|
- lib/lighthouse/schema_cache.rb
|
|
166
171
|
- lib/lighthouse/schema_factory.rb
|