110 lines
3.1 KiB
C#
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;
|
|
}
|