gleam-spacetraders-sdk/src/spacetraders_sdk.gleam
2025-06-18 20:04:15 +10:00

93 lines
2.2 KiB
Gleam

import gleam/dynamic.{type Dynamic}
import gleam/dynamic/decode.{type Decoder}
import gleam/http/request.{type Request}
import gleam/httpc.{type HttpError}
import gleam/json.{type DecodeError}
import gleam/option.{type Option}
import gleam/result
import spacetraders_models/meta.{type Meta}
import spacetraders_sdk/internal/jwt
pub type ErrorResponse {
ErrorResponse(
code: Int,
message: String,
data: Option(Dynamic),
request_id: Option(String),
)
}
pub type ApiError {
HttpcError(HttpError)
JsonDecodeError(DecodeError)
ResponseError(ErrorResponse)
}
pub type ApiResponse(a) =
Result(a, ApiError)
pub type PagedData(data) {
PagedData(data: data, meta: Meta)
}
pub opaque type AccountToken {
AccountToken(token: String)
}
pub opaque type AgentToken {
AgentToken(token: String)
}
pub type TokenParseError {
InvalidToken
IncorrectType
}
pub type AuthMethod {
AccountAuth(AccountToken)
AgentAuth(AgentToken)
NoAuth
}
pub fn parse_account_token(
value: String,
) -> Result(AccountToken, TokenParseError) {
use jwt <- result.try(jwt.parse(value) |> result.replace_error(InvalidToken))
case jwt.payload.subject {
"account-token" -> Ok(AccountToken(value))
_ -> Error(IncorrectType)
}
}
pub fn account_token_decoder() -> Decoder(AccountToken) {
use value <- decode.then(decode.string)
case parse_account_token(value) {
Ok(token) -> decode.success(token)
Error(_) -> decode.failure(AccountToken("invalid"), "AccountToken")
}
}
pub fn parse_agent_token(value: String) -> Result(AgentToken, TokenParseError) {
use jwt <- result.try(jwt.parse(value) |> result.replace_error(InvalidToken))
case jwt.payload.subject {
"agent-token" -> Ok(AgentToken(value))
_ -> Error(IncorrectType)
}
}
pub fn agent_token_decoder() -> Decoder(AgentToken) {
use value <- decode.then(decode.string)
case parse_agent_token(value) {
Ok(token) -> decode.success(token)
Error(_) -> decode.failure(AgentToken("invalid"), "AgentToken")
}
}
@internal
pub fn set_request_auth(req: Request(a), auth_method: AuthMethod) -> Request(a) {
case auth_method {
NoAuth -> req
AccountAuth(AccountToken(token)) | AgentAuth(AgentToken(token)) ->
req |> request.set_header("Authorization", "Bearer " <> token)
}
}