-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathGtsEntityOperations.cs
More file actions
82 lines (70 loc) · 3.24 KB
/
Copy pathGtsEntityOperations.cs
File metadata and controls
82 lines (70 loc) · 3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
using System.Text.Json.Nodes;
using Gts.Extraction;
using Gts.Store;
namespace Gts.Application;
/// <summary>Adds entities to a registry with the same rules as the GTS HTTP API.</summary>
public static class GtsEntityOperations
{
public sealed record AddResult(bool Ok, string Id, string? SchemaId, bool IsSchema, string? Error);
public static async Task<AddResult> TryAddAsync(
GtsRegistry registry,
JsonObject body,
bool validate,
GtsExtractOptions? extractOptions = null,
CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
var opt = extractOptions ?? GtsExtractOptions.Default;
var entity = GtsJsonEntity.ExtractEntity(body, opt);
var extract = GtsJsonEntity.ExtractId(body, opt);
if (!entity.IsSchema)
{
if (string.IsNullOrEmpty(entity.SelectedEntityField))
return new AddResult(false, "", null, false, "Instance must have an id field");
}
else
{
if (entity.GtsId is null)
return new AddResult(false, "", null, true, "Unable to detect GTS ID in schema");
}
if (validate && entity.IsSchema)
{
var rawId = body.TryGetPropertyValue("$id", out var idn) ? idn?.GetValue<string>() : null;
if (!string.IsNullOrEmpty(rawId) && rawId.StartsWith("gts.", StringComparison.Ordinal) &&
!rawId.StartsWith("gts://", StringComparison.Ordinal))
return new AddResult(false, "", null, true, "Schema $id must use gts:// URI format, not plain gts. prefix");
}
try
{
GtsSchemaRefFormatValidator.ValidateRefs(body);
}
catch (Exception ex)
{
return new AddResult(false, "", null, entity.IsSchema, ex.Message);
}
if (entity.IsSchema && entity.GtsId is not null)
{
var schemaVr = await registry.ValidateSchemaAsync(entity.GtsId, entity.Content, cancellationToken)
.ConfigureAwait(false);
if (!schemaVr.Ok)
{
var msg = schemaVr.Errors is { Count: > 0 }
? string.Join("; ", schemaVr.Errors)
: (schemaVr.FailureReason ?? "Schema validation failed");
return new AddResult(false, entity.GtsId.Id, entity.SchemaId, true, msg);
}
await registry.SaveAsync(entity).ConfigureAwait(false);
var idOut = entity.GtsId.Id;
return new AddResult(true, idOut, string.IsNullOrEmpty(entity.SchemaId) ? null : entity.SchemaId, true, null);
}
await registry.SaveAsync(entity).ConfigureAwait(false);
if (validate && !entity.IsSchema && entity.GtsId is not null)
{
var vr = await registry.ValidateInstanceAsync(entity.GtsId.Id, cancellationToken).ConfigureAwait(false);
if (!vr.Ok)
return new AddResult(false, entity.GtsId.Id, entity.SchemaId, false, vr.FailureReason ?? "Validation failed");
}
var idOut = entity.GtsId?.Id ?? extract.Id ?? "";
return new AddResult(true, idOut, string.IsNullOrEmpty(entity.SchemaId) ? null : entity.SchemaId, entity.IsSchema, null);
}
}