///|
/// Transport types the client is written against.
///
/// This mirrors `src/fetch-types.ts` from notion-sdk-js. The client never calls
/// the network directly: it is handed a `Fetch` function, so the same logic can
/// run on top of Node's fetch, the browser, an edge runtime, or a fake in tests.
/// Keeping the surface minimal is what makes that compatibility possible.
///|
/// Options passed to a `Fetch` implementation.
pub(all) struct HttpRequestInit {
/// HTTP method, already upper-cased for the transport.
http_method : String
/// Request headers as name/value pairs.
headers : Array[(String, String)]
/// Serialized request body, when the request has one.
body : String?
/// How long the transport may wait before failing the request.
timeout_ms : Int
/// Opaque agent label, ignored by transports that have no such concept.
agent : String?
}
///|
/// The response shape the client reads.
///
/// `text` returns the response body. It is a function so a transport can defer
/// reading the body until the caller decides to.
pub(all) struct HttpResponse {
/// Whether the request succeeded (`response.ok` in fetch).
ok : Bool
/// HTTP status code.
status : Int
/// Response headers as name/value pairs.
headers : Array[(String, String)]
/// Reads the response body as text.
text : () -> String
}
///|
/// A `fetch`-compatible function.
///
/// The first argument is the absolute URL, the second the request options.
pub type Fetch = (String, HttpRequestInit) -> HttpResponse raise
///|
/// Builds an `HttpResponse` from an already-read body.
pub fn HttpResponse::from_text(
status~ : Int,
headers~ : Array[(String, String)],
body~ : String,
) -> HttpResponse {
let ok = status >= 200 && status < 300
{ ok, status, headers, text: () => body, }
}
///|
/// The default transport. It fails loudly because the MoonBit SDK does not
/// bundle an HTTP stack; pass `fetch` to `ClientOptions` to connect one.
pub fn default_fetch(
_url : String,
_init : HttpRequestInit,
) -> HttpResponse raise {
raise NotionClientError(
NotionError::new(
kind=UnknownHTTPResponseError,
code=ClientErrorCode::ResponseError.to_string(),
message="No fetch implementation was provided. Pass `fetch` in ClientOptions " +
"to connect an HTTP transport (for example one built on moonbitlang/async).",
),
)
}