Compare commits

...

18 commits
v1.1.0 ... main

Author SHA1 Message Date
050cef92e4 Bump version to 1.5.5
Some checks failed
test / test (push) Has been cancelled
2025-06-25 12:03:23 +10:00
de20cb5001 Handle float values without decimal point 2025-06-25 12:03:04 +10:00
aed9b6413f Bump version to 1.5.4
Some checks are pending
test / test (push) Waiting to run
2025-06-25 10:24:00 +10:00
a4edaa71e1 Add to_string functions for tokens 2025-06-25 10:23:38 +10:00
89ff1b3520 Bump version to 1.5.3
Some checks failed
test / test (push) Has been cancelled
2025-06-20 00:16:52 +10:00
59ecc25dc7 Fix code example in readme 2025-06-20 00:16:24 +10:00
35b1d0c1fc Bump version to 1.5.2
Some checks are pending
test / test (push) Waiting to run
2025-06-19 23:38:35 +10:00
f9944d6878 Fix incorrect auth on supply_construction_site endpoint 2025-06-19 23:38:22 +10:00
70a30ff132 Bump version to 1.5.1
Some checks are pending
test / test (push) Waiting to run
2025-06-18 20:30:53 +10:00
bc25e15faf Bump version to 1.5.0
Some checks are pending
test / test (push) Waiting to run
2025-06-18 20:04:27 +10:00
c1a7debb84 Remove reexports 2025-06-18 20:04:15 +10:00
c41a0c5dba Bump version to 1.4.0
Some checks are pending
test / test (push) Waiting to run
2025-06-18 19:44:53 +10:00
6236a6f11f More package restructuring 2025-06-18 19:44:38 +10:00
54f09d7635 Bump version to 1.3.0
Some checks are pending
test / test (push) Waiting to run
2025-06-18 16:06:08 +10:00
d7fb43b292 Remove empty main method
Some checks are pending
test / test (push) Waiting to run
2025-06-18 16:05:35 +10:00
97dc0228ea Fix package structure 2025-06-18 16:05:10 +10:00
00fdca952f Bump version to 1.2.0
Some checks are pending
test / test (push) Waiting to run
2025-06-18 15:53:54 +10:00
5d8599a33d Remove unnecessary authentication for unauthenticated endpoints 2025-06-18 15:53:40 +10:00
127 changed files with 1110 additions and 1266 deletions

View file

@ -7,12 +7,11 @@
gleam add spacetraders_sdk@1 gleam add spacetraders_sdk@1
``` ```
```gleam ```gleam
import spacetraders_sdk import spacetraders_api
pub fn main() -> Nil { pub fn main() -> Nil {
let assert Ok(server_status) = get_server_status() let assert Ok(server_status) = spacetraders_api.get_server_status()
echo server_status io.println(server_status.status)
Nil
} }
``` ```

View file

@ -1,5 +1,5 @@
name = "spacetraders_sdk" name = "spacetraders_sdk"
version = "1.1.0" version = "1.5.5"
gleam = ">= 1.11.0" gleam = ">= 1.11.0"
description = "A Gleam SDK for the spacetraders.io game API" description = "A Gleam SDK for the spacetraders.io game API"
licences = ["MIT"] licences = ["MIT"]

View file

@ -1,69 +0,0 @@
import gleam/dynamic/decode
import gleam/json
import models/account.{type Account}
import models/agent.{type Agent}
import models/agent_symbol.{type AgentSymbol}
import models/contract.{type Contract}
import models/faction.{type Faction}
import models/faction_symbol.{type FactionSymbol}
import models/ship.{type Ship}
import utils/api.{type ApiResponse}
import utils/auth.{type AccountToken, type AgentToken, AccountAuth, AgentAuth}
pub fn get_account(token: AgentToken) -> ApiResponse(Account) {
let request = api.get(AgentAuth(token), "/my/account")
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_data_response(
response,
decode.field("account", account.decoder(), decode.success),
)
_ -> api.parse_error_response(response)
}
}
pub type AgentRegistered {
AgentRegistered(
token: AgentToken,
agent: Agent,
faction: Faction,
contract: Contract,
ships: List(Ship),
)
}
pub fn register_new_agent(
token: AccountToken,
agent_symbol: AgentSymbol,
faction_symbol: FactionSymbol,
) -> ApiResponse(AgentRegistered) {
let request =
api.post_json(
AccountAuth(token),
"/register",
json.object([
#("symbol", agent_symbol.encode(agent_symbol)),
#("faction", faction_symbol.encode(faction_symbol)),
]),
)
use response <- api.try_send(request)
case response.status {
201 ->
api.parse_data_response(response, {
use token <- decode.field("token", auth.agent_token_decoder())
use agent <- decode.field("agent", agent.decoder())
use faction <- decode.field("faction", faction.decoder())
use contract <- decode.field("contract", contract.decoder())
use ships <- decode.field("ships", decode.list(ship.decoder()))
decode.success(AgentRegistered(
token:,
agent:,
faction:,
contract:,
ships:,
))
})
_ -> api.parse_error_response(response)
}
}

View file

@ -1,59 +0,0 @@
import gleam/dynamic/decode
import gleam/option.{type Option}
import models/agent.{type Agent}
import models/agent_event.{type AgentEvent}
import models/agent_symbol.{type AgentSymbol}
import models/public_agent.{type PublicAgent}
import utils/api.{type ApiResponse, type PagedData}
import utils/auth.{type AgentToken, AgentAuth}
pub fn list_public_agents(
token: AgentToken,
page: Option(Int),
limit: Option(Int),
) -> ApiResponse(PagedData(List(PublicAgent))) {
let request = api.get_page(AgentAuth(token), "/agents", page, limit)
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_paged_data_response(
response,
decode.list(public_agent.decoder()),
)
_ -> api.parse_error_response(response)
}
}
pub fn get_public_agent(
token: AgentToken,
agent_symbol: AgentSymbol,
) -> ApiResponse(PublicAgent) {
let request =
api.get(
AgentAuth(token),
"/agents/" <> agent_symbol.to_string(agent_symbol),
)
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, public_agent.decoder())
_ -> api.parse_error_response(response)
}
}
pub fn get_agent(token: AgentToken) -> ApiResponse(Agent) {
let request = api.get(AgentAuth(token), "/my/agent")
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, agent.decoder())
_ -> api.parse_error_response(response)
}
}
pub fn get_agent_events(token: AgentToken) -> ApiResponse(List(AgentEvent)) {
let request = api.get(AgentAuth(token), "/my/agent/events")
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, decode.list(agent_event.decoder()))
_ -> api.parse_error_response(response)
}
}

View file

@ -1,127 +0,0 @@
import endpoints/fleet
import gleam/dynamic/decode
import gleam/json
import gleam/option.{type Option}
import models/agent.{type Agent}
import models/contract.{type Contract}
import models/contract_id.{type ContractId}
import models/ship_cargo.{type ShipCargo}
import models/ship_symbol.{type ShipSymbol}
import models/trade_symbol.{type TradeSymbol}
import utils/api.{type ApiResponse, type PagedData}
import utils/auth.{type AgentToken, AgentAuth}
pub fn list_contracts(
token: AgentToken,
page: Option(Int),
limit: Option(Int),
) -> ApiResponse(PagedData(List(Contract))) {
let request = api.get_page(AgentAuth(token), "/my/contracts", page, limit)
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_paged_data_response(response, decode.list(contract.decoder()))
_ -> api.parse_error_response(response)
}
}
pub fn get_contract(
token: AgentToken,
contract_id: ContractId,
) -> ApiResponse(Contract) {
let request =
api.get(
AgentAuth(token),
"/my/contracts/" <> contract_id.to_string(contract_id),
)
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, contract.decoder())
_ -> api.parse_error_response(response)
}
}
pub type ContractAccepted {
ContractAccepted(contract: Contract, agent: Agent)
}
pub fn accept_contract(
token: AgentToken,
contract_id: ContractId,
) -> ApiResponse(ContractAccepted) {
let request =
api.post(
AgentAuth(token),
"/my/contracts/" <> contract_id.to_string(contract_id) <> "/accept",
)
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_data_response(response, {
use contract <- decode.field("contract", contract.decoder())
use agent <- decode.field("agent", agent.decoder())
decode.success(ContractAccepted(contract:, agent:))
})
_ -> api.parse_error_response(response)
}
}
pub type ContractFulfilled {
ContractFulfilled(contract: Contract, agent: Agent)
}
pub fn fulfill_contract(
token: AgentToken,
contract_id: ContractId,
) -> ApiResponse(ContractFulfilled) {
let request =
api.post(
AgentAuth(token),
"/my/contracts/" <> contract_id.to_string(contract_id) <> "/fulfill",
)
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_data_response(response, {
use contract <- decode.field("contract", contract.decoder())
use agent <- decode.field("agent", agent.decoder())
decode.success(ContractFulfilled(contract:, agent:))
})
_ -> api.parse_error_response(response)
}
}
pub type ContractCargoDelivered {
ContractCargoDelivered(contract: Contract, cargo: ShipCargo)
}
pub fn deliver_contract_cargo(
token: AgentToken,
contract_id: ContractId,
ship_symbol: ShipSymbol,
trade_symbol: TradeSymbol,
units: Int,
) -> ApiResponse(ContractCargoDelivered) {
let request =
api.post_json(
AgentAuth(token),
"/my/contracts/" <> contract_id.to_string(contract_id) <> "/deliver",
json.object([
#("shipSymbol", ship_symbol.encode(ship_symbol)),
#("tradeSymbol", trade_symbol.encode(trade_symbol)),
#("units", json.int(units)),
]),
)
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_data_response(response, {
use contract <- decode.field("contract", contract.decoder())
use cargo <- decode.field("cargo", ship_cargo.decoder())
decode.success(ContractCargoDelivered(contract:, cargo:))
})
_ -> api.parse_error_response(response)
}
}
pub const negotiate_contract = fleet.negotiate_contract

View file

@ -1,28 +0,0 @@
import gleam/dict.{type Dict}
import gleam/dynamic/decode
import models/trade_symbol.{type TradeSymbol}
import utils/api.{type ApiResponse}
import utils/auth.{NoAuth}
pub type ExportToImportMap =
Dict(TradeSymbol, List(TradeSymbol))
pub fn get_supply_chain() -> ApiResponse(ExportToImportMap) {
let request = api.get(NoAuth, "/market/supply-chain")
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_data_response(
response,
decode.field(
"exportToImportMap",
decode.dict(
trade_symbol.decoder(),
decode.list(trade_symbol.decoder()),
),
decode.success,
),
)
_ -> api.parse_error_response(response)
}
}

