Class: ZeroRuby::Schema

Inherits:
Object
  • Object
show all
Defined in:
lib/zero_ruby/schema.rb

Overview

Schema class for registering and processing Zero mutations.

Examples:

class ZeroSchema < ZeroRuby::Schema
  mutation "works.create", handler: Mutations::WorkCreate
  mutation "works.update", handler: Mutations::WorkUpdate
end

Class Method Summary collapse

Class Method Details

.execute(push_data, context:, lmid_store: nil) ⇒ Hash

Execute a Zero push request. This is the main entry point for processing mutations.

Examples:

Basic usage

body = JSON.parse(request.body.read)
result = ZeroSchema.execute(body, context: {current_user: user})
render json: result

Parameters:

  • push_data (Hash)

    The parsed push request body

  • context (Hash)

    Context hash to pass to mutations (e.g., current_user:)

  • lmid_store (LmidStore, nil) (defaults to: nil)

    Optional LMID store override

Returns:

  • (Hash)

    Result hash: […] on success, {…} on failure



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/zero_ruby/schema.rb', line 56

def execute(push_data, context:, lmid_store: nil)
  validate_push_structure!(push_data)

  push_version = push_data["pushVersion"]
  supported_version = ZeroRuby.configuration.supported_push_version

  unless push_version == supported_version
    mutations = push_data["mutations"] || []
    mutation_ids = mutations.map { |m| {id: m["id"], clientID: m["clientID"]} }

    return {
      kind: "PushFailed",
      origin: "server",
      reason: "unsupportedPushVersion",
      message: "Unsupported push version: #{push_version}. Expected: #{supported_version}",
      mutationIDs: mutation_ids
    }
  end

  store = lmid_store || ZeroRuby.configuration.lmid_store_instance
  processor = PushProcessor.new(
    schema: self,
    lmid_store: store
  )
  processor.process(push_data, context)
rescue ParseError => e
  {
    kind: "PushFailed",
    origin: "server",
    reason: "parse",
    message: e.message,
    mutationIDs: []
  }
end

.execute_mutation(mutation_data, context, &transact) ⇒ Hash

Execute a single mutation. Used by PushProcessor for LMID-tracked mutations.

Parameters:

  • mutation_data (Hash)

    The mutation data from Zero

  • context (Hash)

    Context hash to pass to mutations

  • transact (Proc)

    Block that wraps transactional work

Returns:

  • (Hash)

    Empty hash on success

Raises:



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/zero_ruby/schema.rb', line 99

def execute_mutation(mutation_data, context, &transact)
  name = normalize_mutation_name(mutation_data["name"])
  handler = mutations[name]
  raise MutationNotFoundError.new(name) unless handler

  raw_args = extract_args(mutation_data)
  params = transform_keys(raw_args)

  handler.new(params, context).call(&transact)
rescue Dry::Struct::Error => e
  raise ValidationError.new(ErrorFormatter.format_struct_error(e))
rescue Dry::Types::CoercionError => e
  raise ValidationError.new([ErrorFormatter.format_coercion_error(e)])
rescue Dry::Types::ConstraintError => e
  raise ValidationError.new([ErrorFormatter.format_constraint_error(e)])
end

.handler_for(name) ⇒ Class?

Get handler class for a mutation name

Parameters:

  • name (String)

    The mutation name

Returns:

  • (Class, nil)

    The handler class or nil if not found



35
36
37
# File 'lib/zero_ruby/schema.rb', line 35

def handler_for(name)
  mutations[normalize_mutation_name(name)]
end

.mutation(name, handler:) ⇒ Object

Register a mutation handler

Parameters:

  • name (String)

    The mutation name (e.g., “works.create”)

  • handler (Class)

    The mutation class to handle this mutation



19
20
21
# File 'lib/zero_ruby/schema.rb', line 19

def mutation(name, handler:)
  mutations[name.to_s] = handler
end

.mutationsObject

Get all registered mutations



24
25
26
27
28
29
30
# File 'lib/zero_ruby/schema.rb', line 24

def mutations
  @mutations ||= if superclass.respond_to?(:mutations)
    superclass.mutations.dup
  else
    {}
  end
end

.to_typescriptString

Generate TypeScript type definitions from registered mutations

Returns:

  • (String)

    TypeScript type definitions



41
42
43
# File 'lib/zero_ruby/schema.rb', line 41

def to_typescript
  TypeScriptGenerator.new(self).generate
end