Files
2026-06-21 20:10:02 +02:00

88 lines
3.2 KiB
C#

using EonaCat.DoxaApi.Models;
namespace EonaCat.DoxaApi.Generation
{
// This file is part of the EonaCat project(s) which is released under the Apache License.
// See the LICENSE file or go to https://EonaCat.com/license for full license details.
/// <summary>
/// Produces schema-shaped, deterministic-but-plausible fake JSON values for a given
/// <see cref="SchemaModel"/>. Used by the built-in mock server so that frontend teams
/// can develop against an API before its real implementation exists.
/// </summary>
public static class MockResponseGenerator
{
public static object? Generate(SchemaModel? schema, ApiDocument doc, int depth = 0, HashSet<string>? seen = null)
{
seen ??= new HashSet<string>();
if (schema is null || depth > 8)
{
return null;
}
if (schema.RefName is not null)
{
if (!seen.Add(schema.RefName))
{
return new Dictionary<string, object?>();
}
if (doc.Schemas.TryGetValue(schema.RefName, out var resolved))
{
return Generate(resolved, doc, depth + 1, seen);
}
return new Dictionary<string, object?>();
}
switch (schema.Type)
{
case "string":
return MockString(schema.Format);
case "integer":
return RandomInt(depth);
case "number":
return Math.Round(RandomInt(depth) + 0.5, 2);
case "boolean":
return depth % 2 == 0;
case "enum":
return schema.EnumValues?.Count > 0 ? schema.EnumValues[0] : "value";
case "array":
return new List<object?>
{
Generate(schema.Items, doc, depth + 1, seen),
Generate(schema.Items, doc, depth + 1, seen)
};
case "object":
{
if (schema.Properties is null)
{
return new Dictionary<string, object?>();
}
var obj = new Dictionary<string, object?>();
foreach (var (key, propSchema) in schema.Properties)
{
obj[key] = Generate(propSchema, doc, depth + 1, seen);
}
return obj;
}
default:
return null;
}
}
private static object MockString(string? format) => format switch
{
"date-time" => DateTime.UtcNow.ToString("O"),
"date" => DateOnly.FromDateTime(DateTime.UtcNow).ToString("yyyy-MM-dd"),
"time" => TimeOnly.FromDateTime(DateTime.UtcNow).ToString("HH:mm:ss"),
"uuid" => Guid.NewGuid().ToString(),
"uri" => "https://example.com/resource",
_ => "string"
};
private static int RandomInt(int depth) => 1 + depth;
}
}