View file

@ -1,60 +0,0 @@
import gleam/dynamic/decode
import gleam/option.{type Option}
import models/faction.{type Faction}
import models/faction_symbol.{type FactionSymbol}
import utils/api.{type ApiResponse, type PagedData}
import utils/auth.{type AgentToken, AgentAuth}
pub fn list_factions(
token: AgentToken,
page: Option(Int),
limit: Option(Int),
) -> ApiResponse(PagedData(List(Faction))) {
let request = api.get_page(AgentAuth(token), "/factions", page, limit)
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_paged_data_response(response, decode.list(faction.decoder()))
_ -> api.parse_error_response(response)
}
}
pub fn get_faction(
token: AgentToken,
symbol: FactionSymbol,
) -> ApiResponse(Faction) {
let request =
api.get(AgentAuth(token), "/factions/" <> faction_symbol.to_string(symbol))
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, faction.decoder())
_ -> api.parse_error_response(response)
}
}
pub type FactionReputation {
FactionReputation(symbol: FactionSymbol, reputation: Int)
}
fn faction_reputation_decoder() {
use symbol <- decode.field("symbol", faction_symbol.decoder())
use reputation <- decode.field("reputation", decode.int)
decode.success(FactionReputation(symbol:, reputation:))
}
pub fn get_my_factions(
token: AgentToken,
page: Option(Int),
limit: Option(Int),
) -> ApiResponse(PagedData(List(FactionReputation))) {
let request = api.get_page(AgentAuth(token), "/my/factions", page, limit)
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_paged_data_response(
response,
decode.list(faction_reputation_decoder()),
)
_ -> api.parse_error_response(response)
}
}

View file

@ -1,203 +0,0 @@
import birl.{type Time}
import gleam/dynamic/decode.{type Decoder}
import gleam/option.{type Option}
import gleam/uri.{type Uri}
import models/agent_symbol.{type AgentSymbol}
import utils/api.{type ApiResponse}
import utils/auth.{NoAuth}
pub type Stats {
Stats(
accounts: Option(Int),
agents: Int,
ships: Int,
systems: Int,
waypoints: Int,
)
}
fn stats_decoder() -> Decoder(Stats) {
use accounts <- decode.optional_field(
"accounts",
option.None,
decode.optional(decode.int),
)
use agents <- decode.field("agents", decode.int)
use ships <- decode.field("ships", decode.int)
use systems <- decode.field("systems", decode.int)
use waypoints <- decode.field("waypoints", decode.int)
decode.success(Stats(accounts:, agents:, ships:, systems:, waypoints:))
}
pub type Health {
Health(last_market_update: Option(Time))
}
fn health_decoder() -> Decoder(Health) {
use last_market_update <- decode.optional_field(
"lastMarketUpdate",
option.None,
decode.optional(api.time_decoder()),
)
decode.success(Health(last_market_update:))
}
pub type CreditLeaderboardEntry {
CreditLeaderboardEntry(agent_symbol: AgentSymbol, credits: Int)
}
fn credit_leaderboard_entry_decoder() -> Decoder(CreditLeaderboardEntry) {
use agent_symbol <- decode.field("agentSymbol", agent_symbol.decoder())
use credits <- decode.field("credits", decode.int)
decode.success(CreditLeaderboardEntry(agent_symbol:, credits:))
}
pub type ChartLeaderboardEntry {
ChartLeaderboardEntry(agent_symbol: AgentSymbol, chart_count: Int)
}
fn chart_leaderboard_entry_decoder() -> Decoder(ChartLeaderboardEntry) {
use agent_symbol <- decode.field("agentSymbol", agent_symbol.decoder())
use chart_count <- decode.field("chartCount", decode.int)
decode.success(ChartLeaderboardEntry(agent_symbol:, chart_count:))
}
pub type Leaderboards {
Leaderboards(
most_credits: List(CreditLeaderboardEntry),
most_submitted_charts: List(ChartLeaderboardEntry),
)
}
fn leaderboards_decoder() -> Decoder(Leaderboards) {
use most_credits <- decode.field(
"mostCredits",
decode.list(credit_leaderboard_entry_decoder()),
)
use most_submitted_charts <- decode.field(
"mostSubmittedCharts",
decode.list(chart_leaderboard_entry_decoder()),
)
decode.success(Leaderboards(most_credits:, most_submitted_charts:))
}
pub type ServerResets {
ServerResets(next: Time, frequency: String)
}
fn server_resets_decoder() -> Decoder(ServerResets) {
use next <- decode.field("next", api.time_decoder())
use frequency <- decode.field("frequency", decode.string)
decode.success(ServerResets(next:, frequency:))
}
pub type Announcement {
Announcement(title: String, body: String)
}
fn announcement_decoder() -> Decoder(Announcement) {
use title <- decode.field("title", decode.string)
use body <- decode.field("body", decode.string)
decode.success(Announcement(title:, body:))
}
pub type Link {
Link(name: String, url: Uri)
}
fn link_decoder() -> Decoder(Link) {
use name <- decode.field("name", decode.string)
use url <- decode.field("url", {
use value <- decode.then(decode.string)
case uri.parse(value) {
Ok(time) -> decode.success(time)
Error(Nil) -> decode.failure(uri.empty, "Uri")
}
})
decode.success(Link(name:, url:))
}
pub type ServerStatus {
ServerStatus(
status: String,
version: String,
reset_date: Time,
description: String,
stats: Stats,
health: Health,
leaderboards: Leaderboards,
server_resets: ServerResets,
announcements: List(Announcement),
links: List(Link),
)
}
fn server_status_decoder() -> Decoder(ServerStatus) {
use status <- decode.field("status", decode.string)
use version <- decode.field("version", decode.string)
use reset_date <- decode.field("resetDate", {
use value <- decode.then(decode.string)
case birl.from_naive(value) {
Ok(time) -> decode.success(time)
Error(Nil) -> decode.failure(birl.now(), "Time")
}
})
use description <- decode.field("description", decode.string)
use stats <- decode.field("stats", stats_decoder())
use health <- decode.field("health", health_decoder())
use leaderboards <- decode.field("leaderboards", leaderboards_decoder())
use server_resets <- decode.field("serverResets", server_resets_decoder())
use announcements <- decode.field(
"announcements",
decode.list(announcement_decoder()),
)
use links <- decode.field("links", decode.list(link_decoder()))
decode.success(ServerStatus(
status:,
version:,
reset_date:,
description:,
stats:,
health:,
leaderboards:,
server_resets:,
announcements:,
links:,
))
}
pub fn get_server_status() -> ApiResponse(ServerStatus) {
let request = api.get(NoAuth, "/")
use response <- api.try_send(request)
case response.status {
200 -> api.parse_response(response, server_status_decoder())
_ -> api.parse_error_response(response)
}
}
pub type ErrorCode {
ErrorCode(code: Int, name: String)
}
fn error_code_decoder() -> Decoder(ErrorCode) {
use code <- decode.field("code", decode.int)
use name <- decode.field("name", decode.string)
decode.success(ErrorCode(code:, name:))
}
pub fn list_error_codes() -> ApiResponse(List(ErrorCode)) {
let request = api.get(NoAuth, "/error-codes")
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_response(
response,
decode.field(
"errorCodes",
decode.list(error_code_decoder()),
decode.success,
),
)
_ -> api.parse_error_response(response)
}
}

View file

@ -1,223 +0,0 @@
import gleam/dynamic/decode
import gleam/json
import gleam/list
import gleam/option.{type Option}
import models/construction.{type Construction}
import models/jump_gate.{type JumpGate}
import models/market.{type Market}
import models/ship_cargo.{type ShipCargo}
import models/ship_symbol.{type ShipSymbol}
import models/shipyard.{type Shipyard}
import models/system.{type System}
import models/system_symbol.{type SystemSymbol}
import models/trade_symbol.{type TradeSymbol}
import models/waypoint.{type Waypoint}
import models/waypoint_symbol.{type WaypointSymbol}
import models/waypoint_trait_symbol.{type WaypointTraitSymbol}
import models/waypoint_type.{type WaypointType}
import utils/api.{type ApiResponse, type PagedData}
import utils/auth.{type AgentToken, AgentAuth}
pub fn list_systems(
token: AgentToken,
page: Option(Int),
limit: Option(Int),
) -> ApiResponse(PagedData(List(System))) {
let request = api.get_page(AgentAuth(token), "/systems", page, limit)
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_paged_data_response(response, decode.list(system.decoder()))
_ -> api.parse_error_response(response)
}
}
pub fn get_system(
token: AgentToken,
system_symbol: SystemSymbol,
) -> ApiResponse(System) {
let request =
api.get(
AgentAuth(token),
"/systems/" <> system_symbol.to_string(system_symbol),
)
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, system.decoder())
_ -> api.parse_error_response(response)
}
}
pub fn list_system_waypoints(
token: AgentToken,
system_symbol: SystemSymbol,
page: Option(Int),
limit: Option(Int),
type_: Option(WaypointType),
traits: List(WaypointTraitSymbol),
) -> ApiResponse(PagedData(List(Waypoint))) {
let query =
list.map(traits, fn(trait) {
#("traits", waypoint_trait_symbol.to_string(trait))
})
let query = case type_ {
option.Some(type_) -> [#("type", waypoint_type.to_string(type_)), ..query]
option.None -> query
}
let request =
api.get_page_with_query(
AgentAuth(token),
"/systems/" <> system_symbol.to_string(system_symbol) <> "/waypoints",
page,
limit,
query,
)
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_paged_data_response(response, decode.list(waypoint.decoder()))
_ -> api.parse_error_response(response)
}
}
pub fn get_waypoint(
token: AgentToken,
system_symbol: SystemSymbol,
waypoint_symbol: WaypointSymbol,
) -> ApiResponse(Waypoint) {
let request =
api.get(
AgentAuth(token),
"/systems/"
<> system_symbol.to_string(system_symbol)
<> "/waypoints/"
<> waypoint_symbol.to_string(waypoint_symbol),
)
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, waypoint.decoder())
_ -> api.parse_error_response(response)
}
}
pub fn get_construction_site(
token: AgentToken,
system_symbol: SystemSymbol,
waypoint_symbol: WaypointSymbol,
) -> ApiResponse(Construction) {
let request =
api.get(
AgentAuth(token),
"/systems/"
<> system_symbol.to_string(system_symbol)
<> "/waypoints/"
<> waypoint_symbol.to_string(waypoint_symbol)
<> "/construction",
)
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, construction.decoder())
_ -> api.parse_error_response(response)
}
}
pub type ConstructionSiteSupplied {
ConstructionSiteSupplied(construction: Construction, cargo: ShipCargo)
}
pub fn supply_construction_site(
token: AgentToken,
system_symbol: SystemSymbol,
waypoint_symbol: WaypointSymbol,
ship_symbol: ShipSymbol,
trade_symbol: TradeSymbol,
units: Int,
) -> ApiResponse(ConstructionSiteSupplied) {
let request =
api.post_json(
AgentAuth(token),
"/systems/"
<> system_symbol.to_string(system_symbol)
<> "/waypoints/"
<> waypoint_symbol.to_string(waypoint_symbol)
<> "/construction/supply",
json.object([
#("shipSymbol", ship_symbol.encode(ship_symbol)),
#("tradeSymbol", trade_symbol.encode(trade_symbol)),
#("units", json.int(units)),
]),
)
use response <- api.try_send(request)
case response.status {
201 ->
api.parse_data_response(response, {
use construction <- decode.field("construction", construction.decoder())
use cargo <- decode.field("cargo", ship_cargo.decoder())
decode.success(ConstructionSiteSupplied(construction:, cargo:))
})
_ -> api.parse_error_response(response)
}
}
pub fn get_market(
token: AgentToken,
system_symbol: SystemSymbol,
waypoint_symbol: WaypointSymbol,
) -> ApiResponse(Market) {
let request =
api.get(
AgentAuth(token),
"/systems/"
<> system_symbol.to_string(system_symbol)
<> "/waypoints/"
<> waypoint_symbol.to_string(waypoint_symbol)
<> "/market",
)
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, market.decoder())
_ -> api.parse_error_response(response)
}
}
pub fn get_jump_gate(
token: AgentToken,
system_symbol: SystemSymbol,
waypoint_symbol: WaypointSymbol,
) -> ApiResponse(JumpGate) {
let request =
api.get(
AgentAuth(token),
"/systems/"
<> system_symbol.to_string(system_symbol)
<> "/waypoints/"
<> waypoint_symbol.to_string(waypoint_symbol)
<> "/jump-gate",
)
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, jump_gate.decoder())
_ -> api.parse_error_response(response)
}
}
pub fn get_shipyard(
token,
system_symbol,
waypoint_symbol,
) -> ApiResponse(Shipyard) {
let request =
api.get(
AgentAuth(token),
"/systems/"
<> system_symbol
<> "/waypoints/"
<> waypoint_symbol
<> "/shipyard",
)
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, shipyard.decoder())
_ -> api.parse_error_response(response)
}
}

