graphiti_gql 0.2.1 → 0.2.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff76a3032a8378019cc0034c48cc1bd33302a8d662515fd722d970e642ee355e
4
- data.tar.gz: 532980890cd827d260bceebd5f944eeb999a561cde6df3e14cff5ddbfaa5f146
3
+ metadata.gz: 84a7ebf615007ac087b7bab32e53b78fc1bbdb7abcd9d65e38beac1ec7e578fc
4
+ data.tar.gz: d5c625d0e34f750d8fc3bc8c71f39ccabb70aa1c87340978620e965137e15feb
5
5
  SHA512:
6
- metadata.gz: 8a67a1e359377aa6682b2f23fd0461b2547a05df41c14739d4abf691d879682dd8cd83a4e4deda386855ae6c7a587feb453b2aff5490d2e0d44998955ff6bba9
7
- data.tar.gz: f5f83d5859fc24f3215723d3abd7d1105dcefc3f02002853f829a4d954923444df0d1a37c0cbbb736dbb79df9745dd1be1c197c6151b07febb117272eb12e8e7
6
+ metadata.gz: e8ea8defdb4712239187bcbb14a0d5dbeee9e52bf11a7c32dd747da2eae62247ef66fda15dd63b57886920a895f8215fe7a33b8eb3dc156194b3b2e3fd2f75c6
7
+ data.tar.gz: 42f885befb9c54a6b915642e40f2d2bb8704571c901c392f2a6fe11196d805113ca7af546ff15db7b336fdceff172ba2c27e9f443381462db26b4b44461eab6b
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- graphiti_gql (0.2.1)
4
+ graphiti_gql (0.2.2)
5
5
  graphiti (~> 1.3.9)
6
6
  graphql (~> 2.0)
7
7
  graphql-batch (~> 0.5)
@@ -47,7 +47,7 @@ GEM
47
47
  jsonapi-serializable (~> 0.3.0)
48
48
  graphiti_errors (1.1.2)
49
49
  jsonapi-serializable (~> 0.1)
50
- graphql (2.0.7)
50
+ graphql (2.0.11)
51
51
  graphql-batch (0.5.1)
52
52
  graphql (>= 1.10, < 3)
53
53
  promise.rb (~> 0.7.2)
