Import from internal git

This commit is contained in:
2025-10-11 13:08:09 +02:00
commit 97aaa715dc
175 changed files with 7014 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
namespace Core.Actions;
public class DotnetPublish
{
public required Location LocalRoot;
public required Location DockerRoot;
public required string Image;
public required string Registry;
public required Location PackageFolder;
public required string AuthorizationToken;
public required string PackageVersion { get; set; }
public required string PackageFile { get; set; }
}

View File

@@ -0,0 +1,19 @@
namespace Core.Actions;
public class JavaPublish
{
public required Location LocalRoot;
public required Location DockerRoot;
public required string Image;
public required Location TemplateFolder;
public required Location OutputFolder;
public required string Group;
public required string Artifact;
public required string Version;
public required string Registry;
public required string Username;
public required string Password;
}

View File

@@ -0,0 +1,16 @@
namespace Core.Actions;
public class JavascriptPublish
{
public required Location LocalRoot;
public required Location DockerRoot;
public required string Image;
public required string Registry;
public required string PackageName;
public required string Version;
public required Location SpecFile;
public required Location FrontFolder;
}

View File

@@ -0,0 +1,7 @@
namespace Core.Actions;
public class PackageDeletion
{
public required string Username;
public required string Password;
}

View File

@@ -0,0 +1,8 @@
namespace Core.Actions;
public class PlantUmlExport
{
public required Location LocalRoot;
public required Location Template;
public required Location Output;
}

View File

@@ -0,0 +1,29 @@
using Core.Dto;
using Core.SpecConfig;
namespace Core;
public class ArgumentsExtractor
{
private ArgumentsDto _args;
public GenerationType? GenType =>
_args.ClientOnly ? GenerationType.Client :
_args.ModelsOnly ? GenerationType.Common :
_args.ApiOnly ? GenerationType.Server :
null;
public PublishType PublishType =>
_args.SafePublish ? PublishType.Safe :
_args.ForcePublish ? PublishType.Force :
PublishType.No;
public string Spec => _args.SpecName;
public bool ExportPuml => _args.ExportPuml;
public ArgumentsExtractor(ArgumentsDto args)
{
_args = args;
}
}

16
Core/Core.csproj Normal file
View File

@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.9.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Services.Common" Version="1.0.0" />
<PackageReference Include="YamlDotNet" Version="15.1.2" />
</ItemGroup>
</Project>

31
Core/Dto/ArgumentsDto.cs Normal file
View File

@@ -0,0 +1,31 @@
using CommandLine;
namespace Core.Dto;
public class ArgumentsDto
{
[Option('g', "gui", Required = false)]
public bool Gui { get; set; }
[Option('n', "name", Required = false)]
public string SpecName { get; set; } = null!;
[Option('a', "api-only", Required = false, Default = false)]
public bool ApiOnly { get; set; }
[Option('m', "models-only", Required = false, Default = false)]
public bool ModelsOnly { get; set; }
[Option('c', "client-only", Required = false, Default = false)]
public bool ClientOnly { get; set; }
[Option('s', "safe-publish", Required = false, Default = false)]
public bool SafePublish { get; set; }
[Option('f', "force-publish", Required = false, Default = false)]
public bool ForcePublish { get; set; }
[Option('e', "export-puml", Required = false, Default = false)]
public bool ExportPuml { get; set; }
}

View File

@@ -0,0 +1,25 @@
using Newtonsoft.Json;
namespace Core.Dto;
public class PackageDataDto
{
[JsonProperty("id")]
public string Id;
[JsonProperty("repository")]
public string Repository;
[JsonProperty("format")]
public string Format;
[JsonProperty("group")]
public string Group;
[JsonProperty("name")]
public string Name;
[JsonProperty("version")]
public string Version;
}

View File

@@ -0,0 +1,14 @@
namespace Core.Dto.Settings;
/// <summary>
/// This class gathers all credentials-related configurations
/// </summary>
public class CredentialsConfigDto
{
public string Token { get; set; } = "";
public string Email { get; set; } = "";
public string Username { get; set; } = "";
public string Password { get; set; } = "";
public string AlwaysAuth { get; set; } = "";
}

View File

@@ -0,0 +1,11 @@
namespace Core.Dto.Settings;
/// <summary>
/// This class gathers all default-related configurations
/// </summary>
public class DefaultArgumentsConfigDto
{
public string SpecIdentifier { get; set; } = "";
public string GeneratorVersion { get; set; } = "";
}

