diff --git a/ThunderstoreCLI/Commands/BuildCommand.cs b/ThunderstoreCLI/Commands/BuildCommand.cs index b37abb1..3cdbeac 100644 --- a/ThunderstoreCLI/Commands/BuildCommand.cs +++ b/ThunderstoreCLI/Commands/BuildCommand.cs @@ -309,7 +309,7 @@ public static string SerializeManifest(Config config) public static List ValidateConfig(Config config, bool throwIfErrors = true) { - var v = new Validator("build"); + var v = new CommandValidator("build"); v.AddIfEmpty(config.PackageConfig.Namespace, "Package Namespace"); v.AddIfEmpty(config.PackageConfig.Name, "Package Name"); v.AddIfNotSemver(config.PackageConfig.VersionNumber, "Package VersionNumber"); diff --git a/ThunderstoreCLI/Configuration/Validator.cs b/ThunderstoreCLI/Commands/CommandValidator.cs similarity index 93% rename from ThunderstoreCLI/Configuration/Validator.cs rename to ThunderstoreCLI/Commands/CommandValidator.cs index f39b696..fbd7ac6 100644 --- a/ThunderstoreCLI/Configuration/Validator.cs +++ b/ThunderstoreCLI/Commands/CommandValidator.cs @@ -1,14 +1,14 @@ using ThunderstoreCLI.Utils; -namespace ThunderstoreCLI.Configuration; +namespace ThunderstoreCLI.Commands; /// Helper for validating command-specific configurations -public class Validator +public class CommandValidator { private List _errors; private string _name; - public Validator(string commandName, List? errors = null) + public CommandValidator(string commandName, List? errors = null) { _name = commandName; _errors = errors ?? new List(); diff --git a/ThunderstoreCLI/Commands/InitCommand.cs b/ThunderstoreCLI/Commands/InitCommand.cs index 6aaa02f..a63bb57 100644 --- a/ThunderstoreCLI/Commands/InitCommand.cs +++ b/ThunderstoreCLI/Commands/InitCommand.cs @@ -76,7 +76,7 @@ public static string BuildReadme(Config config) private static void ValidateConfig(Config config) { - var v = new Validator("init"); + var v = new CommandValidator("init"); v.AddIfEmpty(config.PackageConfig.Namespace, "Package Namespace"); v.AddIfEmpty(config.PackageConfig.Name, "Package Name"); v.AddIfNotSemver(config.PackageConfig.VersionNumber, "Package VersionNumber"); diff --git a/ThunderstoreCLI/Commands/PublishCommand.cs b/ThunderstoreCLI/Commands/PublishCommand.cs index 4658229..de07e9b 100644 --- a/ThunderstoreCLI/Commands/PublishCommand.cs +++ b/ThunderstoreCLI/Commands/PublishCommand.cs @@ -290,7 +290,7 @@ private static async Task UploadChunk(UploadI private static void ValidateConfig(Config config, bool justReturnErrors = false) { var buildConfigErrors = BuildCommand.ValidateConfig(config, false); - var v = new Validator("publish", buildConfigErrors); + var v = new CommandValidator("publish", buildConfigErrors); v.AddIfEmpty(config.AuthConfig.AuthToken, "Auth AuthToken"); v.ThrowIfErrors(); } diff --git a/ThunderstoreCLI/Configuration/Config.cs b/ThunderstoreCLI/Configuration/Config.cs index af7ba0d..ff35a83 100644 --- a/ThunderstoreCLI/Configuration/Config.cs +++ b/ThunderstoreCLI/Configuration/Config.cs @@ -37,7 +37,7 @@ public static Config FromCLI(IConfigProvider cliConfig) providers.Add(new EnvironmentConfig()); if (cliConfig is CLIConfig) providers.Add(new ProjectFileConfig()); - providers.Add(new BaseConfig()); + providers.Add(new DefaultConfig()); return Parse(providers.ToArray()); } @@ -102,7 +102,10 @@ public PackageUploadMetadata GetUploadMetadata(string fileUuid) return new PackageUploadMetadata() { AuthorName = PackageConfig.Namespace, - Categories = PublishConfig.Categories, + Categories = PublishConfig.Categories!.GetOrDefault("") ?? Array.Empty(), + CommunityCategories = PublishConfig.Categories! + .Where(kvp => kvp.Key != "") + .ToDictionary(kvp => kvp.Key, kvp => kvp.Value), Communities = PublishConfig.Communities, HasNsfwContent = PackageConfig.ContainsNsfwContent ?? false, UploadUUID = fileUuid @@ -212,7 +215,7 @@ public class PublishConfig { public string? File { get; set; } public string[]? Communities { get; set; } - public string[]? Categories { get; set; } + public Dictionary? Categories { get; set; } } public class AuthConfig diff --git a/ThunderstoreCLI/Configuration/BaseConfig.cs b/ThunderstoreCLI/Configuration/DefaultConfig.cs similarity index 97% rename from ThunderstoreCLI/Configuration/BaseConfig.cs rename to ThunderstoreCLI/Configuration/DefaultConfig.cs index 16f32a1..c78cef7 100644 --- a/ThunderstoreCLI/Configuration/BaseConfig.cs +++ b/ThunderstoreCLI/Configuration/DefaultConfig.cs @@ -1,6 +1,6 @@ namespace ThunderstoreCLI.Configuration; -class BaseConfig : EmptyConfig +class DefaultConfig : EmptyConfig { public override GeneralConfig? GetGeneralConfig() { diff --git a/ThunderstoreCLI/Configuration/ProjectFileConfig.cs b/ThunderstoreCLI/Configuration/ProjectFileConfig.cs index 2afec61..33323a3 100644 --- a/ThunderstoreCLI/Configuration/ProjectFileConfig.cs +++ b/ThunderstoreCLI/Configuration/ProjectFileConfig.cs @@ -62,7 +62,7 @@ public override void Parse(Config currentConfig) { return new PublishConfig() { - Categories = Project.Publish?.Categories, + Categories = Project.Publish?.Categories.Categories, Communities = Project.Publish?.Communities }; } diff --git a/ThunderstoreCLI/Models/PublishModels.cs b/ThunderstoreCLI/Models/PublishModels.cs index f4aa90d..cb2e0af 100644 --- a/ThunderstoreCLI/Models/PublishModels.cs +++ b/ThunderstoreCLI/Models/PublishModels.cs @@ -10,6 +10,8 @@ public class PackageUploadMetadata : BaseJson [JsonProperty("communities")] public string[]? Communities { get; set; } + [JsonProperty("community_categories")] public Dictionary? CommunityCategories { get; set; } + [JsonProperty("has_nsfw_content")] public bool HasNsfwContent { get; set; } [JsonProperty("upload_uuid")] public string? UploadUUID { get; set; } diff --git a/ThunderstoreCLI/Models/ThunderstoreProject.cs b/ThunderstoreCLI/Models/ThunderstoreProject.cs index 2b7bbba..6b09b7a 100644 --- a/ThunderstoreCLI/Models/ThunderstoreProject.cs +++ b/ThunderstoreCLI/Models/ThunderstoreProject.cs @@ -8,6 +8,29 @@ namespace ThunderstoreCLI.Models; [TomlDoNotInlineObject] public class ThunderstoreProject : BaseToml { + public struct CategoryDictionary + { + public Dictionary Categories; + } + + static ThunderstoreProject() + { + TomletMain.RegisterMapper( + dict => TomletMain.ValueFrom(dict.Categories), + toml => toml switch + { + TomlArray arr => new CategoryDictionary + { + Categories = new Dictionary + { + { "", arr.ArrayValues.Select(v => v.StringValue).ToArray() } + } + }, + TomlTable table => new CategoryDictionary { Categories = TomletMain.To>(table) }, + _ => throw new NotSupportedException() + }); + } + [TomlDoNotInlineObject] public class ConfigData { @@ -75,10 +98,15 @@ public class PublishData { "riskofrain2" }; + [TomlProperty("categories")] - public string[] Categories { get; set; } = + [TomlDoNotInlineObject] + public CategoryDictionary Categories { get; set; } = new() { - "items", "skills" + Categories = new Dictionary + { + { "riskofrain2", new[] { "items", "skills" } } + } }; } [TomlProperty("publish")] @@ -112,7 +140,7 @@ public ThunderstoreProject(Config config) }; Publish = new PublishData() { - Categories = config.PublishConfig.Categories!, + Categories = new CategoryDictionary { Categories = config.PublishConfig.Categories! }, Communities = config.PublishConfig.Communities!, Repository = config.GeneralConfig.Repository }; diff --git a/ThunderstoreCLI/Utils/DictionaryExtensions.cs b/ThunderstoreCLI/Utils/DictionaryExtensions.cs new file mode 100644 index 0000000..6257624 --- /dev/null +++ b/ThunderstoreCLI/Utils/DictionaryExtensions.cs @@ -0,0 +1,9 @@ +namespace ThunderstoreCLI.Utils; + +public static class DictionaryExtensions +{ + public static TValue? GetOrDefault(this Dictionary dict, TKey key) where TKey : notnull + { + return dict.TryGetValue(key, out var value) ? value : default; + } +}