@@ -0,0 +1,210 @@
1
+ module GraphitiGql
2
+ module ActiveResource
3
+ extend ActiveSupport::Concern
4
+
5
+ class Node < OpenStruct
6
+ def initialize(resource, hash)
7
+ @resource = resource
8
+ hash.each_pair do |key, value|
9
+ if value.is_a?(Hash)
10
+ if (sideload = resource.sideload(key))
11
+ if value.key?(:edges)
12
+ hash[key] = value[:edges].map { |v| Node.new(sideload.resource.class, v[:node]) }
13
+ else
14
+ hash[key] = Node.new(sideload.resource.class, value)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ super(hash)
20
+ end
21
+
22
+ def decoded_id
23
+ Base64.decode64(self.id)
24
+ end
25
+
26
+ def int_id
27
+ decoded_id.to_i
28
+ end
29
+ end
30
+
31
+ class Proxy
32
+ def initialize(resource, params, ctx)
33
+ @resource = resource
34
+ @ctx = ctx
35
+ @params = params.deep_transform_keys { |key| key.to_s.camelize(:lower).to_sym }
36
+ (@params[:sort] || []).each do |sort|
37
+ sort[:att] = sort[:att].to_s.camelize(:lower)
38
+ sort[:dir] = sort[:dir].to_s
39
+ end
40
+ end
41
+
42
+ def to_h(symbolize_keys: true)
43
+ result = GraphitiGql.run(query, @params, @ctx)
44
+ result = result.deep_symbolize_keys if symbolize_keys
45
+ @response = result
46
+ result
47
+ end
48
+
49
+ def nodes
50
+ return [] unless data
51
+ nodes = edges.map { |e| underscore(e[:node]) }
52
+ nodes.map { |n| Node.new(@resource, n) }
53
+ end
54
+ alias :to_a :nodes
55
+
56
+ def response
57
+ @response ||= to_h
58
+ end
59
+
60
+ def data
61
+ if response.key?(:data)
62
+ response[:data]
63
+ else
64
+ raise "Tried to access 'data', but these errors were returned instead: #{error_messages.join(". ")}."
65
+ end
66
+ end
67
+
68
+ def errors
69
+ response[:errors]
70
+ end
71
+
72
+ def error_messages
73
+ response[:errors].map { |e| e[:message] }
74
+ end
75
+
76
+ def edges
77
+ data[data.keys.first][:edges]
78
+ end
79
+
80
+ def stats
81
+ underscore(data[data.keys.first][:stats])
82
+ end
83
+
84
+ def page_info
85
+ underscore(data[data.keys.first][:pageInfo])
86
+ end
87
+
88
+ def query
89
+ name = Schema.registry.key_for(@resource)
90
+ filter_bang = "!" if @resource.filters.values.any? { |f| f[:required] }
91
+ sortvar = "$sort: [#{name}Sort!]," if @resource.sorts.any?
92
+
93
+ if !(fields = @params[:fields])
94
+ fields = []
95
+ @resource.attributes.each_pair do |name, config|
96
+ (fields << name) if config[:readable]
97
+ end
98
+ end
99
+
100
+ q = %|
101
+ query #{name} (
102
+ $filter: #{name}Filter#{filter_bang},
103
+ #{sortvar}
104
+ $first: Int,
105
+ $last: Int,
106
+ $before: String,
107
+ $after: String,
108
+ ) {
109
+ #{@resource.graphql_entrypoint} (
110
+ filter: $filter,
111
+ #{ 'sort: $sort,' if sortvar }
112
+ first: $first,
113
+ last: $last,
114
+ before: $before,
115
+ after: $after,
116
+ ) {
117
+ edges {
118
+ node {|
119
+
120
+ fields.each do |name|
121
+ q << %|
122
+ #{name.to_s.camelize(:lower)}|
123
+ end
124
+
125
+ if @params[:include]
126
+ includes = Array(@params[:include])
127
+ # NB HASH (?)
128
+ includes.each do |inc|
129
+ sideload = @resource.sideload(inc.to_sym)
130
+ to_one = [:belongs_to, :has_one, :polymorphic_belongs_to].include?(sideload.type)
131
+ indent = " " if !to_one
132
+ q << %|
133
+ #{inc.to_s.camelize(:lower)} {|
134
+ if !to_one
135
+ q << %|
136
+ edges {
137
+ node {|
138
+ end
139
+
140
+ r = @resource.sideload(inc.to_sym).resource
141
+ r.attributes.each_pair do |name, config|
142
+ next unless config[:readable]
143
+ q << %|
144
+ #{indent}#{name.to_s.camelize(:lower)}|
145
+ end
146
+
147
+ if to_one
148
+ q << %|
149
+ }|
150
+ else
151
+ q << %|
152
+ }
153
+ }
154
+ }|
155
+ end
156
+ end
157
+ end
158
+
159
+ q << %|
160
+ }
161
+ }
162
+ pageInfo {
163
+ startCursor
164
+ endCursor
165
+ hasNextPage
166
+ hasPreviousPage
167
+ }|
168
+
169
+ if @params[:stats]
170
+ q << %|
171
+ stats {|
172
+ @params[:stats].each_pair do |name, calculations|
173
+ q << %|
174
+ #{name.to_s.camelize(:lower)} {|
175
+ Array(calculations).each do |calc|
176
+ q << %|
177
+ #{calc.to_s.camelize(:lower)}|
178
+ end
179
+
180
+ q << %|
181
+ }|
182
+ end
183
+ q << %|
184
+ }|
185
+ end
186
+
187
+ q << %|
188
+ }
189
+ }
190
+ |
191
+
192
+ q
193
+ end
194
+
195
+ private
196
+
197
+ def underscore(hash)
198
+ hash.deep_transform_keys { |k| k.to_s.underscore.to_sym }
199
+ end
200
+ end
201
+
202
+ class_methods do
203
+ def gql(params = {}, ctx = {})
204
+ Proxy.new(self, params, ctx)
205
+ end
206
+ end
207
+ end
208
+ end
209
+
210
+ Graphiti::Resource.send(:include, GraphitiGql::ActiveResource)
@@ -9,9 +9,18 @@ module GraphitiGql
9
9
  GraphitiGql.schema!
10
10
  end
11
11
 
12
+ module ControllerContext
13
+ def graphql_context
14
+ ctx = { controller: self }
15
+ ctx[:current_user] = current_user if respond_to?(:current_user)
16
+ ctx
17
+ end
18
+ end
19
+
12
20
  initializer "graphiti_gql.define_controller" do
