120 lines
4.3 KiB
C#
120 lines
4.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text.Json;
|
|
|
|
namespace Sozsoft.Platform.Data.Seeds;
|
|
|
|
/// <summary>
|
|
/// Component'in designer dokumanindaki (Props) Data sekmesi endpoint'lerini cozup
|
|
/// CRUD endpoint katalogu ile eslestiren ortak mantik.
|
|
/// <para>
|
|
/// Cozum kaydetme sirasinda (CustomComponentAppService) katalogu veritabanindan okur;
|
|
/// boylece <c>DataSources</c> sutunu tasarimci dokumanindan tutarli sekilde uretilir.
|
|
/// </para>
|
|
/// </summary>
|
|
public static class CustomComponentDataSourceResolver
|
|
{
|
|
private static readonly JsonSerializerOptions JsonReadOptions = new()
|
|
{
|
|
PropertyNameCaseInsensitive = true
|
|
};
|
|
|
|
/// <summary>Eslestirmede kullanilan CRUD endpoint tanimi.</summary>
|
|
public sealed class CrudEndpointReference
|
|
{
|
|
public string EntityName { get; set; } = string.Empty;
|
|
public string Method { get; set; } = string.Empty;
|
|
public string Path { get; set; } = string.Empty;
|
|
public string OperationType { get; set; } = string.Empty;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Props icindeki <c>visualDesigner.dataSources</c> listesini okur ve her kaydi method + path
|
|
/// ile <paramref name="endpoints"/> icinde arar. Eslesmeyen (elle yazilmis ya da custom)
|
|
/// endpoint'ler de listede kalir; yalnizca entity/seed dosyasi alanlari bos gelir.
|
|
/// </summary>
|
|
public static List<CustomComponentSeedDataSourceDto> Resolve(
|
|
string? props,
|
|
IReadOnlyCollection<CrudEndpointReference> endpoints)
|
|
{
|
|
var documentSources = ParseDocumentDataSources(props);
|
|
if (documentSources.Count == 0)
|
|
{
|
|
return [];
|
|
}
|
|
|
|
var resolved = new List<CustomComponentSeedDataSourceDto>();
|
|
|
|
foreach (var source in documentSources)
|
|
{
|
|
var method = (source.Method ?? string.Empty).Trim().ToUpperInvariant();
|
|
var url = (source.Url ?? string.Empty).Trim();
|
|
if (url.Length == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Ayni method + path birden fazla bilesene baglanmis olabilir; tekrarlari eleriz.
|
|
if (resolved.Exists(x => x.Method == method && string.Equals(x.Url, url, StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var endpoint = endpoints.FirstOrDefault(x =>
|
|
string.Equals(x.Method?.Trim(), method, StringComparison.OrdinalIgnoreCase) &&
|
|
string.Equals(x.Path?.Trim(), url, StringComparison.OrdinalIgnoreCase));
|
|
|
|
resolved.Add(new CustomComponentSeedDataSourceDto
|
|
{
|
|
Name = (source.Name ?? string.Empty).Trim(),
|
|
Method = method,
|
|
Url = url,
|
|
ResponsePath = string.IsNullOrWhiteSpace(source.ResponsePath) ? null : source.ResponsePath.Trim(),
|
|
EntityName = endpoint?.EntityName,
|
|
OperationType = endpoint?.OperationType,
|
|
SeedFile = endpoint == null
|
|
? null
|
|
: $"{SeedPathResolver.CrudFolder}/{endpoint.EntityName}.json"
|
|
});
|
|
}
|
|
|
|
return resolved;
|
|
}
|
|
|
|
/// <summary>Props JSON'undaki designer dokumanindan yalnizca dataSources dizisini ayiklar.</summary>
|
|
private static List<DesignerDataSourceDto> ParseDocumentDataSources(string? props)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(props))
|
|
{
|
|
return [];
|
|
}
|
|
|
|
try
|
|
{
|
|
using var document = JsonDocument.Parse(props);
|
|
if (!document.RootElement.TryGetProperty("visualDesigner", out var designer) ||
|
|
designer.ValueKind != JsonValueKind.Object ||
|
|
!designer.TryGetProperty("dataSources", out var dataSources) ||
|
|
dataSources.ValueKind != JsonValueKind.Array)
|
|
{
|
|
return [];
|
|
}
|
|
|
|
return JsonSerializer.Deserialize<List<DesignerDataSourceDto>>(dataSources.GetRawText(), JsonReadOptions) ?? [];
|
|
}
|
|
catch (JsonException)
|
|
{
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/// <summary>Designer dokumanindaki tek bir data source kaydi.</summary>
|
|
private sealed class DesignerDataSourceDto
|
|
{
|
|
public string? Name { get; set; }
|
|
public string? Method { get; set; }
|
|
public string? Url { get; set; }
|
|
public string? ResponsePath { get; set; }
|
|
}
|
|
}
|