Class: Generator::Operation

Inherits:
Object
  • Object
show all
Includes:
Formatter
Defined in:
lib/generator/operation.rb

Constant Summary collapse

DEFAULT_TEMPLATE =
File.read(Config.template_path("operation"))

Constants included from Formatter

Formatter::MAX_LINE_LENGTH

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Formatter

#convert_doc_links_to_full_url, #convert_html_links_to_yard, #format_method_definition, #split_long_comment_line

Constructor Details

#initialize(path, verb, operation, api_name_with_version, template: DEFAULT_TEMPLATE) ⇒ Operation

Returns a new instance of Operation.



19
20
21
22
23
24
25
# File 'lib/generator/operation.rb', line 19

def initialize(path, verb, operation, api_name_with_version, template: DEFAULT_TEMPLATE)
  @path = path
  @verb = verb
  @operation = operation
  @api_name_with_version = api_name_with_version
  @template = template
end

Instance Attribute Details

#api_name_with_versionObject (readonly)

Returns the value of attribute api_name_with_version.



17
18
19
# File 'lib/generator/operation.rb', line 17

def api_name_with_version
  @api_name_with_version
end

#operationObject (readonly)

Returns the value of attribute operation.



17
18
19
# File 'lib/generator/operation.rb', line 17

def operation
  @operation
end

#pathObject (readonly)

Returns the value of attribute path.



17
18
19
# File 'lib/generator/operation.rb', line 17

def path
  @path
end

#templateObject (readonly)

Returns the value of attribute template.



17
18
19
# File 'lib/generator/operation.rb', line 17

def template
  @template
end

#verbObject (readonly)

Returns the value of attribute verb.



17
18
19
# File 'lib/generator/operation.rb', line 17

def verb
  @verb
end

Instance Method Details

#body_param_nameObject



122
123
124
125
# File 'lib/generator/operation.rb', line 122

def body_param_name
  body_param = parameters.find { |p| p["in"] == "body" }
  body_param["name"].underscore if body_param
end

#descriptionObject



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/generator/operation.rb', line 35

def description
  description = operation["description"]

  # Remove usage plan details
  # Some API models have literal \n strings instead of actual newlines
  delimiter = description.include?("\\n") ? "\\n" : "\n"
  lines = description.split(delimiter)
  usage_plan_index = lines.find_index { |line| line.downcase.include?("usage plan") }
  lines = lines[0...usage_plan_index] if usage_plan_index
  # Join lines back together, preserving blank lines for proper paragraph separation
  description = lines.join("\n").strip

  # Ensure **Note:** and **Examples:** start on new lines with blank lines before them
  # Handle both **Note:** and __Note__: formats (will be normalized to ** later)
  description = description.gsub(/(\S)\s*((\*\*|__)(Note|Examples?):(\*\*|__))/, "\\1\n\n\\2")

  description = convert_html_links_to_yard(description)
  description = convert_doc_links_to_full_url(description)

  split_long_comment_line(description, base_indent: 6)
end

#has_typed_response?Boolean

Returns:

  • (Boolean)


151
152
153
# File 'lib/generator/operation.rb', line 151

def has_typed_response?
  !!operation_id && response_model[:model]
end

#method_definitionObject



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/generator/operation.rb', line 87

def method_definition
  method_name = operation["operationId"].underscore

  required_params = parameters.select { |p| p["required"] }&.map { |p| p["name"].underscore } || []
  optional_params = parameters.reject do |p|
    p["required"]
  end.map do |p|
    default_value = p["default"]

    # Handle array parameters with string defaults (OpenAPI spec inconsistency)
    formatted_default = if p["type"] == "array" && default_value.is_a?(String)
      "[\"#{default_value}\"]"
    elsif default_value.is_a?(String)
      "\"#{default_value}\""
    elsif default_value.is_a?(Array)
      default_value.inspect
    else
      default_value || "nil"
    end

    "#{p["name"].underscore}: #{formatted_default}"
  end
  params = required_params + optional_params

  format_method_definition(method_name, params, base_indent: 6)
end

#operation_idObject



27
28
29
# File 'lib/generator/operation.rb', line 27

def operation_id
  operation["operationId"]
end

#parametersObject



159
160
161
# File 'lib/generator/operation.rb', line 159

def parameters
  @parameters ||= ParameterBuilder.new(operation, path.parameters, rate_limit).build
end

#query_paramsObject



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/generator/operation.rb', line 127

def query_params
  hash = {}
  parameters.select { |p| p["in"] == "query" }.each do |p|
    param_name = p["name"].underscore
    value = param_name

    # If parameter is array type, add array handling
    if p["type"] == "array"
      value = "stringify_array(#{param_name})"
    end

    hash[p["name"]] = value
  end
  hash
end

#rate_limitObject



163
164
165
# File 'lib/generator/operation.rb', line 163

def rate_limit
  @rate_limit ||= RateLimitParser.new(operation).parse
end

#renderObject



31
32
33
# File 'lib/generator/operation.rb', line 31

def render
  ERB.new(template, trim_mode: "-").result(binding)
end

#request_argsObject



143
144
145
146
147
148
149
# File 'lib/generator/operation.rb', line 143

def request_args
  args = ["path"]
  args << "body:" if body_param_name
  args << "params:" if query_params.any?

  args
end

#response_modelObject



155
156
157
# File 'lib/generator/operation.rb', line 155

def response_model
  @response_model ||= ResponseModel.new(operation).build
end

#sandbox_ruleObject



114
115
116
117
118
119
120
# File 'lib/generator/operation.rb', line 114

def sandbox_rule
  if !static_sandbox? && !dynamic_sandbox?
    "cannot_sandbox!\n\n"
  elsif sandbox_only?
    "must_sandbox!\n\n"
  end
end

#tagsObject



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
# File 'lib/generator/operation.rb', line 57

def tags
  output = parameters.map do |param|
    param_type = param["type"] ? param["type"].capitalize : "Object"
    param_type = "Hash" if param["schema"]
    if param_type == "Array"
      items_type = param.dig("items", "type")
      param_type = items_type ? "Array<#{items_type.capitalize}>" : "Array"
    end
    param_name = param["name"].underscore
    param_description = param["description"]&.gsub(/\s+/, " ")
    param_description = convert_html_links_to_yard(param_description) if param_description
    param_description = convert_doc_links_to_full_url(param_description) if param_description

    "@param #{param_name} [#{param_type}] #{param_description}"
  end

  if static_sandbox?
    output.unshift("@note This operation can make a static sandbox call.")
  elsif dynamic_sandbox?
    output.unshift("@note This operation can make a dynamic sandbox call.")
  end
  output << "@return [Peddler::Response] The API response"

  output.map do |line|
    line = convert_html_links_to_yard(line)
    line = convert_doc_links_to_full_url(line)
    split_long_comment_line(line, base_indent: 6)
  end
end