Files
git.stella-ops.org/src/Symbols/StellaOps.Symbols.Ingestor.Cli/ManifestWriter.cs
StellaOps Bot 999e26a48e up
2025-12-13 02:22:15 +02:00

110 lines
3.1 KiB
C#

using System.Text.Json;
using System.Text.Json.Serialization;
using StellaOps.Symbols.Core.Models;
namespace StellaOps.Symbols.Ingestor.Cli;
/// <summary>
/// Writes symbol manifests to various formats.
/// </summary>
public static class ManifestWriter
{
private static readonly JsonSerializerOptions JsonOptions = new()
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
Converters = { new JsonStringEnumConverter() },
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
/// <summary>
/// Writes manifest to JSON file.
/// </summary>
public static async Task<string> WriteJsonAsync(
SymbolManifest manifest,
string outputDir,
CancellationToken cancellationToken = default)
{
Directory.CreateDirectory(outputDir);
var fileName = $"{manifest.DebugId}.symbols.json";
var filePath = Path.Combine(outputDir, fileName);
var json = JsonSerializer.Serialize(manifest, JsonOptions);
await File.WriteAllTextAsync(filePath, json, cancellationToken).ConfigureAwait(false);
return filePath;
}
/// <summary>
/// Writes DSSE envelope to file.
/// </summary>
public static async Task<string> WriteDsseAsync(
string payload,
string payloadType,
string signature,
string keyId,
string outputDir,
string debugId,
CancellationToken cancellationToken = default)
{
Directory.CreateDirectory(outputDir);
var envelope = new DsseEnvelope
{
PayloadType = payloadType,
Payload = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(payload)),
Signatures =
[
new DsseSignature { KeyId = keyId, Sig = signature }
]
};
var fileName = $"{debugId}.symbols.dsse.json";
var filePath = Path.Combine(outputDir, fileName);
var json = JsonSerializer.Serialize(envelope, JsonOptions);
await File.WriteAllTextAsync(filePath, json, cancellationToken).ConfigureAwait(false);
return filePath;
}
/// <summary>
/// Reads manifest from JSON file.
/// </summary>
public static async Task<SymbolManifest?> ReadJsonAsync(
string filePath,
CancellationToken cancellationToken = default)
{
var json = await File.ReadAllTextAsync(filePath, cancellationToken).ConfigureAwait(false);
return JsonSerializer.Deserialize<SymbolManifest>(json, JsonOptions);
}
}
/// <summary>
/// DSSE envelope structure.
/// </summary>
public sealed class DsseEnvelope
{
[JsonPropertyName("payloadType")]
public string PayloadType { get; set; } = string.Empty;
[JsonPropertyName("payload")]
public string Payload { get; set; } = string.Empty;
[JsonPropertyName("signatures")]
public List<DsseSignature> Signatures { get; set; } = [];
}
/// <summary>
/// DSSE signature.
/// </summary>
public sealed class DsseSignature
{
[JsonPropertyName("keyid")]
public string KeyId { get; set; } = string.Empty;
[JsonPropertyName("sig")]
public string Sig { get; set; } = string.Empty;
}