From 4534d4dbf5f5071fa71c5dec4444bf4b2bbd040c Mon Sep 17 00:00:00 2001 From: Rory& Date: Sun, 14 Dec 2025 23:18:35 +0100 Subject: admin api packaging --- extra/admin-api/Spacebar.ConfigModel/Class1.cs | 64 +++++++++++ .../Extensions/JsonExtensions.cs | 119 +++++++++++++++++++++ .../Spacebar.ConfigModel.csproj | 9 ++ 3 files changed, 192 insertions(+) create mode 100644 extra/admin-api/Spacebar.ConfigModel/Class1.cs create mode 100644 extra/admin-api/Spacebar.ConfigModel/Extensions/JsonExtensions.cs create mode 100644 extra/admin-api/Spacebar.ConfigModel/Spacebar.ConfigModel.csproj (limited to 'extra/admin-api/Spacebar.ConfigModel') diff --git a/extra/admin-api/Spacebar.ConfigModel/Class1.cs b/extra/admin-api/Spacebar.ConfigModel/Class1.cs new file mode 100644 index 00000000..948ca91a --- /dev/null +++ b/extra/admin-api/Spacebar.ConfigModel/Class1.cs @@ -0,0 +1,64 @@ +using System.Text.Json.Serialization; + +namespace Spacebar.ConfigModel; + +public class Config +{ + [JsonPropertyName("admin")] public EndpointConfig Admin { get; set; } = null!; + [JsonPropertyName("api")] public EndpointConfig Api { get; set; } = null!; + [JsonPropertyName("gateway")] public EndpointConfig Gateway { get; set; } = null!; + [JsonPropertyName("cdn")] public EndpointConfig Cdn { get; set; } = null!; + + public Config ReadFromKv(Dictionary kv) + { + // to object + + + foreach (var (key, value) in kv) + { + switch (key.Split('_', 2)[0]) + { + default: + Console.WriteLine($"Unrecognized config key prefix: {key}"); + continue; + } + } + + return this; + } +} + +public class EndpointConfig +{ + [JsonPropertyName("endpointPrivate")] public string? EndpointPrivate { get; set; } + [JsonPropertyName("endpointPublic")] public string? EndpointPublic { get; set; } + + public EndpointConfig ReadFromKv(Dictionary kv, string prefix) + { + foreach (var (key, value) in kv) + { + if (!key.StartsWith(prefix + "_")) continue; + var subKey = key[(prefix + "_").Length..]; + switch (subKey) + { + case "ENDPOINT_PRIVATE": + EndpointPrivate = value?.ToString(); + break; + case "ENDPOINT_PUBLIC": + EndpointPublic = value?.ToString(); + break; + default: + Console.WriteLine($"Unrecognized config key: {key}"); + break; + } + } + + return this; + } +} + +public class ApiConfig : EndpointConfig +{ + [JsonPropertyName("activeVersions")] public List ActiveVersions { get; set; } = null!; + [JsonPropertyName("defaultVersion")] public string DefaultVersion { get; set; } = null!; +} \ No newline at end of file diff --git a/extra/admin-api/Spacebar.ConfigModel/Extensions/JsonExtensions.cs b/extra/admin-api/Spacebar.ConfigModel/Extensions/JsonExtensions.cs new file mode 100644 index 00000000..20ae7331 --- /dev/null +++ b/extra/admin-api/Spacebar.ConfigModel/Extensions/JsonExtensions.cs @@ -0,0 +1,119 @@ +using System.Text.Json; +using System.Text.Json.Nodes; + +namespace Spacebar.ConfigModel.Extensions; + +public static class JsonExtensions +{ + extension(Dictionary kv) + { + public JsonObject ToNestedJsonObject(string path = "$") + { + JsonObject root = new(); + // group by prefix + var groups = kv.GroupBy(kvItem => kvItem.Key.Split('_', 2)[0]); + foreach (var group in groups) + { + var prefix = group.Key; + + if (group.Count() == 1 && !group.First().Key.Contains('_')) + { + root[prefix] = group.First().Value == null ? null : JsonNode.Parse(group.First().Value!); + Console.WriteLine("[CONFIG] Single Key: {0}.{1}, Value: {2}", path, prefix, root[prefix]?.ToJsonString()); + continue; + } + + var nestedValues = group.Where(x => x.Key.Contains('_')).ToDictionary(kvItem => kvItem.Key[(prefix.Length + 1)..], kvItem => kvItem.Value); + + if (nestedValues.All(x => int.TryParse(x.Key.Split('_')[0], out _))) + { + Console.WriteLine("[CONFIG] Array Key Detected: {0}.{1}", path, prefix); + var arr = new JsonArray(); + if (nestedValues.All(x => x.Key.Contains('_'))) + { + var objs = nestedValues.GroupBy(x => x.Key.Split('_', 2)[0]); + foreach (var objGroup in objs.OrderBy(x => int.Parse(x.Key))) + { + var i = objGroup.Key; + var objValues = objGroup.ToDictionary(kvItem => kvItem.Key[(i.Length + 1)..], kvItem => kvItem.Value); + var obj = objValues.ToNestedJsonObject($"{path}.{prefix}[{i}]"); + arr.Add(obj); + Console.WriteLine($" - ${path}.{prefix}[{i}]: {obj.ToJsonString()}"); + } + } + else + foreach (var (i, arrayItem) in nestedValues.OrderBy(x => int.Parse(x.Key))) + { + arr.Add(arrayItem == null ? null : JsonNode.Parse(arrayItem)); + Console.WriteLine($" - {path}.{prefix}[{i}]: {arrayItem}"); + } + + root[prefix] = arr; + } + else + { + root[prefix] = nestedValues.ToNestedJsonObject($"{path}.{prefix}"); + } + } + + return root; + } + } + + extension(JsonObject jo) + { + public Dictionary ToFlatKv(string path = "$") + { + var kv = new Dictionary(); + var jso = new JsonSerializerOptions() + { + Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping + }; + + foreach (var (key, value) in jo) + { + var currentPath = path == "$" ? key : $"{path}_{key}"; + + switch (value) + { + case JsonObject nestedObj: + var nestedKv = nestedObj.ToFlatKv(currentPath); + foreach (var (nestedKey, nestedValue) in nestedKv) + { + kv[nestedKey] = nestedValue; + } + + break; + case JsonArray arr: + for (int i = 0; i < arr.Count; i++) + { + var item = arr[i]; + var itemPath = $"{currentPath}_{i}"; + switch (item) + { + case JsonObject arrObj: + var arrObjKv = arrObj.ToFlatKv(itemPath); + foreach (var (arrObjKey, arrObjValue) in arrObjKv) + { + kv[arrObjKey] = arrObjValue; + } + + break; + default: + kv[itemPath] = item?.ToJsonString(jso); + break; + } + } + + break; + default: + Console.WriteLine(value?.GetType()); + kv[currentPath] = value?.ToJsonString(jso); + break; + } + } + + return kv; + } + } +} \ No newline at end of file diff --git a/extra/admin-api/Spacebar.ConfigModel/Spacebar.ConfigModel.csproj b/extra/admin-api/Spacebar.ConfigModel/Spacebar.ConfigModel.csproj new file mode 100644 index 00000000..237d6616 --- /dev/null +++ b/extra/admin-api/Spacebar.ConfigModel/Spacebar.ConfigModel.csproj @@ -0,0 +1,9 @@ + + + + net10.0 + enable + enable + + + -- cgit 1.5.1