View File

@@ -0,0 +1,13 @@
namespace Core.Dto.Settings;
/// <summary>
/// This class gathers docker images
/// </summary>
public class DockerImagesConfigDto
{
public string JavascriptImage { get; set; } = "";
public string OpenApiGeneratorImage { get; set; } = "";
public string DotnetSdkImage { get; set; } = "";
public string MavenImage { get; set; } = "";
}

View File

@@ -0,0 +1,8 @@
namespace Core.Dto.Settings;
public class DotnetConfigDto
{
public string ServerFolder { init; get; } = "";
public string CommonFolder { init; get; } = "";
public string ClientFolder { init; get; } = "";
}

View File

@@ -0,0 +1,12 @@
namespace Core.Dto.Settings;
/// <summary>
/// This class gathers environment-related configuration
/// </summary>
public class EnvironmentConfigDto
{
public string Invite { get; set; } = "";
public string LocalRoot { get; set; } = "";
public string DockerRoot { get; set; } = "";
}

View File

@@ -0,0 +1,7 @@
namespace Core.Dto.Settings;
public class GeneralConfigDto
{
public string ApiFolder { init; get; } = "";
public string OutputFolder { init; get; } = "";
}

View File

@@ -0,0 +1,6 @@
namespace Core.Dto.Settings;
public class JavaConfigDto
{
public string Folder { init; get; } = "";
}

View File

@@ -0,0 +1,8 @@
namespace Core.Dto.Settings;
public class JavascriptConfigDto
{
public string Folder { init; get; } = "";
}

View File

@@ -0,0 +1,15 @@
namespace Core.Dto.Settings;
public class OpenApiConfigDto
{
public string OutputFolder { init; get; } = "";
public string GeneratorConfigFile { init; get; } = "";
public string GeneratorIgnoreFile { init; get; } = "";
public string SpecExtension {init; get; } = "";
public string SchemasIdentifier {init; get; } = "";
public string ConfigExtension {init; get; } = "";
public string ConfigIdentifier {init; get; } = "";
}

View File

@@ -0,0 +1,11 @@
namespace Core.Dto.Settings;
/// <summary>
/// This class gathers publish-related configurations
/// </summary>
public class PublishConfigDto
{
public string NpmRegistry { get; set; } = "";
public string NugetRegistry { get; set; } = "";
public string MavenRegistry { get; set; } = "";
}

View File

@@ -0,0 +1,12 @@
namespace Core.Dto.Settings;
public class TemplatesConfigDto
{
public string Folder { init; get; } = "";
public string PlantUml { init; get; } = "";
public string DotnetServerGeneratorConfig { init; get; } = "";
public string DotnetClientGeneratorConfig { init; get; } = "";
public string JavaGeneratorConfig { init; get; } = "";
public string ServerIgnore { init; get; } = "";
public string ClientIgnore { init; get; } = "";
}

View File

@@ -0,0 +1,19 @@
using YamlDotNet.Serialization;
namespace Core.Dto.Yaml;
public class OpenApiYamlDto
{
[YamlMember(Alias = "openapi")]
public string? Openapi { get; set; }
[YamlMember(Alias = "info")]
public IDictionary<string, object>? Info { get; set; }
[YamlMember(Alias = "tags")]
public IList<object>? Tags { get; set; }
[YamlMember(Alias = "components")]
public IDictionary<string, IDictionary<string, object>>? Components { get; set; }
}

View File

@@ -0,0 +1,26 @@
using Newtonsoft.Json;
namespace Core.Dto.Yaml;
[JsonObject]
public class PackageConfigDto
{
[JsonProperty("name")]
public string Name { get; set; } = "";
[JsonProperty("type")]
public string Type { get; set; } = "";
[JsonProperty("dotnetPackage")]
public string DotnetPackage { get; set; } = "";
[JsonProperty("javascriptPackage")]
public string JavascriptPackage { get; set; } = "";
[JsonProperty("keepModels")]
public bool KeepModels { get; set; }
[JsonProperty("priority")]
public int Priority { get; set; }
}

View File

@@ -0,0 +1,19 @@
using Newtonsoft.Json;
namespace Core.Dto.Yaml;
public class SpecConfigDto
{
[JsonProperty("packageTypes")]
public Dictionary<string, List<string>> PackageTypes { get; set; } = [];
[JsonProperty("javaGroup")]
public string JavaGroup { get; set; } = "";
[JsonProperty("modelSuffix")]
public string ModelSuffix { get; set; } = "";
[JsonProperty("packages")]
public List<PackageConfigDto> Packages { get; set; } = [];
}

View File

@@ -0,0 +1,3 @@
namespace Core.Events;
public record DisplayEventArgs(string? Content);

View File

@@ -0,0 +1,17 @@
namespace Core.Events;
public class DisplayEmitter
{
public event EventHandler<DisplayEventArgs>? OnSay;
public event EventHandler<DisplayEventArgs>? OnWarn;
public void Say(object? sender, string message)
{
OnSay?.Invoke(this, new DisplayEventArgs(message));
}
public void Warn(object? sender, string message)
{
OnWarn?.Invoke(this, new DisplayEventArgs(message));
}
}

9
Core/Events/IEmitter.cs Normal file
View File

@@ -0,0 +1,9 @@
namespace Core.Events;
/*public interface IEmitter<T>
{
public event EventHandler<T>? OnSay;
public event EventHandler<T>? OnWarn;
public void Say(object? sender, T args);
public void Warn(object? sender, T args);
}*/

View File

@@ -0,0 +1,3 @@
namespace Core.Exceptions;
public class ConfigException(string message) : Exception(message);

View File

@@ -0,0 +1,3 @@
namespace Core.Exceptions;
public class FillerException(string message) : Exception(message);

View File

@@ -0,0 +1,3 @@
namespace Core.Exceptions;
public class CommandExecutionException(string message) : Exception(message);

View File

@@ -0,0 +1,3 @@
namespace Core.Exceptions;
public class PackageVersionException(string message) : Exception(message);

View File

@@ -0,0 +1,3 @@
namespace Core.Exceptions;
public class WeirdException(string message) : Exception(message);

View File

@@ -0,0 +1,15 @@
namespace Core.Helpers;
public static class EnumHelper
{
/// <summary>
/// Retrieved maximum possible value in an enum. In other words, return the number of values contained in the enum
/// </summary>
/// <typeparam name="T">Enum</typeparam>
/// <returns>Number of possible values</returns>
public static int GetMaxValue<T>() where T : Enum
{
var i = Enum.GetValues(typeof(T)).Length;
return i;
}
}

View File

@@ -0,0 +1,85 @@
using System.Text;
namespace Core.Helpers;
/// <summary>
/// Provides some path-related actions
/// </summary>
public static class PathHelper
{
/// <summary>
/// Verifies the existence of a path
/// </summary>
/// <param name="path">Path to check</param>
/// <exception cref="FileNotFoundException">If the given path does not exist</exception>
public static void CheckPathValidity(string path)
{
if (!File.Exists(path)) throw new FileNotFoundException($"Could not found file at {path}");
}
/// <summary>
/// Create a file and all its parents directories if the file does not exists
/// </summary>
/// <param name="path"></param>
public static void CreateFileIfNotExists(string path)
{
if (!File.Exists(path)) Directory.CreateDirectory(Path.GetDirectoryName(path)!);
}
/// <summary>
/// Extracts raw text from a file references by given path
/// </summary>
/// <param name="path">Location of file</param>
/// <returns>Raw text</returns>
/// <exception cref="FileNotFoundException">If the given path does not exist</exception>
public static string TextFrom(string path)
{
CheckPathValidity(path);
return File.ReadAllText(path);
}
/// <summary>
/// Get the folder containing the last item of a given path
///
/// </summary>
/// <param name="path">The given path</param>
/// <returns>The folder containing the last element of the given path</returns>
public static string GetFolder(string path)
{
path = path.Replace("\\", "/");
var s = path.Split("/").ToList();
s.RemoveAt(s.Count-1);
var r = string.Join("/", s) + "/";
return r;
}
public static string GetName(string path)
{
return path.Split("/")[0];
}
/// <summary>
/// Concatenates a string representing the path of a folder and a string representing a file name
/// The strings come from default arguments.
/// </summary>
/// <returns>Concatenated path</returns>
public static string FullPath(params string[] pathItems)
{
StringBuilder builder = new StringBuilder();
foreach (var pi in pathItems)
{
builder.Append(pi);
}
return AbsolutePath(builder.ToString());
}
/// <summary>
/// Returns the absolute path based on a relative path
/// </summary>
/// <param name="relative">relative path</param>
/// <returns>Absolute path as string</returns>
public static string AbsolutePath(string relative)
{
return Path.GetFullPath(relative);
}
}

