Skip to content

Instantly share code, notes, and snippets.

@ta1kt0me
Created January 28, 2017 01:48
Show Gist options
  • Select an option

  • Save ta1kt0me/4c4b6144675e56dae0941ac28216590e to your computer and use it in GitHub Desktop.

Select an option

Save ta1kt0me/4c4b6144675e56dae0941ac28216590e to your computer and use it in GitHub Desktop.
Swagger client generator
require 'yaml'
require 'active_support/core_ext/string/inflections'
require 'byebug'
class SwaggerClientClassBuilder
attr_accessor :path, :method_builders
def initialize
@method_builders = []
end
def build
" class #{class_name}\n#{methods} end\n"
end
def methods
method_builders.map(&:build).join("\n")
end
def class_name
token = path.split('/').reject(&:empty?).each_slice(2).inject([]) do |e, (a, b)|
if !b
e << a
else b&.match?(/{ #{ a.singularize}ID}/)
e << a.singularize
end
e
end
token.map(&:camelize).join
end
end
class SwaggerClientMethodBuilder
attr_accessor :method, :requireds, :optionals, :options, :params, :auth, :class_builder, :domain
def initialize(domain)
@domain = domain
end
def build
<<-TEMP
def #{method}(#{requireds.map { |e| "#{e['name'].underscore}, " }.join}options = {})
#{connection}
res = conn.#{method} do |f|
f.url "#{url}"
#{ ' f.headers["Authorization"] = "Bearer #{ENV[\'TOKEN\']}"' if auth }
#{ ' f.body = { ' + build_body + ' }' if need_body? && param_exists? }
end
res.body
end
TEMP
end
private
def connection
if need_body?
<<-EOS
conn = Faraday.new(:url => '#{domain}') do |faraday|
faraday.request :multipart
faraday.request :url_encoded
faraday.response :logger
faraday.adapter Faraday.default_adapter
end
EOS
else
"conn = Faraday.new(:url => '#{domain}')"
end
end
def build_body
h = []
h << requireds_except_path_params.map { |e| "#{e['name']}: " + '' + "#{e['name']}" + '' }
h << optionals.map { |e| "#{e['name']}: " + 'options[:' + "#{e['name']}" + ']' }
h.flatten.join(", ")
end
def param_exists?
!(requireds_except_path_params.empty? && optionals.empty?)
end
def need_body?
%w(post put).include? method
end
def url
if need_body?
extracted_string_path
else
extracted_string_path + "?" + query_string
end
end
def path
class_builder.path
end
def extracted_string_path
path.gsub(/\{\w+\}/) { |e| "\##{e.underscore}" }
end
def query_string
query = []
query << requireds_except_path_params.map { |e| "#{e['name']}=" + '#{' + "#{e['name']}" + '}'}
query << optionals.map { |e| "#{e['name']}=" + '#{options[:' + "#{e['name']}" + ']}' }
query.flatten.join("&")
end
def requireds_except_path_params
requireds.reject { |param| path_params.include? param["name"].underscore }
end
def path_params
path.scan(/\{(\w+)\}/).flatten.map(&:underscore)
end
end
result = ''
result += "require 'active_support/core_ext/string/inflections'\n"
result += "require 'faraday'\n"
result += "require 'json'\n\n"
result += "module SwaggerClient\n"
spec = YAML.load_file('spec.yaml')
paths = spec["paths"]
paths.keys.each do |path|
class_builder = SwaggerClientClassBuilder.new
class_builder.path = path
path_spec = paths[path]
path_spec.keys.each do |method|
method_builder = SwaggerClientMethodBuilder.new(ARGV[0])
method_builder.method = method
method_builder.class_builder = class_builder
method_spec = path_spec[method]
if params = method_spec["parameters"]
param_names = params.map { |param| param["name"].underscore }
requireds = params.select { |param| param["required"] }
optionals = params - requireds
method_builder.params = param_names
method_builder.requireds = requireds
method_builder.optionals = optionals
end
if method_spec["security"]&.any? { |h| h.key?("accessTokenAuth") }
method_builder.auth = true
end
class_builder.method_builders << method_builder
end
result += class_builder.build + "\n"
end
result += "end\n"
File.write('swagger_client.rb', result)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment