Class: Rage::OpenAPI::Parsers::Ext::Alba::Visitor

Inherits:
Prism::Visitor
  • Object
show all
Defined in:
lib/rage/openapi/parsers/ext/alba.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parser, is_collection) ⇒ Visitor

Returns a new instance of Visitor.



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 83

def initialize(parser, is_collection)
  @parser = parser
  @is_collection = is_collection

  @schema = {}
  @segment = @schema
  @context = nil
  @prev_contexts = []

  @self_name = nil
  @root_key = nil
  @root_key_for_collection = nil
  @root_key_proc = nil
  @key_transformer = nil
  @collection_key = false
  @meta = {}
end

Instance Attribute Details

#collection_keyObject

Returns the value of attribute collection_key.



81
82
83
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 81

def collection_key
  @collection_key
end

#key_transformerObject

Returns the value of attribute key_transformer.



81
82
83
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 81

def key_transformer
  @key_transformer
end

#metaObject

Returns the value of attribute meta.



81
82
83
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 81

def meta
  @meta
end

#root_keyObject

Returns the value of attribute root_key.



81
82
83
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 81

def root_key
  @root_key
end

#root_key_for_collectionObject

Returns the value of attribute root_key_for_collection.



81
82
83
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 81

def root_key_for_collection
  @root_key_for_collection
end

#root_key_procObject

Returns the value of attribute root_key_proc.



81
82
83
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 81

def root_key_proc
  @root_key_proc
end

#schemaObject

Returns the value of attribute schema.



81
82
83
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 81

def schema
  @schema
end

Instance Method Details

#build_schemaObject



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 114

def build_schema
  result = { "type" => "object" }

  result["properties"] = @schema if @schema.any?

  if @root_key_proc
    dynamic_root_key, dynamic_root_key_for_collection = @root_key_proc.call(@self_name)

    @root_key = dynamic_root_key
    @root_key_for_collection = dynamic_root_key_for_collection
  end

  if @is_collection
    result = if @collection_key && @root_key_for_collection
      { "type" => "object", "properties" => { @root_key_for_collection => { "type" => "object", "additionalProperties" => result }, **@meta } }
    elsif @collection_key
      { "type" => "object", "additionalProperties" => result }
    elsif @root_key_for_collection
      { "type" => "object", "properties" => { @root_key_for_collection => { "type" => "array", "items" => result }, **@meta } }
    else
      { "type" => "array", "items" => result }
    end
  elsif @root_key
    result = { "type" => "object", "properties" => { @root_key => result, **@meta } }
  end

  result = deep_transform_keys(result) if @key_transformer

  result
end

#visit_assoc_node(node) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 218

def visit_assoc_node(node)
  value = case node.value
  when Prism::StringNode
    node.value.content
  when Prism::ArrayNode
    context = with_context { visit(node.value) }
    context.symbols[0] || context.consts[0]
  else
    node.value.slice
  end

  @context.keywords[node.key.value] = value
end

#visit_call_node(node) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 145

def visit_call_node(node)
  case node.name
  when :root_key
    @root_key_proc = nil
    context = with_context { visit(node.arguments) }
    @root_key, @root_key_for_collection = context.symbols

  when :attributes, :attribute
    context = with_context { visit(node.arguments) }
    context.symbols.each { |symbol| @segment[symbol] = { "type" => "string" } }
    context.keywords.except("if").each { |key, type| @segment[key] = get_type_definition(type) }

  when :nested, :nested_attribute
    context = with_context { visit(node.arguments) }
    with_inner_segment(context.symbols[0]) { visit(node.block) }

  when :meta
    context = with_context do
      visit(node.arguments)
      visit(node.block)
    end

    key = context.symbols[0] || "meta"
    unless context.nil
      @meta = { key => hash_to_openapi_schema(context.hashes[0]) }
    end

  when :many, :has_many, :one, :has_one, :association
    is_array = node.name == :many || node.name == :has_many
    context = with_context { visit(node.arguments) }
    association = context.symbols[0]
    key = context.keywords["key"] || association

    if node.block
      with_inner_segment(key, is_array:) { visit(node.block) }
    else
      resource = context.keywords["resource"] || (::Alba.inflector && "#{::Alba.inflector.classify(association.to_s)}Resource")
      resolved = Rage::OpenAPI.__resolve_resource(resource, @parser.namespace)

      @segment[key] = if resolved
        is_array ? @parser.__parse_nested("[#{resource}]") : @parser.__parse_nested(resource)
      else
        base = { "type" => "object" }
        is_array ? { "type" => "array", "items" => base } : base
      end
    end

  when :transform_keys
    context = with_context { visit(node.arguments) }
    @key_transformer = get_key_transformer(context.symbols[0])

  when :collection_key
    @collection_key = true

  when :root_key!
    if (inflector = ::Alba.inflector)
      @root_key, @root_key_for_collection = nil

      @root_key_proc = ->(resource_name) do
        suffix = resource_name.end_with?("Resource") ? "Resource" : "Serializer"
        name = inflector.demodulize(resource_name).delete_suffix(suffix)

        inflector.underscore(name).yield_self { |key| [key, inflector.pluralize(key)] }
      end
    end
  end
end

#visit_class_node(node) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 101

def visit_class_node(node)
  @self_name ||= node.name.to_s

  if node.name =~ /Resource$|Serializer$/ && node.superclass
    visitor = @parser.__parse(node.superclass.name)
    @root_key, @root_key_for_collection, @root_key_proc = visitor.root_key, visitor.root_key_for_collection, visitor.root_key_proc
    @key_transformer, @collection_key, @meta = visitor.key_transformer, visitor.collection_key, visitor.meta
    @schema.merge!(visitor.schema)
  end

  super
end

#visit_constant_read_node(node) ⇒ Object



232
233
234
235
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 232

def visit_constant_read_node(node)
  return unless @context
  @context.consts << node.name.to_s
end

#visit_hash_node(node) ⇒ Object



213
214
215
216
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 213

def visit_hash_node(node)
  parsed_hash = YAML.safe_load(node.slice) rescue nil
  @context.hashes << parsed_hash if parsed_hash
end

#visit_nil_node(node) ⇒ Object



241
242
243
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 241

def visit_nil_node(node)
  @context.nil = true
end

#visit_symbol_node(node) ⇒ Object



237
238
239
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 237

def visit_symbol_node(node)
  @context.symbols << node.value
end