Module: Kanji::Type::ClassInterface

Includes:
Dry::Core::Constants
Included in:
Kanji::Type
Defined in:
lib/kanji/type/class_interface.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#_associationsObject (readonly)

Returns the value of attribute _associations.



16
17
18
# File 'lib/kanji/type/class_interface.rb', line 16

def _associations
  @_associations
end

#_attributesObject (readonly)

Returns the value of attribute _attributes.



16
17
18
# File 'lib/kanji/type/class_interface.rb', line 16

def _attributes
  @_attributes
end

#_descriptionObject (readonly)

Returns the value of attribute _description.



16
17
18
# File 'lib/kanji/type/class_interface.rb', line 16

def _description
  @_description
end

#_nameObject (readonly)

Returns the value of attribute _name.



16
17
18
# File 'lib/kanji/type/class_interface.rb', line 16

def _name
  @_name
end

#_repo_nameObject (readonly)

Returns the value of attribute _repo_name.



16
17
18
# File 'lib/kanji/type/class_interface.rb', line 16

def _repo_name
  @_repo_name
end

Instance Method Details

#assoc(name, type = nil, description = nil, **kwargs, &block) ⇒ Object



73
74
75
76
77
78
79
80
# File 'lib/kanji/type/class_interface.rb', line 73

def assoc(name, type = nil, description = nil, **kwargs, &block)
  if @_associations.map(&:name).include?(name)
    fail AttributeError, "Association #{name} is already defined"
  else
    @_associations <<
    AttributeDefiner.new(name, type, description, kwargs, &block).call
  end
end

#attribute(name, type = nil, description = nil, **kwargs, &block) ⇒ Object



64
65
66
67
68
69
70
71
# File 'lib/kanji/type/class_interface.rb', line 64

def attribute(name, type = nil, description = nil, **kwargs, &block)
  if @_attributes.map(&:name).include?(name)
    fail AttributeError, "Attribute #{name} is already defined"
  else
    @_attributes <<
      AttributeDefiner.new(name, type, description, kwargs, &block).call
  end
end

#create(&block) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
# File 'lib/kanji/type/class_interface.rb', line 86

def create(&block)
  register :create_mutation do
    Kanji::Graph::RegisterMutation.new(
      return_type: resolve(:graphql_type),
      attributes: @_attributes.reject { |attr| attr.name == :id },
      name: "Create#{demodulized_type_name}Mutation",
      description: "Create a new #{demodulized_type_name}.",
      resolve: block
    ).call
  end
end

#create_value_objectObject



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/kanji/type/class_interface.rb', line 138

def create_value_object
  builder = Dry::Core::ClassBuilder.new(
    name: "#{instance_variable_get(:@_name)}Value",
    parent: Dry::Struct::Value
  )
  klass = builder.call

  klass.constructor_type(:schema)

  instance_variable_get(:@_attributes).each do |attribute|
    klass.attribute(attribute.name, attribute.type)
  end

  klass
end

#demodulized_type_nameObject



82
83
84
# File 'lib/kanji/type/class_interface.rb', line 82

def demodulized_type_name
  @_demodulized_type_name ||= Dry::Core::Inflector.demodulize(self.to_s)
end

#description(description) ⇒ Object



60
61
62
# File 'lib/kanji/type/class_interface.rb', line 60

def description(description)
  @_description = description
end

#destroy(&block) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
# File 'lib/kanji/type/class_interface.rb', line 110

def destroy(&block)
  register :destroy_mutation do
    Kanji::Graph::RegisterMutation.new(
      return_type: resolve(:graphql_type),
      attributes: [@_attributes.find { |attr| attr.name == :id }],
      name: "Destroy#{demodulized_type_name}Mutation",
      description: "Destroy a #{demodulized_type_name}.",
      resolve: block
    ).call
  end
end

#finalize(klass) ⇒ Object



44
45
46
47
48
49
# File 'lib/kanji/type/class_interface.rb', line 44

def finalize(klass)
  klass.register :graphql_type, graphql_type(klass)
  klass.register :schema, -> { klass.register_schema }
  klass.register :value_object, -> { klass.create_value_object }
  klass.instance_variable_set(:@_repo_name, get_repo_name(klass))
end

#get_repo_name(klass) ⇒ Object



51
52
53
54
# File 'lib/kanji/type/class_interface.rb', line 51

def get_repo_name(klass)
  name = Dry::Core::Inflector.underscore(klass._name)
  Dry::Core::Inflector.pluralize(name).to_sym
end

#graphql_type(klass) ⇒ Object



19
20
21
22
23
24
25
# File 'lib/kanji/type/class_interface.rb', line 19

def graphql_type(klass)
  Kanji::Graph::RegisterObject.new(
    attributes: klass._attributes + klass._associations,
    name: klass._name,
    description: klass._description
  ).call
end

#inherited(klass) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/kanji/type/class_interface.rb', line 27

def inherited(klass)
  super

  klass.instance_variable_set(:@_attributes, [])
  klass.instance_variable_set(:@_values, {})
  klass.instance_variable_set(:@_associations, [])

  klass.attribute(:id, Kanji::Types::Int, "The primary key")

  TracePoint.trace(:end) do |t|
    if klass == t.self
      self.finalize(klass)
      t.disable
    end
  end
end

#name(name) ⇒ Object



56
57
58
# File 'lib/kanji/type/class_interface.rb', line 56

def name(name)
  @_name = name
end

#register_schemaObject



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/kanji/type/class_interface.rb', line 122

def register_schema
  attributes = _attributes

  Dry::Validation.JSON do
    configure { config.type_specs = true }

    attributes.each do |attribute|
      if attribute.options[:required]
        required(attribute.name, attribute.type).filled
      else
        optional(attribute.name, attribute.type).maybe
      end
    end
  end
end

#update(&block) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/kanji/type/class_interface.rb', line 98

def update(&block)
  register :update_mutation do
    Kanji::Graph::RegisterMutation.new(
      return_type: resolve(:graphql_type),
      attributes: @_attributes,
      name: "Update#{demodulized_type_name}Mutation",
      description: "Update an instance of #{demodulized_type_name}.",
      resolve: block
    ).call
  end
end