nulogy_graphql_api 0.4.0 → 1.0.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/.rubocop.yml +117 -0
- data/Appraisals +1 -0
- data/CHANGELOG.md +39 -9
- data/README.md +83 -20
- data/gemfiles/rails_5.gemfile +2 -1
- data/gemfiles/rails_6.gemfile +1 -1
- data/lib/nulogy_graphql_api.rb +3 -0
- data/lib/nulogy_graphql_api/rspec.rb +2 -2
- data/lib/nulogy_graphql_api/rspec/graphql_helpers.rb +2 -2
- data/lib/nulogy_graphql_api/schema/base_mutation.rb +12 -0
- data/lib/nulogy_graphql_api/tasks/schema_changes_checker.rb +32 -0
- data/lib/nulogy_graphql_api/tasks/schema_generator.rb +37 -0
- data/lib/nulogy_graphql_api/version.rb +1 -1
- data/lib/tasks/graphql_schema.rake +5 -69
- data/nulogy_graphql_api.gemspec +6 -5
- metadata +34 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8abde35aa513cd066444a4f67427ce59a53a4e0ecba57f6e404893b7364ff57
|
4
|
+
data.tar.gz: f779d84620bcd6945e9be210bf271aaf55ab33c7952eaea9eb9ed4f34d486857
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6932ab2af2b84d41567627f772a036ff3adb79a57cd8b0d55c897e45f3569c9b843419b49ea09978a307b93d8aa7abcec6dcbcd0ffa9b8e058563713c4fef479
|
7
|
+
data.tar.gz: 1b2588c7c65128f435b4ce474aaf89fe1d6937c90f55efa98758864ab847520867c6624aa26241b6de6728ab443e9b49d4d971fa733da4d432230b73742ba6e2
|
data/.rubocop.yml
CHANGED
@@ -6,6 +6,9 @@ inherit_from:
|
|
6
6
|
AllCops:
|
7
7
|
TargetRubyVersion: 2.6
|
8
8
|
|
9
|
+
Gemspec/DateAssignment:
|
10
|
+
Enabled: true
|
11
|
+
|
9
12
|
Layout/EmptyLinesAroundAttributeAccessor:
|
10
13
|
Enabled: true
|
11
14
|
|
@@ -38,18 +41,72 @@ Layout/MultilineOperationIndentation:
|
|
38
41
|
Layout/SpaceAroundMethodCallOperator:
|
39
42
|
Enabled: false
|
40
43
|
|
44
|
+
Layout/SpaceBeforeBrackets:
|
45
|
+
Enabled: true
|
46
|
+
|
47
|
+
Lint/AmbiguousAssignment:
|
48
|
+
Enabled: true
|
49
|
+
|
50
|
+
Lint/DeprecatedConstants:
|
51
|
+
Enabled: true
|
52
|
+
|
41
53
|
Lint/DeprecatedOpenSSLConstant:
|
42
54
|
Enabled: true
|
43
55
|
|
56
|
+
Lint/DuplicateBranch:
|
57
|
+
Enabled: true
|
58
|
+
|
59
|
+
Lint/DuplicateElsifCondition:
|
60
|
+
Enabled: true
|
61
|
+
|
62
|
+
Lint/DuplicateRegexpCharacterClassElement:
|
63
|
+
Enabled: true
|
64
|
+
|
65
|
+
Lint/EmptyBlock:
|
66
|
+
Enabled: true
|
67
|
+
|
68
|
+
Lint/EmptyClass:
|
69
|
+
Enabled: true
|
70
|
+
|
71
|
+
Lint/LambdaWithoutLiteralBlock:
|
72
|
+
Enabled: true
|
73
|
+
|
44
74
|
Lint/MixedRegexpCaptureTypes:
|
45
75
|
Enabled: true
|
46
76
|
|
77
|
+
Lint/NoReturnInBeginEndBlocks:
|
78
|
+
Enabled: true
|
79
|
+
|
80
|
+
Lint/NumberedParameterAssignment:
|
81
|
+
Enabled: true
|
82
|
+
|
83
|
+
Lint/OrAssignmentToConstant:
|
84
|
+
Enabled: true
|
85
|
+
|
47
86
|
Lint/RaiseException:
|
48
87
|
Enabled: false
|
49
88
|
|
89
|
+
Lint/RedundantDirGlobSort:
|
90
|
+
Enabled: true
|
91
|
+
|
50
92
|
Lint/StructNewOverride:
|
51
93
|
Enabled: false
|
52
94
|
|
95
|
+
Lint/SymbolConversion:
|
96
|
+
Enabled: true
|
97
|
+
|
98
|
+
Lint/ToEnumArguments:
|
99
|
+
Enabled: true
|
100
|
+
|
101
|
+
Lint/TripleQuotes:
|
102
|
+
Enabled: true
|
103
|
+
|
104
|
+
Lint/UnexpectedBlockArity:
|
105
|
+
Enabled: true
|
106
|
+
|
107
|
+
Lint/UnmodifiedReduceAccumulator:
|
108
|
+
Enabled: true
|
109
|
+
|
53
110
|
Metrics:
|
54
111
|
Enabled: false
|
55
112
|
|
@@ -74,18 +131,57 @@ RSpec/MessageSpies:
|
|
74
131
|
RSpec/NotToNot:
|
75
132
|
EnforcedStyle: to_not
|
76
133
|
|
134
|
+
Style/AccessorGrouping:
|
135
|
+
Enabled: true
|
136
|
+
|
137
|
+
Style/ArgumentsForwarding:
|
138
|
+
Enabled: true
|
139
|
+
|
140
|
+
Style/ArrayCoercion:
|
141
|
+
Enabled: true
|
142
|
+
|
143
|
+
Style/BisectedAttrAccessor:
|
144
|
+
Enabled: true
|
145
|
+
|
146
|
+
Style/CaseLikeIf:
|
147
|
+
Enabled: true
|
148
|
+
|
149
|
+
Style/CollectionCompact:
|
150
|
+
Enabled: true
|
151
|
+
|
152
|
+
Style/DocumentDynamicEvalDefinition:
|
153
|
+
Enabled: true
|
154
|
+
|
155
|
+
Style/EndlessMethod:
|
156
|
+
Enabled: true
|
157
|
+
|
77
158
|
Style/ExponentialNotation:
|
78
159
|
Enabled: false
|
79
160
|
|
161
|
+
Style/HashAsLastArrayItem:
|
162
|
+
Enabled: true
|
163
|
+
|
164
|
+
Style/HashConversion:
|
165
|
+
Enabled: true
|
166
|
+
|
80
167
|
Style/HashEachMethods:
|
81
168
|
Enabled: false
|
82
169
|
|
170
|
+
Style/HashExcept:
|
171
|
+
Enabled: true
|
172
|
+
|
173
|
+
Style/HashLikeCase:
|
174
|
+
Enabled: true
|
175
|
+
|
83
176
|
Style/HashTransformKeys:
|
84
177
|
Enabled: false
|
85
178
|
|
86
179
|
Style/HashTransformValues:
|
87
180
|
Enabled: false
|
88
181
|
|
182
|
+
Style/IfWithBooleanLiteralBranches:
|
183
|
+
Enabled: true
|
184
|
+
|
89
185
|
Style/BlockDelimiters:
|
90
186
|
Enabled: false
|
91
187
|
|
@@ -110,9 +206,24 @@ Style/GuardClause:
|
|
110
206
|
Style/MutableConstant:
|
111
207
|
Enabled: false
|
112
208
|
|
209
|
+
Style/NegatedIfElseCondition:
|
210
|
+
Enabled: true
|
211
|
+
|
113
212
|
Style/RaiseArgs:
|
114
213
|
Enabled: false
|
115
214
|
|
215
|
+
Style/RedundantArgument:
|
216
|
+
Enabled: true
|
217
|
+
|
218
|
+
Style/RedundantAssignment:
|
219
|
+
Enabled: true
|
220
|
+
|
221
|
+
Style/RedundantFetchBlock:
|
222
|
+
Enabled: true
|
223
|
+
|
224
|
+
Style/RedundantFileExtensionInRequire:
|
225
|
+
Enabled: true
|
226
|
+
|
116
227
|
Style/RedundantRegexpCharacterClass:
|
117
228
|
Enabled: true
|
118
229
|
|
@@ -131,6 +242,12 @@ Style/SlicingWithRange:
|
|
131
242
|
Style/StringLiterals:
|
132
243
|
EnforcedStyle: double_quotes
|
133
244
|
|
245
|
+
Style/SwapValues:
|
246
|
+
Enabled: true
|
247
|
+
|
248
|
+
Style/NilLambda:
|
249
|
+
Enabled: true
|
250
|
+
|
134
251
|
Style/SymbolArray:
|
135
252
|
Enabled: false
|
136
253
|
|
data/Appraisals
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,12 +2,42 @@
|
|
2
2
|
|
3
3
|
## master (unreleased)
|
4
4
|
|
5
|
+
## 1.0.0 (2021-05-17)
|
6
|
+
|
7
|
+
**Changes**
|
8
|
+
|
9
|
+
* **(Breaking)** Change argument to `SchemaGenerator`
|
10
|
+
|
11
|
+
The `SchemaGenerator` now takes the path to the `schema.graphql` and the schema class as required arguments.
|
12
|
+
See [the update in the README](README.md#Schema-Generation).
|
13
|
+
|
14
|
+
## 0.6.0 (2021-02-24)
|
15
|
+
|
16
|
+
**Changes**
|
17
|
+
|
18
|
+
* **(Potentially Breaking)** Bump graphql gem version to 1.12.5
|
19
|
+
|
20
|
+
## 0.5.3 (2020-08-11)
|
21
|
+
|
22
|
+
* Add `BaseMutation`.
|
23
|
+
|
24
|
+
## 0.5.1 (2020-08-11)
|
25
|
+
|
26
|
+
* Add the `schema_generation_context?` attribute to the GraphQL `context` when generating the schema.
|
27
|
+
|
28
|
+
## 0.5.0 (2020-08-05)
|
29
|
+
|
30
|
+
**Changes**
|
31
|
+
|
32
|
+
* **(Breaking)** Add `context` to the Rake task that generates the schema file.
|
33
|
+
This changes the way the schema is parsed. Please refer to the README file to see an example of how to use `context`.
|
34
|
+
|
5
35
|
## 0.4.0 (2020-07-06)
|
6
36
|
|
7
|
-
**
|
37
|
+
**Changes**
|
8
38
|
|
9
|
-
* Remove the GraphqlApiController
|
10
|
-
* Add the ErrorHandling controller concern
|
39
|
+
* **(Breaking)** Remove the GraphqlApiController
|
40
|
+
* **(Breaking)** Add the ErrorHandling controller concern
|
11
41
|
|
12
42
|
## 0.3.1 (2020-07-03)
|
13
43
|
|
@@ -15,20 +45,20 @@
|
|
15
45
|
|
16
46
|
## 0.3.0 (2020-06-25)
|
17
47
|
|
18
|
-
**
|
48
|
+
**Changes**
|
19
49
|
|
20
|
-
* Remove spec helpers related to subscriptions
|
50
|
+
* **(Breaking)** Remove spec helpers related to subscriptions
|
21
51
|
|
22
52
|
## 0.2.0 (2020-06-24)
|
23
53
|
|
24
|
-
**
|
54
|
+
**Changes**
|
25
55
|
|
26
|
-
* Rename `GraphqlExecutor.call` to `execute`
|
27
|
-
* Change `schema` parameter on `execute_graphql` test helper to positional
|
56
|
+
* **(Breaking)** Rename `GraphqlExecutor.call` to `execute`
|
57
|
+
* **(Breaking)** Change `schema` parameter on `execute_graphql` test helper to positional
|
28
58
|
|
29
59
|
## 0.1.1 (2020-06-24)
|
30
60
|
|
31
|
-
**
|
61
|
+
**Changes**
|
32
62
|
|
33
63
|
* RSpec custom matchers
|
34
64
|
* RSpec helpers
|
data/README.md
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
# NulogyGraphqlApi
|
2
2
|
|
3
|
+
## Intent
|
4
|
+
|
5
|
+
Help Nulogy applications be compliant with the [Standard on Error-handling in GraphQL](https://trello.com/c/N5cHt4Gp/7-error-handling-in-graphql-apis).
|
6
|
+
|
3
7
|
## Installation
|
4
8
|
|
5
9
|
Add this line to your application's Gemfile:
|
6
10
|
|
7
11
|
```ruby
|
8
|
-
gem "nulogy_graphql_api", "0.
|
12
|
+
gem "nulogy_graphql_api", "1.0.0"
|
9
13
|
```
|
10
14
|
|
11
15
|
And then execute:
|
@@ -25,7 +29,8 @@ Or install it yourself as:
|
|
25
29
|
- [Types](#types)
|
26
30
|
- [UserErrorType](#usererrortype)
|
27
31
|
- [UUID](#uuid)
|
28
|
-
- [
|
32
|
+
- [Schema Generation](#schema-generation)
|
33
|
+
- [Node Visibility](#node-visibility)
|
29
34
|
|
30
35
|
#### Testing
|
31
36
|
|
@@ -36,9 +41,9 @@ Or install it yourself as:
|
|
36
41
|
|
37
42
|
#### Receiving Requests
|
38
43
|
|
39
|
-
Given that you have already defined your GraphQL `Schema` you can receive requests by defining a controller action and execute the params by calling the `NulogyGraphqlApi::GraphqlExecutor`.
|
44
|
+
Given that you have already defined your GraphQL `Schema` you can receive requests by defining a controller action and execute the params by calling the `NulogyGraphqlApi::GraphqlExecutor`.
|
40
45
|
|
41
|
-
- Remember to configure your routes to include the controller action.
|
46
|
+
- Remember to configure your routes to include the controller action.
|
42
47
|
- We called the action `execute` in the example below, but you can call it whatever makes more sense for your app.
|
43
48
|
|
44
49
|
```ruby
|
@@ -48,9 +53,9 @@ module MyApp
|
|
48
53
|
|
49
54
|
def execute
|
50
55
|
NulogyGraphqlApi::GraphqlExecutor.execute(
|
51
|
-
params,
|
52
|
-
context,
|
53
|
-
Schema,
|
56
|
+
params,
|
57
|
+
context,
|
58
|
+
Schema,
|
54
59
|
NulogyGraphqlApi::TransactionService.new
|
55
60
|
)
|
56
61
|
end
|
@@ -69,7 +74,7 @@ module MyApp
|
|
69
74
|
|
70
75
|
def render_error(exception)
|
71
76
|
MyApp::ExceptionNotifier.notify(exception)
|
72
|
-
|
77
|
+
|
73
78
|
super
|
74
79
|
end
|
75
80
|
end
|
@@ -87,10 +92,10 @@ module MyApp
|
|
87
92
|
class CreateEntity < GraphQL::Schema::Mutation
|
88
93
|
field :entity, MyApp::EntityType, null: false
|
89
94
|
field :errors, [NulogyGraphqlApi::Types::UserErrorType], null: false
|
90
|
-
|
95
|
+
|
91
96
|
def resolve(args)
|
92
97
|
entity = create_entity(args)
|
93
|
-
|
98
|
+
|
94
99
|
{
|
95
100
|
entity: entity,
|
96
101
|
errors: extract_errors(entity)
|
@@ -98,7 +103,7 @@ module MyApp
|
|
98
103
|
end
|
99
104
|
|
100
105
|
def extract_errors(entity)
|
101
|
-
entity.errors.map do |attribute, message|
|
106
|
+
entity.errors.map do |attribute, message|
|
102
107
|
{
|
103
108
|
path: path_for(attribute),
|
104
109
|
message: entity.errors.full_message(attribute, message)
|
@@ -121,20 +126,63 @@ module MyApp
|
|
121
126
|
end
|
122
127
|
```
|
123
128
|
|
124
|
-
###
|
129
|
+
### Schema Generation
|
125
130
|
|
126
|
-
There is a Rake task to generate the `schema.graphql` file.
|
131
|
+
There is a Rake task to generate the `schema.graphql` file. You need to provide the `schema_file_path` and the schema class so that the task can detect breaking changes and generate the file. If you don't have a schema file because it's your first time generating it then the rake task will just create one for you in the path provided.
|
132
|
+
|
133
|
+
There is also a third argument `context`. You'll have to configure it to be able to generate the SDL of fields or types that are only visible for more privileged users.
|
127
134
|
|
128
135
|
```ruby
|
129
|
-
namespace :
|
136
|
+
namespace :graphql_api do
|
130
137
|
desc "Generate the graphql schema of the api."
|
131
138
|
|
132
139
|
task :generate_schema => :environment do
|
133
|
-
|
134
|
-
|
140
|
+
schema_file_path = MyApp::Engine.root.join("schema.graphql")
|
141
|
+
schema = MyApp::Namespace::To::Schema
|
135
142
|
|
136
|
-
|
137
|
-
.
|
143
|
+
NulogyGraphqlApi::Tasks::SchemaGenerator
|
144
|
+
.new(schema_file_path, schema)
|
145
|
+
.generate_schema
|
146
|
+
end
|
147
|
+
end
|
148
|
+
```
|
149
|
+
|
150
|
+
### Node visibility
|
151
|
+
|
152
|
+
When you customize the visibility of parts of your graph you have to make sure that all nodes are visible when the schema is being generated by the rake task. You can do so by using the `schema_generation_context?` attribute that is added to the context by the `SchemaGenerator` mentioned in the previous section.
|
153
|
+
|
154
|
+
Here is how to use it:
|
155
|
+
|
156
|
+
##### On fields
|
157
|
+
```ruby
|
158
|
+
field :entity, MyApp::EntityType, null: false do
|
159
|
+
description "Find an entity by ID"
|
160
|
+
argument :id, ID, required: true
|
161
|
+
|
162
|
+
def visible?(context)
|
163
|
+
context[:schema_generation_context?] || context[:current_user].superuser?
|
164
|
+
end
|
165
|
+
end
|
166
|
+
```
|
167
|
+
|
168
|
+
|
169
|
+
##### On mutations
|
170
|
+
|
171
|
+
In this case the `schema_generation_context?` attribute is checked by the `BaseMutation` class. All you have to do is inheriting from it and override `visible?` passing a block to the base method.
|
172
|
+
|
173
|
+
```ruby
|
174
|
+
module MyApp
|
175
|
+
class CreateEntity < NulogyGraphqlApi::Schema::BaseMutation
|
176
|
+
field :entity, MyApp::EntityType, null: false
|
177
|
+
field :errors, [NulogyGraphqlApi::Types::UserErrorType], null: false
|
178
|
+
|
179
|
+
def self.visible?(context)
|
180
|
+
super { context[:current_user].super_user? }
|
181
|
+
end
|
182
|
+
|
183
|
+
def resolve(args)
|
184
|
+
# ...
|
185
|
+
end
|
138
186
|
end
|
139
187
|
end
|
140
188
|
```
|
@@ -154,7 +202,7 @@ RSpec.configure do |config|
|
|
154
202
|
config.include NulogyGraphqlApi::GraphqlMatchers, graphql: true
|
155
203
|
config.include NulogyGraphqlApi::GraphqlHelpers, graphql: true
|
156
204
|
end
|
157
|
-
```
|
205
|
+
```
|
158
206
|
|
159
207
|
#### Test helpers
|
160
208
|
|
@@ -231,7 +279,22 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
231
279
|
|
232
280
|
## Contributing
|
233
281
|
|
234
|
-
|
282
|
+
We treat this project as an internal "open source" project. Everyone at Nulogy is welcome to submit Pull Requests.
|
283
|
+
|
284
|
+
### Submitting Pull Requests
|
285
|
+
|
286
|
+
The Directly Responsible Individual (DRI) for this project is Daniel Silva.
|
287
|
+
|
288
|
+
When you are happy with your changes:
|
289
|
+
|
290
|
+
1. Add description of changes to the top of the [CHANGELOG](./CHANGELOG.md) file, under the `## master (unreleased)` section subdivided into the following categories:
|
291
|
+
- New Features
|
292
|
+
- Bug Fixes
|
293
|
+
- Changes
|
294
|
+
- *prepend these with* **(Breaking)***,* **(Potentially Breaking)** *or just leave it blank in case neither applies*
|
295
|
+
|
296
|
+
1. Create a Pull Request.
|
297
|
+
1. Notify #nulogy-graphql-api Slack channel to get the DRI review and merge your changes.
|
235
298
|
|
236
299
|
## License
|
237
300
|
|
data/gemfiles/rails_5.gemfile
CHANGED
data/gemfiles/rails_6.gemfile
CHANGED
data/lib/nulogy_graphql_api.rb
CHANGED
@@ -3,7 +3,10 @@ require "graphql"
|
|
3
3
|
require "nulogy_graphql_api/error_handling"
|
4
4
|
require "nulogy_graphql_api/graphql_executor"
|
5
5
|
require "nulogy_graphql_api/graphql_response"
|
6
|
+
require "nulogy_graphql_api/schema/base_mutation"
|
6
7
|
require "nulogy_graphql_api/transaction_service"
|
8
|
+
require "nulogy_graphql_api/tasks/schema_changes_checker"
|
9
|
+
require "nulogy_graphql_api/tasks/schema_generator"
|
7
10
|
require "nulogy_graphql_api/types/user_error_type"
|
8
11
|
require "nulogy_graphql_api/types/uuid"
|
9
12
|
require "nulogy_graphql_api/version"
|
@@ -1,4 +1,4 @@
|
|
1
1
|
# relative-require all rspec files
|
2
|
-
Dir[File.dirname(__FILE__)
|
3
|
-
require "nulogy_graphql_api/rspec
|
2
|
+
Dir["#{File.dirname(__FILE__)}/rspec/*.rb"].each do |file|
|
3
|
+
require "nulogy_graphql_api/rspec/#{File.basename(file, File.extname(file))}"
|
4
4
|
end
|
@@ -16,8 +16,8 @@ module NulogyGraphqlApi
|
|
16
16
|
def request_graphql(url, query, variables: {}, headers: {})
|
17
17
|
params = { query: query, variables: variables }.to_json
|
18
18
|
default_headers = {
|
19
|
-
|
20
|
-
|
19
|
+
CONTENT_TYPE: "application/json",
|
20
|
+
HTTP_AUTHORIZATION: basic_auth_token(default_user.login)
|
21
21
|
}
|
22
22
|
|
23
23
|
post url, params: params, headers: default_headers.merge(headers)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "graphql/schema_comparator"
|
2
|
+
require "rainbow"
|
3
|
+
|
4
|
+
module NulogyGraphqlApi
|
5
|
+
module Tasks
|
6
|
+
class SchemaChangesChecker
|
7
|
+
def check_changes(old_schema, new_schema)
|
8
|
+
compare_result = GraphQL::SchemaComparator.compare(old_schema, new_schema)
|
9
|
+
|
10
|
+
abort "Task aborted!\n #{Rainbow('No schema changes found.').green}" if compare_result.identical?
|
11
|
+
abort "Task aborted!" unless accept_breaking_changes?(compare_result)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def accept_breaking_changes?(compare_result)
|
17
|
+
return true if !compare_result.breaking? && compare_result.dangerous_changes.none?
|
18
|
+
|
19
|
+
puts Rainbow("\nThe current GraphQL Schema has breaking or dangerous changes:").yellow
|
20
|
+
|
21
|
+
compare_result.breaking_changes.concat(compare_result.dangerous_changes).each do |change|
|
22
|
+
puts Rainbow("\n\n- #{change.message} #{change.dangerous? ? '(Dangerous)' : '(Breaking)'}").yellow
|
23
|
+
puts Rainbow(" #{change.criticality.reason}").yellow
|
24
|
+
end
|
25
|
+
|
26
|
+
puts "\n\nDo you want to update the schema anyway? [Y/n]"
|
27
|
+
|
28
|
+
$stdin.gets.chomp.downcase != "n"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module NulogyGraphqlApi
|
2
|
+
module Tasks
|
3
|
+
class SchemaGenerator
|
4
|
+
def initialize(schema_output_path, schema_definition, context: {})
|
5
|
+
@schema_output_path = schema_output_path
|
6
|
+
@schema_definition = schema_definition
|
7
|
+
@context = context.merge(
|
8
|
+
schema_generation_context?: true
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate_schema
|
13
|
+
check_changes
|
14
|
+
write_schema_to_file
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def check_changes
|
20
|
+
return if old_schema.blank?
|
21
|
+
|
22
|
+
SchemaChangesChecker.new.check_changes(old_schema, @schema_definition)
|
23
|
+
end
|
24
|
+
|
25
|
+
def old_schema
|
26
|
+
return unless File.exist?(@schema_output_path)
|
27
|
+
|
28
|
+
File.read(@schema_output_path)
|
29
|
+
end
|
30
|
+
|
31
|
+
def write_schema_to_file
|
32
|
+
File.write(@schema_output_path, schema_definition)
|
33
|
+
puts Rainbow("\nSuccessfully updated #{@schema_output_path}").green
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -1,75 +1,11 @@
|
|
1
1
|
namespace :nulogy_graphql_api do
|
2
2
|
desc "Generate a schema.graphql file"
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
compare_result = GraphQL::SchemaComparator.compare(old_schema, new_schema)
|
4
|
+
task :generate_schema, [:schema_output_path, :schema_definition_path] => :environment do |_task, args|
|
5
|
+
abort "schema_definition_path is required" unless args.key?(:schema_definition_path)
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
private
|
13
|
-
|
14
|
-
def accept_breaking_changes?(compare_result)
|
15
|
-
return true if !compare_result.breaking? && compare_result.dangerous_changes.none?
|
16
|
-
|
17
|
-
puts Rainbow("\nThe current GraphQL Schema has breaking or dangerous changes:").yellow
|
18
|
-
|
19
|
-
compare_result.breaking_changes.concat(compare_result.dangerous_changes).each do |change|
|
20
|
-
puts Rainbow("\n\n- #{change.message} #{change.dangerous? ? '(Dangerous)' : '(Breaking)'}").yellow
|
21
|
-
puts Rainbow(" #{change.criticality.reason}").yellow
|
22
|
-
end
|
23
|
-
|
24
|
-
puts "\n\nDo you want to update the schema anyway? [Y/n]"
|
25
|
-
|
26
|
-
STDIN.gets.chomp != "n"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
class GraphqlSchemaGenerator
|
31
|
-
SCHEMA_FILE_NAME = "schema.graphql"
|
32
|
-
|
33
|
-
def generate_schema(old_schema_file_path, new_schema_file_path)
|
34
|
-
@old_schema_file_path = old_schema_file_path
|
35
|
-
@new_schema_file_path = new_schema_file_path
|
36
|
-
|
37
|
-
generate_schema_file
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def check_changes(old_schema, new_schema)
|
43
|
-
GraphqlSchemaChangesChecker.new.check_changes(old_schema, new_schema)
|
44
|
-
end
|
45
|
-
|
46
|
-
def new_schema
|
47
|
-
require @new_schema_file_path
|
48
|
-
|
49
|
-
GraphQL::Schema.descendants.first.to_definition
|
50
|
-
end
|
51
|
-
|
52
|
-
def old_schema
|
53
|
-
return nil unless File.exists?(@old_schema_file_path)
|
54
|
-
|
55
|
-
File.read(@old_schema_file_path)
|
56
|
-
end
|
57
|
-
|
58
|
-
def generate_schema_file
|
59
|
-
check_changes(old_schema, new_schema) if old_schema
|
60
|
-
|
61
|
-
write_new_schema_file
|
62
|
-
end
|
63
|
-
|
64
|
-
def write_new_schema_file
|
65
|
-
File.write(@old_schema_file_path, new_schema)
|
66
|
-
puts Rainbow("\nSuccessfully updated #{@old_schema_file_path}").green
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
task :generate_schema, [:old_schema_file_path, :new_schema_file_path] => :environment do |_task, args|
|
71
|
-
abort "new_schema_file_path is required" unless args.key?(:new_schema_file_path)
|
72
|
-
|
73
|
-
GraphqlSchemaGenerator.new.generate_schema(args[:old_schema_file_path], args[:new_schema_file_path])
|
7
|
+
NulogyGraphqlApi::Tasks::SchemaGenerator
|
8
|
+
.new(args[:schema_output_path], args[:schema_definition_path], context: {})
|
9
|
+
.generate_schema
|
74
10
|
end
|
75
11
|
end
|
data/nulogy_graphql_api.gemspec
CHANGED
@@ -28,14 +28,15 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
29
29
|
spec.require_paths = ["lib"]
|
30
30
|
|
31
|
-
spec.add_dependency "graphql", "~> 1.
|
32
|
-
spec.add_dependency "graphql-schema_comparator", "~> 0.
|
31
|
+
spec.add_dependency "graphql", "~> 1.12.5"
|
32
|
+
spec.add_dependency "graphql-schema_comparator", "~> 1.0.0"
|
33
33
|
spec.add_dependency "rails", ">= 5.2.4", "< 6.1.0"
|
34
|
+
spec.add_dependency "rainbow", "~> 3.0.0"
|
34
35
|
|
35
|
-
spec.add_development_dependency "appraisal", "~> 2.
|
36
|
+
spec.add_development_dependency "appraisal", "~> 2.3.0"
|
36
37
|
spec.add_development_dependency "rspec-rails", "~> 3.9.0"
|
37
|
-
spec.add_development_dependency "rubocop", "~> 0
|
38
|
+
spec.add_development_dependency "rubocop", "~> 1.10.0"
|
38
39
|
spec.add_development_dependency "rubocop-performance", "~> 1.6"
|
39
|
-
spec.add_development_dependency "rubocop-rspec", "~>
|
40
|
+
spec.add_development_dependency "rubocop-rspec", "~> 2.2.0"
|
40
41
|
spec.add_development_dependency "sqlite3", "~> 1.4.2"
|
41
42
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nulogy_graphql_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Silva
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.12.5
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 1.12.5
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: graphql-schema_comparator
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 1.0.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: 1.0.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rails
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,20 +58,34 @@ dependencies:
|
|
58
58
|
- - "<"
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: 6.1.0
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rainbow
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 3.0.0
|
68
|
+
type: :runtime
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 3.0.0
|
61
75
|
- !ruby/object:Gem::Dependency
|
62
76
|
name: appraisal
|
63
77
|
requirement: !ruby/object:Gem::Requirement
|
64
78
|
requirements:
|
65
79
|
- - "~>"
|
66
80
|
- !ruby/object:Gem::Version
|
67
|
-
version: 2.
|
81
|
+
version: 2.3.0
|
68
82
|
type: :development
|
69
83
|
prerelease: false
|
70
84
|
version_requirements: !ruby/object:Gem::Requirement
|
71
85
|
requirements:
|
72
86
|
- - "~>"
|
73
87
|
- !ruby/object:Gem::Version
|
74
|
-
version: 2.
|
88
|
+
version: 2.3.0
|
75
89
|
- !ruby/object:Gem::Dependency
|
76
90
|
name: rspec-rails
|
77
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -92,14 +106,14 @@ dependencies:
|
|
92
106
|
requirements:
|
93
107
|
- - "~>"
|
94
108
|
- !ruby/object:Gem::Version
|
95
|
-
version:
|
109
|
+
version: 1.10.0
|
96
110
|
type: :development
|
97
111
|
prerelease: false
|
98
112
|
version_requirements: !ruby/object:Gem::Requirement
|
99
113
|
requirements:
|
100
114
|
- - "~>"
|
101
115
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
116
|
+
version: 1.10.0
|
103
117
|
- !ruby/object:Gem::Dependency
|
104
118
|
name: rubocop-performance
|
105
119
|
requirement: !ruby/object:Gem::Requirement
|
@@ -120,14 +134,14 @@ dependencies:
|
|
120
134
|
requirements:
|
121
135
|
- - "~>"
|
122
136
|
- !ruby/object:Gem::Version
|
123
|
-
version:
|
137
|
+
version: 2.2.0
|
124
138
|
type: :development
|
125
139
|
prerelease: false
|
126
140
|
version_requirements: !ruby/object:Gem::Requirement
|
127
141
|
requirements:
|
128
142
|
- - "~>"
|
129
143
|
- !ruby/object:Gem::Version
|
130
|
-
version:
|
144
|
+
version: 2.2.0
|
131
145
|
- !ruby/object:Gem::Dependency
|
132
146
|
name: sqlite3
|
133
147
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,7 +156,7 @@ dependencies:
|
|
142
156
|
- - "~>"
|
143
157
|
- !ruby/object:Gem::Version
|
144
158
|
version: 1.4.2
|
145
|
-
description:
|
159
|
+
description:
|
146
160
|
email:
|
147
161
|
- danielsi@nulogy.com
|
148
162
|
executables: []
|
@@ -175,6 +189,9 @@ files:
|
|
175
189
|
- lib/nulogy_graphql_api/rspec.rb
|
176
190
|
- lib/nulogy_graphql_api/rspec/graphql_helpers.rb
|
177
191
|
- lib/nulogy_graphql_api/rspec/graphql_matchers.rb
|
192
|
+
- lib/nulogy_graphql_api/schema/base_mutation.rb
|
193
|
+
- lib/nulogy_graphql_api/tasks/schema_changes_checker.rb
|
194
|
+
- lib/nulogy_graphql_api/tasks/schema_generator.rb
|
178
195
|
- lib/nulogy_graphql_api/transaction_service.rb
|
179
196
|
- lib/nulogy_graphql_api/types/user_error_type.rb
|
180
197
|
- lib/nulogy_graphql_api/types/uuid.rb
|
@@ -189,7 +206,7 @@ metadata:
|
|
189
206
|
changelog_uri: https://github.com/nulogy/nulogy_graphql_api/blob/master/CHANGELOG.md
|
190
207
|
source_code_uri: https://github.com/nulogy/nulogy_graphql_api
|
191
208
|
bug_tracker_uri: https://github.com/nulogy/nulogy_graphql_api/issues
|
192
|
-
post_install_message:
|
209
|
+
post_install_message:
|
193
210
|
rdoc_options: []
|
194
211
|
require_paths:
|
195
212
|
- lib
|
@@ -204,8 +221,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
204
221
|
- !ruby/object:Gem::Version
|
205
222
|
version: '0'
|
206
223
|
requirements: []
|
207
|
-
rubygems_version: 3.
|
208
|
-
signing_key:
|
224
|
+
rubygems_version: 3.2.9
|
225
|
+
signing_key:
|
209
226
|
specification_version: 4
|
210
227
|
summary: Standard tooling for building GraphQL apis
|
211
228
|
test_files: []
|