13
21
  require "#{Rails.root}/app/controllers/application_controller"
14
22
  app_controller = GraphitiGql.config.application_controller || ::ApplicationController
23
+ app_controller.send(:include, ControllerContext)
15
24
 
16
25
  # rubocop:disable Lint/ConstantDefinitionInBlock(Standard)
17
26
  class GraphitiGql::ExecutionController < app_controller
@@ -20,9 +29,15 @@ module GraphitiGql
20
29
  variables = params[:variables] || {}
21
30
  result = GraphitiGql.run params[:query],
22
31
  params[:variables],
23
- { current_user: current_user }
32
+ graphql_context
24
33
  render json: result
25
34
  end
35
+
36
+ private
37
+
38
+ def default_context
39
+ defined?(:current_user)
40
+ end
26
41
  end
27
42
  end
28
43
  end
@@ -11,6 +11,27 @@ module GraphitiGql
11
11
  end
12
12
  end
13
13
 
14
+ def selections
15
+ return @selections if @selections
16
+ lookahead = context[:current_arguments]
17
+ .keyword_arguments[:lookahead]
18
+ nodes = lookahead.selection(:nodes)
19
+ if !nodes.selected?
20
+ nodes = lookahead
21
+ .selection(:edges)
22
+ .selection(:node)
23
+ end
24
+
25
+ if !nodes.selected?
26
+ nodes = lookahead
27
+ end
28
+
29
+ @selections = nodes
30
+ .selections
31
+ .map(&:name).map { |name| name.to_s.underscore.to_sym }
32
+ @selections
33
+ end
34
+
14
35
  class_methods do
15
36
  def attribute(*args)
16
37
  super(*args).tap do
@@ -159,7 +180,11 @@ module GraphitiGql
159
180
  end
160
181
 
161
182
  _in = definition.constructor do |input|
162
- Time.zone.parse(input)
183
+ if input.is_a?(ActiveSupport::TimeWithZone)
184
+ input = input.utc.round(10).iso8601(6)
185
+ else
186
+ Time.zone.parse(input)
187
+ end
163
188
  end
164
189
 
165
190
  # Register it with Graphiti
@@ -53,7 +53,8 @@ module GraphitiGql
53
53
  end
54
54
  else
55
55
  params = {filter: {id: {eq: ids.join(",")}}}
56
- records = @sideload.resource.class.all(params).data
56
+ resource = Schema.registry.get(@sideload.resource.class)[:resource]
57
+ records = resource.all(params).data
57
58
  map = records.index_by { |record| record.id }
58
59
  ids.each { |id| fulfill(id, map[id]) }
59
60
  end
@@ -1,12 +1,12 @@
1
1
  module GraphitiGql
2
2
  module Loaders
3
3
  class HasMany < Many
4
- def assign(ids, proxy)
4
+ def assign(parent_records, proxy)
5
5
  records = proxy.data
6
6
  map = records.group_by { |record| record.send(@sideload.foreign_key) }
7
- ids.each do |id|
8
- data = [map[id] || [], proxy]
9
- fulfill(id, data)
7
+ parent_records.each do |pr|
8
+ data = [map[pr.send(@sideload.primary_key)] || [], proxy]
9
+ fulfill(pr, data)
10
10
  end
11
11
  end
12
12
  end
@@ -0,0 +1,15 @@
1
+ module GraphitiGql
2
+ module Loaders
3
+ class HasOne < Many
4
+ def assign(parent_records, proxy)
5
+ records = proxy.data
6
+ parent_records.each do |pr|
7
+ corresponding = records.find do |r|
8
+ r.send(@sideload.foreign_key) == pr.send(@sideload.primary_key)
9
+ end
10
+ fulfill(pr, corresponding)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -6,6 +6,8 @@ module GraphitiGql
6
6
  PolymorphicHasMany.for(sideload, params)
7
7
  elsif sideload.type == :many_to_many
8
8
  ManyToMany.for(sideload, params)
9
+ elsif sideload.type == :has_one
10
+ HasOne.for(sideload, params)
9
11
  else
10
12
  HasMany.for(sideload, params)
11
13
  end
@@ -16,13 +18,26 @@ module GraphitiGql
16
18
  @params = params
17
19
  end
18
20
 
