rails-openapi-gen 0.0.2 → 0.0.3

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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -0
  3. data/CLAUDE.md +17 -5
  4. data/README.md +25 -0
  5. data/lib/rails-openapi-gen/ast_nodes/array_node.rb +101 -0
  6. data/lib/rails-openapi-gen/ast_nodes/base_node.rb +139 -0
  7. data/lib/rails-openapi-gen/ast_nodes/comment_data.rb +180 -0
  8. data/lib/rails-openapi-gen/ast_nodes/node_factory.rb +206 -0
  9. data/lib/rails-openapi-gen/ast_nodes/object_node.rb +129 -0
  10. data/lib/rails-openapi-gen/ast_nodes/partial_node.rb +111 -0
  11. data/lib/rails-openapi-gen/ast_nodes/property_node.rb +74 -0
  12. data/lib/rails-openapi-gen/ast_nodes.rb +129 -0
  13. data/lib/rails-openapi-gen/configuration.rb +154 -22
  14. data/lib/rails-openapi-gen/debug_helpers.rb +185 -0
  15. data/lib/rails-openapi-gen/engine.rb +1 -1
  16. data/lib/rails-openapi-gen/generators/yaml_generator.rb +242 -27
  17. data/lib/rails-openapi-gen/generators.rb +5 -0
  18. data/lib/rails-openapi-gen/importer.rb +164 -145
  19. data/lib/rails-openapi-gen/parsers/comment_parser.rb +1 -1
  20. data/lib/rails-openapi-gen/parsers/comment_parsers/attribute_parser.rb +7 -7
  21. data/lib/rails-openapi-gen/parsers/comment_parsers/base_attribute_parser.rb +5 -9
  22. data/lib/rails-openapi-gen/parsers/comment_parsers/body_parser.rb +6 -6
  23. data/lib/rails-openapi-gen/parsers/comment_parsers/conditional_parser.rb +1 -1
  24. data/lib/rails-openapi-gen/parsers/comment_parsers/operation_parser.rb +5 -5
  25. data/lib/rails-openapi-gen/parsers/comment_parsers/param_parser.rb +6 -6
  26. data/lib/rails-openapi-gen/parsers/comment_parsers/query_parser.rb +6 -6
  27. data/lib/rails-openapi-gen/parsers/controller_parser.rb +64 -20
  28. data/lib/rails-openapi-gen/parsers/jbuilder/ast_parser.rb +914 -0
  29. data/lib/rails-openapi-gen/parsers/jbuilder/call_detectors/array_call_detector.rb +103 -0
  30. data/lib/rails-openapi-gen/parsers/jbuilder/call_detectors/base_detector.rb +107 -0
  31. data/lib/rails-openapi-gen/parsers/jbuilder/call_detectors/cache_call_detector.rb +112 -0
  32. data/lib/rails-openapi-gen/parsers/jbuilder/call_detectors/json_call_detector.rb +91 -0
  33. data/lib/rails-openapi-gen/parsers/jbuilder/call_detectors/key_format_detector.rb +27 -0
  34. data/lib/rails-openapi-gen/parsers/jbuilder/call_detectors/null_handling_detector.rb +27 -0
  35. data/lib/rails-openapi-gen/parsers/jbuilder/call_detectors/object_manipulation_detector.rb +27 -0
  36. data/lib/rails-openapi-gen/parsers/jbuilder/call_detectors/partial_call_detector.rb +125 -0
  37. data/lib/rails-openapi-gen/parsers/jbuilder/call_detectors.rb +95 -0
  38. data/lib/rails-openapi-gen/parsers/jbuilder/jbuilder_parser.rb +39 -0
  39. data/lib/rails-openapi-gen/parsers/jbuilder/operation_comment_parser.rb +26 -0
  40. data/lib/rails-openapi-gen/parsers/jbuilder/processors/array_processor.rb +266 -0
  41. data/lib/rails-openapi-gen/parsers/jbuilder/processors/base_processor.rb +235 -0
  42. data/lib/rails-openapi-gen/parsers/jbuilder/processors/composite_processor.rb +97 -0
  43. data/lib/rails-openapi-gen/parsers/jbuilder/processors/object_processor.rb +176 -0
  44. data/lib/rails-openapi-gen/parsers/jbuilder/processors/partial_processor.rb +69 -0
  45. data/lib/rails-openapi-gen/parsers/jbuilder/processors/property_processor.rb +68 -0
  46. data/lib/rails-openapi-gen/parsers/jbuilder/processors.rb +10 -0
  47. data/lib/rails-openapi-gen/parsers/jbuilder/property_comment_parser.rb +26 -0
  48. data/lib/rails-openapi-gen/parsers/jbuilder.rb +10 -0
  49. data/lib/rails-openapi-gen/parsers/routes_parser.rb +83 -9
  50. data/lib/rails-openapi-gen/parsers/template_processors/jbuilder_template_processor.rb +125 -131
  51. data/lib/rails-openapi-gen/parsers/template_processors/response_template_processor.rb +8 -12
  52. data/lib/rails-openapi-gen/parsers/template_processors.rb +6 -0
  53. data/lib/rails-openapi-gen/parsers.rb +9 -0
  54. data/lib/rails-openapi-gen/processors/ast_to_schema_processor.rb +226 -0
  55. data/lib/rails-openapi-gen/processors/base_processor.rb +124 -0
  56. data/lib/rails-openapi-gen/processors/component_schema_processor.rb +35 -0
  57. data/lib/rails-openapi-gen/processors/openapi_schema_processor.rb +218 -0
  58. data/lib/rails-openapi-gen/processors.rb +7 -0
  59. data/lib/rails-openapi-gen/railtie.rb +1 -1
  60. data/lib/rails-openapi-gen/tasks/openapi.rake +4 -4
  61. data/lib/rails-openapi-gen/version.rb +1 -1
  62. data/lib/rails-openapi-gen.rb +169 -196
  63. data/lib/tasks/openapi_import.rake +35 -36
  64. data/rails-openapi-gen.gemspec +6 -5
  65. metadata +62 -23
  66. data/lib/rails-openapi-gen/parsers/jbuilder_parser.rb +0 -529
@@ -0,0 +1,206 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsOpenapiGen::AstNodes
4
+ # Factory class for creating AST nodes
5
+ # Provides convenient methods for creating different types of nodes
6
+ class NodeFactory
7
+ class << self
8
+ # Create a property node
9
+ # @param property_name [String] Name of the property
10
+ # @param comment_data [CommentData, Hash, nil] Comment data
11
+ # @param is_conditional [Boolean] Whether property is conditional
12
+ # @param is_component_ref [Boolean] Whether this is a component reference
13
+ # @param component_name [String, nil] Name of the referenced component
14
+ # @param parent [BaseNode, nil] Parent node
15
+ # @return [PropertyNode] Created property node
16
+ def create_property(property_name:, comment_data: nil, is_conditional: false, is_component_ref: false, component_name: nil, parent: nil)
17
+ PropertyNode.new(
18
+ property_name: property_name,
19
+ comment_data: normalize_comment_data(comment_data),
20
+ is_conditional: is_conditional,
21
+ is_component_ref: is_component_ref,
22
+ component_name: component_name,
23
+ parent: parent
24
+ )
25
+ end
26
+
27
+ # Create an array node
28
+ # @param property_name [String, nil] Name of the array property
29
+ # @param comment_data [CommentData, Hash, nil] Comment data
30
+ # @param is_conditional [Boolean] Whether array is conditional
31
+ # @param is_root_array [Boolean] Whether this is a root array (json.array!)
32
+ # @param parent [BaseNode, nil] Parent node
33
+ # @return [ArrayNode] Created array node
34
+ def create_array(property_name: nil, comment_data: nil, is_conditional: false, is_root_array: false, parent: nil)
35
+ ArrayNode.new(
36
+ property_name: property_name,
37
+ comment_data: normalize_comment_data(comment_data, default_type: 'array'),
38
+ is_conditional: is_conditional,
39
+ is_root_array: is_root_array,
40
+ parent: parent
41
+ )
42
+ end
43
+
44
+ # Create an object node
45
+ # @param property_name [String] Name of the object property
46
+ # @param comment_data [CommentData, Hash, nil] Comment data
47
+ # @param is_conditional [Boolean] Whether object is conditional
48
+ # @param parent [BaseNode, nil] Parent node
49
+ # @return [ObjectNode] Created object node
50
+ def create_object(property_name:, comment_data: nil, is_conditional: false, parent: nil)
51
+ ObjectNode.new(
52
+ property_name: property_name,
53
+ comment_data: normalize_comment_data(comment_data, default_type: 'object'),
54
+ is_conditional: is_conditional,
55
+ parent: parent
56
+ )
57
+ end
58
+
59
+ # Create a partial node
60
+ # @param partial_path [String] Path to the partial
61
+ # @param property_name [String, nil] Name of the property (for nested partials)
62
+ # @param comment_data [CommentData, Hash, nil] Comment data
63
+ # @param is_conditional [Boolean] Whether partial is conditional
64
+ # @param local_variables [Hash] Local variables passed to partial
65
+ # @param parent [BaseNode, nil] Parent node
66
+ # @return [PartialNode] Created partial node
67
+ def create_partial(partial_path:, property_name: nil, comment_data: nil, is_conditional: false, local_variables: {}, parent: nil)
68
+ PartialNode.new(
69
+ partial_path: partial_path,
70
+ property_name: property_name,
71
+ comment_data: normalize_comment_data(comment_data),
72
+ is_conditional: is_conditional,
73
+ local_variables: local_variables,
74
+ parent: parent
75
+ )
76
+ end
77
+
78
+ # Create a node from hash data (backward compatibility)
79
+ # @param hash_data [Hash] Hash containing node data
80
+ # @return [BaseNode] Created node
81
+ def from_hash(hash_data)
82
+ return hash_data unless hash_data.is_a?(Hash)
83
+
84
+ case hash_data[:node_type]&.to_sym
85
+ when :array
86
+ create_array(
87
+ property_name: hash_data[:property_name] || hash_data[:property],
88
+ comment_data: hash_data[:comment_data],
89
+ is_conditional: hash_data[:is_conditional] || false,
90
+ is_root_array: hash_data[:is_root_array] || hash_data[:is_array_root] || false
91
+ )
92
+ when :object
93
+ create_object(
94
+ property_name: hash_data[:property_name] || hash_data[:property],
95
+ comment_data: hash_data[:comment_data],
96
+ is_conditional: hash_data[:is_conditional] || false
97
+ )
98
+ when :partial
99
+ create_partial(
100
+ partial_path: hash_data[:partial_path],
101
+ property_name: hash_data[:property_name] || hash_data[:property],
102
+ comment_data: hash_data[:comment_data],
103
+ is_conditional: hash_data[:is_conditional] || false,
104
+ local_variables: hash_data[:local_variables] || {}
105
+ )
106
+ else
107
+ # Check if this is an array property that should be preserved as hash
108
+ if hash_data[:is_array] && hash_data[:array_item_properties]
109
+ # Return hash data directly to preserve array information
110
+ hash_data
111
+ else
112
+ create_property(
113
+ property_name: hash_data[:property_name] || hash_data[:property],
114
+ comment_data: hash_data[:comment_data],
115
+ is_conditional: hash_data[:is_conditional] || false
116
+ )
117
+ end
118
+ end
119
+ end
120
+
121
+ # Create nodes from an array of hash data
122
+ # @param hash_array [Array<Hash>] Array of hash data
123
+ # @return [Array<BaseNode>] Array of created nodes
124
+ def from_hash_array(hash_array)
125
+ return [] unless hash_array.is_a?(Array)
126
+
127
+ hash_array.map { |hash_data| from_hash(hash_data) }
128
+ end
129
+
130
+ # Create a tree structure from nested hash data
131
+ # @param hash_data [Hash] Root hash data
132
+ # @return [BaseNode] Root node with children
133
+ def create_tree(hash_data)
134
+ root_node = from_hash(hash_data)
135
+
136
+ # Add children if present
137
+ if hash_data[:children]
138
+ hash_data[:children].each do |child_data|
139
+ child_node = create_tree(child_data)
140
+ root_node.add_child(child_node)
141
+ end
142
+ end
143
+
144
+ # Add specific child types
145
+ add_specific_children(root_node, hash_data)
146
+
147
+ root_node
148
+ end
149
+
150
+ private
151
+
152
+ # Normalize comment data to CommentData instance
153
+ # @param data [CommentData, Hash, nil] Comment data input
154
+ # @param default_type [String, nil] Default type if not specified
155
+ # @return [CommentData] Normalized comment data
156
+ def normalize_comment_data(data, default_type: nil)
157
+ return CommentData.new(type: default_type) if data.nil?
158
+ return data if data.is_a?(CommentData)
159
+
160
+ # Convert hash to CommentData
161
+ CommentData.new(
162
+ type: data[:type] || default_type,
163
+ description: data[:description],
164
+ required: data[:required],
165
+ enum: data[:enum],
166
+ field_name: data[:field_name],
167
+ items: data[:items],
168
+ conditional: data[:conditional],
169
+ format: data[:format],
170
+ example: data[:example]
171
+ )
172
+ end
173
+
174
+ # Add specific children based on node type
175
+ # @param node [BaseNode] Parent node
176
+ # @param hash_data [Hash] Hash data containing children
177
+ # @return [void]
178
+ def add_specific_children(node, hash_data)
179
+ case node
180
+ when ArrayNode
181
+ # Add array items
182
+ if hash_data[:items]
183
+ hash_data[:items].each do |item_data|
184
+ item_node = from_hash(item_data)
185
+ node.add_item(item_node)
186
+ end
187
+ end
188
+ when ObjectNode
189
+ # Add object properties
190
+ if hash_data[:properties]
191
+ hash_data[:properties].each do |prop_data|
192
+ prop_node = from_hash(prop_data)
193
+ node.add_property(prop_node)
194
+ end
195
+ end
196
+ when PartialNode
197
+ # Add parsed properties
198
+ if hash_data[:properties]
199
+ properties = from_hash_array(hash_data[:properties])
200
+ node.add_parsed_properties(properties)
201
+ end
202
+ end
203
+ end
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsOpenapiGen::AstNodes
4
+ # Represents an object node in Jbuilder template (json.object do...end)
5
+ class ObjectNode < BaseNode
6
+ attr_reader :property_name, :comment_data, :is_conditional # json.xxx # @openapi comments # if/else
7
+
8
+ def initialize(property_name:, comment_data: nil, is_conditional: false, parent: nil, metadata: {})
9
+ super(parent: parent, metadata: metadata)
10
+ @property_name = property_name
11
+ @comment_data = comment_data || CommentData.new(type: 'object')
12
+ @is_conditional = is_conditional
13
+ end
14
+
15
+ # Add a property to this object
16
+ # @param property_node [BaseNode] Property node to add
17
+ # @return [BaseNode] The added property node
18
+ def add_property(property_node)
19
+ add_child(property_node)
20
+ end
21
+
22
+ # Get all properties in this object
23
+ # @return [Array<BaseNode>] Property nodes
24
+ def properties
25
+ @children
26
+ end
27
+
28
+ # Get required properties for OpenAPI schema
29
+ # @return [Array<String>] Names of required properties
30
+ def required_properties
31
+ properties.select do |property|
32
+ if property.respond_to?(:required?)
33
+ property.required?
34
+ else
35
+ # Handle legacy Hash objects
36
+ property.is_a?(Hash) && property[:required] == true
37
+ end
38
+ end.map do |property|
39
+ if property.respond_to?(:property_name)
40
+ property.property_name
41
+ else
42
+ # Handle legacy Hash objects
43
+ property[:property_name] || property[:property]
44
+ end
45
+ end.compact
46
+ end
47
+
48
+ # Get optional properties for OpenAPI schema
49
+ # @return [Array<String>] Names of optional properties
50
+ def optional_properties
51
+ properties.select do |property|
52
+ if property.respond_to?(:optional?)
53
+ property.optional?
54
+ else
55
+ # Handle legacy Hash objects
56
+ property.is_a?(Hash) && property[:required] != true
57
+ end
58
+ end.map do |property|
59
+ if property.respond_to?(:property_name)
60
+ property.property_name
61
+ else
62
+ # Handle legacy Hash objects
63
+ property[:property_name] || property[:property]
64
+ end
65
+ end.compact
66
+ end
67
+
68
+ # Check if this object is required in OpenAPI schema
69
+ # @return [Boolean] True if object is required
70
+ def required?
71
+ @comment_data.required? && !@is_conditional
72
+ end
73
+
74
+ # Check if this object is optional in OpenAPI schema
75
+ # @return [Boolean] True if object is optional
76
+ def optional?
77
+ !required?
78
+ end
79
+
80
+ # Get the description for this object
81
+ # @return [String, nil] Object description
82
+ def description
83
+ @comment_data.description
84
+ end
85
+
86
+ # Find a property by name
87
+ # @param name [String] Property name to find
88
+ # @return [BaseNode, nil] Property node or nil if not found
89
+ def find_property(name)
90
+ properties.find do |prop|
91
+ if prop.respond_to?(:property_name)
92
+ prop.property_name == name
93
+ else
94
+ # Handle legacy Hash objects
95
+ (prop[:property_name] || prop[:property]) == name
96
+ end
97
+ end
98
+ end
99
+
100
+ # Check if object has any properties
101
+ # @return [Boolean] True if object has properties
102
+ def has_properties?
103
+ !properties.empty?
104
+ end
105
+
106
+ # Convert to hash representation
107
+ # @return [Hash] Hash representation
108
+ def to_h
109
+ super.merge(
110
+ property_name: @property_name,
111
+ comment_data: @comment_data&.to_h,
112
+ is_conditional: @is_conditional,
113
+ required: required?,
114
+ openapi_type: 'object',
115
+ description: description,
116
+ properties: properties.map { |prop| prop.respond_to?(:to_h) ? prop.to_h : prop },
117
+ required_properties: required_properties,
118
+ optional_properties: optional_properties
119
+ ).compact
120
+ end
121
+
122
+ # Accept visitor for visitor pattern
123
+ # @param visitor [Object] Visitor object
124
+ # @return [Object] Result from visitor
125
+ def accept(visitor)
126
+ visitor.visit_object(self)
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsOpenapiGen::AstNodes
4
+ # Represents a partial node in Jbuilder template (json.partial!)
5
+ class PartialNode < BaseNode
6
+ attr_reader :partial_path, :property_name, :comment_data, :is_conditional, :local_variables
7
+
8
+ def initialize(
9
+ partial_path:,
10
+ property_name: nil,
11
+ comment_data: nil,
12
+ is_conditional: false,
13
+ local_variables: {},
14
+ parent: nil,
15
+ metadata: {}
16
+ )
17
+ super(parent: parent, metadata: metadata)
18
+ @partial_path = partial_path
19
+ @property_name = property_name
20
+ @comment_data = comment_data || CommentData.new
21
+ @is_conditional = is_conditional
22
+ @local_variables = local_variables
23
+ end
24
+
25
+ # Resolve the absolute path of the partial
26
+ # @param base_path [String] Base path for resolution
27
+ # @return [String] Resolved partial path
28
+ def resolve_path(base_path = nil)
29
+ return @partial_path if @partial_path.start_with?('/')
30
+
31
+ if base_path
32
+ File.join(File.dirname(base_path), "#{@partial_path}.json.jbuilder")
33
+ else
34
+ "#{@partial_path}.json.jbuilder"
35
+ end
36
+ end
37
+
38
+ # Check if this partial is required in OpenAPI schema
39
+ # @return [Boolean] True if partial is required
40
+ def required?
41
+ @comment_data.required? && !@is_conditional
42
+ end
43
+
44
+ # Check if this partial is optional in OpenAPI schema
45
+ # @return [Boolean] True if partial is optional
46
+ def optional?
47
+ !required?
48
+ end
49
+
50
+ # Get the description for this partial
51
+ # @return [String, nil] Partial description
52
+ def description
53
+ @comment_data.description
54
+ end
55
+
56
+ # Check if partial has local variables
57
+ # @return [Boolean] True if partial has local variables
58
+ def has_locals?
59
+ !@local_variables.empty?
60
+ end
61
+
62
+ # Get local variable names
63
+ # @return [Array<String>] Local variable names
64
+ def local_names
65
+ @local_variables.keys
66
+ end
67
+
68
+ # Get value for a local variable
69
+ # @param name [String] Local variable name
70
+ # @return [Object] Local variable value
71
+ def local_value(name)
72
+ @local_variables[name]
73
+ end
74
+
75
+ # Add parsed properties from the partial
76
+ # @param properties [Array<BaseNode>] Properties from parsed partial
77
+ # @return [Array<BaseNode>] Added properties
78
+ def add_parsed_properties(properties)
79
+ properties.each { |prop| add_child(prop) }
80
+ properties
81
+ end
82
+
83
+ # Get all properties from the parsed partial
84
+ # @return [Array<BaseNode>] Properties from partial
85
+ def properties
86
+ @children
87
+ end
88
+
89
+ # Convert to hash representation
90
+ # @return [Hash] Hash representation
91
+ def to_h
92
+ super.merge(
93
+ partial_path: @partial_path,
94
+ property_name: @property_name,
95
+ comment_data: @comment_data&.to_h,
96
+ is_conditional: @is_conditional,
97
+ required: required?,
98
+ description: description,
99
+ local_variables: @local_variables,
100
+ properties: properties.map { |prop| prop.respond_to?(:to_h) ? prop.to_h : prop }
101
+ ).compact
102
+ end
103
+
104
+ # Accept visitor for visitor pattern
105
+ # @param visitor [Object] Visitor object
106
+ # @return [Object] Result from visitor
107
+ def accept(visitor)
108
+ visitor.visit_partial(self)
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsOpenapiGen
4
+ module AstNodes
5
+ # Represents a property node in Jbuilder template (json.property_name)
6
+ class PropertyNode < BaseNode
7
+ attr_reader :property_name, :comment_data, :is_conditional, :is_component_ref, :component_name # json.xxx # @openapi comments # if/else # whether this is a component reference # name of referenced component
8
+
9
+ def initialize(property_name:, comment_data: nil, is_conditional: false, is_component_ref: false, component_name: nil, parent: nil, metadata: {})
10
+ super(parent: parent, metadata: metadata)
11
+ @property_name = property_name
12
+ @comment_data = comment_data || CommentData.new
13
+ @is_conditional = is_conditional
14
+ @is_component_ref = is_component_ref
15
+ @component_name = component_name
16
+ end
17
+
18
+ # Check if this property is required in OpenAPI schema
19
+ # @return [Boolean] True if property is required
20
+ def required?
21
+ @comment_data.required? && !@is_conditional
22
+ end
23
+
24
+ # Check if this property is optional in OpenAPI schema
25
+ # @return [Boolean] True if property is optional
26
+ def optional?
27
+ !required?
28
+ end
29
+
30
+ # Get the OpenAPI type for this property
31
+ # @return [String] OpenAPI type
32
+ def openapi_type
33
+ @comment_data.type || 'string'
34
+ end
35
+
36
+ # Get the description for this property
37
+ # @return [String, nil] Property description
38
+ def description
39
+ @comment_data.description
40
+ end
41
+
42
+ # Get enum values if specified
43
+ # @return [Array, nil] Enum values
44
+ def enum_values
45
+ @comment_data.enum
46
+ end
47
+
48
+ # Convert to hash representation
49
+ # @return [Hash] Hash representation
50
+ def to_h
51
+ super.merge(
52
+ property_name: @property_name,
53
+ comment_data: @comment_data&.to_h,
54
+ is_conditional: @is_conditional,
55
+ is_component_ref: @is_component_ref,
56
+ component_name: @component_name,
57
+ required: required?,
58
+ openapi_type: openapi_type,
59
+ description: description,
60
+ enum: enum_values,
61
+ # Backward compatibility - also provide property for Generator
62
+ property: @property_name
63
+ ).compact
64
+ end
65
+
66
+ # Accept visitor for visitor pattern
67
+ # @param visitor [Object] Visitor object
68
+ # @return [Object] Result from visitor
69
+ def accept(visitor)
70
+ visitor.visit_property(self)
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsOpenapiGen
4
+ module AstNodes
5
+ autoload :BaseNode, "rails-openapi-gen/ast_nodes/base_node"
6
+ autoload :PropertyNode, "rails-openapi-gen/ast_nodes/property_node"
7
+ autoload :ArrayNode, "rails-openapi-gen/ast_nodes/array_node"
8
+ autoload :PartialNode, "rails-openapi-gen/ast_nodes/partial_node"
9
+ autoload :ObjectNode, "rails-openapi-gen/ast_nodes/object_node"
10
+ autoload :CommentData, "rails-openapi-gen/ast_nodes/comment_data"
11
+ autoload :NodeFactory, "rails-openapi-gen/ast_nodes/node_factory"
12
+
13
+ # Legacy compatibility classes - will be deprecated
14
+ # These maintain backward compatibility with existing code
15
+ class PropertyNodeFactory < NodeFactory
16
+ # Delegate to NodeFactory for backward compatibility
17
+ class << self
18
+ def from_hash(hash_data)
19
+ NodeFactory.from_hash(hash_data)
20
+ end
21
+
22
+ def create_simple(property:, comment_data: nil, is_conditional: false)
23
+ NodeFactory.create_property(
24
+ property_name: property,
25
+ comment_data: comment_data,
26
+ is_conditional: is_conditional
27
+ )
28
+ end
29
+
30
+ def create_array(property:, comment_data: nil, is_conditional: false, array_item_properties: [])
31
+ node = NodeFactory.create_array(
32
+ property_name: property,
33
+ comment_data: comment_data,
34
+ is_conditional: is_conditional
35
+ )
36
+ array_item_properties.each { |item| node.add_item(item) }
37
+ node
38
+ end
39
+
40
+ def create_object(property:, comment_data: nil, is_conditional: false, nested_properties: [])
41
+ node = NodeFactory.create_object(
42
+ property_name: property,
43
+ comment_data: comment_data,
44
+ is_conditional: is_conditional
45
+ )
46
+ nested_properties.each { |prop| node.add_property(prop) }
47
+ node
48
+ end
49
+
50
+ def create_array_root(comment_data: nil, array_item_properties: [])
51
+ node = NodeFactory.create_array(
52
+ comment_data: comment_data,
53
+ is_root_array: true
54
+ )
55
+ array_item_properties.each { |item| node.add_item(item) }
56
+ node
57
+ end
58
+ end
59
+ end
60
+
61
+ # Legacy property node classes for backward compatibility
62
+ class SimplePropertyNode < PropertyNode
63
+ def initialize(property:, comment_data: nil, is_conditional: false)
64
+ super(property_name: property, comment_data: comment_data, is_conditional: is_conditional)
65
+ end
66
+
67
+ def property
68
+ property_name
69
+ end
70
+ end
71
+
72
+ class ArrayPropertyNode < ArrayNode
73
+ def initialize(property:, comment_data: nil, is_conditional: false, array_item_properties: [])
74
+ super(property_name: property, comment_data: comment_data, is_conditional: is_conditional)
75
+ array_item_properties.each { |item| add_item(item) }
76
+ end
77
+
78
+ def property
79
+ property_name
80
+ end
81
+
82
+ def array_item_properties
83
+ items
84
+ end
85
+
86
+ def add_item_property(property_node)
87
+ add_item(property_node)
88
+ end
89
+ end
90
+
91
+ class ObjectPropertyNode < ObjectNode
92
+ def initialize(property:, comment_data: nil, is_conditional: false, nested_properties: [])
93
+ super(property_name: property, comment_data: comment_data, is_conditional: is_conditional)
94
+ nested_properties.each { |prop| add_property(prop) }
95
+ end
96
+
97
+ def property
98
+ property_name
99
+ end
100
+
101
+ def nested_properties
102
+ properties
103
+ end
104
+
105
+ def add_nested_property(property_node)
106
+ add_property(property_node)
107
+ end
108
+ end
109
+
110
+ class ArrayRootNode < ArrayNode
111
+ def initialize(comment_data: nil, array_item_properties: [])
112
+ super(property_name: 'items', comment_data: comment_data, is_root_array: true)
113
+ array_item_properties.each { |item| add_item(item) }
114
+ end
115
+
116
+ def property
117
+ property_name
118
+ end
119
+
120
+ def array_item_properties
121
+ items
122
+ end
123
+
124
+ def add_item_property(property_node)
125
+ add_item(property_node)
126
+ end
127
+ end
128
+ end
129
+ end