diff --git a/bin/build-openapi-yaml.rb b/bin/build-openapi-yaml.rb index 4152a27eb..19291e81f 100755 --- a/bin/build-openapi-yaml.rb +++ b/bin/build-openapi-yaml.rb @@ -437,12 +437,45 @@ def merge_operations(new_api_object, old_api_object, uri, method) #remove dups new_api_object["parameters"] = new_api_object["parameters"].uniq { |p| p["name"] } - # make sure if we have a requestBody, we pass that along in the merge. This will blow up if we have two operations that take request bodies but don't have the same request body - if old_api_object["requestBody"] && !new_api_object["requestBody"] - new_api_object["requestBody"] = old_api_object["requestBody"] + request_body = merge_request_bodies(new_api_object, old_api_object) + new_api_object["requestBody"] = request_body if request_body + + new_api_object +end + +def merge_request_bodies(new_api_object, old_api_object) + return if !new_api_object["requestBody"] && !old_api_object["requestBody"] + + # if there is no request body defined on the new API, mark the current request body as not required + unless new_api_object["requestBody"] + return { "required" => false, "content" => old_api_object["requestBody"]["content"] } + end + + request_body = { "content" => {} } + + # if the old API does not have a request body, mark it as not required + if old_api_object["requestBody"] + request_body["content"] = old_api_object["requestBody"]["content"] + else + return { "required" => false, "content" => new_api_object["requestBody"]["content"] } end - return new_api_object + # Merge new request bodies into definition + new_api_object["requestBody"]["content"].each do |media_type, media_type_definition| + # if there is no request body for the media_type defined, just set it + unless request_body["content"][media_type] + request_body["content"][media_type] = media_type_definition + break + end + + # if there is already a oneOf node, wrap the current schema + unless request_body["content"][media_type]["schema"].key?("oneOf") + request_body["content"][media_type]["schema"] = { "oneOf" => [request_body["content"][media_type]["schema"]] } + end + request_body["content"][media_type]["schema"]["oneOf"] << media_type_definition["schema"] + end + + request_body end def build_path(uri, json, paths, include_optional_segment_param, options) @@ -485,6 +518,7 @@ def build_path(uri, json, paths, include_optional_segment_param, options) segmentparams = jsonparams.select{|p| p["type"] == "urlSegment"} queryparams = jsonparams.select{|p| p["type"] == "urlParameter"} bodyparams = jsonparams.select{|p| p["type"] == "body"} + formparams = jsonparams.select{|p| p["type"] == "form"} queryparams.each do |p| params << build_openapi_paramobj(p, "query") @@ -506,12 +540,22 @@ def build_path(uri, json, paths, include_optional_segment_param, options) end end - if bodyparams && bodyparams.length > 0 - openapiobj["requestBody"] = {} - openapiobj["requestBody"]["content"] = {} - openapiobj["requestBody"]["content"]["application/json"] = {} - openapiobj["requestBody"]["content"]["application/json"]["schema"] = {} - openapiobj["requestBody"]["content"]["application/json"]["schema"]["$ref"] = make_ref(bodyparams[0]["javaType"]) + if formparams&.any? || bodyparams&.any? + request_body = {} + + if bodyparams&.any? + request_body["application/json"] = { + "schema" => { + "$ref" => make_ref(bodyparams[0]["javaType"]) + } + } + end + + if formparams&.any? + request_body["application/x-www-form-urlencoded"] = build_openapi_form_schema(formparams) + end + + openapiobj["requestBody"] = { "content" => request_body } end end @@ -560,6 +604,28 @@ def add_header_params(params, json) params << header_param end +def build_openapi_form_schema(form_parameters) + properties = {} + required = [] + + form_parameters.each do |param| + property = build_openapi_form_schema_property(param) + properties[param["name"]] = property + + required << param["name"] unless param_optional(param["comments"]) + end + + + { "schema" => { "type" => "object", "properties" => properties, "required" => required } } +end + +def build_openapi_form_schema_property(param) + property = convert_primitive(param["javaType"]) + property["description"] = param["comments"].join(" ").delete("\n").strip + property["enum"] = [param["value"]] if param["value"] + property +end + def build_openapi_paramobj(jsonparamobj, paramtype) paramobj = {} paramobj["name"] = jsonparamobj["name"]