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; 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('/') + "/"), // Enforce TLS — reject plain HTTP at the OS level DefaultRequestVersion = new Version(2, 0), }; _http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", cfg.Token); } public async Task GetConfigAsync() { var res = await _http.GetFromJsonAsync("api/cli/config"); 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> GetNotesAsync() { var res = await _http.GetFromJsonAsync("api/cli/notes"); 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 )).ToList(); } public async Task GetNoteAsync(string slug) { var res = await _http.GetFromJsonAsync($"api/cli/notes/{slug}"); return new NoteContent( Slug: res.GetProperty("slug").GetString()!, Markdown: res.GetProperty("markdown").GetString()!, Hash: res.GetProperty("hash").GetString()! ); } public async Task PutNoteAsync(string slug, string markdown) { var body = JsonSerializer.Serialize(new { markdown }); var content = new StringContent(body, Encoding.UTF8, "application/json"); var res = await _http.PutAsync($"api/cli/notes/{slug}", content); res.EnsureSuccessStatusCode(); var json = await res.Content.ReadFromJsonAsync(); return json.GetProperty("hash").GetString()!; } public async Task DeleteNoteAsync(string slug) { var res = await _http.DeleteAsync($"api/cli/notes/{slug}"); res.EnsureSuccessStatusCode(); } public async Task RebuildIndexAsync() { var res = await _http.PostAsync("api/cli/rebuild", null); res.EnsureSuccessStatusCode(); } public void Dispose() => _http.Dispose(); }