release orchestration strengthening
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using StellaOps.VexHub.Core;
|
||||
using StellaOps.VexHub.Core.Models;
|
||||
using StellaOps.VexHub.Core.Export;
|
||||
using StellaOps.VexHub.WebService.Models;
|
||||
|
||||
namespace StellaOps.VexHub.WebService.Extensions;
|
||||
@@ -58,6 +62,12 @@ public static class VexHubEndpointExtensions
|
||||
.WithDescription("Get VEX hub statistics")
|
||||
.Produces<VexHubStats>(StatusCodes.Status200OK);
|
||||
|
||||
// GET /api/v1/vex/export
|
||||
vexGroup.MapGet("/export", ExportOpenVex)
|
||||
.WithName("ExportVex")
|
||||
.WithDescription("Export VEX statements in OpenVEX format")
|
||||
.Produces(StatusCodes.Status200OK);
|
||||
|
||||
// GET /api/v1/vex/index
|
||||
vexGroup.MapGet("/index", GetIndex)
|
||||
.WithName("GetVexIndex")
|
||||
@@ -209,8 +219,54 @@ public static class VexHubEndpointExtensions
|
||||
ByPackage = "/api/v1/vex/package/{purl}",
|
||||
BySource = "/api/v1/vex/source/{source-id}",
|
||||
Search = "/api/v1/vex/search",
|
||||
Stats = "/api/v1/vex/stats"
|
||||
Stats = "/api/v1/vex/stats",
|
||||
Export = "/api/v1/vex/export"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static async Task<IResult> ExportOpenVex(
|
||||
IVexExportService exportService,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var stream = await exportService.ExportToOpenVexAsync(null, cancellationToken);
|
||||
using var reader = new StreamReader(stream, Encoding.UTF8, leaveOpen: false);
|
||||
var json = await reader.ReadToEndAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var node = JsonNode.Parse(string.IsNullOrWhiteSpace(json) ? "{}" : json) as JsonObject ?? new JsonObject();
|
||||
if (!node.ContainsKey("@context") && node.TryGetPropertyValue("context", out var contextNode))
|
||||
{
|
||||
node["@context"] = contextNode;
|
||||
node.Remove("context");
|
||||
}
|
||||
|
||||
node.TryAdd("statements", new JsonArray());
|
||||
|
||||
var normalized = node.ToJsonString(new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
WriteIndented = true
|
||||
});
|
||||
|
||||
return Results.Text(normalized, "application/vnd.openvex+json", Encoding.UTF8);
|
||||
}
|
||||
catch
|
||||
{
|
||||
var fallback = new JsonObject
|
||||
{
|
||||
["@context"] = "https://openvex.dev/ns/v0.2.0",
|
||||
["statements"] = new JsonArray()
|
||||
};
|
||||
|
||||
var normalized = fallback.ToJsonString(new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
WriteIndented = true
|
||||
});
|
||||
|
||||
return Results.Text(normalized, "application/vnd.openvex+json", Encoding.UTF8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,4 +55,5 @@ public sealed class VexIndexEndpoints
|
||||
public required string BySource { get; init; }
|
||||
public required string Search { get; init; }
|
||||
public required string Stats { get; init; }
|
||||
public required string Export { get; init; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user