Files
ScadaBridge/src/ZB.MOM.WW.ScadaBridge.CLI/Commands/SharedSchemaCommands.cs
T
2026-09-10 00:51:45 -04:00

82 lines
4.2 KiB
C#

using System.CommandLine;
using System.CommandLine.Parsing;
using System.Text.Json;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>CLI adapters for the shared JSON schema library management contracts.</summary>
public static class SharedSchemaCommands
{
/// <summary>Builds the shared-schema list/get/create/update/delete command group.</summary>
/// <param name="urlOption">Management URL option.</param>
/// <param name="formatOption">Output format option.</param>
/// <param name="usernameOption">Authentication username option.</param>
/// <param name="passwordOption">Authentication password option.</param>
/// <returns>The configured shared-schema group.</returns>
public static Command Build(Option<string> urlOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
{
var group = new Command("shared-schema") { Description = "Manage the shared JSON schema library" };
var list = new Command("list") { Description = "List shared schemas" };
list.SetAction((ParseResult result) => Send(result, new ListSharedSchemasCommand()));
group.Add(list);
group.Add(BuildIdentity("get", id => new GetSharedSchemaCommand(id)));
group.Add(BuildEdit(update: false));
group.Add(BuildEdit(update: true));
group.Add(BuildIdentity("delete", id => new DeleteSharedSchemaCommand(id)));
return group;
Task<int> Send(ParseResult result, object command) => CommandHelpers.ExecuteCommandAsync(
result, urlOption, formatOption, usernameOption, passwordOption, command);
Command BuildIdentity(string verb, Func<int, object> makeCommand)
{
var id = new Option<int>("--id") { Description = "Shared schema ID", Required = true };
var command = new Command(verb) { Description = $"{(verb == "get" ? "Get" : "Delete")} a shared schema by ID" };
command.Add(id);
command.SetAction((ParseResult result) => Send(result, makeCommand(result.GetValue(id))));
return command;
}
Command BuildEdit(bool update)
{
var id = new Option<int>("--id") { Description = "Shared schema ID", Required = true };
var name = new Option<string>("--name") { Description = "Schema library name", Required = true };
var scope = new Option<string?>("--scope") { Description = "Optional schema scope; omission clears scope on update" };
var file = new Option<string>("--schema-file") { Description = "Path to the JSON schema document", Required = true };
var command = new Command(update ? "update" : "create")
{
Description = update ? "Replace a shared schema's name, scope, and JSON document" : "Create a shared schema from a JSON file"
};
if (update) command.Add(id);
command.Add(name); command.Add(scope); command.Add(file);
command.SetAction(async (ParseResult result) =>
{
string json;
try
{
json = await File.ReadAllTextAsync(result.GetValue(file)!);
using var parsed = JsonDocument.Parse(json);
}
catch (JsonException ex)
{
OutputFormatter.WriteError($"Invalid schema JSON: {ex.Message}", "INVALID_JSON");
return 1;
}
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException or ArgumentException)
{
OutputFormatter.WriteError($"Could not read schema file: {ex.Message}", "FILE_ERROR");
return 1;
}
// Structural schema validation, uniqueness, and authorization remain server-owned.
object request = update
? new UpdateSharedSchemaCommand(result.GetValue(id), result.GetValue(name)!, result.GetValue(scope), json)
: new CreateSharedSchemaCommand(result.GetValue(name)!, result.GetValue(scope), json);
return await Send(result, request);
});
return command;
}
}
}