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.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 55

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
  @key_transformer = nil
  @collection_key = false
  @meta = {}
end

Instance Attribute Details

#collection_keyObject

Returns the value of attribute collection_key.



53
54
55
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 53

def collection_key
  @collection_key
end

#key_transformerObject

Returns the value of attribute key_transformer.



53
54
55
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 53

def key_transformer
  @key_transformer
end

#metaObject

Returns the value of attribute meta.



53
54
55
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 53

def meta
  @meta
end

#root_keyObject

Returns the value of attribute root_key.



53
54
55
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 53

def root_key
  @root_key
end

#root_key_for_collectionObject

Returns the value of attribute root_key_for_collection.



53
54
55
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 53

def root_key_for_collection
  @root_key_for_collection
end

#schemaObject

Returns the value of attribute schema.



53
54
55
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 53

def schema
  @schema
end

Instance Method Details

#build_schemaObject



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 85

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

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

  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



175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 175

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



109
110
111
112
113
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 109

def visit_call_node(node)
  case node.name
  when :root_key
    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) }
    key = context.keywords["key"] || context.symbols[0]

    if node.block
      with_inner_segment(key, is_array:) { visit(node.block) }
    else
      resource = context.keywords["resource"] || (::Alba.inflector && "#{::Alba.inflector.classify(key.to_s)}Resource")
      is_valid_resource = @parser.namespace.const_get(resource) rescue false

      @segment[key] = if is_array
        @parser.__parse_nested(is_valid_resource ? "[#{resource}]" : "[Rage]") # TODO
      else
        @parser.__parse_nested(is_valid_resource ? resource : "Rage")
      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)
      suffix = @self_name.end_with?("Resource") ? "Resource" : "Serializer"
      name = inflector.demodulize(@self_name).delete_suffix(suffix)
      @root_key = inflector.underscore(name)
      @root_key_for_collection = inflector.pluralize(@root_key) if @is_collection
    end
  end
end

#visit_class_node(node) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 72

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 = visitor.root_key, visitor.root_key_for_collection
    @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



189
190
191
192
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 189

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

#visit_hash_node(node) ⇒ Object



170
171
172
173
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 170

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



198
199
200
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 198

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

#visit_symbol_node(node) ⇒ Object



194
195
196
# File 'lib/rage/openapi/parsers/ext/alba.rb', line 194

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