19
- def perform(ids)
20
- raise ::Graphiti::Errors::UnsupportedPagination if paginating? && ids.length > 1
21
- raise Errors::UnsupportedStats if requesting_stats? && ids.length > 1 && !can_group?
21
+ def perform(parent_records)
22
+ raise ::Graphiti::Errors::UnsupportedPagination if paginating? && parent_records.length > 1
23
+ raise Errors::UnsupportedStats if requesting_stats? && parent_records.length > 1 && !can_group?
22
24
 
23
- build_params(ids)
24
- proxy = @sideload.resource.class.all(@params)
25
- assign(ids, proxy)
25
+ ids = parent_records.map do |pr|
26
+ pk = pr.send(@sideload.primary_key)
27
+ if @sideload.polymorphic_as
28
+ hash = {}
29
+ hash[@sideload.foreign_key] = pk
30
+ hash[:"#{@sideload.polymorphic_as}_type"] = pr.class.name
31
+ hash
32
+ else
33
+ pk
34
+ end
35
+ end
36
+
37
+ build_params(ids, parent_records)
38
+ resource = Schema.registry.get(@sideload.resource.class)[:resource]
39
+ proxy = resource.all(@params)
40
+ assign(parent_records, proxy)
26
41
  end
27
42
 
28
43
  def assign(ids, proxy)
@@ -31,7 +46,7 @@ module GraphitiGql
31
46
 
32
47
  private
33
48
 
34
- def build_params(ids)
49
+ def build_params(ids, parent_records)
35
50
  @params[:filter] ||= {}
36
51
 
37
52
  if @sideload.polymorphic_as
@@ -59,6 +74,10 @@ module GraphitiGql
59
74
  @params[:page] ||= {}
60
75
  @params[:page][:size] = 999
61
76
  end
77
+
78
+ if @sideload.params_proc
79
+ @sideload.params_proc.call(@params, parent_records)
80
+ end
62
81
  end
63
82
 
64
83
  def paginating?
@@ -1,16 +1,16 @@
1
1
  module GraphitiGql
2
2
  module Loaders
3
3
  class ManyToMany < Many
4
- def assign(ids, proxy)
4
+ def assign(parent_records, proxy)
5
5
  thru = @sideload.foreign_key.keys.first
6
6
  fk = @sideload.foreign_key[thru]
7
7
  add_join_table_magic(proxy)
8
8
  records = proxy.data
9
- ids.each do |id|
9
+ parent_records.each do |pr|
10
10
  corresponding = records.select do |record|
11
- record.send(:"_edge_#{fk}") == id
11
+ record.send(:"_edge_#{fk}") == pr.send(@sideload.primary_key)
12
12
  end
13
- fulfill(id, [corresponding, proxy])
13
+ fulfill(pr, [corresponding, proxy])
14
14
  end
15
15
  end
16
16
 
@@ -1,15 +1,18 @@
1
1
  module GraphitiGql
2
2
  module Loaders
3
3
  class PolymorphicHasMany < Many
4
- def assign(ids, proxy)
4
+ def assign(parent_records, proxy)
5
5
  records = proxy.data
6
- ids.each do |id|
6
+ parent_records.each do |pr|
7
7
  corresponding = records.select do |record|
8
- record.send("#{@sideload.polymorphic_as}_type") == id[:"#{@sideload.polymorphic_as}_type"] &&
9
- record.send(@sideload.foreign_key) == id[@sideload.foreign_key]
8
+ child_ft = record.send("#{@sideload.polymorphic_as}_type")
9
+ child_fk = record.send(@sideload.foreign_key)
10
+ parent_ft = pr.class.name
11
+ parent_fk = pr.send(@sideload.primary_key)
12
+ child_ft == parent_ft && child_fk == parent_fk
10
13
  end
11
14
  data = [corresponding || [], proxy]
12
- fulfill(id, data)
15
+ fulfill(pr, data)
13
16
  end
14
17
  end
15
18
  end
@@ -29,7 +29,7 @@ module GraphitiGql
29
29
  name = Registry.instance.key_for(@resource)
30
30
  stat_graphql_name = "#{name}Stats"
31
31
  return Registry.instance[stat_graphql_name][:type] if Registry.instance[stat_graphql_name]
32
- klass = Class.new(GraphQL::Schema::Object)
32
+ klass = Class.new(Schema.base_object)
33
33
  klass.graphql_name(stat_graphql_name)
34
34
  @resource.stats.each_pair do |name, config|
35
35
  calc_class = build_calc_class(stat_graphql_name, name, config.calculations.keys)
@@ -41,7 +41,7 @@ module GraphitiGql
41
41
 
42
42
  def build_calc_class(stat_graphql_name, stat_name, calculations)
43
43
  name = "#{stat_graphql_name}#{stat_name}Calculations"
44
- klass = Class.new(GraphQL::Schema::Object)
44
+ klass = Class.new(Schema.base_object)
45
45
  klass.graphql_name(name)
46
46
  calculations.each do |calc|
47
47
  klass.field calc, Float, null: false
@@ -12,32 +12,31 @@ module GraphitiGql
12
12
  end
13
13
 
14
14
  def apply(type)
15
- field = type.field @sideload.name,
16
- @sideload_type.connection_type,
17
- null: false,
15
+ opts = {
16
+ null: has_one?,
18
17
  connection: false,
19
- extensions: [RelayConnectionExtension],
20
18
  extras: [:lookahead]
19
+ }
20
+ opts[:extensions] = [RelayConnectionExtension] unless has_one?
21
+ field_type = has_one? ? @sideload_type : @sideload_type.connection_type
22
+ field = type.field @sideload.name,
23
+ field_type,
24
+ **opts
21
25
  ListArguments.new(@sideload.resource.class, @sideload).apply(field)
22
26
  _sideload = @sideload
23
27
  type.define_method(@sideload.name) do |**arguments|
24
28
  Util.is_readable_sideload!(_sideload)
25
29
  params = Util.params_from_args(arguments)
26
- pk = object.send(_sideload.primary_key)
27
- id = if _sideload.polymorphic_as
28
- hash = {}
29
- hash[_sideload.foreign_key] = pk
30
- hash[:"#{_sideload.polymorphic_as}_type"] = object.class.name
31
- id = hash
32
- else
33
- id = pk
34
- end
35
- Loaders::Many.factory(_sideload, params).load(id)
30
+ Loaders::Many.factory(_sideload, params).load(object)
36
31
  end
37
32
  end
38
33
 
39
34
  private
40
35
 
36
+ def has_one?
37
+ @sideload.type == :has_one
38
+ end
39
+
41
40
  def customized_edge?
42
41
  @sideload.type == :many_to_many && @sideload.class.edge_resource
43
42
  end
@@ -19,7 +19,9 @@ module GraphitiGql
19
19
  if _sideload.type == :has_one
20
20
  id = object.send(_sideload.primary_key)
21
21
  params = { filter: { _sideload.foreign_key => { eq: id } } }
22
- return _sideload.resource.class.all(params).data[0]
22
+
23
+ resource = Schema.registry.get(@sideload.resource.class)[:resource]
24
+ return resource.all(params).data[0]
23
25
  end
24
26
 
25
27
  lookahead = arguments[:lookahead]
@@ -3,9 +3,8 @@ module GraphitiGql
3
3
  class Query
4
4
  def initialize(resources, existing_query: nil)
5
5
  @resources = resources
6
- @query_class = Class.new(existing_query || ::GraphQL::Schema::Object)
6
+ @query_class = Class.new(existing_query || Schema.base_object)
7
7
  @query_class.graphql_name "Query"
8
- @query_class.field_class ::GraphQL::Schema::Field
9
8
  end
10
9
 
11
10
  def build
@@ -32,7 +31,7 @@ module GraphitiGql
32
31
 
33
32
  def add_relationships
34
33
  each_relationship do |type, sideload_type, sideload|
35
- if [:has_many, :many_to_many].include?(sideload.type)
34
+ if [:has_many, :many_to_many, :has_one].include?(sideload.type)
36
35
  Fields::ToMany.new(sideload, sideload_type).apply(type)
37
36
  else
38
37
  Fields::ToOne.new(sideload, sideload_type).apply(type)
@@ -68,7 +68,7 @@ module GraphitiGql
68
68
  Registry.instance[registry_name][:type]
69
69
  end
70
70
  else
71
- klass = Class.new(GraphQL::Schema::Object)
71
+ klass = Class.new(Schema.base_object)
72
72
  end
73
73
 
74
74
  klass
@@ -32,6 +32,21 @@ module GraphitiGql
32
32
  end
33
33
  end
34
34
 
35
+ def self.base_object
36
+ klass = Class.new(GraphQL::Schema::Object)
37
+ # TODO make this config maybe
38
+ if defined?(ActionView)
39
+ klass.send(:include, ActionView::Helpers::TranslationHelper)
40
+ klass.class_eval do
41
+ def initialize(*)
42
+ super
43
+ @virtual_path = "."
44
+ end
45
+ end
46
+ end
47
+ klass
48
+ end
49
+
35
50
  def self.registry
36
51
  Registry.instance
37
52
  end
@@ -2,149 +2,62 @@ module GraphitiGql
2
2
  module SpecHelper
3
3
  extend ActiveSupport::Concern
4
4
 
5
- class Node < OpenStruct
6
- def decoded_id
7
- Base64.decode64(self.id)
8
- end
9
-
10
- def int_id
11
- decoded_id.to_i
12
- end
13
- end
14
-
15
- class Util
16
- def self.underscore(hash)
17
- hash.deep_transform_keys { |k| k.to_s.underscore.to_sym }
18
- end
19
- end
20
-
21
- def query
22
- name = Schema.registry.key_for(resource)
23
- q = %|
24
- query #{name} (
25
- $filter: #{name}Filter,
26
- $sort: [#{name}Sort!],
27
- $first: Int,
28
- $last: Int,
29
- $before: String,
30
- $after: String,
31
- ) {
32
- #{resource.graphql_entrypoint} (
33
- filter: $filter,
34
- sort: $sort,
35
- first: $first,
36
- last: $last,
37
- before: $before,
38
- after: $after,
39
- ) {
40
- edges {
41
- node {|
42
-
43
- fields.each do |name|
44
- q << %|
45
- #{name.to_s.camelize(:lower)}|
46
- end
5
+ included do
6
+ extend Forwardable
7
+ def_delegators :result,
8
+ :page_info,
9
+ :errors,
10
+ :error_messages,
11
+ :nodes,
12
+ :stats
13
+
14
+ if defined?(RSpec)
15
+ let(:params) do
16
+ fields = []
17
+ resource.attributes.each_pair do |name, config|
18
+ (fields << name) if config[:readable]
19
+ end
20
+ { fields: fields }
21
+ end
22
+ let(:resource) { described_class }
23
+ let(:ctx) { {} }
47
24
 
48
- q << %|
49
- }
50
- }
51
- pageInfo {
52
- startCursor
53
- endCursor
54
- hasNextPage
55
- hasPreviousPage
56
- }|
57
-
58
- if params[:stats]
59
- q << %|
60
- stats {|
61
- params[:stats].each_pair do |name, calculations|
62
- q << %|
63
- #{name.to_s.camelize(:lower)} {|
64
- Array(calculations).each do |calc|
65
- q << %|
66
- #{calc.to_s.camelize(:lower)}|
25
+ def self.only_fields(*fields)
26
+ before do
27
+ fields.each { |f| params[:fields].select! { |p| p == f } }
67
28
  end
68
-
69
- q << %|
70
- }|
71
29
  end
72
- q << %|
73
- }|
74
- end
75
-
76
- q << %|
77
- }
78
- }
79
- |
80
-
81
- q
82
- end
83
30
 
84
- def run
85
- lambda do
86
- gql_params = params.deep_transform_keys { |key| key.to_s.camelize(:lower).to_sym }
87
- (gql_params[:sort] || []).each do |sort|
88
- sort[:att] = sort[:att].to_s.camelize(:lower)
89
- sort[:dir] = sort[:dir].to_s
31
+ def self.except_fields(*fields)
32
+ before do
33
+ fields.each { |f| params[:fields].reject! { |p| p == f } }
34
+ end
90
35
  end
91
- GraphitiGql.run(query, gql_params, ctx).deep_symbolize_keys
92
36
  end
93
37
  end
94
38
 
95
- def run!
96
- @response = run.call
97
- end
98
-
99
- def response
100
- @response ||= run!
101
- end
102
-
103
- def errors
104
- response[:errors]
105
- end
106
-
107
- def error_messages
108
- response[:errors].map { |e| e[:message] }
109
- end
110
-
111
- def nodes
112
- return [] unless data
113
- nodes = edges.map { |e| Util.underscore(e[:node]) }
114
- nodes.map { |n| ::GraphitiGql::SpecHelper::Node.new(n) }
115
- end
116
-
117
- def data
118
- if response.key?(:data)
119
- response[:data]
39
+ def gql_datetime(timestamp, precise = false)
40
+ if precise
41
+ timestamp.utc.round(10).iso8601(6)
120
42
  else
121
- raise "Tried to access 'data', but these errors were returned instead: #{error_messages.join(". ")}."
43
+ DateTime.parse(timestamp.to_s).iso8601
122
44
  end
123
45
  end
124
46
 
125
- def edges
126
- data[data.keys.first][:edges]
127
- end
128
-
129
- def stats
130
- Util.underscore(data[data.keys.first][:stats])
47
+ def run
48
+ lambda do
49
+ proxy = resource.gql(params, ctx)
50
+ proxy.to_h
51
+ proxy
52
+ end
131
53
  end
132
54
 
133
- def page_info
134
- Util.underscore(data[data.keys.first][:pageInfo])
55
+ def run!
56
+ @result = run.call
135
57
  end
136
58
 
137
- included do
138
- let(:params) { {} }
139
- let(:resource) { described_class }
140
- let(:ctx) { {} }
141
- let(:fields) do
142
- fields = []
143
- resource.attributes.each_pair do |name, config|
144
- (fields << name) if config[:readable]
145
- end
146
- fields
147
- end
59
+ def result
60
+ @result ||= run!
148
61
  end
149
62
  end
150
63
  end
@@ -1,3 +1,3 @@
1
1
  module GraphitiGql
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.4"
3
3
  end
data/lib/graphiti_gql.rb CHANGED
@@ -9,6 +9,7 @@ require "graphiti_gql/loaders/has_many"
9
9
  require "graphiti_gql/loaders/many_to_many"
10
10
  require "graphiti_gql/loaders/polymorphic_has_many"
11
11
  require "graphiti_gql/loaders/belongs_to"
12
+ require "graphiti_gql/loaders/has_one"
12
13
  require "graphiti_gql/response_shim"
13
14
  require "graphiti_gql/schema"
14
15
  require "graphiti_gql/schema/connection"
@@ -24,6 +25,7 @@ require "graphiti_gql/schema/fields/to_many"
24
25
  require "graphiti_gql/schema/fields/to_one"
25
26
  require "graphiti_gql/schema/fields/attribute"
26
27
  require "graphiti_gql/schema/fields/stats"
28
+ require "graphiti_gql/active_resource"
27
29
  require "graphiti_gql/engine" if defined?(Rails)
28
30
 
29
31
  module GraphitiGql
@@ -64,6 +66,9 @@ module GraphitiGql
64
66
  end
65
67
 
66
68
  def self.run(query_string, variables = {}, context = {})
69
+ if context.empty? && Graphiti.context[:object]
70
+ context = Graphiti.context[:object]
71
+ end
67
72
  Graphiti.with_context(context) do
68
73
  result = schema.execute query_string,
69
74
  variables: variables,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphiti_gql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lee Richmond
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-06-23 00:00:00.000000000 Z
11
+ date: 2022-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -108,7 +108,7 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '7.0'
111
- description:
111
+ description:
112
112
  email:
113
113
  - richmolj@gmail.com
114
114
  executables: []
@@ -137,11 +137,13 @@ files:
137
137
  - config/routes.rb
138
138
  - graphiti_gql.gemspec
139
139
  - lib/graphiti_gql.rb
140
+ - lib/graphiti_gql/active_resource.rb
140
141
  - lib/graphiti_gql/engine.rb
141
142
  - lib/graphiti_gql/errors.rb
142
143
  - lib/graphiti_gql/graphiti_hax.rb
143
144
  - lib/graphiti_gql/loaders/belongs_to.rb
144
145
  - lib/graphiti_gql/loaders/has_many.rb
146
+ - lib/graphiti_gql/loaders/has_one.rb
145
147
  - lib/graphiti_gql/loaders/many.rb
146
148
  - lib/graphiti_gql/loaders/many_to_many.rb
147
149
  - lib/graphiti_gql/loaders/polymorphic_has_many.rb
@@ -167,7 +169,7 @@ licenses:
167
169
  - MIT
168
170
  metadata:
169
171
  homepage_uri: https://www.graphiti.dev
170
- post_install_message:
172
+ post_install_message:
171
173
  rdoc_options: []
172
174
  require_paths:
173
175
  - lib
@@ -182,8 +184,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
182
184
  - !ruby/object:Gem::Version
183
185
  version: '0'
184
186
  requirements: []
185
- rubygems_version: 3.3.7
186
- signing_key:
187
+ rubygems_version: 3.0.3.1
188
+ signing_key:
187
189
  specification_version: 4
188
190
  summary: GraphQL support for Graphiti
189
191
  test_files: []