import { operation, buildingBase, buildingCommonMethods, buildingView, requestBodySchema, response200, response500, security, statusSchema, tags, } from '../../chunks.ts'; const base = buildingBase('Trade'); const buildingIdRequestBody = requestBodySchema({ type: 'object', required: ['building_id'], properties: { building_id: { type: 'integer', description: 'The unique id of the building.' } }, }); // A tradeable item, per the Trade docs — resources (quantity-based), glyphs, plans, prisoners, or ships. const tradeableItemSchema = { type: 'object', properties: { type: { type: 'string', enum: ['glyph', 'plan', 'prisoner', 'ship'] }, // Resources are passed as a bare {resource_name: quantity} pair instead of a typed item. name: { type: 'string' }, quantity: { type: 'integer' }, plan_type: { type: 'string' }, level: { type: 'integer' }, extra_build_level: { type: 'integer' }, prisoner_id: { type: 'integer' }, ship_id: { type: 'integer' }, }, }; // A posted-trade row as returned by view_market / view_my_market. Matches the transporter / // mercenaries guild market row shape: `date_offered` and a pre-rendered `offer` string list // (e.g. "10,000 apple"), not the typed tradeableItemSchema used when *posting* a trade. const marketEntrySchema = { type: 'object', required: ['id', 'date_offered', 'ask', 'offer'], properties: { id: { type: 'integer' }, date_offered: { type: 'string' }, ask: { type: 'number' }, offer: { type: 'array', items: { type: 'string' }, description: 'Human-readable item descriptions, e.g. "10,000 apple".', }, empire: { type: 'object', properties: { id: { type: 'integer' }, name: { type: 'string' } } }, body: { type: 'object', properties: { id: { type: 'integer' }, name: { type: 'string' } } }, transmitter_delivery_time: { type: 'integer' }, }, }; export const trade = { ...buildingCommonMethods(base), ...buildingView(base), [`${base}/add_to_market`]: { post: { ...tags(base), ...security(), ...operation('Add to market.', 'Posts a trade offer for other players to accept.'), ...requestBodySchema({ type: 'object', required: ['building_id', 'offer', 'ask'], properties: { building_id: { type: 'integer', description: 'The unique id of the building.' }, offer: { type: 'array', items: tradeableItemSchema, description: 'The items to trade (resources, glyphs, plans, prisoners, or ships).', }, ask: { type: 'number', minimum: 0.1, maximum: 100, description: 'Essentia amount requested.', }, options: { type: 'object', description: 'Optional trade options.', properties: { ship_id: { type: 'integer', description: 'The unique id of the ship.' } }, }, }, }), responses: { ...response200('Posts a trade offer for other players to accept.', { type: 'object', required: ['trade_id', 'status'], properties: { trade_id: { type: 'integer' }, status: statusSchema() }, }), ...response500(), }, }, }, [`${base}/view_market`]: { post: { ...tags(base), ...security(), ...operation('View market.', "Lists other players' posted trades."), ...requestBodySchema({ type: 'object', required: ['building_id'], properties: { building_id: { type: 'integer', description: 'The unique id of the building.' }, page_number: { type: 'integer', description: 'Defaults to 1. 25 items per page.' }, filter: { type: 'string', enum: ['food', 'ore', 'water', 'waste', 'energy', 'glyph', 'prisoner', 'ship', 'plan'], description: 'Optional. Narrows the list to trades offering one kind of object.', }, }, }), responses: { ...response200("Lists other players' posted trades.", { type: 'object', required: ['trades', 'trade_count', 'status'], properties: { trades: { type: 'array', items: marketEntrySchema }, trade_count: { type: 'integer', description: 'Total matching trades across all pages (the pager is sized from this).', }, status: statusSchema(), }, }), ...response500(), }, }, }, [`${base}/view_my_market`]: { post: { ...tags(base), ...security(), ...operation('View my market.', 'Lists trades posted by this empire.'), ...requestBodySchema({ type: 'object', required: ['building_id'], properties: { building_id: { type: 'integer', description: 'The unique id of the building.' }, page_number: { type: 'integer', description: 'Defaults to 1.' }, }, }), responses: { ...response200('Lists trades posted by this empire.', { type: 'object', required: ['trades', 'trade_count', 'status'], properties: { trades: { type: 'array', items: marketEntrySchema }, trade_count: { type: 'integer', description: 'Total trades posted by this empire across all pages.', }, status: statusSchema(), }, }), ...response500(), }, }, }, [`${base}/accept_from_market`]: { post: { ...tags(base), ...security(), ...operation( 'Accept from market.', "Accepts another player's trade. Throws 1016 if the trade is no longer valid." ), ...requestBodySchema({ type: 'object', required: ['building_id', 'trade_id'], properties: { building_id: { type: 'integer', description: 'The unique id of the building.' }, trade_id: { type: 'integer', description: 'The unique id of the trade.' }, }, }), responses: { ...response200( "Accepts another player's trade. Throws 1016 if the trade is no longer valid.", { type: 'object', required: ['status'], properties: { status: statusSchema() } } ), ...response500(), }, }, }, [`${base}/withdraw_from_market`]: { post: { ...tags(base), ...security(), ...operation( 'Withdraw from market.', 'Cancels a trade this empire posted and retrieves the offered items.' ), ...requestBodySchema({ type: 'object', required: ['building_id', 'trade_id'], properties: { building_id: { type: 'integer', description: 'The unique id of the building.' }, trade_id: { type: 'integer', description: 'The unique id of the trade.' }, }, }), responses: { ...response200('Cancels a trade this empire posted and retrieves the offered items.', { type: 'object', required: ['status'], properties: { status: statusSchema() }, }), ...response500(), }, }, }, [`${base}/push_items`]: { post: { ...tags(base), ...security(), ...operation('Push items.', 'Transfers resources/items between planets this empire owns.'), ...requestBodySchema({ type: 'object', required: ['building_id', 'target_id', 'items'], properties: { building_id: { type: 'integer', description: 'The unique id of the building.' }, target_id: { type: 'integer', description: 'The destination planet, which must be owned by this empire.', }, items: { type: 'array', items: tradeableItemSchema, description: 'The items to ship to the target planet (resources, glyphs, plans, prisoners, or ships).', }, options: { type: 'object', description: 'Optional push options.', properties: { ship_id: { type: 'integer', description: 'The unique id of the ship.' }, stay: { type: 'integer', enum: [1, 0], description: 'Leave the ship at the destination (requires a dock there).', }, }, }, }, }), responses: { ...response200('Transfers resources/items between planets this empire owns.', { type: 'object', required: ['status', 'ship'], properties: { ship: { type: 'object', properties: { name: { type: 'string' }, type: { type: 'string' }, date_arrives: { type: 'string' }, }, }, status: statusSchema(), }, }), ...response500(), }, }, }, [`${base}/get_stored_resources`]: { post: { ...tags(base), ...security(), ...operation( 'Get stored resources.', 'Lists resources available in storage, by type and quantity.' ), ...buildingIdRequestBody, responses: { ...response200('Lists resources available in storage, by type and quantity.', { type: 'object', required: ['resources', 'status'], properties: { resources: { type: 'object', additionalProperties: { type: 'integer' } }, status: statusSchema(), }, }), ...response500(), }, }, }, [`${base}/get_trade_ships`]: { post: { ...tags(base), ...security(), ...operation( 'Get trade ships.', 'Lists cargo vessels available for trading, with estimated travel time.' ), ...requestBodySchema({ type: 'object', required: ['building_id'], properties: { building_id: { type: 'integer', description: 'The unique id of the building.' }, target_body_id: { type: 'integer', description: 'The unique id of the body being shipped to. If given, travel time is estimated.', }, }, }), responses: { ...response200('Lists cargo vessels available for trading, with estimated travel time.', { type: 'object', required: ['ships', 'status'], properties: { ships: { type: 'array', items: { type: 'object', properties: { id: { type: 'integer' }, name: { type: 'string' }, type: { type: 'string' }, hold_size: { type: 'integer' }, speed: { type: 'integer' }, estimated_travel_time: { type: 'integer' }, }, }, }, status: statusSchema(), }, }), ...response500(), }, }, }, [`${base}/get_ships`]: { post: { ...tags(base), ...security(), ...operation('Get ships.', 'Lists tradeable ships, with hold size and speed.'), ...buildingIdRequestBody, responses: { ...response200('Lists tradeable ships, with hold size and speed.', { type: 'object', required: ['ships', 'status'], properties: { ships: { type: 'array', items: { type: 'object', properties: { id: { type: 'integer' }, name: { type: 'string' }, type: { type: 'string' }, hold_size: { type: 'integer' }, speed: { type: 'integer' }, }, }, }, status: statusSchema(), }, }), ...response500(), }, }, }, [`${base}/get_waste_ships`]: { post: { ...tags(base), ...security(), ...operation('Get waste ships.', 'Lists scow vessels available for waste transport.'), ...buildingIdRequestBody, responses: { ...response200('Lists scow vessels available for waste transport.', { type: 'object', required: ['ships', 'status'], properties: { ships: { type: 'array', items: { type: 'object', properties: { id: { type: 'integer' }, name: { type: 'string' }, task: { type: 'string' }, speed: { type: 'integer' }, hold_size: { type: 'integer' }, }, }, }, status: statusSchema(), }, }), ...response500(), }, }, }, [`${base}/get_supply_ships`]: { post: { ...tags(base), ...security(), ...operation('Get supply ships.', 'Lists hulk vessels available for resource supply chains.'), ...buildingIdRequestBody, responses: { ...response200('Lists hulk vessels available for resource supply chains.', { type: 'object', required: ['ships', 'status'], properties: { ships: { type: 'array', items: { type: 'object', properties: { id: { type: 'integer' }, name: { type: 'string' }, task: { type: 'string' }, speed: { type: 'integer' }, hold_size: { type: 'integer' }, }, }, }, status: statusSchema(), }, }), ...response500(), }, }, }, [`${base}/view_supply_chains`]: { post: { ...tags(base), ...security(), ...operation('View supply chains.', "Lists this ministry's active resource supply chains."), ...buildingIdRequestBody, responses: { ...response200("Lists this ministry's active resource supply chains.", { type: 'object', required: ['supply_chains', 'max_supply_chains', 'status'], properties: { supply_chains: { type: 'array', items: { type: 'object', properties: { id: { type: 'integer' }, resource_type: { type: 'string' }, resource_hour: { type: 'integer' }, percent_transferred: { type: 'number' }, stalled: { type: 'integer', enum: [1, 0] }, }, }, }, max_supply_chains: { type: 'integer' }, status: statusSchema(), }, }), ...response500(), }, }, }, [`${base}/create_supply_chain`]: { post: { ...tags(base), ...security(), ...operation( 'Create supply chain.', 'Establishes a new resource supply chain to a target planet.' ), ...requestBodySchema({ type: 'object', required: ['building_id', 'target_id', 'resource_type', 'resource_hour'], properties: { building_id: { type: 'integer', description: 'The unique id of the building.' }, target_id: { type: 'integer', description: 'The unique id of a planet you control to send the items to.', }, resource_type: { type: 'string', description: 'The resource to transfer, e.g. "water", "gold", "apple".', }, resource_hour: { type: 'integer', description: 'The amount of the resource to transfer each hour. Set to 0 to suspend the chain.', }, }, }), responses: { ...response200('Establishes a new resource supply chain to a target planet.', { type: 'object', required: ['status'], properties: { status: statusSchema() }, }), ...response500(), }, }, }, [`${base}/update_supply_chain`]: { post: { ...tags(base), ...security(), ...operation('Update supply chain.', 'Modifies an existing supply chain.'), ...requestBodySchema({ type: 'object', required: ['building_id', 'supply_chain_id', 'resource_type', 'resource_hour'], properties: { building_id: { type: 'integer', description: 'The unique id of the building.' }, supply_chain_id: { type: 'integer', description: 'The unique id of the supply chain.' }, resource_type: { type: 'string', description: 'The resource to transfer, e.g. "water", "gold", "apple".', }, resource_hour: { type: 'integer', description: 'Set to 0 to suspend the chain.' }, }, }), responses: { ...response200('Modifies an existing supply chain.', { type: 'object', required: ['status'], properties: { status: statusSchema() }, }), ...response500(), }, }, }, [`${base}/delete_supply_chain`]: { post: { ...tags(base), ...security(), ...operation('Delete supply chain.', 'Removes a supply chain.'), ...requestBodySchema({ type: 'object', required: ['building_id', 'supply_chain_id'], properties: { building_id: { type: 'integer', description: 'The unique id of the building.' }, supply_chain_id: { type: 'integer', description: 'The unique id of the supply chain.' }, }, }), responses: { ...response200('Removes a supply chain.', { type: 'object', required: ['status'], properties: { status: statusSchema() }, }), ...response500(), }, }, }, [`${base}/add_supply_ship_to_fleet`]: { post: { ...tags(base), ...security(), ...operation( 'Add supply ship to fleet.', 'Assigns a hulk to supply chain service. Throws 1009 on failure.' ), ...requestBodySchema({ type: 'object', required: ['building_id', 'ship_id'], properties: { building_id: { type: 'integer', description: 'The unique id of the building.' }, ship_id: { type: 'integer', description: 'The unique id of the ship.' }, }, }), responses: { ...response200('Assigns a hulk to supply chain service. Throws 1009 on failure.', { type: 'object', required: ['status'], properties: { status: statusSchema() }, }), ...response500(), }, }, }, [`${base}/remove_supply_ship_from_fleet`]: { post: { ...tags(base), ...security(), ...operation( 'Remove supply ship from fleet.', 'Returns a hulk to the spaceport from supply chain duty.' ), ...requestBodySchema({ type: 'object', required: ['building_id', 'ship_id'], properties: { building_id: { type: 'integer', description: 'The unique id of the building.' }, ship_id: { type: 'integer', description: 'The unique id of the ship.' }, }, }), responses: { ...response200('Returns a hulk to the spaceport from supply chain duty.', { type: 'object', required: ['status'], properties: { status: statusSchema() }, }), ...response500(), }, }, }, [`${base}/view_waste_chains`]: { post: { ...tags(base), ...security(), ...operation( 'View waste chains.', 'Lists waste chains (a default chain exists for the local star).' ), ...buildingIdRequestBody, responses: { ...response200('Lists waste chains (a default chain exists for the local star).', { type: 'object', required: ['waste_chain', 'status'], properties: { waste_chain: { type: 'array', items: { type: 'object', properties: { id: { type: 'integer' }, waste_hour: { type: 'integer' }, percent_transferred: { type: 'number' }, }, }, }, status: statusSchema(), }, }), ...response500(), }, }, }, [`${base}/update_waste_chain`]: { post: { ...tags(base), ...security(), ...operation('Update waste chain.', 'Adjusts the transfer rate of a waste chain.'), ...requestBodySchema({ type: 'object', required: ['building_id', 'waste_chain_id', 'waste_hour'], properties: { building_id: { type: 'integer', description: 'The unique id of the building.' }, waste_chain_id: { type: 'integer', description: 'The unique id of the waste chain.' }, waste_hour: { type: 'integer', description: 'The amount of waste to transfer each hour. Set to 0 to stop.', }, }, }), responses: { ...response200('Adjusts the transfer rate of a waste chain.', { type: 'object', required: ['status'], properties: { status: statusSchema() }, }), ...response500(), }, }, }, [`${base}/add_waste_ship_to_fleet`]: { post: { ...tags(base), ...security(), ...operation( 'Add waste ship to fleet.', 'Assigns a scow to waste transport duty. Throws 1009 on failure.' ), ...requestBodySchema({ type: 'object', required: ['building_id', 'ship_id'], properties: { building_id: { type: 'integer', description: 'The unique id of the building.' }, ship_id: { type: 'integer', description: 'The unique id of the ship.' }, }, }), responses: { ...response200('Assigns a scow to waste transport duty. Throws 1009 on failure.', { type: 'object', required: ['status'], properties: { status: statusSchema() }, }), ...response500(), }, }, }, [`${base}/remove_waste_ship_from_fleet`]: { post: { ...tags(base), ...security(), ...operation( 'Remove waste ship from fleet.', 'Returns a scow to the spaceport from waste transport duty.' ), ...requestBodySchema({ type: 'object', required: ['building_id', 'ship_id'], properties: { building_id: { type: 'integer', description: 'The unique id of the building.' }, ship_id: { type: 'integer', description: 'The unique id of the ship.' }, }, }), responses: { ...response200('Returns a scow to the spaceport from waste transport duty.', { type: 'object', required: ['status'], properties: { status: statusSchema() }, }), ...response500(), }, }, }, [`${base}/get_prisoners`]: { post: { ...tags(base), ...security(), ...operation('Get prisoners.', 'Lists tradeable spies, with level and sentence expiration.'), ...buildingIdRequestBody, responses: { ...response200('Lists tradeable spies, with level and sentence expiration.', { type: 'object', required: ['prisoners', 'status'], properties: { prisoners: { type: 'array', items: { type: 'object', properties: { id: { type: 'integer' }, name: { type: 'string' }, level: { type: 'integer' }, sentence_expires: { type: 'string' }, }, }, }, status: statusSchema(), }, }), ...response500(), }, }, }, [`${base}/get_plan_summary`]: { post: { ...tags(base), ...security(), ...operation('Get plan summary.', 'Summarizes owned plans by type, level, and quantity.'), ...buildingIdRequestBody, responses: { ...response200('Summarizes owned plans by type, level, and quantity.', { type: 'object', required: ['plans', 'status'], properties: { plans: { type: 'array', items: { type: 'object', properties: { name: { type: 'string' }, level: { type: 'integer' }, extra_build_level: { type: 'integer' }, quantity: { type: 'integer' }, }, }, }, status: statusSchema(), }, }), ...response500(), }, }, }, [`${base}/get_glyph_summary`]: { post: { ...tags(base), ...security(), ...operation('Get glyph summary.', 'Summarizes owned glyphs by type and quantity.'), ...buildingIdRequestBody, responses: { ...response200('Summarizes owned glyphs by type and quantity.', { type: 'object', required: ['glyphs', 'status'], properties: { glyphs: { type: 'array', items: { type: 'object', properties: { type: { type: 'string' }, quantity: { type: 'integer' } }, }, }, status: statusSchema(), }, }), ...response500(), }, }, }, [`${base}/report_abuse`]: { post: { ...tags(base), ...security(), ...operation('Report abuse.', 'Flags a suspicious trade for moderation review.'), ...requestBodySchema({ type: 'object', required: ['building_id', 'trade_id'], properties: { building_id: { type: 'integer', description: 'The unique id of the building.' }, trade_id: { type: 'integer', description: 'The unique id of the trade.' }, }, }), responses: { ...response200('Flags a suspicious trade for moderation review.', { type: 'object', required: ['status'], properties: { status: statusSchema() }, }), ...response500(), }, }, }, };