View file

@ -1,42 +1,356 @@
import birl.{type Time}
import gleam/dict.{type Dict}
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/json import gleam/json
import gleam/list
import gleam/option.{type Option} import gleam/option.{type Option}
import models/agent.{type Agent} import gleam/uri.{type Uri}
import models/chart.{type Chart} import spacetraders_models/account.{type Account}
import models/chart_transaction.{type ChartTransaction} import spacetraders_models/agent.{type Agent}
import models/contract.{type Contract} import spacetraders_models/agent_event.{type AgentEvent}
import models/cooldown.{type Cooldown} import spacetraders_models/agent_symbol.{type AgentSymbol}
import models/extraction.{type Extraction} import spacetraders_models/chart.{type Chart}
import models/market_transaction.{type MarketTransaction} import spacetraders_models/chart_transaction.{type ChartTransaction}
import models/module_symbol.{type ModuleSymbol} import spacetraders_models/construction.{type Construction}
import models/mount_symbol.{type MountSymbol} import spacetraders_models/contract.{type Contract}
import models/refinement_produce.{type RefinementProduce} import spacetraders_models/contract_id.{type ContractId}
import models/refinement_yield.{type RefinementYield} import spacetraders_models/cooldown.{type Cooldown}
import models/repair_transaction.{type RepairTransaction} import spacetraders_models/extraction.{type Extraction}
import models/scanned_ship.{type ScannedShip} import spacetraders_models/faction.{type Faction}
import models/scanned_system.{type ScannedSystem} import spacetraders_models/faction_symbol.{type FactionSymbol}
import models/scanned_waypoint.{type ScannedWaypoint} import spacetraders_models/jump_gate.{type JumpGate}
import models/scrap_transaction.{type ScrapTransaction} import spacetraders_models/market.{type Market}
import models/ship.{type Ship} import spacetraders_models/market_transaction.{type MarketTransaction}
import models/ship_cargo.{type ShipCargo} import spacetraders_models/module_symbol.{type ModuleSymbol}
import models/ship_condition_event.{type ShipConditionEvent} import spacetraders_models/mount_symbol.{type MountSymbol}
import models/ship_fuel.{type ShipFuel} import spacetraders_models/public_agent.{type PublicAgent}
import models/ship_modification_transaction.{type ShipModificationTransaction} import spacetraders_models/refinement_produce.{type RefinementProduce}
import models/ship_module.{type ShipModule} import spacetraders_models/refinement_yield.{type RefinementYield}
import models/ship_mount.{type ShipMount} import spacetraders_models/repair_transaction.{type RepairTransaction}
import models/ship_nav.{type ShipNav} import spacetraders_models/scanned_ship.{type ScannedShip}
import models/ship_nav_flight_mode.{type ShipNavFlightMode} import spacetraders_models/scanned_system.{type ScannedSystem}
import models/ship_symbol.{type ShipSymbol} import spacetraders_models/scanned_waypoint.{type ScannedWaypoint}
import models/ship_type.{type ShipType} import spacetraders_models/scrap_transaction.{type ScrapTransaction}
import models/shipyard_transaction.{type ShipyardTransaction} import spacetraders_models/ship.{type Ship}
import models/siphon.{type Siphon} import spacetraders_models/ship_cargo.{type ShipCargo}
import models/survey.{type Survey} import spacetraders_models/ship_condition_event.{type ShipConditionEvent}
import models/trade_symbol.{type TradeSymbol} import spacetraders_models/ship_fuel.{type ShipFuel}
import models/waypoint.{type Waypoint} import spacetraders_models/ship_modification_transaction.{
import models/waypoint_modifier.{type WaypointModifier} type ShipModificationTransaction,
import models/waypoint_symbol.{type WaypointSymbol} }
import utils/api.{type ApiResponse, type PagedData} import spacetraders_models/ship_module.{type ShipModule}
import utils/auth.{type AgentToken, AgentAuth} 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/shipyard_transaction.{type ShipyardTransaction}
import spacetraders_models/siphon.{type Siphon}
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_modifier.{type WaypointModifier}
import spacetraders_models/waypoint_symbol.{type WaypointSymbol}
import spacetraders_models/waypoint_trait_symbol.{type WaypointTraitSymbol}
import spacetraders_models/waypoint_type.{type WaypointType}
import spacetraders_sdk.{
type AccountToken, type AgentToken, type ApiResponse, type PagedData,
AccountAuth, AgentAuth, NoAuth,
}
import spacetraders_sdk/internal/api
import spacetraders_sdk/internal/time
pub fn get_account(token: AgentToken) -> ApiResponse(Account) {
let request = api.get(AgentAuth(token), "/my/account")
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_data_response(
response,
decode.field("account", account.decoder(), decode.success),
)
_ -> api.parse_error_response(response)
}
}
pub type AgentRegistered {
AgentRegistered(
token: AgentToken,
agent: Agent,
faction: Faction,
contract: Contract,
ships: List(Ship),
)
}
pub fn register_new_agent(
token: AccountToken,
agent_symbol: AgentSymbol,
faction_symbol: FactionSymbol,
) -> ApiResponse(AgentRegistered) {
let request =
api.post_json(
AccountAuth(token),
"/register",
json.object([
#("symbol", agent_symbol.encode(agent_symbol)),
#("faction", faction_symbol.encode(faction_symbol)),
]),
)
use response <- api.try_send(request)
case response.status {
201 ->
api.parse_data_response(response, {
use token <- decode.field(
"token",
spacetraders_sdk.agent_token_decoder(),
)
use agent <- decode.field("agent", agent.decoder())
use faction <- decode.field("faction", faction.decoder())
use contract <- decode.field("contract", contract.decoder())
use ships <- decode.field("ships", decode.list(ship.decoder()))
decode.success(AgentRegistered(
token:,
agent:,
faction:,
contract:,
ships:,
))
})
_ -> api.parse_error_response(response)
}
}
pub fn list_public_agents(
page: Option(Int),
limit: Option(Int),
) -> ApiResponse(PagedData(List(PublicAgent))) {
let request = api.get_page(NoAuth, "/agents", page, limit)
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_paged_data_response(
response,
decode.list(public_agent.decoder()),
)
_ -> api.parse_error_response(response)
}
}
pub fn get_public_agent(agent_symbol: AgentSymbol) -> ApiResponse(PublicAgent) {
let request =
api.get(NoAuth, "/agents/" <> agent_symbol.to_string(agent_symbol))
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, public_agent.decoder())
_ -> api.parse_error_response(response)
}
}
pub fn get_agent(token: AgentToken) -> ApiResponse(Agent) {
let request = api.get(AgentAuth(token), "/my/agent")
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, agent.decoder())
_ -> api.parse_error_response(response)
}
}
pub fn get_agent_events(token: AgentToken) -> ApiResponse(List(AgentEvent)) {
let request = api.get(AgentAuth(token), "/my/agent/events")
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, decode.list(agent_event.decoder()))
_ -> api.parse_error_response(response)
}
}
pub fn list_contracts(
token: AgentToken,
page: Option(Int),
limit: Option(Int),
) -> ApiResponse(PagedData(List(Contract))) {
let request = api.get_page(AgentAuth(token), "/my/contracts", page, limit)
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_paged_data_response(response, decode.list(contract.decoder()))
_ -> api.parse_error_response(response)
}
}
pub fn get_contract(
token: AgentToken,
contract_id: ContractId,
) -> ApiResponse(Contract) {
let request =
api.get(
AgentAuth(token),
"/my/contracts/" <> contract_id.to_string(contract_id),
)
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, contract.decoder())
_ -> api.parse_error_response(response)
}
}
pub type ContractAccepted {
ContractAccepted(contract: Contract, agent: Agent)
}
pub fn accept_contract(
token: AgentToken,
contract_id: ContractId,
) -> ApiResponse(ContractAccepted) {
let request =
api.post(
AgentAuth(token),
"/my/contracts/" <> contract_id.to_string(contract_id) <> "/accept",
)
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_data_response(response, {
use contract <- decode.field("contract", contract.decoder())
use agent <- decode.field("agent", agent.decoder())
decode.success(ContractAccepted(contract:, agent:))
})
_ -> api.parse_error_response(response)
}
}
pub type ContractFulfilled {
ContractFulfilled(contract: Contract, agent: Agent)
}
pub fn fulfill_contract(
token: AgentToken,
contract_id: ContractId,
) -> ApiResponse(ContractFulfilled) {
let request =
api.post(
AgentAuth(token),
"/my/contracts/" <> contract_id.to_string(contract_id) <> "/fulfill",
)
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_data_response(response, {
use contract <- decode.field("contract", contract.decoder())
use agent <- decode.field("agent", agent.decoder())
decode.success(ContractFulfilled(contract:, agent:))
})
_ -> api.parse_error_response(response)
}
}
pub type ContractCargoDelivered {
ContractCargoDelivered(contract: Contract, cargo: ShipCargo)
}
pub fn deliver_contract_cargo(
token: AgentToken,
contract_id: ContractId,
ship_symbol: ShipSymbol,
trade_symbol: TradeSymbol,
units: Int,
) -> ApiResponse(ContractCargoDelivered) {
let request =
api.post_json(
AgentAuth(token),
"/my/contracts/" <> contract_id.to_string(contract_id) <> "/deliver",
json.object([
#("shipSymbol", ship_symbol.encode(ship_symbol)),
#("tradeSymbol", trade_symbol.encode(trade_symbol)),
#("units", json.int(units)),
]),
)
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_data_response(response, {
use contract <- decode.field("contract", contract.decoder())
use cargo <- decode.field("cargo", ship_cargo.decoder())
decode.success(ContractCargoDelivered(contract:, cargo:))
})
_ -> api.parse_error_response(response)
}
}
pub type ExportToImportMap =
Dict(TradeSymbol, List(TradeSymbol))
pub fn get_supply_chain() -> ApiResponse(ExportToImportMap) {
let request = api.get(NoAuth, "/market/supply-chain")
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_data_response(
response,
decode.field(
"exportToImportMap",
decode.dict(
trade_symbol.decoder(),
decode.list(trade_symbol.decoder()),
),
decode.success,
),
)
_ -> api.parse_error_response(response)
}
}
pub fn list_factions(
page: Option(Int),
limit: Option(Int),
) -> ApiResponse(PagedData(List(Faction))) {
let request = api.get_page(NoAuth, "/factions", page, limit)
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_paged_data_response(response, decode.list(faction.decoder()))
_ -> api.parse_error_response(response)
}
}
pub fn get_faction(symbol: FactionSymbol) -> ApiResponse(Faction) {
let request =
api.get(NoAuth, "/factions/" <> faction_symbol.to_string(symbol))
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, faction.decoder())
_ -> api.parse_error_response(response)
}
}
pub type FactionReputation {
FactionReputation(symbol: FactionSymbol, reputation: Int)
}
pub fn get_my_factions(
token: AgentToken,
page: Option(Int),
limit: Option(Int),
) -> ApiResponse(PagedData(List(FactionReputation))) {
let request = api.get_page(AgentAuth(token), "/my/factions", page, limit)
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_paged_data_response(
response,
decode.list({
use symbol <- decode.field("symbol", faction_symbol.decoder())
use reputation <- decode.field("reputation", decode.int)
decode.success(FactionReputation(symbol:, reputation:))
}),
)
_ -> api.parse_error_response(response)
}
}
pub fn list_ships( pub fn list_ships(
token: AgentToken, token: AgentToken,
@ -1070,3 +1384,384 @@ pub fn patch_ship_nav(
_ -> api.parse_error_response(response) _ -> api.parse_error_response(response)
} }
} }
pub type Stats {
Stats(
accounts: Option(Int),
agents: Int,
ships: Int,
systems: Int,
waypoints: Int,
)
}
fn stats_decoder() -> Decoder(Stats) {
use accounts <- decode.optional_field(
"accounts",
option.None,
decode.optional(decode.int),
)
use agents <- decode.field("agents", decode.int)
use ships <- decode.field("ships", decode.int)
use systems <- decode.field("systems", decode.int)
use waypoints <- decode.field("waypoints", decode.int)
decode.success(Stats(accounts:, agents:, ships:, systems:, waypoints:))
}
pub type Health {
Health(last_market_update: Option(Time))
}
fn health_decoder() -> Decoder(Health) {
use last_market_update <- decode.optional_field(
"lastMarketUpdate",
option.None,
decode.optional(time.datetime_decoder()),
)
decode.success(Health(last_market_update:))
}
pub type CreditLeaderboardEntry {
CreditLeaderboardEntry(agent_symbol: AgentSymbol, credits: Int)
}
fn credit_leaderboard_entry_decoder() -> Decoder(CreditLeaderboardEntry) {
use agent_symbol <- decode.field("agentSymbol", agent_symbol.decoder())
use credits <- decode.field("credits", decode.int)
decode.success(CreditLeaderboardEntry(agent_symbol:, credits:))
}
pub type ChartLeaderboardEntry {
ChartLeaderboardEntry(agent_symbol: AgentSymbol, chart_count: Int)
}
fn chart_leaderboard_entry_decoder() -> Decoder(ChartLeaderboardEntry) {
use agent_symbol <- decode.field("agentSymbol", agent_symbol.decoder())
use chart_count <- decode.field("chartCount", decode.int)
decode.success(ChartLeaderboardEntry(agent_symbol:, chart_count:))
}
pub type Leaderboards {
Leaderboards(
most_credits: List(CreditLeaderboardEntry),
most_submitted_charts: List(ChartLeaderboardEntry),
)
}
fn leaderboards_decoder() -> Decoder(Leaderboards) {
use most_credits <- decode.field(
"mostCredits",
decode.list(credit_leaderboard_entry_decoder()),
)
use most_submitted_charts <- decode.field(
"mostSubmittedCharts",
decode.list(chart_leaderboard_entry_decoder()),
)
decode.success(Leaderboards(most_credits:, most_submitted_charts:))
}
pub type ServerResets {
ServerResets(next: Time, frequency: String)
}
fn server_resets_decoder() -> Decoder(ServerResets) {
use next <- decode.field("next", time.datetime_decoder())
use frequency <- decode.field("frequency", decode.string)
decode.success(ServerResets(next:, frequency:))
}
pub type Announcement {
Announcement(title: String, body: String)
}
fn announcement_decoder() -> Decoder(Announcement) {
use title <- decode.field("title", decode.string)
use body <- decode.field("body", decode.string)
decode.success(Announcement(title:, body:))
}
pub type Link {
Link(name: String, url: Uri)
}
fn link_decoder() -> Decoder(Link) {
use name <- decode.field("name", decode.string)
use url <- decode.field("url", {
use value <- decode.then(decode.string)
case uri.parse(value) {
Ok(time) -> decode.success(time)
Error(Nil) -> decode.failure(uri.empty, "Uri")
}
})
decode.success(Link(name:, url:))
}
pub type ServerStatus {
ServerStatus(
status: String,
version: String,
reset_date: Time,
description: String,
stats: Stats,
health: Health,
leaderboards: Leaderboards,
server_resets: ServerResets,
announcements: List(Announcement),
links: List(Link),
)
}
fn server_status_decoder() -> Decoder(ServerStatus) {
use status <- decode.field("status", decode.string)
use version <- decode.field("version", decode.string)
use reset_date <- decode.field("resetDate", time.date_decoder())
use description <- decode.field("description", decode.string)
use stats <- decode.field("stats", stats_decoder())
use health <- decode.field("health", health_decoder())
use leaderboards <- decode.field("leaderboards", leaderboards_decoder())
use server_resets <- decode.field("serverResets", server_resets_decoder())
use announcements <- decode.field(
"announcements",
decode.list(announcement_decoder()),
)
use links <- decode.field("links", decode.list(link_decoder()))
decode.success(ServerStatus(
status:,
version:,
reset_date:,
description:,
stats:,
health:,
leaderboards:,
server_resets:,
announcements:,
links:,
))
}
pub fn get_server_status() -> ApiResponse(ServerStatus) {
let request = api.get(NoAuth, "/")
use response <- api.try_send(request)
case response.status {
200 -> api.parse_response(response, server_status_decoder())
_ -> api.parse_error_response(response)
}
}
pub type ErrorCode {
ErrorCode(code: Int, name: String)
}
fn error_code_decoder() -> Decoder(ErrorCode) {
use code <- decode.field("code", decode.int)
use name <- decode.field("name", decode.string)
decode.success(ErrorCode(code:, name:))
}
pub fn list_error_codes() -> ApiResponse(List(ErrorCode)) {
let request = api.get(NoAuth, "/error-codes")
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_response(
response,
decode.field(
"errorCodes",
decode.list(error_code_decoder()),
decode.success,
),
)
_ -> api.parse_error_response(response)
}
}
pub fn list_systems(
page: Option(Int),
limit: Option(Int),
) -> ApiResponse(PagedData(List(System))) {
let request = api.get_page(NoAuth, "/systems", page, limit)
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_paged_data_response(response, decode.list(system.decoder()))
_ -> api.parse_error_response(response)
}
}
pub fn get_system(system_symbol: SystemSymbol) -> ApiResponse(System) {
let request =
api.get(NoAuth, "/systems/" <> system_symbol.to_string(system_symbol))
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, system.decoder())
_ -> api.parse_error_response(response)
}
}
pub fn list_system_waypoints(
system_symbol: SystemSymbol,
page: Option(Int),
limit: Option(Int),
type_: Option(WaypointType),
traits: List(WaypointTraitSymbol),
) -> ApiResponse(PagedData(List(Waypoint))) {
let query =
list.map(traits, fn(trait) {
#("traits", waypoint_trait_symbol.to_string(trait))
})
let query = case type_ {
option.Some(type_) -> [#("type", waypoint_type.to_string(type_)), ..query]
option.None -> query
}
let request =
api.get_page_with_query(
NoAuth,
"/systems/" <> system_symbol.to_string(system_symbol) <> "/waypoints",
page,
limit,
query,
)
use response <- api.try_send(request)
case response.status {
200 ->
api.parse_paged_data_response(response, decode.list(waypoint.decoder()))
_ -> api.parse_error_response(response)
}
}
pub fn get_waypoint(
system_symbol: SystemSymbol,
waypoint_symbol: WaypointSymbol,
) -> ApiResponse(Waypoint) {
let request =
api.get(
NoAuth,
"/systems/"
<> system_symbol.to_string(system_symbol)
<> "/waypoints/"
<> waypoint_symbol.to_string(waypoint_symbol),
)
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, waypoint.decoder())
_ -> api.parse_error_response(response)
}
}
pub fn get_construction_site(
system_symbol: SystemSymbol,
waypoint_symbol: WaypointSymbol,
) -> ApiResponse(Construction) {
let request =
api.get(
NoAuth,
"/systems/"
<> system_symbol.to_string(system_symbol)
<> "/waypoints/"
<> waypoint_symbol.to_string(waypoint_symbol)
<> "/construction",
)
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, construction.decoder())
_ -> api.parse_error_response(response)
}
}
pub type ConstructionSiteSupplied {
ConstructionSiteSupplied(construction: Construction, cargo: ShipCargo)
}
pub fn supply_construction_site(
token: AgentToken,
system_symbol: SystemSymbol,
waypoint_symbol: WaypointSymbol,
ship_symbol: ShipSymbol,
trade_symbol: TradeSymbol,
units: Int,
) -> ApiResponse(ConstructionSiteSupplied) {
let request =
api.post_json(
AgentAuth(token),
"/systems/"
<> system_symbol.to_string(system_symbol)
<> "/waypoints/"
<> waypoint_symbol.to_string(waypoint_symbol)
<> "/construction/supply",
json.object([
#("shipSymbol", ship_symbol.encode(ship_symbol)),
#("tradeSymbol", trade_symbol.encode(trade_symbol)),
#("units", json.int(units)),
]),
)
use response <- api.try_send(request)
case response.status {
201 ->
api.parse_data_response(response, {
use construction <- decode.field("construction", construction.decoder())
use cargo <- decode.field("cargo", ship_cargo.decoder())
decode.success(ConstructionSiteSupplied(construction:, cargo:))
})
_ -> api.parse_error_response(response)
}
}
pub fn get_market(
system_symbol: SystemSymbol,
waypoint_symbol: WaypointSymbol,
) -> ApiResponse(Market) {
let request =
api.get(
NoAuth,
"/systems/"
<> system_symbol.to_string(system_symbol)
<> "/waypoints/"
<> waypoint_symbol.to_string(waypoint_symbol)
<> "/market",
)
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, market.decoder())
_ -> api.parse_error_response(response)
}
}
pub fn get_jump_gate(
system_symbol: SystemSymbol,
waypoint_symbol: WaypointSymbol,
) -> ApiResponse(JumpGate) {
let request =
api.get(
NoAuth,
"/systems/"
<> system_symbol.to_string(system_symbol)
<> "/waypoints/"
<> waypoint_symbol.to_string(waypoint_symbol)
<> "/jump-gate",
)
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, jump_gate.decoder())
_ -> api.parse_error_response(response)
}
}
pub fn get_shipyard(
system_symbol: SystemSymbol,
waypoint_symbol: WaypointSymbol,
) -> ApiResponse(Shipyard) {
let request =
api.get(
NoAuth,
"/systems/"
<> system_symbol.to_string(system_symbol)
<> "/waypoints/"
<> waypoint_symbol.to_string(waypoint_symbol)
<> "/shipyard",
)
use response <- api.try_send(request)
case response.status {
200 -> api.parse_data_response(response, shipyard.decoder())
_ -> api.parse_error_response(response)
}
}

