using System.Security.Claims;
using NpgsqlRest.HttpClientType;
namespace NpgsqlRest;
///
/// Result of a programmatic routine invocation via .
///
public readonly record struct RoutineInvokeResult(int StatusCode, string? Body, string? ContentType, bool IsSuccess);
///
/// Public entry point for invoking an NpgsqlRest endpoint in-process (no network hop), running the
/// full endpoint pipeline against a synthetic request. This is the supported surface for plugins
/// (e.g. NpgsqlRest.Mcp's tools/call) and host code to execute routines — so plugins never need
/// access to core internals.
///
/// Available only after UseNpgsqlRest has built the endpoints (see ).
/// Pass the user argument to run as a specific principal — execution-level authorization
/// (`authorize`) and claims-to-parameter binding then apply as for a real authenticated request.
///
///
public static class RoutineInvoker
{
/// True once endpoints have been built and internal invocation is wired up.
public static bool IsAvailable => InternalRequestHandler.IsAvailable;
///
/// Invoke an endpoint by HTTP method + path (path may include a query string; templated paths
/// like /api/x/{id} are matched by passing a concrete path). Returns the rendered response.
///
public static async Task InvokeAsync(
string method,
string path,
IDictionary? headers = null,
string? body = null,
string? contentType = null,
ClaimsPrincipal? user = null,
CancellationToken cancellationToken = default)
{
var headerDict = headers as Dictionary
?? (headers is null ? null : new Dictionary(headers));
var response = await InternalRequestHandler.ExecuteAsync(
method, path, headerDict, body, contentType, cancellationToken, user);
return new RoutineInvokeResult(response.StatusCode, response.Body, response.ContentType, response.IsSuccess);
}
}