Skip to content

Instantly share code, notes, and snippets.

@kpol
Last active January 30, 2019 22:21
Show Gist options
  • Save kpol/3e76ecf37024d4be364f8a5782557f9a to your computer and use it in GitHub Desktop.
Save kpol/3e76ecf37024d4be364f8a5782557f9a to your computer and use it in GitHub Desktop.
Consolidates enums for Swagger file
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
namespace OpenApi.Extensions
{
/// <summary>
/// Consolidates enums based on <code>x-type-fullname</code> vendor extension.
/// <example>
/// {
/// "name": "enumA",
/// "in": "query",
/// "required": true,
/// "type": "string",
/// "enum": ["A", "B"],
/// "x-nullable": false,
/// "x-type-fullname": "Serko.Services.Swagger.WebTest.EnumA"
/// }
/// </example>
/// </summary>
public class SwaggerXTypeEnumConsolidator
{
/// <summary>
/// Swagger spec file vendor extension name.
/// </summary>
public const string XTypeFullName = "x-type-fullname";
/// <summary>
/// Modifies input Swagger spec file.
/// </summary>
/// <param name="swaggerJObject"></param>
/// <returns>Modified Swagger spec file.</returns>
public string ModifySwaggerSpec(JObject swaggerJObject)
{
// get all enums
var enums = swaggerJObject.Descendants().OfType<JProperty>()
.Where(d => d.Name == "enum" && d.Parent[XTypeFullName] != null).ToList();
var enumsHashSet = new HashSet<string>();
var distinctEnums = enums
.Select(e =>
new Enum(e.Parent[XTypeFullName].Value<string>())
{
Values = e.Value.Values<string>().ToList()
})
.Where(i => enumsHashSet.Add(i.FullName)).ToList();
// replace all enums with references
foreach (var e in enums)
{
var p = (JObject)e.Parent;
p.Remove("enum");
p.Add(new JProperty("$ref", $"#/definitions/{p[XTypeFullName].Value<string>().Replace("+", string.Empty)}"));
}
var definitions = (JObject)swaggerJObject["definitions"];
// add enum definitions into definitions section of Swagger spec file
foreach (var enumParameter in distinctEnums)
{
// replacing "+" to prevent incorrect naming for nested enums
definitions.Add(new JProperty(enumParameter.FullName.Replace("+", string.Empty),
new JObject(new JProperty("enum", enumParameter.Values), new JProperty("type", "string"))));
}
return swaggerJObject.ToString();
}
private class Enum
{
public Enum(string fullName)
{
FullName = fullName;
}
public string FullName { get; }
public IList<string> Values { get; set; }
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment