gleam-spacetraders-api-fetch/src/spacetraders_api_fetch.gleam
Lily Rose 6ad642cbd5
Some checks are pending
test / test (push) Waiting to run
Initial commit
2025-07-09 03:13:32 +10:00

788 lines
20 KiB
Gleam

import gleam/fetch.{type FetchError}
import gleam/http/request.{type Request}
import gleam/http/response.{type Response}
import gleam/javascript/promise.{type Promise}
import gleam/json.{type DecodeError}
import gleam/option.{type Option}
import gleam/result
import spacetraders_api.{
type AgentRegistered, type ApiResponse, type CargoPurchased, type CargoSold,
type CargoTransferred, type ChartCreated, type ConstructionSiteSupplied,
type ContractAccepted, type ContractCargoDelivered, type ContractFulfilled,
type ErrorCode, type ExportToImportMap, type FactionReputation,
type ResourcesExtracted, type ResourcesSiphoned, type Scan, type ServerStatus,
type ShipJumped, type ShipModuleInstalled, type ShipModuleRemoved,
type ShipMountInstalled, type ShipMountRemoved, type ShipNavPatched,
type ShipNavigated, type ShipPurchased, type ShipRefined, type ShipRefueled,
type ShipRepaired, type ShipScrapped, type ShipWarped, type SurveyCreated,
}
import spacetraders_models/account.{type Account}
import spacetraders_models/account_token.{type AccountToken}
import spacetraders_models/agent.{type Agent}
import spacetraders_models/agent_event.{type AgentEvent}
import spacetraders_models/agent_symbol.{type AgentSymbol}
import spacetraders_models/agent_token.{type AgentToken}
import spacetraders_models/construction.{type Construction}
import spacetraders_models/contract.{type Contract}
import spacetraders_models/contract_id.{type ContractId}
import spacetraders_models/cooldown.{type Cooldown}
import spacetraders_models/faction.{type Faction}
import spacetraders_models/faction_symbol.{type FactionSymbol}
import spacetraders_models/jump_gate.{type JumpGate}
import spacetraders_models/market.{type Market}
import spacetraders_models/module_symbol.{type ModuleSymbol}
import spacetraders_models/mount_symbol.{type MountSymbol}
import spacetraders_models/paged_data.{type PagedData}
import spacetraders_models/public_agent.{type PublicAgent}
import spacetraders_models/refinement_produce.{type RefinementProduce}
import spacetraders_models/repair_transaction.{type RepairTransaction}
import spacetraders_models/scanned_ship.{type ScannedShip}
import spacetraders_models/scanned_system.{type ScannedSystem}
import spacetraders_models/scanned_waypoint.{type ScannedWaypoint}
import spacetraders_models/scrap_transaction.{type ScrapTransaction}
import spacetraders_models/ship.{type Ship}
import spacetraders_models/ship_cargo.{type ShipCargo}
import spacetraders_models/ship_module.{type ShipModule}
import spacetraders_models/ship_mount.{type ShipMount}
import spacetraders_models/ship_nav.{type ShipNav}
import spacetraders_models/ship_nav_flight_mode.{type ShipNavFlightMode}
import spacetraders_models/ship_symbol.{type ShipSymbol}
import spacetraders_models/ship_type.{type ShipType}
import spacetraders_models/shipyard.{type Shipyard}
import spacetraders_models/spacetraders_error.{type SpacetradersError}
import spacetraders_models/survey.{type Survey}
import spacetraders_models/system.{type System}
import spacetraders_models/system_symbol.{type SystemSymbol}
import spacetraders_models/trade_symbol.{type TradeSymbol}
import spacetraders_models/waypoint.{type Waypoint}
import spacetraders_models/waypoint_symbol.{type WaypointSymbol}
import spacetraders_models/waypoint_trait_symbol.{type WaypointTraitSymbol}
import spacetraders_models/waypoint_type.{type WaypointType}
pub type FetchApiError {
ClientError(FetchError)
JsonDecodeError(DecodeError)
ServerError(SpacetradersError)
}
pub type FetchApiResponse(data) =
Promise(Result(data, FetchApiError))
fn send(request: Request(BitArray)) -> FetchApiResponse(Response(BitArray)) {
fetch.send_bits(request)
|> promise.await(fn(res) {
case res {
Ok(fetch_body) ->
fetch.read_bytes_body(fetch_body)
|> promise.map(result.map_error(_, ClientError))
Error(err) -> promise.resolve(Error(ClientError(err)))
}
})
}
fn try_send(
request: Request(BitArray),
apply fun: fn(Response(BitArray)) -> ApiResponse(data),
) -> FetchApiResponse(data) {
use res <- promise.map_try(send(request))
fun(res)
|> result.map_error(fn(api_error) {
case api_error {
spacetraders_api.JsonDecodeError(e) -> JsonDecodeError(e)
spacetraders_api.ServerError(e) -> ServerError(e)
}
})
}
pub fn get_account(token: AgentToken) -> FetchApiResponse(Account) {
try_send(
spacetraders_api.get_account_request(token),
spacetraders_api.get_account_response,
)
}
pub fn register_new_agent(
token: AccountToken,
agent_symbol: AgentSymbol,
faction_symbol: FactionSymbol,
) -> FetchApiResponse(AgentRegistered) {
try_send(
spacetraders_api.register_new_agent_request(
token,
agent_symbol,
faction_symbol,
),
spacetraders_api.register_new_agent_response,
)
}
pub fn list_public_agents(
page: Option(Int),
limit: Option(Int),
) -> FetchApiResponse(PagedData(List(PublicAgent))) {
try_send(
spacetraders_api.list_public_agents_request(page, limit),
spacetraders_api.list_public_agents_response,
)
}
pub fn get_public_agent(
agent_symbol: AgentSymbol,
) -> FetchApiResponse(PublicAgent) {
try_send(
spacetraders_api.get_public_agent_request(agent_symbol),
spacetraders_api.get_public_agent_response,
)
}
pub fn get_agent(token: AgentToken) -> FetchApiResponse(Agent) {
try_send(
spacetraders_api.get_agent_request(token),
spacetraders_api.get_agent_response,
)
}
pub fn get_agent_events(token: AgentToken) -> FetchApiResponse(List(AgentEvent)) {
try_send(
spacetraders_api.get_agent_events_request(token),
spacetraders_api.get_agent_events_response,
)
}
pub fn list_contracts(
token: AgentToken,
page: Option(Int),
limit: Option(Int),
) -> FetchApiResponse(PagedData(List(Contract))) {
try_send(
spacetraders_api.list_contracts_request(token, page, limit),
spacetraders_api.list_contracts_response,
)
}
pub fn get_contract(
token: AgentToken,
contract_id: ContractId,
) -> FetchApiResponse(Contract) {
try_send(
spacetraders_api.get_contract_request(token, contract_id),
spacetraders_api.get_contract_response,
)
}
pub fn accept_contract(
token: AgentToken,
contract_id: ContractId,
) -> FetchApiResponse(ContractAccepted) {
try_send(
spacetraders_api.accept_contract_request(token, contract_id),
spacetraders_api.accept_contract_response,
)
}
pub fn fulfill_contract(
token: AgentToken,
contract_id: ContractId,
) -> FetchApiResponse(ContractFulfilled) {
try_send(
spacetraders_api.fulfill_contract_request(token, contract_id),
spacetraders_api.fulfill_contract_response,
)
}
pub fn deliver_contract_cargo(
token: AgentToken,
contract_id: ContractId,
ship_symbol: ShipSymbol,
trade_symbol: TradeSymbol,
units: Int,
) -> FetchApiResponse(ContractCargoDelivered) {
try_send(
spacetraders_api.deliver_contract_cargo_request(
token,
contract_id,
ship_symbol,
trade_symbol,
units,
),
spacetraders_api.deliver_contract_cargo_response,
)
}
pub fn get_supply_chain() -> FetchApiResponse(ExportToImportMap) {
try_send(
spacetraders_api.get_supply_chain_request(),
spacetraders_api.get_supply_chain_response,
)
}
pub fn list_factions(
page: Option(Int),
limit: Option(Int),
) -> FetchApiResponse(PagedData(List(Faction))) {
try_send(
spacetraders_api.list_factions_request(page, limit),
spacetraders_api.list_factions_response,
)
}
pub fn get_faction(symbol: FactionSymbol) -> FetchApiResponse(Faction) {
try_send(
spacetraders_api.get_faction_request(symbol),
spacetraders_api.get_faction_response,
)
}
pub fn get_my_factions(
token: AgentToken,
page: Option(Int),
limit: Option(Int),
) -> FetchApiResponse(PagedData(List(FactionReputation))) {
try_send(
spacetraders_api.get_my_factions_request(token, page, limit),
spacetraders_api.get_my_factions_response,
)
}
pub fn list_ships(
token: AgentToken,
page: Option(Int),
limit: Option(Int),
) -> FetchApiResponse(PagedData(List(Ship))) {
try_send(
spacetraders_api.list_ships_request(token, page, limit),
spacetraders_api.list_ships_response,
)
}
pub fn purchase_ship(
token: AgentToken,
ship_type: ShipType,
waypoint_symbol: WaypointSymbol,
) -> FetchApiResponse(ShipPurchased) {
try_send(
spacetraders_api.purchase_ship_request(token, ship_type, waypoint_symbol),
spacetraders_api.purchase_ship_response,
)
}
pub fn get_ship(
token: AgentToken,
ship_symbol: ShipSymbol,
) -> FetchApiResponse(Ship) {
try_send(
spacetraders_api.get_ship_request(token, ship_symbol),
spacetraders_api.get_ship_response,
)
}
pub fn create_chart(
token: AgentToken,
ship_symbol: ShipSymbol,
) -> FetchApiResponse(ChartCreated) {
try_send(
spacetraders_api.create_chart_request(token, ship_symbol),
spacetraders_api.create_chart_response,
)
}
pub fn negotiate_contract(
token: AgentToken,
ship_symbol: String,
) -> FetchApiResponse(Contract) {
try_send(
spacetraders_api.negotiate_contract_request(token, ship_symbol),
spacetraders_api.negotiate_contract_response,
)
}
pub fn get_ship_cooldown(
token: AgentToken,
ship_symbol: ShipSymbol,
) -> FetchApiResponse(Option(Cooldown)) {
try_send(
spacetraders_api.get_ship_cooldown_request(token, ship_symbol),
spacetraders_api.get_ship_cooldown_response,
)
}
pub fn dock_ship(
token: AgentToken,
ship_symbol: ShipSymbol,
) -> FetchApiResponse(ShipNav) {
try_send(
spacetraders_api.dock_ship_request(token, ship_symbol),
spacetraders_api.dock_ship_response,
)
}
pub fn extract_resources(
token: AgentToken,
ship_symbol: ShipSymbol,
) -> FetchApiResponse(ResourcesExtracted) {
try_send(
spacetraders_api.extract_resources_request(token, ship_symbol),
spacetraders_api.extract_resources_response,
)
}
pub fn extract_resources_with_survey(
token: AgentToken,
ship_symbol: ShipSymbol,
survey: Survey,
) -> FetchApiResponse(ResourcesExtracted) {
try_send(
spacetraders_api.extract_resources_with_survey_request(
token,
ship_symbol,
survey,
),
spacetraders_api.extract_resources_with_survey_response,
)
}
pub fn jettison_cargo(
token: AgentToken,
ship_symbol: ShipSymbol,
trade_symbol: TradeSymbol,
units: Int,
) -> FetchApiResponse(ShipCargo) {
try_send(
spacetraders_api.jettison_cargo_request(
token,
ship_symbol,
trade_symbol,
units,
),
spacetraders_api.jettison_cargo_response,
)
}
pub fn jump_ship(
token: AgentToken,
ship_symbol: ShipSymbol,
waypoint_symbol: WaypointSymbol,
) -> FetchApiResponse(ShipJumped) {
try_send(
spacetraders_api.jump_ship_request(token, ship_symbol, waypoint_symbol),
spacetraders_api.jump_ship_response,
)
}
pub fn scan_systems(
token: AgentToken,
ship_symbol: ShipSymbol,
) -> FetchApiResponse(Scan(ScannedSystem)) {
try_send(
spacetraders_api.scan_systems_request(token, ship_symbol),
spacetraders_api.scan_systems_response,
)
}
pub fn scan_waypoints(
token: AgentToken,
ship_symbol: ShipSymbol,
) -> FetchApiResponse(Scan(ScannedWaypoint)) {
try_send(
spacetraders_api.scan_waypoints_request(token, ship_symbol),
spacetraders_api.scan_waypoints_response,
)
}
pub fn scan_ships(
token: AgentToken,
ship_symbol: ShipSymbol,
) -> FetchApiResponse(Scan(ScannedShip)) {
try_send(
spacetraders_api.scan_ships_request(token, ship_symbol),
spacetraders_api.scan_ships_response,
)
}
pub fn scrap_ship(
token: AgentToken,
ship_symbol: ShipSymbol,
) -> FetchApiResponse(ShipScrapped) {
try_send(
spacetraders_api.scrap_ship_request(token, ship_symbol),
spacetraders_api.scrap_ship_response,
)
}
pub fn get_scrap_ship(
token: AgentToken,
ship_symbol: ShipSymbol,
) -> FetchApiResponse(ScrapTransaction) {
try_send(
spacetraders_api.get_scrap_ship_request(token, ship_symbol),
spacetraders_api.get_scrap_ship_response,
)
}
pub fn navigate_ship(
token: AgentToken,
ship_symbol: ShipSymbol,
waypoint_symbol: WaypointSymbol,
) -> FetchApiResponse(ShipNavigated) {
try_send(
spacetraders_api.navigate_ship_request(token, ship_symbol, waypoint_symbol),
spacetraders_api.navigate_ship_response,
)
}
pub fn warp_ship(
token: AgentToken,
ship_symbol: ShipSymbol,
waypoint_symbol: WaypointSymbol,
) -> FetchApiResponse(ShipWarped) {
try_send(
spacetraders_api.warp_ship_request(token, ship_symbol, waypoint_symbol),
spacetraders_api.warp_ship_response,
)
}
pub fn orbit_ship(
token: AgentToken,
ship_symbol: ShipSymbol,
) -> FetchApiResponse(ShipNav) {
try_send(
spacetraders_api.orbit_ship_request(token, ship_symbol),
spacetraders_api.orbit_ship_response,
)
}
pub fn purchase_cargo(
token: AgentToken,
ship_symbol: ShipSymbol,
trade_symbol: TradeSymbol,
) -> FetchApiResponse(CargoPurchased) {
try_send(
spacetraders_api.purchase_cargo_request(token, ship_symbol, trade_symbol),
spacetraders_api.purchase_cargo_response,
)
}
pub fn refine_ship(
token: AgentToken,
ship_symbol: ShipSymbol,
produce: RefinementProduce,
) -> FetchApiResponse(ShipRefined) {
try_send(
spacetraders_api.refine_ship_request(token, ship_symbol, produce),
spacetraders_api.refine_ship_response,
)
}
pub fn refuel_ship(
token: AgentToken,
ship_symbol: ShipSymbol,
units: Option(Int),
from_cargo: Option(Bool),
) -> FetchApiResponse(ShipRefueled) {
try_send(
spacetraders_api.refuel_ship_request(token, ship_symbol, units, from_cargo),
spacetraders_api.refuel_ship_response,
)
}
pub fn repair_ship(
token: AgentToken,
ship_symbol: ShipSymbol,
) -> FetchApiResponse(ShipRepaired) {
try_send(
spacetraders_api.repair_ship_request(token, ship_symbol),
spacetraders_api.repair_ship_response,
)
}
pub fn get_repair_ship(
token: AgentToken,
ship_symbol: ShipSymbol,
) -> FetchApiResponse(RepairTransaction) {
try_send(
spacetraders_api.get_repair_ship_request(token, ship_symbol),
spacetraders_api.get_repair_ship_response,
)
}
pub fn sell_cargo(
token: AgentToken,
ship_symbol: ShipSymbol,
trade_symbol: TradeSymbol,
units: Int,
) -> FetchApiResponse(CargoSold) {
try_send(
spacetraders_api.sell_cargo_request(token, ship_symbol, trade_symbol, units),
spacetraders_api.sell_cargo_response,
)
}
pub fn siphon_resources(
token: AgentToken,
ship_symbol: ShipSymbol,
) -> FetchApiResponse(ResourcesSiphoned) {
try_send(
spacetraders_api.siphon_resources_request(token, ship_symbol),
spacetraders_api.siphon_resources_response,
)
}
pub fn create_survey(
token: AgentToken,
ship_symbol: ShipSymbol,
) -> FetchApiResponse(SurveyCreated) {
try_send(
spacetraders_api.create_survey_request(token, ship_symbol),
spacetraders_api.create_survey_response,
)
}
pub fn transfer_cargo(
token: AgentToken,
ship_symbol: ShipSymbol,
trade_symbol: TradeSymbol,
units: Int,
target_ship_symbol: ShipSymbol,
) -> FetchApiResponse(CargoTransferred) {
try_send(
spacetraders_api.transfer_cargo_request(
token,
ship_symbol,
trade_symbol,
units,
target_ship_symbol,
),
spacetraders_api.transfer_cargo_response,
)
}
pub fn get_ship_cargo(
token: AgentToken,
ship_symbol: ShipSymbol,
) -> FetchApiResponse(ShipCargo) {
try_send(
spacetraders_api.get_ship_cargo_request(token, ship_symbol),
spacetraders_api.get_ship_cargo_response,
)
}
pub fn get_ship_modules(
token: AgentToken,
ship_symbol: ShipSymbol,
) -> FetchApiResponse(List(ShipModule)) {
try_send(
spacetraders_api.get_ship_modules_request(token, ship_symbol),
spacetraders_api.get_ship_modules_response,
)
}
pub fn install_ship_module(
token: AgentToken,
ship_symbol: ShipSymbol,
module_symbol: ModuleSymbol,
) -> FetchApiResponse(ShipModuleInstalled) {
try_send(
spacetraders_api.install_ship_module_request(
token,
ship_symbol,
module_symbol,
),
spacetraders_api.install_ship_module_response,
)
}
pub fn remove_ship_module(
token: AgentToken,
ship_symbol: ShipSymbol,
module_symbol: ModuleSymbol,
) -> FetchApiResponse(ShipModuleRemoved) {
try_send(
spacetraders_api.remove_ship_module_request(
token,
ship_symbol,
module_symbol,
),
spacetraders_api.remove_ship_module_response,
)
}
pub fn get_ship_mounts(
token: AgentToken,
ship_symbol: ShipSymbol,
) -> FetchApiResponse(List(ShipMount)) {
try_send(
spacetraders_api.get_ship_mounts_request(token, ship_symbol),
spacetraders_api.get_ship_mounts_response,
)
}
pub fn install_ship_mount(
token: AgentToken,
ship_symbol: ShipSymbol,
mount_symbol: MountSymbol,
) -> FetchApiResponse(ShipMountInstalled) {
try_send(
spacetraders_api.install_ship_mount_request(
token,
ship_symbol,
mount_symbol,
),
spacetraders_api.install_ship_mount_response,
)
}
pub fn remove_ship_mount(
token: AgentToken,
ship_symbol: ShipSymbol,
mount_symbol: MountSymbol,
) -> FetchApiResponse(ShipMountRemoved) {
try_send(
spacetraders_api.remove_ship_mount_request(token, ship_symbol, mount_symbol),
spacetraders_api.remove_ship_mount_response,
)
}
pub fn get_ship_nav(
token: AgentToken,
ship_symbol: ShipSymbol,
) -> FetchApiResponse(ShipNav) {
try_send(
spacetraders_api.get_ship_nav_request(token, ship_symbol),
spacetraders_api.get_ship_nav_response,
)
}
pub fn patch_ship_nav(
token: AgentToken,
ship_symbol: ShipSymbol,
flight_mode: ShipNavFlightMode,
) -> FetchApiResponse(ShipNavPatched) {
try_send(
spacetraders_api.patch_ship_nav_request(token, ship_symbol, flight_mode),
spacetraders_api.patch_ship_nav_response,
)
}
pub fn get_server_status() -> FetchApiResponse(ServerStatus) {
try_send(
spacetraders_api.get_server_status_request(),
spacetraders_api.get_server_status_response,
)
}
pub fn list_error_codes() -> FetchApiResponse(List(ErrorCode)) {
try_send(
spacetraders_api.list_error_codes_request(),
spacetraders_api.list_error_codes_response,
)
}
pub fn list_systems(
page: Option(Int),
limit: Option(Int),
) -> FetchApiResponse(PagedData(List(System))) {
try_send(
spacetraders_api.list_systems_request(page, limit),
spacetraders_api.list_systems_response,
)
}
pub fn get_system(system_symbol: SystemSymbol) -> FetchApiResponse(System) {
try_send(
spacetraders_api.get_system_request(system_symbol),
spacetraders_api.get_system_response,
)
}
pub fn list_system_waypoints(
system_symbol: SystemSymbol,
page: Option(Int),
limit: Option(Int),
type_: Option(WaypointType),
traits: List(WaypointTraitSymbol),
) -> FetchApiResponse(PagedData(List(Waypoint))) {
try_send(
spacetraders_api.list_system_waypoints_request(
system_symbol,
page,
limit,
type_,
traits,
),
spacetraders_api.list_system_waypoints_response,
)
}
pub fn get_waypoint(
system_symbol: SystemSymbol,
waypoint_symbol: WaypointSymbol,
) -> FetchApiResponse(Waypoint) {
try_send(
spacetraders_api.get_waypoint_request(system_symbol, waypoint_symbol),
spacetraders_api.get_waypoint_response,
)
}
pub fn get_construction_site(
system_symbol: SystemSymbol,
waypoint_symbol: WaypointSymbol,
) -> FetchApiResponse(Construction) {
try_send(
spacetraders_api.get_construction_site_request(
system_symbol,
waypoint_symbol,
),
spacetraders_api.get_construction_site_response,
)
}
pub fn supply_construction_site(
token: AgentToken,
system_symbol: SystemSymbol,
waypoint_symbol: WaypointSymbol,
ship_symbol: ShipSymbol,
trade_symbol: TradeSymbol,
units: Int,
) -> FetchApiResponse(ConstructionSiteSupplied) {
try_send(
spacetraders_api.supply_construction_site_request(
token,
system_symbol,
waypoint_symbol,
ship_symbol,
trade_symbol,
units,
),
spacetraders_api.supply_construction_site_response,
)
}
pub fn get_market(
system_symbol: SystemSymbol,
waypoint_symbol: WaypointSymbol,
) -> FetchApiResponse(Market) {
try_send(
spacetraders_api.get_market_request(system_symbol, waypoint_symbol),
spacetraders_api.get_market_response,
)
}
pub fn get_jump_gate(
system_symbol: SystemSymbol,
waypoint_symbol: WaypointSymbol,
) -> FetchApiResponse(JumpGate) {
try_send(
spacetraders_api.get_jump_gate_request(system_symbol, waypoint_symbol),
spacetraders_api.get_jump_gate_response,
)
}
pub fn get_shipyard(
system_symbol: SystemSymbol,
waypoint_symbol: WaypointSymbol,
) -> FetchApiResponse(Shipyard) {
try_send(
spacetraders_api.get_shipyard_request(system_symbol, waypoint_symbol),
spacetraders_api.get_shipyard_response,
)
}