View file

@ -1,8 +1,8 @@
import birl.{type Time} import birl.{type Time}
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/option.{type Option} import gleam/option.{type Option}
import models/account_id.{type AccountId} import spacetraders_models/account_id.{type AccountId}
import utils/api import spacetraders_sdk/internal/time
pub type Account { pub type Account {
Account( Account(
@ -25,6 +25,6 @@ pub fn decoder() -> Decoder(Account) {
option.None, option.None,
decode.optional(decode.string), decode.optional(decode.string),
) )
use created_at <- decode.field("createdAt", api.time_decoder()) use created_at <- decode.field("createdAt", time.datetime_decoder())
decode.success(Account(id:, email:, token:, created_at:)) decode.success(Account(id:, email:, token:, created_at:))
} }

View file

@ -1,8 +1,8 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/account_id.{type AccountId} import spacetraders_models/account_id.{type AccountId}
import models/agent_symbol.{type AgentSymbol} import spacetraders_models/agent_symbol.{type AgentSymbol}
import models/faction_symbol.{type FactionSymbol} import spacetraders_models/faction_symbol.{type FactionSymbol}
import models/waypoint_symbol.{type WaypointSymbol} import spacetraders_models/waypoint_symbol.{type WaypointSymbol}
pub type Agent { pub type Agent {
Agent( Agent(

View file

@ -2,8 +2,8 @@ import birl.{type Time}
import gleam/dynamic.{type Dynamic} import gleam/dynamic.{type Dynamic}
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/option.{type Option} import gleam/option.{type Option}
import models/agent_event_id.{type AgentEventId} import spacetraders_models/agent_event_id.{type AgentEventId}
import utils/api import spacetraders_sdk/internal/time
pub type AgentEvent { pub type AgentEvent {
AgentEvent( AgentEvent(
@ -24,6 +24,6 @@ pub fn decoder() -> Decoder(AgentEvent) {
option.None, option.None,
decode.optional(decode.dynamic), decode.optional(decode.dynamic),
) )
use created_at <- decode.field("createdAt", api.time_decoder()) use created_at <- decode.field("createdAt", time.datetime_decoder())
decode.success(AgentEvent(id:, type_:, message:, data:, created_at:)) decode.success(AgentEvent(id:, type_:, message:, data:, created_at:))
} }

View file

@ -1,8 +1,8 @@
import birl.{type Time} import birl.{type Time}
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/agent_symbol.{type AgentSymbol} import spacetraders_models/agent_symbol.{type AgentSymbol}
import models/waypoint_symbol.{type WaypointSymbol} import spacetraders_models/waypoint_symbol.{type WaypointSymbol}
import utils/api import spacetraders_sdk/internal/time
pub type Chart { pub type Chart {
Chart( Chart(
@ -18,6 +18,6 @@ pub fn decoder() -> Decoder(Chart) {
waypoint_symbol.decoder(), waypoint_symbol.decoder(),
) )
use submitted_by <- decode.field("submittedBy", agent_symbol.decoder()) use submitted_by <- decode.field("submittedBy", agent_symbol.decoder())
use submitted_on <- decode.field("submittedOn", api.time_decoder()) use submitted_on <- decode.field("submittedOn", time.datetime_decoder())
decode.success(Chart(waypoint_symbol:, submitted_by:, submitted_on:)) decode.success(Chart(waypoint_symbol:, submitted_by:, submitted_on:))
} }

View file

@ -1,8 +1,8 @@
import birl.{type Time} import birl.{type Time}
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/ship_symbol.{type ShipSymbol} import spacetraders_models/ship_symbol.{type ShipSymbol}
import models/waypoint_symbol.{type WaypointSymbol} import spacetraders_models/waypoint_symbol.{type WaypointSymbol}
import utils/api import spacetraders_sdk/internal/time
pub type ChartTransaction { pub type ChartTransaction {
ChartTransaction( ChartTransaction(
@ -20,7 +20,7 @@ pub fn decoder() -> Decoder(ChartTransaction) {
) )
use ship_symbol <- decode.field("shipSymbol", ship_symbol.decoder()) use ship_symbol <- decode.field("shipSymbol", ship_symbol.decoder())
use total_price <- decode.field("totalPrice", decode.int) use total_price <- decode.field("totalPrice", decode.int)
use timestamp <- decode.field("timestamp", api.time_decoder()) use timestamp <- decode.field("timestamp", time.datetime_decoder())
decode.success(ChartTransaction( decode.success(ChartTransaction(
waypoint_symbol:, waypoint_symbol:,
ship_symbol:, ship_symbol:,

View file

@ -1,6 +1,6 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/construction_material.{type ConstructionMaterial} import spacetraders_models/construction_material.{type ConstructionMaterial}
import models/waypoint_symbol.{type WaypointSymbol} import spacetraders_models/waypoint_symbol.{type WaypointSymbol}
pub type Construction { pub type Construction {
Construction( Construction(

View file

@ -1,5 +1,5 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/trade_symbol.{type TradeSymbol} import spacetraders_models/trade_symbol.{type TradeSymbol}
pub type ConstructionMaterial { pub type ConstructionMaterial {
ConstructionMaterial(trade_symbol: TradeSymbol, required: Int, fulfilled: Int) ConstructionMaterial(trade_symbol: TradeSymbol, required: Int, fulfilled: Int)

View file

@ -1,11 +1,11 @@
import birl.{type Time} import birl.{type Time}
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/option.{type Option} import gleam/option.{type Option}
import models/contract_id.{type ContractId} import spacetraders_models/contract_id.{type ContractId}
import models/contract_terms.{type ContractTerms} import spacetraders_models/contract_terms.{type ContractTerms}
import models/contract_type.{type ContractType} import spacetraders_models/contract_type.{type ContractType}
import models/faction_symbol.{type FactionSymbol} import spacetraders_models/faction_symbol.{type FactionSymbol}
import utils/api import spacetraders_sdk/internal/time
pub type Contract { pub type Contract {
Contract( Contract(
@ -29,7 +29,7 @@ pub fn decoder() -> Decoder(Contract) {
use deadline_to_accept <- decode.optional_field( use deadline_to_accept <- decode.optional_field(
"deadlineToAccept", "deadlineToAccept",
option.None, option.None,
decode.optional(api.time_decoder()), decode.optional(time.datetime_decoder()),
) )
decode.success(Contract( decode.success(Contract(
id:, id:,

View file

@ -1,6 +1,6 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/trade_symbol.{type TradeSymbol} import spacetraders_models/trade_symbol.{type TradeSymbol}
import models/waypoint_symbol.{type WaypointSymbol} import spacetraders_models/waypoint_symbol.{type WaypointSymbol}
pub type ContractDeliverGood { pub type ContractDeliverGood {
ContractDeliverGood( ContractDeliverGood(

View file

@ -1,9 +1,9 @@
import birl.{type Time} import birl.{type Time}
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/option.{type Option} import gleam/option.{type Option}
import models/contract_deliver_good.{type ContractDeliverGood} import spacetraders_models/contract_deliver_good.{type ContractDeliverGood}
import models/contract_payment.{type ContractPayment} import spacetraders_models/contract_payment.{type ContractPayment}
import utils/api import spacetraders_sdk/internal/time
pub type ContractTerms { pub type ContractTerms {
ContractTerms( ContractTerms(
@ -14,7 +14,7 @@ pub type ContractTerms {
} }
pub fn decoder() -> Decoder(ContractTerms) { pub fn decoder() -> Decoder(ContractTerms) {
use deadline <- decode.field("deadline", api.time_decoder()) use deadline <- decode.field("deadline", time.datetime_decoder())
use payment <- decode.field("payment", contract_payment.decoder()) use payment <- decode.field("payment", contract_payment.decoder())
use deliver <- decode.optional_field( use deliver <- decode.optional_field(
"deliver", "deliver",

View file

@ -1,8 +1,8 @@
import birl.{type Time} import birl.{type Time}
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/option.{type Option} import gleam/option.{type Option}
import models/ship_symbol.{type ShipSymbol} import spacetraders_models/ship_symbol.{type ShipSymbol}
import utils/api import spacetraders_sdk/internal/time
pub type Cooldown { pub type Cooldown {
Cooldown( Cooldown(
@ -20,7 +20,7 @@ pub fn decoder() -> Decoder(Cooldown) {
use expiration <- decode.optional_field( use expiration <- decode.optional_field(
"expiration", "expiration",
option.None, option.None,
decode.optional(api.time_decoder()), decode.optional(time.datetime_decoder()),
) )
decode.success(Cooldown( decode.success(Cooldown(
ship_symbol:, ship_symbol:,

View file

@ -1,6 +1,6 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/extraction_yield.{type ExtractionYield} import spacetraders_models/extraction_yield.{type ExtractionYield}
import models/ship_symbol.{type ShipSymbol} import spacetraders_models/ship_symbol.{type ShipSymbol}
pub type Extraction { pub type Extraction {
Extraction(ship_symbol: ShipSymbol, yield: ExtractionYield) Extraction(ship_symbol: ShipSymbol, yield: ExtractionYield)

View file

@ -1,5 +1,5 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/trade_symbol.{type TradeSymbol} import spacetraders_models/trade_symbol.{type TradeSymbol}
pub type ExtractionYield { pub type ExtractionYield {
ExtractionYield(symbol: TradeSymbol, units: Int) ExtractionYield(symbol: TradeSymbol, units: Int)

View file

@ -1,8 +1,8 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/option.{type Option} import gleam/option.{type Option}
import models/faction_symbol.{type FactionSymbol} import spacetraders_models/faction_symbol.{type FactionSymbol}
import models/faction_trait.{type FactionTrait} import spacetraders_models/faction_trait.{type FactionTrait}
import models/waypoint_symbol.{type WaypointSymbol} import spacetraders_models/waypoint_symbol.{type WaypointSymbol}
pub type Faction { pub type Faction {
Faction( Faction(

View file

@ -1,5 +1,5 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/faction_trait_symbol.{type FactionTraitSymbol} import spacetraders_models/faction_trait_symbol.{type FactionTraitSymbol}
pub type FactionTrait { pub type FactionTrait {
FactionTrait(symbol: FactionTraitSymbol, name: String, description: String) FactionTrait(symbol: FactionTraitSymbol, name: String, description: String)

View file

@ -1,5 +1,5 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/waypoint_symbol.{type WaypointSymbol} import spacetraders_models/waypoint_symbol.{type WaypointSymbol}
pub type JumpGate { pub type JumpGate {
JumpGate(symbol: WaypointSymbol, connections: List(WaypointSymbol)) JumpGate(symbol: WaypointSymbol, connections: List(WaypointSymbol))

View file

@ -1,9 +1,9 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/option.{type Option} import gleam/option.{type Option}
import models/market_symbol.{type MarketSymbol} import spacetraders_models/market_symbol.{type MarketSymbol}
import models/market_trade_good.{type MarketTradeGood} import spacetraders_models/market_trade_good.{type MarketTradeGood}
import models/market_transaction.{type MarketTransaction} import spacetraders_models/market_transaction.{type MarketTransaction}
import models/trade_good.{type TradeGood} import spacetraders_models/trade_good.{type TradeGood}
pub type Market { pub type Market {
Market( Market(

View file

@ -1,9 +1,9 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/option.{type Option} import gleam/option.{type Option}
import models/activity_level.{type ActivityLevel} import spacetraders_models/activity_level.{type ActivityLevel}
import models/supply_level.{type SupplyLevel} import spacetraders_models/supply_level.{type SupplyLevel}
import models/trade_good_type.{type TradeGoodType} import spacetraders_models/trade_good_type.{type TradeGoodType}
import models/trade_symbol.{type TradeSymbol} import spacetraders_models/trade_symbol.{type TradeSymbol}
pub type MarketTradeGood { pub type MarketTradeGood {
MarketTradeGood( MarketTradeGood(

View file

@ -1,10 +1,10 @@
import birl.{type Time} import birl.{type Time}
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/ship_symbol.{type ShipSymbol} import spacetraders_models/ship_symbol.{type ShipSymbol}
import models/trade_symbol.{type TradeSymbol} import spacetraders_models/trade_symbol.{type TradeSymbol}
import models/transaction_type.{type TransactionType} import spacetraders_models/transaction_type.{type TransactionType}
import models/waypoint_symbol.{type WaypointSymbol} import spacetraders_models/waypoint_symbol.{type WaypointSymbol}
import utils/api import spacetraders_sdk/internal/time
pub type MarketTransaction { pub type MarketTransaction {
MarketTransaction( MarketTransaction(
@ -30,7 +30,7 @@ pub fn decoder() -> Decoder(MarketTransaction) {
use units <- decode.field("units", decode.int) use units <- decode.field("units", decode.int)
use price_per_unit <- decode.field("pricePerUnit", decode.int) use price_per_unit <- decode.field("pricePerUnit", decode.int)
use total_price <- decode.field("totalPrice", decode.int) use total_price <- decode.field("totalPrice", decode.int)
use timestamp <- decode.field("timestamp", api.time_decoder()) use timestamp <- decode.field("timestamp", time.datetime_decoder())
decode.success(MarketTransaction( decode.success(MarketTransaction(
waypoint_symbol:, waypoint_symbol:,
ship_symbol:, ship_symbol:,

View file

@ -1,7 +1,7 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/agent_symbol.{type AgentSymbol} import spacetraders_models/agent_symbol.{type AgentSymbol}
import models/faction_symbol.{type FactionSymbol} import spacetraders_models/faction_symbol.{type FactionSymbol}
import models/waypoint_symbol.{type WaypointSymbol} import spacetraders_models/waypoint_symbol.{type WaypointSymbol}
pub type PublicAgent { pub type PublicAgent {
PublicAgent( PublicAgent(

View file

@ -1,5 +1,5 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/trade_symbol.{type TradeSymbol} import spacetraders_models/trade_symbol.{type TradeSymbol}
pub type RefinementYield { pub type RefinementYield {
RefinementYield(trade_symbol: TradeSymbol, units: Int) RefinementYield(trade_symbol: TradeSymbol, units: Int)

View file

@ -1,8 +1,8 @@
import birl.{type Time} import birl.{type Time}
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/ship_symbol.{type ShipSymbol} import spacetraders_models/ship_symbol.{type ShipSymbol}
import models/waypoint_symbol.{type WaypointSymbol} import spacetraders_models/waypoint_symbol.{type WaypointSymbol}
import utils/api import spacetraders_sdk/internal/time
pub type RepairTransaction { pub type RepairTransaction {
RepairTransaction( RepairTransaction(
@ -20,7 +20,7 @@ pub fn decoder() -> Decoder(RepairTransaction) {
) )
use ship_symbol <- decode.field("shipSymbol", ship_symbol.decoder()) use ship_symbol <- decode.field("shipSymbol", ship_symbol.decoder())
use total_price <- decode.field("totalPrice", decode.int) use total_price <- decode.field("totalPrice", decode.int)
use timestamp <- decode.field("timestamp", api.time_decoder()) use timestamp <- decode.field("timestamp", time.datetime_decoder())
decode.success(RepairTransaction( decode.success(RepairTransaction(
waypoint_symbol:, waypoint_symbol:,
ship_symbol:, ship_symbol:,

View file

@ -1,12 +1,12 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/option.{type Option} import gleam/option.{type Option}
import models/scanned_ship_engine.{type ScannedShipEngine} import spacetraders_models/scanned_ship_engine.{type ScannedShipEngine}
import models/scanned_ship_frame.{type ScannedShipFrame} import spacetraders_models/scanned_ship_frame.{type ScannedShipFrame}
import models/scanned_ship_mount.{type ScannedShipMount} import spacetraders_models/scanned_ship_mount.{type ScannedShipMount}
import models/scanned_ship_reactor.{type ScannedShipReactor} import spacetraders_models/scanned_ship_reactor.{type ScannedShipReactor}
import models/ship_nav.{type ShipNav} import spacetraders_models/ship_nav.{type ShipNav}
import models/ship_registration.{type ShipRegistration} import spacetraders_models/ship_registration.{type ShipRegistration}
import models/ship_symbol.{type ShipSymbol} import spacetraders_models/ship_symbol.{type ShipSymbol}
pub type ScannedShip { pub type ScannedShip {
ScannedShip( ScannedShip(

View file

@ -1,5 +1,5 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/engine_symbol.{type EngineSymbol} import spacetraders_models/engine_symbol.{type EngineSymbol}
pub type ScannedShipEngine { pub type ScannedShipEngine {
ScannedShipEngine(symbol: EngineSymbol) ScannedShipEngine(symbol: EngineSymbol)

View file

@ -1,5 +1,5 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/frame_symbol.{type FrameSymbol} import spacetraders_models/frame_symbol.{type FrameSymbol}
pub type ScannedShipFrame { pub type ScannedShipFrame {
ScannedShipFrame(symbol: FrameSymbol) ScannedShipFrame(symbol: FrameSymbol)

View file

@ -1,5 +1,5 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/mount_symbol.{type MountSymbol} import spacetraders_models/mount_symbol.{type MountSymbol}
pub type ScannedShipMount { pub type ScannedShipMount {
ScannedShipMount(symbol: MountSymbol) ScannedShipMount(symbol: MountSymbol)

View file

@ -1,5 +1,5 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/reactor_symbol.{type ReactorSymbol} import spacetraders_models/reactor_symbol.{type ReactorSymbol}
pub type ScannedShipReactor { pub type ScannedShipReactor {
ScannedShipReactor(symbol: ReactorSymbol) ScannedShipReactor(symbol: ReactorSymbol)

View file

@ -1,7 +1,7 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/sector_symbol.{type SectorSymbol} import spacetraders_models/sector_symbol.{type SectorSymbol}
import models/system_symbol.{type SystemSymbol} import spacetraders_models/system_symbol.{type SystemSymbol}
import models/system_type.{type SystemType} import spacetraders_models/system_type.{type SystemType}
pub type ScannedSystem { pub type ScannedSystem {
ScannedSystem( ScannedSystem(

View file

@ -1,12 +1,12 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/option.{type Option} import gleam/option.{type Option}
import models/chart.{type Chart} import spacetraders_models/chart.{type Chart}
import models/system_symbol.{type SystemSymbol} import spacetraders_models/system_symbol.{type SystemSymbol}
import models/waypoint_faction.{type WaypointFaction} import spacetraders_models/waypoint_faction.{type WaypointFaction}
import models/waypoint_orbital.{type WaypointOrbital} import spacetraders_models/waypoint_orbital.{type WaypointOrbital}
import models/waypoint_symbol.{type WaypointSymbol} import spacetraders_models/waypoint_symbol.{type WaypointSymbol}
import models/waypoint_trait.{type WaypointTrait} import spacetraders_models/waypoint_trait.{type WaypointTrait}
import models/waypoint_type.{type WaypointType} import spacetraders_models/waypoint_type.{type WaypointType}
pub type ScannedWaypoint { pub type ScannedWaypoint {
ScannedWaypoint( ScannedWaypoint(

View file

@ -1,8 +1,8 @@
import birl.{type Time} import birl.{type Time}
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/ship_symbol.{type ShipSymbol} import spacetraders_models/ship_symbol.{type ShipSymbol}
import models/waypoint_symbol.{type WaypointSymbol} import spacetraders_models/waypoint_symbol.{type WaypointSymbol}
import utils/api import spacetraders_sdk/internal/time
pub type ScrapTransaction { pub type ScrapTransaction {
ScrapTransaction( ScrapTransaction(
@ -20,7 +20,7 @@ pub fn decoder() -> Decoder(ScrapTransaction) {
) )
use ship_symbol <- decode.field("shipSymbol", ship_symbol.decoder()) use ship_symbol <- decode.field("shipSymbol", ship_symbol.decoder())
use total_price <- decode.field("totalPrice", decode.int) use total_price <- decode.field("totalPrice", decode.int)
use timestamp <- decode.field("timestamp", api.time_decoder()) use timestamp <- decode.field("timestamp", time.datetime_decoder())
decode.success(ScrapTransaction( decode.success(ScrapTransaction(
waypoint_symbol:, waypoint_symbol:,
ship_symbol:, ship_symbol:,

View file

@ -1,16 +1,16 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/cooldown.{type Cooldown} import spacetraders_models/cooldown.{type Cooldown}
import models/ship_cargo.{type ShipCargo} import spacetraders_models/ship_cargo.{type ShipCargo}
import models/ship_crew.{type ShipCrew} import spacetraders_models/ship_crew.{type ShipCrew}
import models/ship_engine.{type ShipEngine} import spacetraders_models/ship_engine.{type ShipEngine}
import models/ship_frame.{type ShipFrame} import spacetraders_models/ship_frame.{type ShipFrame}
import models/ship_fuel.{type ShipFuel} import spacetraders_models/ship_fuel.{type ShipFuel}
import models/ship_module.{type ShipModule} import spacetraders_models/ship_module.{type ShipModule}
import models/ship_mount.{type ShipMount} import spacetraders_models/ship_mount.{type ShipMount}
import models/ship_nav.{type ShipNav} import spacetraders_models/ship_nav.{type ShipNav}
import models/ship_reactor.{type ShipReactor} import spacetraders_models/ship_reactor.{type ShipReactor}
import models/ship_registration.{type ShipRegistration} import spacetraders_models/ship_registration.{type ShipRegistration}
import models/ship_symbol.{type ShipSymbol} import spacetraders_models/ship_symbol.{type ShipSymbol}
pub type Ship { pub type Ship {
Ship( Ship(

View file

@ -1,5 +1,5 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/ship_cargo_item.{type ShipCargoItem} import spacetraders_models/ship_cargo_item.{type ShipCargoItem}
pub type ShipCargo { pub type ShipCargo {
ShipCargo(capacity: Int, units: Int, inventory: List(ShipCargoItem)) ShipCargo(capacity: Int, units: Int, inventory: List(ShipCargoItem))

View file

@ -1,5 +1,5 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/trade_symbol.{type TradeSymbol} import spacetraders_models/trade_symbol.{type TradeSymbol}
pub type ShipCargoItem { pub type ShipCargoItem {
ShipCargoItem( ShipCargoItem(

View file

@ -1,4 +1,5 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/int
import gleam/json.{type Json} import gleam/json.{type Json}
pub opaque type ShipComponentCondition { pub opaque type ShipComponentCondition {
@ -17,7 +18,11 @@ pub fn parse(value: Float) -> Result(ShipComponentCondition, Nil) {
} }
pub fn decoder() -> Decoder(ShipComponentCondition) { pub fn decoder() -> Decoder(ShipComponentCondition) {
use value <- decode.then(decode.float) use value <- decode.then(
decode.one_of(decode.float, [
decode.then(decode.int, fn(i) { decode.success(int.to_float(i)) }),
]),
)
case parse(value) { case parse(value) {
Ok(ship_component_condition) -> decode.success(ship_component_condition) Ok(ship_component_condition) -> decode.success(ship_component_condition)
Error(Nil) -> Error(Nil) ->

View file

@ -1,4 +1,5 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/int
import gleam/json.{type Json} import gleam/json.{type Json}
pub opaque type ShipComponentIntegrity { pub opaque type ShipComponentIntegrity {
@ -17,7 +18,11 @@ pub fn parse(value: Float) -> Result(ShipComponentIntegrity, Nil) {
} }
pub fn decoder() -> Decoder(ShipComponentIntegrity) { pub fn decoder() -> Decoder(ShipComponentIntegrity) {
use value <- decode.then(decode.float) use value <- decode.then(
decode.one_of(decode.float, [
decode.then(decode.int, fn(i) { decode.success(int.to_float(i)) }),
]),
)
case parse(value) { case parse(value) {
Ok(ship_component_integrity) -> decode.success(ship_component_integrity) Ok(ship_component_integrity) -> decode.success(ship_component_integrity)
Error(Nil) -> Error(Nil) ->

View file

@ -1,6 +1,8 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/ship_component.{type ShipComponent} import spacetraders_models/ship_component.{type ShipComponent}
import models/ship_condition_event_symbol.{type ShipConditionEventSymbol} import spacetraders_models/ship_condition_event_symbol.{
type ShipConditionEventSymbol,
}
pub type ShipConditionEvent { pub type ShipConditionEvent {
ShipConditionEvent( ShipConditionEvent(

View file

@ -1,5 +1,5 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/crew_rotation.{type CrewRotation} import spacetraders_models/crew_rotation.{type CrewRotation}
pub type ShipCrew { pub type ShipCrew {
ShipCrew( ShipCrew(

View file

@ -1,9 +1,9 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/engine_symbol.{type EngineSymbol} import spacetraders_models/engine_symbol.{type EngineSymbol}
import models/ship_component_condition.{type ShipComponentCondition} import spacetraders_models/ship_component_condition.{type ShipComponentCondition}
import models/ship_component_integrity.{type ShipComponentIntegrity} import spacetraders_models/ship_component_integrity.{type ShipComponentIntegrity}
import models/ship_component_quality.{type ShipComponentQuality} import spacetraders_models/ship_component_quality.{type ShipComponentQuality}
import models/ship_requirements.{type ShipRequirements} import spacetraders_models/ship_requirements.{type ShipRequirements}
pub type ShipEngine { pub type ShipEngine {
ShipEngine( ShipEngine(

View file

@ -1,9 +1,9 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/frame_symbol.{type FrameSymbol} import spacetraders_models/frame_symbol.{type FrameSymbol}
import models/ship_component_condition.{type ShipComponentCondition} import spacetraders_models/ship_component_condition.{type ShipComponentCondition}
import models/ship_component_integrity.{type ShipComponentIntegrity} import spacetraders_models/ship_component_integrity.{type ShipComponentIntegrity}
import models/ship_component_quality.{type ShipComponentQuality} import spacetraders_models/ship_component_quality.{type ShipComponentQuality}
import models/ship_requirements.{type ShipRequirements} import spacetraders_models/ship_requirements.{type ShipRequirements}
pub type ShipFrame { pub type ShipFrame {
ShipFrame( ShipFrame(

View file

@ -1,6 +1,6 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/option.{type Option} import gleam/option.{type Option}
import models/ship_fuel_consumed.{type ShipFuelConsumed} import spacetraders_models/ship_fuel_consumed.{type ShipFuelConsumed}
pub type ShipFuel { pub type ShipFuel {
ShipFuel(current: Int, capacity: Int, consumed: Option(ShipFuelConsumed)) ShipFuel(current: Int, capacity: Int, consumed: Option(ShipFuelConsumed))

View file

@ -1,6 +1,6 @@
import birl.{type Time} import birl.{type Time}
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import utils/api import spacetraders_sdk/internal/time
pub type ShipFuelConsumed { pub type ShipFuelConsumed {
ShipFuelConsumed(amount: Int, timestamp: Time) ShipFuelConsumed(amount: Int, timestamp: Time)
@ -8,6 +8,6 @@ pub type ShipFuelConsumed {
pub fn decoder() -> Decoder(ShipFuelConsumed) { pub fn decoder() -> Decoder(ShipFuelConsumed) {
use amount <- decode.field("amount", decode.int) use amount <- decode.field("amount", decode.int)
use timestamp <- decode.field("timestamp", api.time_decoder()) use timestamp <- decode.field("timestamp", time.datetime_decoder())
decode.success(ShipFuelConsumed(amount:, timestamp:)) decode.success(ShipFuelConsumed(amount:, timestamp:))
} }

View file

@ -1,9 +1,9 @@
import birl.{type Time} import birl.{type Time}
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/ship_symbol.{type ShipSymbol} import spacetraders_models/ship_symbol.{type ShipSymbol}
import models/trade_symbol.{type TradeSymbol} import spacetraders_models/trade_symbol.{type TradeSymbol}
import models/waypoint_symbol.{type WaypointSymbol} import spacetraders_models/waypoint_symbol.{type WaypointSymbol}
import utils/api import spacetraders_sdk/internal/time
pub type ShipModificationTransaction { pub type ShipModificationTransaction {
ShipModificationTransaction( ShipModificationTransaction(
@ -23,7 +23,7 @@ pub fn decoder() -> Decoder(ShipModificationTransaction) {
use ship_symbol <- decode.field("shipSymbol", ship_symbol.decoder()) use ship_symbol <- decode.field("shipSymbol", ship_symbol.decoder())
use trade_symbol <- decode.field("tradeSymbol", trade_symbol.decoder()) use trade_symbol <- decode.field("tradeSymbol", trade_symbol.decoder())
use total_price <- decode.field("totalPrice", decode.int) use total_price <- decode.field("totalPrice", decode.int)
use timestamp <- decode.field("timestamp", api.time_decoder()) use timestamp <- decode.field("timestamp", time.datetime_decoder())
decode.success(ShipModificationTransaction( decode.success(ShipModificationTransaction(
waypoint_symbol:, waypoint_symbol:,
ship_symbol:, ship_symbol:,

View file

@ -1,7 +1,7 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/option.{type Option} import gleam/option.{type Option}
import models/module_symbol.{type ModuleSymbol} import spacetraders_models/module_symbol.{type ModuleSymbol}
import models/ship_requirements.{type ShipRequirements} import spacetraders_models/ship_requirements.{type ShipRequirements}
pub type ShipModule { pub type ShipModule {
ShipModule( ShipModule(

View file

@ -1,8 +1,8 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/option.{type Option} import gleam/option.{type Option}
import models/mount_deposit.{type MountDeposit} import spacetraders_models/mount_deposit.{type MountDeposit}
import models/mount_symbol.{type MountSymbol} import spacetraders_models/mount_symbol.{type MountSymbol}
import models/ship_requirements.{type ShipRequirements} import spacetraders_models/ship_requirements.{type ShipRequirements}
pub type ShipMount { pub type ShipMount {
ShipMount( ShipMount(

View file

@ -1,9 +1,9 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/ship_nav_flight_mode.{type ShipNavFlightMode} import spacetraders_models/ship_nav_flight_mode.{type ShipNavFlightMode}
import models/ship_nav_route.{type ShipNavRoute} import spacetraders_models/ship_nav_route.{type ShipNavRoute}
import models/ship_nav_status.{type ShipNavStatus} import spacetraders_models/ship_nav_status.{type ShipNavStatus}
import models/system_symbol.{type SystemSymbol} import spacetraders_models/system_symbol.{type SystemSymbol}
import models/waypoint_symbol.{type WaypointSymbol} import spacetraders_models/waypoint_symbol.{type WaypointSymbol}
pub type ShipNav { pub type ShipNav {
ShipNav( ShipNav(

View file

@ -1,7 +1,7 @@
import birl.{type Time} import birl.{type Time}
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/ship_nav_route_waypoint.{type ShipNavRouteWaypoint} import spacetraders_models/ship_nav_route_waypoint.{type ShipNavRouteWaypoint}
import utils/api import spacetraders_sdk/internal/time
pub type ShipNavRoute { pub type ShipNavRoute {
ShipNavRoute( ShipNavRoute(
@ -18,7 +18,7 @@ pub fn decoder() -> Decoder(ShipNavRoute) {
ship_nav_route_waypoint.decoder(), ship_nav_route_waypoint.decoder(),
) )
use origin <- decode.field("origin", ship_nav_route_waypoint.decoder()) use origin <- decode.field("origin", ship_nav_route_waypoint.decoder())
use departure_time <- decode.field("departureTime", api.time_decoder()) use departure_time <- decode.field("departureTime", time.datetime_decoder())
use arrival <- decode.field("arrival", api.time_decoder()) use arrival <- decode.field("arrival", time.datetime_decoder())
decode.success(ShipNavRoute(destination:, origin:, departure_time:, arrival:)) decode.success(ShipNavRoute(destination:, origin:, departure_time:, arrival:))
} }

View file

@ -1,7 +1,7 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/system_symbol.{type SystemSymbol} import spacetraders_models/system_symbol.{type SystemSymbol}
import models/waypoint_symbol.{type WaypointSymbol} import spacetraders_models/waypoint_symbol.{type WaypointSymbol}
import models/waypoint_type.{type WaypointType} import spacetraders_models/waypoint_type.{type WaypointType}
pub type ShipNavRouteWaypoint { pub type ShipNavRouteWaypoint {
ShipNavRouteWaypoint( ShipNavRouteWaypoint(

View file

@ -1,9 +1,9 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/reactor_symbol.{type ReactorSymbol} import spacetraders_models/reactor_symbol.{type ReactorSymbol}
import models/ship_component_condition.{type ShipComponentCondition} import spacetraders_models/ship_component_condition.{type ShipComponentCondition}
import models/ship_component_integrity.{type ShipComponentIntegrity} import spacetraders_models/ship_component_integrity.{type ShipComponentIntegrity}
import models/ship_component_quality.{type ShipComponentQuality} import spacetraders_models/ship_component_quality.{type ShipComponentQuality}
import models/ship_requirements.{type ShipRequirements} import spacetraders_models/ship_requirements.{type ShipRequirements}
pub type ShipReactor { pub type ShipReactor {
ShipReactor( ShipReactor(

View file

@ -1,6 +1,6 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/faction_symbol.{type FactionSymbol} import spacetraders_models/faction_symbol.{type FactionSymbol}
import models/ship_role.{type ShipRole} import spacetraders_models/ship_role.{type ShipRole}
pub type ShipRegistration { pub type ShipRegistration {
ShipRegistration(name: String, faction_symbol: FactionSymbol, role: ShipRole) ShipRegistration(name: String, faction_symbol: FactionSymbol, role: ShipRole)

View file

@ -1,9 +1,9 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/option.{type Option} import gleam/option.{type Option}
import models/ship_type.{type ShipType} import spacetraders_models/ship_type.{type ShipType}
import models/shipyard_ship.{type ShipyardShip} import spacetraders_models/shipyard_ship.{type ShipyardShip}
import models/shipyard_symbol.{type ShipyardSymbol} import spacetraders_models/shipyard_symbol.{type ShipyardSymbol}
import models/shipyard_transaction.{type ShipyardTransaction} import spacetraders_models/shipyard_transaction.{type ShipyardTransaction}
pub type Shipyard { pub type Shipyard {
Shipyard( Shipyard(

View file

@ -1,14 +1,14 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/option.{type Option} import gleam/option.{type Option}
import models/activity_level.{type ActivityLevel} import spacetraders_models/activity_level.{type ActivityLevel}
import models/ship_engine.{type ShipEngine} import spacetraders_models/ship_engine.{type ShipEngine}
import models/ship_frame.{type ShipFrame} import spacetraders_models/ship_frame.{type ShipFrame}
import models/ship_module.{type ShipModule} import spacetraders_models/ship_module.{type ShipModule}
import models/ship_mount.{type ShipMount} import spacetraders_models/ship_mount.{type ShipMount}
import models/ship_reactor.{type ShipReactor} import spacetraders_models/ship_reactor.{type ShipReactor}
import models/ship_type.{type ShipType} import spacetraders_models/ship_type.{type ShipType}
import models/shipyard_ship_crew.{type ShipyardShipCrew} import spacetraders_models/shipyard_ship_crew.{type ShipyardShipCrew}
import models/supply_level.{type SupplyLevel} import spacetraders_models/supply_level.{type SupplyLevel}
pub type ShipyardShip { pub type ShipyardShip {
ShipyardShip( ShipyardShip(

View file

@ -1,9 +1,9 @@
import birl.{type Time} import birl.{type Time}
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/agent_symbol.{type AgentSymbol} import spacetraders_models/agent_symbol.{type AgentSymbol}
import models/ship_type.{type ShipType} import spacetraders_models/ship_type.{type ShipType}
import models/waypoint_symbol.{type WaypointSymbol} import spacetraders_models/waypoint_symbol.{type WaypointSymbol}
import utils/api import spacetraders_sdk/internal/time
pub type ShipyardTransaction { pub type ShipyardTransaction {
ShipyardTransaction( ShipyardTransaction(
@ -23,7 +23,7 @@ pub fn decoder() -> Decoder(ShipyardTransaction) {
use ship_type <- decode.field("shipType", ship_type.decoder()) use ship_type <- decode.field("shipType", ship_type.decoder())
use price <- decode.field("price", decode.int) use price <- decode.field("price", decode.int)
use agent_symbol <- decode.field("agentSymbol", agent_symbol.decoder()) use agent_symbol <- decode.field("agentSymbol", agent_symbol.decoder())
use timestamp <- decode.field("timestamp", api.time_decoder()) use timestamp <- decode.field("timestamp", time.datetime_decoder())
decode.success(ShipyardTransaction( decode.success(ShipyardTransaction(
waypoint_symbol:, waypoint_symbol:,
ship_type:, ship_type:,

View file

@ -1,6 +1,6 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/ship_symbol.{type ShipSymbol} import spacetraders_models/ship_symbol.{type ShipSymbol}
import models/siphon_yield.{type SiphonYield} import spacetraders_models/siphon_yield.{type SiphonYield}
pub type Siphon { pub type Siphon {
Siphon(ship_symbol: ShipSymbol, yield: SiphonYield) Siphon(ship_symbol: ShipSymbol, yield: SiphonYield)

View file

@ -1,5 +1,5 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import models/trade_symbol.{type TradeSymbol} import spacetraders_models/trade_symbol.{type TradeSymbol}
pub type SiphonYield { pub type SiphonYield {
SiphonYield(symbol: TradeSymbol, units: Int) SiphonYield(symbol: TradeSymbol, units: Int)

View file

@ -1,11 +1,11 @@
import birl.{type Time} import birl.{type Time}
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/json.{type Json} import gleam/json.{type Json}
import models/survey_deposit.{type SurveyDeposit} import spacetraders_models/survey_deposit.{type SurveyDeposit}
import models/survey_signature.{type SurveySignature} import spacetraders_models/survey_signature.{type SurveySignature}
import models/survey_size.{type SurveySize} import spacetraders_models/survey_size.{type SurveySize}
import models/waypoint_symbol.{type WaypointSymbol} import spacetraders_models/waypoint_symbol.{type WaypointSymbol}
import utils/api import spacetraders_sdk/internal/time
pub type Survey { pub type Survey {
Survey( Survey(
@ -24,7 +24,7 @@ pub fn decoder() -> Decoder(Survey) {
"deposits", "deposits",
decode.list(survey_deposit.decoder()), decode.list(survey_deposit.decoder()),
) )
use expiration <- decode.field("expiration", api.time_decoder()) use expiration <- decode.field("expiration", time.datetime_decoder())
use size <- decode.field("size", survey_size.decoder()) use size <- decode.field("size", survey_size.decoder())
decode.success(Survey(signature:, symbol:, deposits:, expiration:, size:)) decode.success(Survey(signature:, symbol:, deposits:, expiration:, size:))
} }

View file

@ -1,6 +1,6 @@
import gleam/dynamic/decode.{type Decoder} import gleam/dynamic/decode.{type Decoder}
import gleam/json.{type Json} import gleam/json.{type Json}
import models/trade_symbol.{type TradeSymbol} import spacetraders_models/trade_symbol.{type TradeSymbol}
pub type SurveyDeposit { pub type SurveyDeposit {
SurveyDeposit(symbol: TradeSymbol) SurveyDeposit(symbol: TradeSymbol)

Some files were not shown because too many files have changed in this diff Show more