View File

@@ -0,0 +1,19 @@
namespace Core.Helpers;
public static class TypeHelper
{
/// <summary>
/// Safely cast a less derived object to a more derived object
/// </summary>
/// <param name="obj">Object to cast</param>
/// <typeparam name="TBase">Less derived type</typeparam>
/// <typeparam name="TTarget">More derived type</typeparam>
/// <returns></returns>
/// <exception cref="InvalidOperationException">When data parameter is not a derived of TBase</exception>
public static TTarget SafeCast<TBase, TTarget>(TBase obj)
{
if (obj is not TTarget result)
throw new InvalidOperationException($"Cannot cast {typeof(TBase)} to {typeof(TTarget)}");
return result;
}
}

20
Core/ISpecFile.cs Normal file
View File

@@ -0,0 +1,20 @@
using Core.SpecConfig;
namespace Core;
public interface ISpecFile
{
public Location Location { get; }
public string Name { get; }
public string Folder { get; }
public ISet<string> ScopedRefs { get; set; }
public SpecType SpecType { get; }
public string NugetPackage { get; }
public string MavenGroup { get; }
public string NpmPackage { get; }
public string Version { get; }
public int Priority { get; }
public Queue<ISpecFile>GetTasksBy(Language language, GenerationType type);
}

View File

@@ -0,0 +1,8 @@
using Core.Events;
namespace Core.Interfaces;
public interface IController
{
public DisplayEmitter Emitter { get; set; }
}

View File

@@ -0,0 +1,7 @@
namespace Core.Interfaces;
public interface IDataSourceLoader
{
public void LoadAppsettings();
}

View File

@@ -0,0 +1,6 @@
namespace Core.Interfaces;
public interface IExporter
{
public void Export();
}

View File

@@ -0,0 +1,14 @@
using Core.Settings;
namespace Core.Interfaces;
public interface IGeneratorDirector<T> where T : ISpecFile
{
public Task DotnetServer(T file, DotnetConfig config);
public Task DotnetClient(T file, DotnetConfig config);
public Task Java(T file, JavaConfig config);
public Task Javascript(T file, JavascriptConfig config);
}

View File

@@ -0,0 +1,12 @@
using Core.Dto;
using Core.SpecConfig;
namespace Core.Interfaces;
public interface IRepositoryRequest
{
public Task<List<PackageDataDto>> GetVersions(Language language, string packageName);
public Task<bool> DeleteVersion(string id);
}

14
Core/Interfaces/IView.cs Normal file
View File

@@ -0,0 +1,14 @@
namespace Core.Interfaces;
public interface IView
{
void Exception(string message);
void Warning(string message);
void Info(string message);
void Success(string message);
void Progress(int percentage);
}

84
Core/Location.cs Normal file
View File

