Import from internal git
This commit is contained in:
109
Generator/DataSource/Yaml/OpenApiYamlExtractor.cs
Normal file
109
Generator/DataSource/Yaml/OpenApiYamlExtractor.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using Core;
|
||||
using Core.Dto.Yaml;
|
||||
using Core.Exceptions;
|
||||
using Core.Helpers;
|
||||
using Core.Yaml;
|
||||
using Generator.Mappers;
|
||||
using Newtonsoft.Json;
|
||||
using YamlDotNet.Serialization;
|
||||
|
||||
namespace Generator.DataSource.Yaml;
|
||||
|
||||
public class OpenApiYamlExtractor
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves an openapi-formatted yaml at a specific location
|
||||
/// </summary>
|
||||
/// <param name="path">file location</param>
|
||||
/// <returns></returns>
|
||||
public OpenApiYaml ExtractNode(string path)
|
||||
{
|
||||
var text = PathHelper.TextFrom(path);
|
||||
var deserializer = new DeserializerBuilder()
|
||||
.IgnoreUnmatchedProperties()
|
||||
.Build();
|
||||
|
||||
var dto = deserializer.Deserialize<OpenApiYamlDto>(text);
|
||||
return dto.ToModel(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads all configs that can be found in the config file located at the given path
|
||||
/// </summary>
|
||||
/// <param name="configPath">Given path</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="InvalidOperationException">When config file couldn't has been deserialize</exception>
|
||||
/// <exception cref="ConfigException">When the given path does not exists</exception>
|
||||
public Dictionary<string, YamlConfig> LoadConfigs(string configPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var json = PathHelper.TextFrom(configPath);
|
||||
var configDto = JsonConvert.DeserializeObject<SpecConfigDto>(json);
|
||||
return (configDto ?? throw new InvalidOperationException()).Map();
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
throw new ConfigException($"No config file found at {configPath}. Fix it or i'll never generate anything for you");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract all scoped references of a specification file. In other words, this will extracts all references
|
||||
/// between the given spec file and the closer reference-related schemas, including paths and params files
|
||||
/// </summary>
|
||||
/// <param name="filePath">Given file path</param>
|
||||
/// <returns></returns>
|
||||
public ISet<string> ExtractScopedRefs(string filePath) => ExtractRefs(filePath, false, new HashSet<string>());
|
||||
|
||||
/// <summary>
|
||||
/// Extract all possibles references from a given specification file
|
||||
/// </summary>
|
||||
/// <param name="filePath">Given file path</param>
|
||||
/// <returns></returns>
|
||||
public ISet<string> ExtractAllRefs(string filePath) => ExtractRefs(filePath, true, new HashSet<string>());
|
||||
|
||||
|
||||
private ISet<string> ExtractRefs(string filePath, bool deepSearch, ISet<string> refs)
|
||||
{
|
||||
const string pattern = """(\$ref):\s{1}['|"](.+)['|"]""";
|
||||
var text = PathHelper.TextFrom(filePath);
|
||||
var matches = Regex.Matches(text, pattern);
|
||||
|
||||
foreach (Match m in matches)
|
||||
{
|
||||
var rawReference = m.Groups[2].Value;
|
||||
var absolutePath = AbsolutePathFromRef(filePath, rawReference);
|
||||
|
||||
//If path references itself or circular dependency is detected
|
||||
if (absolutePath == string.Empty || refs.Contains(absolutePath)) continue;
|
||||
|
||||
if (!deepSearch && IsSchema(absolutePath))
|
||||
{
|
||||
refs.Add(absolutePath);
|
||||
continue;
|
||||
}
|
||||
|
||||
var subRefs = ExtractRefs(absolutePath, deepSearch, refs);
|
||||
refs.UnionWith(subRefs);
|
||||
refs.Add(absolutePath);
|
||||
}
|
||||
return refs;
|
||||
}
|
||||
|
||||
|
||||
private string AbsolutePathFromRef(string relative, string reference)
|
||||
{
|
||||
var result = PathHelper.GetFolder(relative) + reference;
|
||||
var r = result.Split("#")[0];
|
||||
return r[^1].Equals('/') ? string.Empty : PathHelper.AbsolutePath(r);
|
||||
}
|
||||
|
||||
private bool IsSchema(string path)
|
||||
{
|
||||
var l = new Location(path);
|
||||
return l.LastElement().Contains("schemas");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user