graphiti_gql 0.2.29 → 0.2.30

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: ade099acc586ef5902b1b30659ca47efed5cfb3e05e3fe1a778fa81b31b27528
4
- data.tar.gz: 3a2226feab0dd284c3aeb832b30d90dc8165a9abc03fc40921aab47eece3d315
3
+ metadata.gz: a02dc0813b461497979a165c77f9116922559c46a54ba26a5130e31832c4bcef
4
+ data.tar.gz: 60a27d5d31c31a39d062d1a65a2c0278ce3ea6f3cba3c4900ed1332525a54460
5
5
  SHA512:
6
- metadata.gz: 318d2eb2831f5d19bdcbdd9fbe6dd0a21fed8435875d9d4de0ca45b65b97515b5ca4f80afca282a5c1e11b85986133f5942ef4e96b21b4cb31ce492d35a07728
7
- data.tar.gz: bc7b778005b056904a8fc4d3be767ee62a711f07fff533ddac833b96723abc5fc8368e9f63ecf2ddc40aee59544990939ff7d26a570a95ccc15ce2d8d5e93542
6
+ metadata.gz: e2a9a66b5dd624962bfffdc733115f8cf0363846db434bf9dfbe76374cd94dd0b9411ccf2aa93ce543a144ad0505e9f8d1e39bcb34b5593a7f870e17d7f13440
7
+ data.tar.gz: eb5004a261e6b7b815eb16ab548591c27beda1231e0875103c75d059c885ed2311b7d8c2b4d1a651d08905facdb8478b328eb5f78ec0fb812dab8cfc5f175583
@@ -37,18 +37,20 @@ module GraphitiGql
37
37
  def edge(name, node_id)
38
38
  found = @edges[name].empty? ? nil : @edges[name]
39
39
  if found && node_id
40
- found.find { |f| f.instance_variable_get(:@node_id) == node_id.to_s }
40
+ found.find do |f|
41
+ gql_node_id = f.instance_variable_get(:@node_id)
42
+ gql_node_id == node_id ||
43
+ gql_node_id == node_id.to_s ||
44
+ gql_node_id == @resource.gid(node_id)
45
+ end
41
46
  else
42
47
  found
43
48
  end
44
49
  end
45
50
 
46
- def decoded_id
47
- Base64.decode64(self.id)
48
- end
49
-
50
- def int_id
51
- decoded_id.to_i
51
+ def _id
52
+ deserialized = @resource.deserialize_gid(id)
53
+ deserialized.to_i.to_s == deserialized ? deserialized.to_i : deserialized
52
54
  end
53
55
  end
54
56
 
@@ -77,7 +79,7 @@ module GraphitiGql
77
79
  data # fire query
78
80
  Node.new(underscore(data[data.keys.first]), @resource)
79
81
  else
80
- nodes.find { |n| n.id == id.to_s }
82
+ nodes.find { |n| n.id == id.to_s || n.id == @resource.gid(id) }
81
83
  end
82
84
  end
83
85
 
@@ -71,13 +71,46 @@ module GraphitiGql
71
71
  end
72
72
 
73
73
  class_methods do
74
+ def gid(*ids)
75
+ ids = ids[0] if ids[0].is_a?(Array) && ids.length == 1
76
+ gids = ids.map { |id| serialize_gid(id) }
77
+ ids.length == 1 ? gids.first : gids
78
+ end
79
+
80
+ def serialize_gid(id)
81
+ Base64.encode64("#{graphql_name}/#{id}")
82
+ end
83
+
84
+ def deserialize_gid(gid, integer = true)
85
+ id = Base64.decode64(gid).split("/").last
86
+ id.to_i.to_s == id ? id.to_i : id
87
+ end
88
+
74
89
  def config
75
90
  return @config if @config
76
91
  super
77
92
  @config = @config.merge(value_objects: {}, is_value_object: false)
78
93
  end
79
94
 
95
+ def graphql_name
96
+ @graphql_name ||= begin
97
+ if name.nil?
98
+ 'Unknown'
99
+ else
100
+ name.gsub('Resource', '').gsub('::', '')
101
+ end
102
+ end
103
+ end
104
+
80
105
  def attribute(*args)
106
+ # new default is :gid, not integer_id
107
+ if args[0] == :id && args[1] == :integer_id
108
+ args[1] = :gid
109
+ opts = args.extract_options!
110
+ opts[:null] = false
111
+ args << opts
112
+ end
113
+
81
114
  super(*args).tap do
82
115
  opts = args.extract_options!
83
116
  att = config[:attributes][args[0]]
@@ -320,6 +353,7 @@ module GraphitiGql
320
353
  description: 'Datetime with milliseconds'
321
354
  }
322
355
 
356
+ # Support ranges
323
357
  [:string, :integer, :float, :datetime, :precise_datetime].each do |kind|
324
358
  duped_hash = Graphiti::Util::Hash.deep_dup(Graphiti::Types[:hash])
325
359
  type = Graphiti::Types[:"#{kind}_range"] = duped_hash
@@ -334,6 +368,29 @@ module GraphitiGql
334
368
  }
335
369
  end
336
370
 
371
+ # Support gid
372
+ gid_going_out = ->(id) {
373
+ resource.gid(id)
374
+ }
375
+
376
+ gid_coming_in = definition.constructor do |input|
377
+ if defined?(ApplicationResource)
378
+ ApplicationResource.deserialize_gid(input)
379
+ else
380
+ Graphiti::Resource.deserialize_gid(input)
381
+ end
382
+ end
383
+
384
+ # Register it with Graphiti
385
+ Graphiti::Types[:gid] = {
386
+ params: gid_coming_in,
387
+ read: gid_going_out,
388
+ write: gid_coming_in,
389
+ kind: 'scalar',
390
+ canonical_name: :gid,
391
+ description: 'Globally-unique identifier',
392
+ }
393
+
337
394
  module ActiveRecordAdapterExtras
338
395
  extend ActiveSupport::Concern
339
396
 
@@ -344,6 +401,8 @@ module GraphitiGql
344
401
  alias_method :filter_precise_datetime_gte, :filter_gte
345
402
  alias_method :filter_precise_datetime_eq, :filter_eq
346
403
  alias_method :filter_precise_datetime_not_eq, :filter_not_eq
404
+ alias_method :filter_gid_eq, :filter_eq
405
+ alias_method :filter_gid_not_eq, :filter_not_eq
347
406
  end
348
407
 
349
408
  # TODO: integration specs mysql vs postgres for case sensitivity
@@ -393,11 +452,14 @@ module GraphitiGql
393
452
  class << self
394
453
  alias :old_default_operators :default_operators
395
454
  def default_operators