@@ -0,0 +1,84 @@
using System.Text;
namespace Core;
public class Location
{
public string Path { get; private set; }
public Location(string path)
{
Path = path;
}
public Location(string[] pathItems)
{
Path = new StringBuilder().AppendJoin("/", pathItems).ToString();
Clean();
}
public Location(Location[] pathItems)
{
Path = new StringBuilder().AppendJoin("/", pathItems.Select(pi => pi.ToString())).ToString();
Clean();
}
public string LastElement()
{
return Path.Split(['/', '\\'])[^1];
}
public bool HasExtension(string extension)
{
return LastElement().Split('.')[^1].Contains(extension);
}
public bool IsInSameFolder(Location loc)
{
loc.Clean();
var folder = GetFolder();
var locFolder = loc.GetFolder();
return folder.Equals(locFolder);
}
public string GetFolder() => Path.Split(['/', '\\'])[^2];
public string GetFileName() => LastElement().Split('.')[0];
public Location ConcatenateWith(string[] relatives)
{
var data = new StringBuilder().AppendJoin("/", relatives).ToString();
var path = new Location(Add(data));
path.Clean();
return path;
}
public Location ConcatenateWith(string relative)
{
var path = new Location(Add(relative));
path.Clean();
return path;
}
public Location ConcatenateWith(Location relative)
{
return ConcatenateWith(relative.ToString());
}
private string Add(string value)
{
var builder = new StringBuilder();
var newPath = builder.AppendJoin("/", [Path, value]);
return newPath.ToString();
}
private void Clean()
{
Path = Path
.Replace(@"\", "/")
.Replace("/./", "/")
.Replace("//", "/");
}
public override string ToString() => Path;
}

25
Core/PackageData.cs Normal file
View File

@@ -0,0 +1,25 @@
using System.Text;
namespace Core;
public class PackageData
{
public string Id;
public string Name;
public string Version;
public PackageData()
{
Id = "";
Name = "";
Version = "";
}
public string GetVersions()
{
return new StringBuilder().AppendJoin(", ", Version).ToString();
}
}

View File

@@ -0,0 +1,47 @@
using System.Collections;
using Core.SpecConfig;
namespace Core.Process;
public class GenerationProcess : IEnumerable
{
public ISpecFile BaseFile { get; private set; }
private List<ProcessTask> _tasks;
private PublishType _publishType;
private GenerationType? _generationType;
public GenerationProcess(ISpecFile spec, PublishType pubType, GenerationType? genType)
{
BaseFile = spec;
_tasks = RetrieveTasks();
_publishType = pubType;
_generationType = genType;
}
private List<ProcessTask> RetrieveTasks()
{
var res = new List<ProcessTask>();
foreach (Language language in Enum.GetValues(typeof(Language)))
{
foreach (GenerationType type in Enum.GetValues(typeof(GenerationType)))
{
var tasks = BaseFile.GetTasksBy(language, type);
if (tasks.Count == 0) continue;
res.Add(new ProcessTask(language, type, _publishType, tasks));
}
}
return _generationType == null ? res
: res.Where(p => p.GenerationType == _generationType).ToList();
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public ProcessEnumerator GetEnumerator()
{
_tasks = RetrieveTasks();
return new ProcessEnumerator(_tasks);
}
}

76
Core/ProcessEnumerator.cs Normal file
View File

@@ -0,0 +1,76 @@
using System.Collections;
using Core.Helpers;
using Core.SpecConfig;
namespace Core;
public class ProcessEnumerator : IEnumerator
{
private int _languagePosition;
private int _typePosition;
private readonly List<ProcessTask> _enumerable;
object IEnumerator.Current => Current;
public ProcessTask Current
{
get
{
return _enumerable.First(pt => (int)pt.GenerationType == _typePosition
&& (int)pt.Language == _languagePosition);
}
}
public ProcessEnumerator(List<ProcessTask> current)
{
_languagePosition = -1;
_typePosition = -1;
_enumerable = current;
}
public bool MoveNext()
{
if (_typePosition == -1 && _languagePosition == -1)
{
_typePosition += 1;
_languagePosition += 1;
} else if (PassedTypeBoundaries())
{
_typePosition = 0;
_languagePosition += 1;
}
else
{
_typePosition += 1;
}
if (!HasElement() && !PassedMaxPosition())
{
MoveNext();
}
return !PassedMaxPosition();
}
public void Reset()
{
_languagePosition = -1;
_typePosition = -1;
}
private bool PassedLanguageBoundaries() => _languagePosition >= EnumHelper.GetMaxValue<Language>() - 1;
private bool PassedTypeBoundaries() => _typePosition >= EnumHelper.GetMaxValue<GenerationType>() - 1;
private bool PassedMaxPosition() => PassedLanguageBoundaries() && PassedTypeBoundaries();
private bool HasElement()
{
var e= _enumerable.FirstOrDefault(pt => (int)pt.GenerationType == _typePosition
&& (int)pt.Language == _languagePosition);
return e != null;
}
}

View File

@@ -0,0 +1,12 @@
namespace Core.Settings;
/// <summary>
/// This class gathers environment-related configuration
/// </summary>
public class BaseConfig
{
public required string Invite { init; get; } = "";
public required Location LocalRoot { init; get; }
public required Location DockerRoot { init; get; }
public required Location TemplateFolder { init; get; }
}

View File

@@ -0,0 +1,13 @@
namespace Core.Settings;
/// <summary>
/// This class gathers all credentials-related configurations
/// </summary>
public class CredentialsConfig
{
public string Token { init; get; } = "";
public string Email { init; get; } = "";
public string Username { init; get; } = "";
public string Password { init; get; } = "";
public string AlwaysAuth { init; get; } = "";
}

View File

@@ -0,0 +1,10 @@
namespace Core.Settings;
/// <summary>
/// This class gathers all default-related configurations
/// </summary>
public class DefaultArgumentsConfig
{
public string SpecIdentifier { get; set; } = "";
}

View File

@@ -0,0 +1,15 @@
namespace Core.Settings;
/// <summary>
/// This class gathers docker images
/// </summary>
public class DockerImagesConfig
{
public string JavascriptImage { init; get; } = "";
public string OpenApiGeneratorImageName { init; get; } = "";
public string OpenApiGeneratorVersion { init; get; } = "";
public string OpenApiGeneratorImage { init; get; } = "";
public string DotnetSdkImage { init; get; } = "";
public string JavaImage { init; get; } = "";
}

View File

@@ -0,0 +1,42 @@
using Core.SpecConfig;
namespace Core.Settings;
public class DotnetConfig : BaseConfig
{
public GenerationType Type { get; set; } = GenerationType.Server;
public required string GenerationImage { init; get; }
public required string BuildImage { init; get; }
public required string PackageFile { init; get; }
public required string PackageFolder { init; get; }
public required Location SpecFile { init; get; }
public required Location OpenApi { init; get; }
public required Location ServerFolder { init; get; }
public required Location CommonFolder { init; get; }
public required Location ClientFolder { init; get; }
public required Location ConfigFile { init; get; }
public required Location IgnoreFile { init; get; }
public required Location ServerConfigTemplate { init; get; }
public required Location ClientConfigTemplate { init; get; }
public required Location ServerIgnoreTemplate { init; get; }
public required Location ClientIgnoreTemplate { init; get; }
public required string Registry;
public required string AuthorizationToken;
public Location OutputFolder()
=> Type switch
{
GenerationType.Server => ServerFolder,
GenerationType.Common => CommonFolder,
GenerationType.Client => ClientFolder,
_ => throw new ArgumentOutOfRangeException(nameof(Type), Type, null)
};
public Location PackageFolderPath() => OutputFolder().ConcatenateWith([PackageFolder, PackageFile]);
public Location OpenApiFolder() => new ([OutputFolder(), OpenApi]);
public Location OpenApiSpecFile() => new Location([OutputFolder(), OpenApi, OpenApi]).ConcatenateWith("openapi.yaml");
public Location OpenApiConfigFile() => new Location([OutputFolder()]).ConcatenateWith("openapi-generator-config.yaml");
public Location ConfigFilePath() => new ([OutputFolder(), ConfigFile]);
public Location IgnoreFilePath() => new ([OutputFolder(), IgnoreFile]);
}

View File

@@ -0,0 +1,8 @@
namespace Core.Settings;
public class GeneralConfig
{
public required Location ApiFolder { init; get; }
public required Location GenerationFolder { init; get; }
}

View File

@@ -0,0 +1,27 @@
namespace Core.Settings;
public class JavaConfig : BaseConfig
{
public required string GenerationImage { init; get; }
public required string BuildImage { init; get; }
public required string Registry { init; get; }
public required string Artifact { init; get; }
public required Location ServerFolder { init; get; }
public required Location ConfigOutput { init; get; }
public required Location ConfigFile { init; get; }
public required Location OpenApi { init; get; }
public required Location SpecFile { get; set; }
public required Location ServerConfigTemplate { init; get; }
public required string Version { get; set; }
public required string Username { get; set; }
public required string Password { get; set; }
public Location OutputFolder() => ServerFolder;
public Location ConfigFilePath() => new ([OutputFolder(), ConfigFile]);
public Location OpenApiFolder() => new ([OutputFolder(), OpenApi]);
//TODO : Hard coded string ???
public Location OpenApiSpecFile() => new Location([OutputFolder(), OpenApi, OpenApi]).ConcatenateWith("openapi.yaml");
}

View File

@@ -0,0 +1,21 @@
namespace Core.Settings;
public class JavascriptConfig : BaseConfig
{
public required string GenerationImage { init; get; }
public required string BuildImage { get; set; }
public required Location ClientFolder { init; get; }
public required string PackageName { init; get; }
public required string OpenApiVersion { init; get; }
public required string Registry { init; get; }
public required Location SpecFile { init; get; }
public required Location OpenApi { init; get; }
public Location OutputFolder() => ClientFolder;
public Location OpenApiFolder() => new ([OutputFolder(), OpenApi]);
public Location OpenApiSpecFile() => new Location([OutputFolder(), OpenApi, OpenApi]).ConcatenateWith("openapi.yaml");
}

View File

@@ -0,0 +1,21 @@
namespace Core.Settings;
public class OpenApiConfig
{
public required Location Folder { get; set; }
public required Location GeneratorConfigFile { get; set; }
public required Location GeneratorIgnoreFile { get; set; }
public required Location SpecFile { get; set; }
public required Location SpecConfig { get; set; }
public required string SpecExtension { get; set; }
public required string SchemasIdentifier { get; set; }
public required string ConfigIdentifier { get; set; }
public void AddRoot(Location root)
{
SpecConfig = root.ConcatenateWith(SpecConfig);
SpecFile = root.ConcatenateWith(SpecFile);
}
}

View File

@@ -0,0 +1,11 @@
namespace Core.Settings;
/// <summary>
/// This class gathers publish-related configurations
/// </summary>
public class PublishConfig
{
public string NpmRegistry { init; get; } = "";
public string NugetRegistry { init; get; } = "";
public string MavenRegistry { init; get; } = "";
}

View File

@@ -0,0 +1,12 @@
namespace Core.Settings;
public class TemplatesConfig
{
public required Location Folder { init; get; }
public required Location PlantUml { init; get; }
public required Location DotnetServerGeneratorConfig { init; get; }
public required Location DotnetClientGeneratorConfig { init; get; }
public required Location JavaGeneratorConfig { init; get; }
public required Location ServerIgnore { init; get; }
public required Location ClientIgnore { init; get; }
}

View File

@@ -0,0 +1,8 @@
namespace Core.SpecConfig;
public enum GenerationType
{
Common = 0,
Server = 1,
Client = 2,
}

View File

@@ -0,0 +1,9 @@
namespace Core.SpecConfig;
public enum Language
{
Dotnet = 0,
Java = 1,
Javascript = 2
}

View File

@@ -0,0 +1,28 @@
namespace Core.SpecConfig;
public class PackageTypes
{
private readonly Dictionary<Language, List<GenerationType>> _types;
public PackageTypes()
{
_types = new Dictionary<Language, List<GenerationType>>();
}
public HashSet<Language> GetLanguages() => _types.Keys.ToHashSet();
public List<GenerationType> GetBy(Language language) => _types[language];
public void Add(Language language, List<GenerationType> types) => _types.Add(language, types);
public bool TryAdd(Language language, GenerationType types)
{
if (!_types.TryGetValue(language, out List<GenerationType>? value)) return false;
value.Add(types);
return true;
}
public bool Has(Language language, GenerationType type)
=> _types.ContainsKey(language) && _types[language].Contains(type);
}

View File

@@ -0,0 +1,17 @@
namespace Core.SpecConfig;
public class ProcessTask
{
public readonly Language Language;
public readonly GenerationType GenerationType;
public readonly PublishType PublishType;
public readonly Queue<ISpecFile> Tasks;
public ProcessTask(Language l, GenerationType g, PublishType p, Queue<ISpecFile> tasks)
{
Language = l;
GenerationType = g;
Tasks = tasks;
PublishType = p;
}
}

View File

@@ -0,0 +1,8 @@
namespace Core.SpecConfig;
public enum PublishType
{
No = 0,
Safe = 1,
Force = 2,
}

View File

@@ -0,0 +1,7 @@
namespace Core.SpecConfig;
public enum SpecType
{
Model = 0,
Api = 1,
}

View File

@@ -0,0 +1,7 @@
namespace Core.Templates;
public interface ITemplateFactory
{
public ITemplate GetTemplate(string templatePath, IDictionary<string, object> data);
}

View File

@@ -0,0 +1,9 @@
using System.Collections;
namespace Core.Templates;
public interface ITemplate
{
public IEnumerable GetData();
public string GetText();
}

View File

@@ -0,0 +1,23 @@
using System.Collections;
namespace Core.Templates;
public class MustacheTemplate : ITemplate
{
private readonly string _text;
private readonly TemplateData<string, object> _data;
public MustacheTemplate(string text)
{
_text = text;
_data = new TemplateData<string, object>();
}
public void AddProperties(IDictionary<string, object> data)
{
_data.AddAll(data);
}
public IEnumerable GetData() => _data.GetData();
public string GetText() => _text;
}

View File

@@ -0,0 +1,19 @@
using Core.Helpers;
namespace Core.Templates;
public class MustacheTemplateFactory : ITemplateFactory
{
public MustacheTemplateFactory()
{
}
public ITemplate GetTemplate(string templatePath, IDictionary<string, object> data)
{
var text = PathHelper.TextFrom(templatePath);
var template = new MustacheTemplate(text);
template.AddProperties(data);
return template;
}
}

View File

@@ -0,0 +1,29 @@
using Services.Common.ObjUtils;
namespace Core.Templates;
public class TemplateData<TK, TV> where TK : notnull
{
private IDictionary<TK, TV> _data;
public TemplateData()
{
_data = new Dictionary<TK, TV>();
}
public void Add(TK key, TV value)
{
_data.Add(key, value);
}
public void AddAll(IDictionary<TK, TV> properties)
{
foreach (var item in properties)
{
_data.Add(item);
}
}
public IDictionary<TK, TV> GetData() => _data.Clone();
}

75
Core/Yaml/OpenApiYaml.cs Normal file
View File

@@ -0,0 +1,75 @@
using Core.SpecConfig;
using MoreLinq;
namespace Core.Yaml;
public class OpenApiYaml : ISpecFile
{
public Location Location { get; }
public string Name => Location.GetFileName();
public string Folder => Location.GetFolder();
public string? Openapi { get; set; }
public IDictionary<string, object>? Info { get; set; }
public IList<object>? Tags { get; set; }
public YamlConfig Config;
public ISet<string> Models;
public ISet<string> IgnoredModels;
public ISet<OpenApiYaml> ReferencedSchemas;
public ISet<string> ScopedRefs { get; set; }
public ISet<string> OutScopedRefs { get; set; }
public IEnumerable<string> Refs => ScopedRefs.Union(OutScopedRefs);
public SpecType SpecType => Config.Type;
public string NugetPackage => Config.NugetPackage;
public string MavenGroup => Config.JavaGroup;
public string NpmPackage => Config.NpmPackage;
public string Version => (string)Info["version"];
public int Priority => Config.Priority;
public OpenApiYaml(string loc)
{
Location = new Location(loc);
Info = new Dictionary<string, object>();
Tags = new List<object>();
Config = new YamlConfig();
IgnoredModels = new HashSet<string>();
ScopedRefs = new HashSet<string>();
OutScopedRefs = new HashSet<string>();
ReferencedSchemas = new HashSet<OpenApiYaml>();
Models = new HashSet<string>();
}
public Queue<ISpecFile> GetTasksBy(Language language, GenerationType type)
{
var tasks = new Queue<ISpecFile>();
var toGenerate = new List<ISpecFile>();
var packageTypes = Config.PackageTypes;
var specs = GetSpecsInSameFolder().ToList();
if (packageTypes.Has(language, type))
toGenerate.AddRange(type switch
{
GenerationType.Server => specs.Where(s => s.SpecType == SpecType.Api),
GenerationType.Client => specs.Where(s => s.SpecType == SpecType.Api),
GenerationType.Common => specs.Where(s => s.SpecType == SpecType.Model),
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
});
toGenerate.Sort((s1, s2) => s2.Priority - s1.Priority);
toGenerate.ForEach(s => tasks.Enqueue(s));
return tasks;
}
private IEnumerable<ISpecFile> GetSpecsInSameFolder()
{
var result = new List<ISpecFile>{ this };
ReferencedSchemas.ForEach(oay =>
{
if (oay.Location.IsInSameFolder(this.Location)) result.Add(oay);
});
return result;
}
}

16
Core/Yaml/YamlConfig.cs Normal file
View File

@@ -0,0 +1,16 @@
using Core.SpecConfig;
namespace Core.Yaml;
public class YamlConfig
{
public PackageTypes PackageTypes;
public int Priority { get; set; }
public SpecType Type { get; set; }
public string NugetPackage { get; set; } = "";
public string NpmPackage { get; set; } = "";
public string JavaGroup { get; set; } = "";
public string ModelSuffix { get; set; } = "";
public bool KeepModels { get; set; } = false;
}