164 lines
4.7 KiB
C#
164 lines
4.7 KiB
C#
using System.Text;
|
|
using Core;
|
|
using Core.Helpers;
|
|
using Core.Yaml;
|
|
using MoreLinq;
|
|
|
|
namespace Generator.DataSource.Yaml;
|
|
|
|
public class YamlBuilder
|
|
{
|
|
private OpenApiYaml _file;
|
|
private bool _isSubNode;
|
|
|
|
private readonly string _configIdentifier;
|
|
private readonly Dictionary<string, YamlConfig> _configs;
|
|
private readonly OpenApiYamlExtractor _extractor;
|
|
|
|
public YamlBuilder(string filePath, string configIdentifier)
|
|
{
|
|
_isSubNode = false;
|
|
_configIdentifier = configIdentifier;
|
|
_file = new OpenApiYaml(filePath);
|
|
_configs = new Dictionary<string, YamlConfig>();
|
|
_extractor = new OpenApiYamlExtractor();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds all raw references to the object to build
|
|
/// </summary>
|
|
public void AddReferences()
|
|
{
|
|
var scopedRefs = _extractor.ExtractScopedRefs(_file.Location.ToString());
|
|
var allRefs = _extractor.ExtractAllRefs(_file.Location.ToString());
|
|
_file.ScopedRefs = scopedRefs;
|
|
_file.OutScopedRefs = allRefs;
|
|
_file.OutScopedRefs.ExceptWith(scopedRefs);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attributes the dedicated config file to the object to build
|
|
/// </summary>
|
|
public void SelectConfig()
|
|
{
|
|
if (_configs.ContainsKey(_file.Location.GetFileName()))
|
|
{
|
|
_file.Config = _configs[_file.Location.GetFileName()];
|
|
}
|
|
else
|
|
{
|
|
throw new Exception($"{_file.Location} cannot be generated. You either made a typo " +
|
|
$"or forgot to register file in {GetConfig(_file.Location)}");
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds all built schemas to the object to build
|
|
/// </summary>
|
|
public void AddSchema()
|
|
{
|
|
using var enumerator = _file.ScopedRefs.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
var loc = new Location(enumerator.Current);
|
|
var fileName = loc.GetFileName();
|
|
|
|
if(!_configs.ContainsKey(fileName)) continue;
|
|
|
|
var schema = _isSubNode ?
|
|
_extractor.ExtractNode(loc.ToString())
|
|
: CreateSubNode(loc.ToString());
|
|
|
|
schema.Config = _configs[fileName];
|
|
_file.ReferencedSchemas.Add(schema);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds the models that will be ignored to the object to build
|
|
/// </summary>
|
|
public void AddIgnoredModels()
|
|
{
|
|
foreach (var reference in _file.Refs)
|
|
{
|
|
var loc = new Location(reference);
|
|
var schema = _extractor.ExtractNode(loc.ToString());
|
|
_file.IgnoredModels.UnionWith(schema.Models);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Simply output the object to build
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public OpenApiYaml Create() => _file;
|
|
|
|
/// <summary>
|
|
/// Loads the object to build
|
|
/// </summary>
|
|
public void LoadSpec()
|
|
{
|
|
_file = _extractor.ExtractNode(_file.Location.ToString());
|
|
_file.Openapi = _file.Openapi;
|
|
if (_file.Info != null) _file.Info = new Dictionary<string, object>(_file.Info);
|
|
_file.Tags = _file.Tags == null ? new List<object>() : [.._file.Tags];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Load all the found config files into the builder
|
|
/// </summary>
|
|
public void LoadConfigs()
|
|
{
|
|
LoadConfig(_file.Location);
|
|
foreach (var reference in _file.Refs) LoadConfig(new Location(reference));
|
|
}
|
|
|
|
private void LoadConfig(Location path)
|
|
{
|
|
var configPath = GetConfig(path)?.ToString();
|
|
|
|
if (configPath == null || _configs.ContainsKey(path.GetFileName())) return;
|
|
|
|
_extractor.LoadConfigs(configPath)
|
|
.ForEach(c => _configs.TryAdd(c.Key, c.Value));
|
|
}
|
|
|
|
private void SetForSubNode() => _isSubNode = true;
|
|
|
|
private OpenApiYaml CreateSubNode(string path)
|
|
{
|
|
var yamlBuilder = new YamlBuilder(path, _configIdentifier);
|
|
|
|
yamlBuilder.SetForSubNode();
|
|
yamlBuilder.LoadSpec();
|
|
yamlBuilder.AddReferences();
|
|
yamlBuilder.LoadConfigs();
|
|
yamlBuilder.AddSchema();
|
|
yamlBuilder.AddIgnoredModels();
|
|
return yamlBuilder.Create();
|
|
}
|
|
|
|
private Location? GetConfig(Location loc)
|
|
{
|
|
var spec = loc.GetFolder();
|
|
var pathItems = loc.Path.Split(['/', '\\']);
|
|
pathItems[^1] = spec + _configIdentifier;
|
|
|
|
var builder = new StringBuilder();
|
|
builder.AppendJoin("/", pathItems);
|
|
|
|
var configPath = builder.ToString();
|
|
|
|
try
|
|
{
|
|
PathHelper.CheckPathValidity(configPath);
|
|
}
|
|
catch (FileNotFoundException)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return new Location(configPath);
|
|
}
|
|
} |