lighthouse-graphql 0.7.0 → 0.7.1
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 +13 -1
- data/docs/generators.md +1 -1
- data/docs/getting-started.md +1 -1
- data/docs/relay.md +52 -3
- data/lib/generators/lighthouse/install/graphql_ruby_install.rb +14 -0
- data/lib/generators/lighthouse/install/install_generator.rb +15 -1
- data/lib/generators/lighthouse/install/templates/schema.graphql.tt +30 -0
- data/lib/lighthouse/graphql/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 504295e8c73043df4b45703bb304b02205a40298e5bc686eb7d3b93dd678478e
|
|
4
|
+
data.tar.gz: f5e1bc31e13856b2f636978eaed1c8d00c5fe6246bba46f4fad513d8ee247dfc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5aa2a3bcb218dc305b68cbb0d2ac1b437fdcd801a0965bc0e9c69de994b8028febb7c6a46fe2edff8e4b39d386b94369a63d603f6899fe1b9065d1a7196fd750
|
|
7
|
+
data.tar.gz: 1dd8ef4b1426c9c4555a087da98aaee17cdbbf3133bd375ee6e2d83e738a4911d5e091545b7b65a3262bf823a8bd7f5e034943cf2124077a9d54c42930ee0b7a
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,17 @@ project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.7.1] - 2026-10-18
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **`lighthouse:install` on graphql-ruby's Relay** (`--relay`, its default) writes `node(id:)`
|
|
14
|
+
and `nodes(ids:)` in the starter `graphql/schema.graphql`, with `interface Node` and a
|
|
15
|
+
`User @node` whose ids are global (`id: ID! @globalId`, `user(id: ID! @globalId(decode: ID) @eq)`).
|
|
16
|
+
Graphql-ruby's `field :node` / `field :nodes` move out of `Types::QueryType`, whose
|
|
17
|
+
`#node` / `#nodes` methods resolve the SDL's fields. This happens only when the schema file
|
|
18
|
+
does not exist yet. An install without Relay writes the starter schema as before.
|
|
19
|
+
|
|
9
20
|
## [0.7.0] - 2026-10-18
|
|
10
21
|
|
|
11
22
|
The schema is written by PHP Lighthouse's rules now: one entrypoint that imports
|
|
@@ -670,7 +681,8 @@ had been running inside a private monorepo as a path gem before being extracted.
|
|
|
670
681
|
- Config-driven extension seams: `Lighthouse.configure`, `resolver_namespaces`,
|
|
671
682
|
`on_error`, and `DirectiveRegistry.register` for app-defined directives.
|
|
672
683
|
|
|
673
|
-
[Unreleased]: https://github.com/Vaz-Innovation/lighthouse-graphql/compare/v0.7.
|
|
684
|
+
[Unreleased]: https://github.com/Vaz-Innovation/lighthouse-graphql/compare/v0.7.1...HEAD
|
|
685
|
+
[0.7.1]: https://github.com/Vaz-Innovation/lighthouse-graphql/compare/v0.7.0...v0.7.1
|
|
674
686
|
[0.7.0]: https://github.com/Vaz-Innovation/lighthouse-graphql/compare/v0.6.0...v0.7.0
|
|
675
687
|
[0.6.0]: https://github.com/Vaz-Innovation/lighthouse-graphql/compare/v0.5.0...v0.6.0
|
|
676
688
|
[0.5.0]: https://github.com/Vaz-Innovation/lighthouse-graphql/compare/v0.4.0...v0.5.0
|
data/docs/generators.md
CHANGED
|
@@ -32,7 +32,7 @@ And it adds Lighthouse's own:
|
|
|
32
32
|
| File | What it is |
|
|
33
33
|
| --- | --- |
|
|
34
34
|
| `config/initializers/lighthouse.rb` | Every [configuration](configuration.md) option, commented out |
|
|
35
|
-
| `graphql/schema.graphql` | A starter schema, unless the
|
|
35
|
+
| `graphql/schema.graphql` | A starter schema, unless the file exists. With graphql-ruby's Relay (`--relay`, its default), it declares `Query.node` and `nodes`, `interface Node`, and a `User @node` with global ids, and `Types::QueryType`'s `field :node` / `:nodes` go: its `#node` / `#nodes` resolve the SDL's |
|
|
36
36
|
| `graphql.config.yml` | IDE configuration, and `.gitignore` entries for the [IDE helper](getting-started.md#ide-support) files |
|
|
37
37
|
| `app/graphql/subscriptions/base_subscription.rb` | With `--subscriptions` only: graphql-ruby has no subscription base. It includes `Lighthouse::GraphQL::Subscription` |
|
|
38
38
|
| `config/routes.rb` | `post "/graphql", to: "graphql#execute"`, when missing |
|
data/docs/getting-started.md
CHANGED
|
@@ -37,7 +37,7 @@ graphql-ruby wrote, and adds Lighthouse's own:
|
|
|
37
37
|
| `app/graphql/types/base_*.rb`, `resolvers/base_resolver.rb`, `mutations/base_mutation.rb` | graphql-ruby's base classes. `BaseObject`, `BaseInterface`, `BaseUnion` and `BaseScalar` include `Lighthouse::GraphQL::Type` |
|
|
38
38
|
| `app/controllers/graphql_controller.rb` | graphql-ruby's controller, replaced by one including `Lighthouse::GraphQL::Controller` |
|
|
39
39
|
| `config/initializers/lighthouse.rb` | Every [configuration](configuration.md) option, commented out at its default |
|
|
40
|
-
| `graphql/schema.graphql` | The schema's entrypoint: a starter schema (`user` via `@find`, `users` via `@paginate`) that assumes a `User` model. Skipped when the file exists |
|
|
40
|
+
| `graphql/schema.graphql` | The schema's entrypoint: a starter schema (`user` via `@find`, `users` via `@paginate`) that assumes a `User` model. With graphql-ruby's Relay, also `node(id:)` and `nodes(ids:)` (see [relay.md](relay.md#relay-through-graphql-ruby)). Skipped when the file exists |
|
|
41
41
|
| `graphql.config.yml` | IDE configuration — see [IDE support](#ide-support) |
|
|
42
42
|
|
|
43
43
|
`--schema=ApiSchema`, `--schema-path=app/schema/schema.graphql`, `--subscriptions`,
|
data/docs/relay.md
CHANGED
|
@@ -160,9 +160,58 @@ directives then work on them. The schema has one kind of global id and one `Node
|
|
|
160
160
|
`ID` gives its id, and `ARRAY` / `TYPE` its class name (`["Tag", 1]`, `"Tag"`).
|
|
161
161
|
- `node:` is the SDL's `Node` interface: `interface Node`, which `@node` adds, and
|
|
162
162
|
`implements Node` refer to `Types::NodeType`. A `@node` type implements it.
|
|
163
|
-
- `Query.node` and `nodes`
|
|
164
|
-
`
|
|
165
|
-
|
|
163
|
+
- `Query.node` and `nodes` find objects with `object_from_id`, through the
|
|
164
|
+
`#node` and `#nodes` methods of `Types::QueryType`. `lighthouse:install`
|
|
165
|
+
declares both fields in the starter `graphql/schema.graphql`, and removes the
|
|
166
|
+
`field :node` / `field :nodes` that graphql-ruby wrote in `Types::QueryType`,
|
|
167
|
+
so the SDL is where they are declared. An SDL field without a resolving
|
|
168
|
+
directive resolves with the root type class's method of its name. If the
|
|
169
|
+
fields stay in `Types::QueryType` instead, they are part of the schema too, and
|
|
170
|
+
the `node` field `@node` would add to `Query` gives way to them.
|
|
171
|
+
|
|
172
|
+
The starter schema `lighthouse:install` writes on graphql-ruby's Relay:
|
|
173
|
+
|
|
174
|
+
```graphql
|
|
175
|
+
type Query {
|
|
176
|
+
"Fetches an object given its ID. Resolved by Types::QueryType#node, with AppSchema.object_from_id."
|
|
177
|
+
node("ID of the object." id: ID!): Node
|
|
178
|
+
|
|
179
|
+
"Fetches a list of objects given a list of IDs. Resolved by Types::QueryType#nodes."
|
|
180
|
+
nodes("IDs of the objects." ids: [ID!]!): [Node]
|
|
181
|
+
|
|
182
|
+
user(id: ID! @globalId(decode: ID) @eq): User @find
|
|
183
|
+
users: [User!]! @paginate(defaultCount: 10)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
interface Node {
|
|
187
|
+
"ID of the object."
|
|
188
|
+
id: ID!
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
type User @node {
|
|
192
|
+
id: ID! @globalId
|
|
193
|
+
name: String
|
|
194
|
+
email: String
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
```ruby
|
|
199
|
+
module Types
|
|
200
|
+
class QueryType < Types::BaseObject
|
|
201
|
+
# Query.node and nodes are declared in graphql/schema.graphql; these methods resolve them.
|
|
202
|
+
def node(id:)
|
|
203
|
+
context.schema.object_from_id(id, context)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def nodes(ids:)
|
|
207
|
+
ids.map { |id| context.schema.object_from_id(id, context) }
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
`lighthouse:install` writes this only when the app has no schema file yet, and
|
|
214
|
+
only on the `node` / `nodes` fields as graphql-ruby writes them.
|
|
166
215
|
|
|
167
216
|
```graphql
|
|
168
217
|
type Tag @node {
|
|
@@ -26,6 +26,10 @@ module Lighthouse::Generators::GraphqlRubyInstall
|
|
|
26
26
|
# The example field graphql-ruby's install puts in each root type.
|
|
27
27
|
TEST_FIELD = /\n+[ \t]*# TODO: remove me\n[ \t]*field :test_field,.*?\n[ \t]*def test_field\n.*?\n[ \t]*end\n/m
|
|
28
28
|
|
|
29
|
+
# The `node` and `nodes` fields graphql-ruby's install (--relay, its default)
|
|
30
|
+
# puts in Types::QueryType, without the methods that resolve them.
|
|
31
|
+
RELAY_FIELDS = /^[ \t]*field :nodes?, \[?Types::NodeType\b.*? do\n(?:[ \t]*argument .*\n)*[ \t]*end\n\n?/
|
|
32
|
+
|
|
29
33
|
# The `resolve_type` stub graphql-ruby's install puts in the schema class.
|
|
30
34
|
RESOLVE_TYPE_STUB = /
|
|
31
35
|
\n+[ \t]*\#\ Union\ and\ Interface\ Resolution\n
|
|
@@ -98,6 +102,16 @@ module Lighthouse::Generators::GraphqlRubyInstall
|
|
|
98
102
|
options[:subscriptions] || exist?(File.join(directory, 'subscriptions', 'base_subscription.rb'))
|
|
99
103
|
end
|
|
100
104
|
|
|
105
|
+
# Did graphql-ruby's install write Relay's side (--relay, its default):
|
|
106
|
+
# Types::NodeType, and Types::QueryType's node and nodes, as it writes them?
|
|
107
|
+
def relay?
|
|
108
|
+
query_type = types_path('query_type.rb')
|
|
109
|
+
return false unless exist?(types_path('node_type.rb')) && exist?(query_type)
|
|
110
|
+
|
|
111
|
+
source = read(query_type)
|
|
112
|
+
source.scan(RELAY_FIELDS).size == 2 && source.include?('def node(id:)') && source.include?('def nodes(ids:)')
|
|
113
|
+
end
|
|
114
|
+
|
|
101
115
|
def graphql_ruby_controller?(source)
|
|
102
116
|
source.include?('def prepare_variables(variables_param)') && source.include?('def handle_error_in_development(e)') &&
|
|
103
117
|
source.include?("#{schema_name}.execute(query, variables: variables, context: context, operation_name: operation_name)")
|
|
@@ -21,6 +21,9 @@ require_relative 'graphql_ruby_install'
|
|
|
21
21
|
# graphql-ruby's and stays, but the `resolve_type` stub (Lighthouse resolves
|
|
22
22
|
# types) and the root types it is built on;
|
|
23
23
|
# - the example `test_field` goes from the root types;
|
|
24
|
+
# - with Relay, the starter SDL declares Query.node and nodes (and a User
|
|
25
|
+
# @node with global ids), so their `field`s go from Types::QueryType, whose
|
|
26
|
+
# #node / #nodes methods resolve the SDL's fields;
|
|
24
27
|
# - graphql-ruby's base object, interface, union and scalar include
|
|
25
28
|
# Lighthouse::GraphQL::Type, so every type class (Types::QueryType,
|
|
26
29
|
# Types::NodeType, what `graphql:object` writes) is Lighthouse's;
|
|
@@ -76,6 +79,7 @@ class Lighthouse::Generators::InstallGenerator < Rails::Generators::Base
|
|
|
76
79
|
return
|
|
77
80
|
end
|
|
78
81
|
|
|
82
|
+
@relay_starter = relay?
|
|
79
83
|
template 'schema.graphql.tt', sdl_schema_path
|
|
80
84
|
end
|
|
81
85
|
|
|
@@ -101,12 +105,15 @@ class Lighthouse::Generators::InstallGenerator < Rails::Generators::Base
|
|
|
101
105
|
add_dataloader if source.include?('use GraphQL::Batch') && source.exclude?('use GraphQL::Dataloader')
|
|
102
106
|
end
|
|
103
107
|
|
|
104
|
-
# The example field goes; the root types' own fields stay.
|
|
108
|
+
# The example field goes; the root types' own fields stay. With Relay, the
|
|
109
|
+
# starter SDL declares Query.node and nodes, so their `field`s go too, and
|
|
110
|
+
# the methods graphql-ruby wrote resolve the SDL's fields.
|
|
105
111
|
def adapt_root_types
|
|
106
112
|
%w[query_type mutation_type subscription_type].each do |name|
|
|
107
113
|
path = types_path("#{name}.rb")
|
|
108
114
|
gsub_file path, TEST_FIELD, "\n" if exist?(path) && read(path).match?(TEST_FIELD)
|
|
109
115
|
end
|
|
116
|
+
move_relay_fields_to_sdl if @relay_starter
|
|
110
117
|
end
|
|
111
118
|
|
|
112
119
|
# Every type class is Lighthouse's: graphql-ruby's base object, interface,
|
|
@@ -223,6 +230,13 @@ class Lighthouse::Generators::InstallGenerator < Rails::Generators::Base
|
|
|
223
230
|
sdl_schema_path == 'graphql/schema.graphql'
|
|
224
231
|
end
|
|
225
232
|
|
|
233
|
+
def move_relay_fields_to_sdl
|
|
234
|
+
path = types_path('query_type.rb')
|
|
235
|
+
gsub_file path, RELAY_FIELDS, ''
|
|
236
|
+
gsub_file path, /^([ \t]*)def node\(id:\)\n/,
|
|
237
|
+
"\\1# Query.node and nodes are declared in #{sdl_schema_path}; these methods resolve them.\n\\1def node(id:)\n"
|
|
238
|
+
end
|
|
239
|
+
|
|
226
240
|
def ide_helper_files
|
|
227
241
|
[Lighthouse::IdeHelper::DIRECTIVES_FILE, Lighthouse::IdeHelper::PROGRAMMATIC_TYPES_FILE]
|
|
228
242
|
end
|
|
@@ -1,15 +1,44 @@
|
|
|
1
1
|
# Starter schema generated by `rails generate lighthouse:install`. It assumes a
|
|
2
2
|
# User model with `name` and `email` columns — replace it with your own types.
|
|
3
|
+
# This file is the schema's entrypoint: split the schema into files it imports
|
|
4
|
+
# (#import user.graphql), which add their fields with `extend type Query`.
|
|
3
5
|
# Directives reference: https://github.com/Vaz-Innovation/lighthouse-graphql/blob/main/docs/directives.md
|
|
4
6
|
|
|
5
7
|
"Indicates what fields are available at the top level of a query operation."
|
|
6
8
|
type Query {
|
|
9
|
+
<% if relay? -%>
|
|
10
|
+
"Fetches an object given its ID. Resolved by Types::QueryType#node, with <%= schema_name %>.object_from_id."
|
|
11
|
+
node("ID of the object." id: ID!): Node
|
|
12
|
+
|
|
13
|
+
"Fetches a list of objects given a list of IDs. Resolved by Types::QueryType#nodes."
|
|
14
|
+
nodes("IDs of the objects." ids: [ID!]!): [Node]
|
|
15
|
+
|
|
16
|
+
"Find a single user by its global id."
|
|
17
|
+
user(id: ID! @globalId(decode: ID) @eq): User @find
|
|
18
|
+
<% else -%>
|
|
7
19
|
"Find a single user by id."
|
|
8
20
|
user(id: ID! @eq): User @find
|
|
21
|
+
<% end -%>
|
|
9
22
|
|
|
10
23
|
"List users, a page at a time (10 by default; pass first: and page:)."
|
|
11
24
|
users: [User!]! @paginate(defaultCount: 10)
|
|
12
25
|
}
|
|
26
|
+
<% if relay? -%>
|
|
27
|
+
|
|
28
|
+
"An object with an ID: graphql-ruby's Types::NodeType."
|
|
29
|
+
interface Node {
|
|
30
|
+
"ID of the object."
|
|
31
|
+
id: ID!
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
"Account of a person who uses this application. @node makes it a Node, which Query.node finds."
|
|
35
|
+
type User @node {
|
|
36
|
+
"Its global id, from <%= schema_name %>.id_from_object (Rails' GlobalID)."
|
|
37
|
+
id: ID! @globalId
|
|
38
|
+
name: String
|
|
39
|
+
email: String
|
|
40
|
+
}
|
|
41
|
+
<% else -%>
|
|
13
42
|
|
|
14
43
|
"Account of a person who uses this application."
|
|
15
44
|
type User {
|
|
@@ -17,3 +46,4 @@ type User {
|
|
|
17
46
|
name: String
|
|
18
47
|
email: String
|
|
19
48
|
}
|
|
49
|
+
<% end -%>
|