noz-cli/NozCli.Core/Client/NozApiClient.cs
kryptomrx b76896dc7a refactor(core): Native AOT - JSON source generators, AOT-safe models and API client
- Add NozJsonContext / NozJsonContextPretty source generator contexts
- Replace all reflection-based JSON with source-generated overloads
- Add NotesCacheFile record for persistent note cache
- Add date field to NoteInfo, CancellationToken to all API methods
- LocalConfig uses source-generated serialization (compact + indented)
2026-05-16 23:20:21 +02:00

88 lines
3.6 KiB
C#

using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
using NozCli.Core.Config;
using NozCli.Core.Models;
using NozCli.Core.Serialization;
namespace NozCli.Core.Client;
public class NozApiClient : IDisposable
{
private readonly HttpClient _http;
public NozApiClient(LocalConfig cfg)
{
_http = new HttpClient
{
BaseAddress = new Uri(cfg.ServerUrl.TrimEnd('/') + "/"),
DefaultRequestVersion = new Version(2, 0),
};
_http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", cfg.Token);
}
public async Task<ServerCapabilities> GetConfigAsync(CancellationToken ct = default)
{
var res = await _http.GetFromJsonAsync("api/cli/config", NozJsonContext.Default.JsonElement, ct);
return new ServerCapabilities(
Server: res.GetProperty("server").GetString()!,
Enabled: res.GetProperty("enabled").GetBoolean(),
AllowPush: res.GetProperty("allow_push").GetBoolean(),
AllowDelete: res.GetProperty("allow_delete").GetBoolean(),
AllowVault: res.GetProperty("allow_vault").GetBoolean(),
AllowRebuild: res.GetProperty("allow_rebuild").GetBoolean()
);
}
public async Task<List<NoteInfo>> GetNotesAsync(CancellationToken ct = default)
{
var res = await _http.GetFromJsonAsync("api/cli/notes", NozJsonContext.Default.JsonElement, ct);
var notes = res.GetProperty("notes");
return notes.EnumerateArray().Select(n => new NoteInfo(
Slug: n.GetProperty("slug").GetString()!,
Title: n.GetProperty("title").GetString()!,
Status: n.GetProperty("status").GetString()!,
Topic: n.GetProperty("topic").GetString()!,
Lang: n.GetProperty("lang").GetString()!,
Private: n.GetProperty("private").GetBoolean(),
Hash: n.TryGetProperty("hash", out var h) ? h.GetString() : null,
Date: n.TryGetProperty("date", out var d) ? d.GetString() : null
)).ToList();
}
public async Task<NoteContent> GetNoteAsync(string slug, CancellationToken ct = default)
{
var res = await _http.GetFromJsonAsync($"api/cli/notes/{slug}", NozJsonContext.Default.JsonElement, ct);
return new NoteContent(
Slug: res.GetProperty("slug").GetString()!,
Markdown: res.GetProperty("markdown").GetString()!,
Hash: res.GetProperty("hash").GetString()!
);
}
public async Task<string> PutNoteAsync(string slug, string markdown, CancellationToken ct = default)
{
var body = JsonSerializer.Serialize(new PushBody(markdown), NozJsonContext.Default.PushBody);
var content = new StringContent(body, Encoding.UTF8, "application/json");
var res = await _http.PutAsync($"api/cli/notes/{slug}", content, ct);
res.EnsureSuccessStatusCode();
var json = await res.Content.ReadFromJsonAsync(NozJsonContext.Default.JsonElement, ct);
return json.GetProperty("hash").GetString()!;
}
public async Task DeleteNoteAsync(string slug, CancellationToken ct = default)
{
var res = await _http.DeleteAsync($"api/cli/notes/{slug}", ct);
res.EnsureSuccessStatusCode();
}
public async Task RebuildIndexAsync(CancellationToken ct = default)
{
var res = await _http.PostAsync("api/cli/rebuild", null, ct);
res.EnsureSuccessStatusCode();
}
public void Dispose() => _http.Dispose();
}