396
- old_default_operators.merge({
397
- precise_datetime: numerical_operators,
455
+ ops = old_default_operators.merge({
456
+ precise_datetime: numerical_operators - [:not_eq],
398
457
  string_enum: [:eq, :not_eq],
399
458
  integer_enum: [:eq, :not_eq],
459
+ gid: [:eq, :not_eq]
400
460
  })
461
+ ops[:datetime] = ops[:datetime] - [:not_eq]
462
+ ops
401
463
  end
402
464
  end
403
465
  end
@@ -1,6 +1,10 @@
1
1
  module GraphitiGql
2
2
  module Loaders
3
- class FakeRecord < Struct.new(:id, :type)
3
+ class FakeRecord < Struct.new(:id, :type, :graphiti_resource)
4
+ def initialize(*args)
5
+ super
6
+ @__graphiti_resource = graphiti_resource
7
+ end
4
8
  end
5
9
 
6
10
  class BelongsTo < GraphQL::Batch::Loader
@@ -21,11 +25,11 @@ module GraphitiGql
21
25
  ids.each do |id|
22
26
  child = @sideload.children.values.find { |c| c.group_name == id[:type].to_sym }
23
27
  type = Schema::Registry.instance.get(child.resource.class, interface: false)[:type]
24
- fulfill(id, FakeRecord.new(id[:id], type))
28
+ fulfill(id, FakeRecord.new(id[:id], type, child.resource))
25
29
  end
26
30
  else
27
31
  type = Schema::Registry.instance.get(@sideload.resource.class)[:type]
28
- ids.each { |id| fulfill(id, FakeRecord.new(id, type)) }
32
+ ids.each { |id| fulfill(id, FakeRecord.new(id, type, @sideload.resource)) }
29
33
  end
30
34
  return
31
35
  end
@@ -40,9 +44,10 @@ module GraphitiGql
40
44
  payload.each_pair do |key, value|
41
45
  params = { filter: {} }
42
46
  klass = @sideload.children.values.find { |c| c.group_name == key.to_sym }
43
- params = {
44
- filter: { id: { eq: value.join(",") } }
45
- }
47
+ filter_ids = value.map { |id| @sideload.resource.class.gid(id.to_s) }
48
+ params = @params.merge({
49
+ filter: { id: { eq: filter_ids } }
50
+ })
46
51
 
47
52
  futures << Concurrent::Future.execute do
48
53
  { type: key, data: klass.resource.class.all(params).data }
@@ -55,9 +60,10 @@ module GraphitiGql
55
60
  end
56
61
  else
57
62
  resource = Schema.registry.get(@sideload.resource.class)[:resource]
58
- params = {}
63
+ params = @params.deep_dup
59
64
  unless resource.singular
60
- params[:filter] = {id: { eq: ids.join(",") } }
65
+ filter_ids = ids.map { |id| @sideload.resource.class.gid(id.to_s) }
66
+ params[:filter] = {id: { eq: filter_ids } }
61
67
  end
62
68
  records = resource.all(params).data
63
69
  if resource.singular
@@ -15,7 +15,7 @@ module GraphitiGql
15
15
 
16
16
  def initialize(sideload, params)
17
17
  @sideload = sideload
18
- @params = params
18
+ @params = params.merge(typecast_filters: false)
19
19
  end
20
20
 
21
21
  def perform(parent_records)
@@ -34,6 +34,7 @@ module GraphitiGql
34
34
  pk
35
35
  end
36
36
  end
37
+ ids.compact!
37
38
 
38
39
  build_params(ids, parent_records)
39
40
  resource = Schema.registry.get(@sideload.resource.class)[:resource]
@@ -53,13 +54,16 @@ module GraphitiGql
53
54
  if @sideload.polymorphic_as
54
55
  type = ids[0][:"#{@sideload.polymorphic_as}_type"]
55
56
  foreign_keys = ids.map { |id| id[@sideload.foreign_key] }
57
+ foreign_keys.map! { |id| @sideload.parent_resource.class.gid(id) }
56
58
  @params[:filter][:"#{@sideload.polymorphic_as}_type"] = type
57
- @params[:filter][@sideload.foreign_key] = foreign_keys.join(",")
59
+ @params[:filter][@sideload.foreign_key] = foreign_keys
58
60
  elsif @sideload.type == :many_to_many
61
+ filter_ids = ids.map { |id| @sideload.parent_resource.class.gid(id) }
59
62
  fk = @sideload.foreign_key.values.first
60
- @params[:filter].merge!(fk => { eq: ids.join(",") })
63
+ @params[:filter].merge!(fk => { eq: filter_ids })
61
64
  elsif !@sideload.parent_resource.class.singular
62
- @params[:filter].merge!(@sideload.foreign_key => { eq: ids.join(",") })
65
+ filter_ids = ids.map { |id| @sideload.parent_resource.class.gid(id) }
66
+ @params[:filter].merge!(@sideload.foreign_key => { eq: filter_ids })
63
67
  end
64
68
 
65
69
  if @params[:stats]
@@ -37,7 +37,16 @@ module GraphitiGql
37
37
  end
38
38
  end
39
39
  return if value.nil?
40
- Graphiti::Types[_config[:type]][:read].call(value)
40
+
41
+ caster = Graphiti::Types[_config[:type]][:read]
42
+ # Dry::Types can't be instance_exec'd
43
+ # This dependency has probably served it's purpose and can be
44
+ # refactored away
45
+ if caster.is_a?(Proc)
46
+ instance_exec(value, &caster)
47
+ else
48
+ caster.call(value)
49
+ end
41
50
  end
42
51
  end
43
52
 
@@ -51,7 +60,6 @@ module GraphitiGql
51
60
  if !field_type
52
61
  canonical_graphiti_type = Graphiti::Types.name_for(@config[:type])
53
62
  field_type = GQL_TYPE_MAP[canonical_graphiti_type.to_sym]
54
- field_type = String if @name == :id
55
63
  end
56
64
  field_type = [field_type] if @config[:type].to_s.starts_with?("array_of")
57
65
  field_type
@@ -12,7 +12,7 @@ module GraphitiGql
12
12
  null: true,
13
13
  extras: [:lookahead]
14
14
  unless @registered[:resource].singular
15
- field.argument(:id, String, required: true)
15
+ field.argument(:id, GraphQL::Types::ID, required: true)
16
16
  end
17
17
  _registered = @registered
18
18
  query.define_method name do |**arguments|
@@ -77,7 +77,6 @@ module GraphitiGql
77
77
  canonical_graphiti_type = Graphiti::Types
78
78
  .name_for(filter_config[:type])
79
79
  type = GQL_TYPE_MAP[canonical_graphiti_type]
80
- type = String if filter_name == :id
81
80
  end
82
81
 
83
82
  if (allowlist = filter_config[:allow])
@@ -60,8 +60,7 @@ module GraphitiGql
60
60
  private
61
61
 
62
62
  def key_for_resource(resource)
63
- resource.graphql_name ||
64
- resource.name.gsub('Resource', '').gsub('::', '')
63
+ resource.graphql_name
65
64
  end
66
65
  end
67
66
  end
@@ -141,6 +141,17 @@ module GraphitiGql
141
141
  klass = Class.new(Schema.base_object)
142
142
  end
143
143
 
144
+ klass.define_method :resource do
145
+ return @resource if @resource
146
+ resource = object.instance_variable_get(:@__graphiti_resource)
147
+ resource_class = resource.class
148
+ if resource_class.polymorphic? && !resource_class.polymorphic_child?
149
+ resource_class = resource_class.resource_for_model(object)
150
+ end
151
+ @resource = resource_class
152
+ resource_class
153
+ end
154
+
144
155
  klass
145
156
  end
146
157
 
@@ -33,6 +33,7 @@ module GraphitiGql
33
33
  integer_id: String,
34
34
  string: String,
35
35
  uuid: String,
36
+ gid: GraphQL::Types::ID,
36
37
  integer: Integer,
37
38
  big_integer: GraphQL::Types::BigInt,
38
39
  float: Float,
@@ -68,7 +69,9 @@ module GraphitiGql
68
69
  end
69
70
 
70
71
  def self.base_object
72
+ return @base_object if @base_object
71
73
  klass = Class.new(GraphQL::Schema::Object)
74
+
72
75
  # TODO make this config maybe
73
76
  if defined?(ActionView)
74
77
  klass.send(:include, ActionView::Helpers::TranslationHelper)
@@ -79,6 +82,7 @@ module GraphitiGql
79
82
  end
80
83
  end
81
84
  end
85
+ @base_object = klass
82
86
  klass
83
87
  end
84
88
 
@@ -74,6 +74,9 @@ module GraphitiGql
74
74
  resource.gql(params.merge(fields: fields), ctx, q, opts)
75
75
  end
76
76
 
77
+ def gid(*ids)
78
+ resource.gid(*ids)
79
+ end
77
80
 
78
81
  def run
79
82
  lambda do
@@ -1,3 +1,3 @@
1
1
  module GraphitiGql
2
- VERSION = "0.2.29"
2
+ VERSION = "0.2.30"
3
3
  end
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.29
4
+ version: 0.2.30
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lee Richmond
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-25 00:00:00.000000000 Z
11
+ date: 2022-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql