Skip to content

Instantly share code, notes, and snippets.

@patsch
Created January 18, 2022 04:32
Show Gist options
  • Save patsch/0482a8db40b091d82be311baa47db3f1 to your computer and use it in GitHub Desktop.
Save patsch/0482a8db40b091d82be311baa47db3f1 to your computer and use it in GitHub Desktop.
Apipie : Combine static ApiPie JSON and Swagger JSON to inject details for array of objects
# -*- coding: utf-8 -*-
require 'fileutils'
# expects #{Rails.root}/doc/apidoc/schema_apipie.json and #{Rails.root}/doc/apidoc/schema_swagger_json.json
# produces: #{Rails.root}/doc/apidoc/schema_swagger_json_nested.json
# add in your lib/tasks folder and run with
# rake apphub:openapi2
namespace :apphub do
desc "Enrich the Swagger JSON generated by rake apipie:static_swagger_json re: Arrays of objects"
# By default OUT="#{Rails.root}/doc/apidoc"
task :openapi2, [:verbose] => :environment do |t, args|
sm = "Must be one of: <code>"
args.with_defaults(:verbose => false)
out = ENV["OUT"] || File.join(::Rails.root, 'doc/apidoc')
jsonfile = File.join(out,"schema_apipie.json")
swaggerfile = File.join(out,"schema_swagger_json.json")
if !File.exist?(jsonfile)
puts "Sorry, but the native JSON input file '#{jsonfile}' could not be found. Try running rake apipie:json"
elsif !File.exist?(swaggerfile)
puts "Sorry, but the swagger JSON input file '#{swaggerfile}' could not be found. Try running rake apipie:static_swagger_json"
else
swagger_hash = JSON.parse(File.open(swaggerfile).read)
api_hash = JSON.parse(File.open(jsonfile).read)
paths = swagger_hash['paths']
paths.each_key { |path|
actions = paths[path]
actions.each_key { |action|
actions[action]['parameters'].each { |param|
schema = param['schema']
if !schema.nil?
#puts "have schema for #{param}"
properties = schema['properties']
properties.each_key { |property|
# puts property
props = properties[property]
if props['type'] == "array"
# puts "Detected array property '#{property}' for path #{path} and action #{action}"
resources = api_hash['docs']['resources']
resources.each_key { |resource|
resources[resource]['methods'].each { |method|
is_match = false
method['apis'].each { |api|
if api['api_url'] == path && api['http_method'].upcase == action.upcase
is_match = true
break
end
}
if is_match
method['params'].each { |method_param|
if method_param['name'] == property && method_param['expected_type'] == "array"
nested = Hash.new
items = props['items']
items['type'] = "object"
items['properties'] = nested
method_param['params'].each { |np|
h = Hash.new
nested[np['name']] = h
h['description'] = np['description'].strip.gsub("<p>","").gsub("</p>","")
h['type'] = np['expected_type']
if !h['validator'].nil? && h['validator'].index(sm) == 0
senum = h['validator'][sm.length,h['validator'].length]
enum_vals = senum.gsub("</code>, ","").gsub("</code>.","").split("<code>")
np['enum'] = enum_vals
end
}
puts "gotcha: #{property} is an #{method_param['expected_type']} : injecting details..."
end
}
end
}
}
end
}
end
}
}
}
updated_swaggerfile = "#{swaggerfile.gsub('.json','')}_nested.json"
File.write(updated_swaggerfile,JSON.dump(swagger_hash))
puts "Please check out #{updated_swaggerfile}"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment