Files
SpaceWanderer/lib/openapi.ts
T

160 lines
5.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import pkg from '@/package.json';
// OpenAPI 3.1 document for the app's public JSON API, kept in code so it can be
// served machine-readable at /api/openapi (see AGENTS.md "## API"). Must be updated
// whenever an endpoint changes.
export const openApiSpec = {
openapi: '3.1.0',
info: {
title: 'SpaceWanderer API',
description:
'JSON API for SpaceWanderer — a single-player turn-based space adventure (one save, no accounts). World endpoints: read the generated world state and jump between adjacent solar systems.',
// Sourced from package.json so it stays in sync with every version bump.
version: pkg.version,
},
// Empty url = current origin (the spec is served from the same host that runs the API).
servers: [{ url: '' }],
paths: {
'/api/version': {
get: {
summary: 'App version',
description: 'The running app version, read from package.json.',
operationId: 'getVersion',
responses: {
200: {
description: 'Current app version',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/AppVersion' },
},
},
},
},
},
},
'/api/world': {
get: {
summary: 'World state',
description:
'The full world of the single active save — every known solar system, jump routes and the turn counter. Auto-initializes a new game (seeded world generation) when no save exists yet.',
operationId: 'getWorld',
responses: {
200: {
description: 'Current world state',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/WorldState' },
},
},
},
},
},
},
'/api/jump': {
post: {
summary: 'Jump to an adjacent solar system',
description:
'Validates that the target is a jump route away from the current system, sets it as current (discovering it if new and generating its neighbours), increments the turn counter and writes a jump event. Returns the fresh world state.',
operationId: 'jumpToSystem',
requestBody: {
required: true,
content: {
'application/json': {
schema: { $ref: '#/components/schemas/JumpRequest' },
},
},
},
responses: {
200: {
description: 'Fresh world state after the jump',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/WorldState' },
},
},
},
400: {
description: 'Malformed body or non-integer systemId',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/Error' },
},
},
},
404: {
description: 'Unknown system id',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/Error' },
},
},
},
409: {
description: 'Target is not adjacent to the current system (or is the current system itself)',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/Error' },
},
},
},
},
},
},
},
components: {
schemas: {
AppVersion: {
type: 'object',
properties: {
version: { type: 'string', description: 'Semver of the running build' },
},
required: ['version'],
},
WorldSystem: {
type: 'object',
properties: {
id: { type: 'integer' },
name: { type: 'string' },
x: { type: 'number', description: '0–100 chart coordinate' },
y: { type: 'number', description: '0–100 chart coordinate' },
discovered: { type: 'boolean' },
current: { type: 'boolean', description: 'True for the system the ship is in now' },
},
required: ['id', 'name', 'x', 'y', 'discovered', 'current'],
},
WorldState: {
type: 'object',
properties: {
systems: { type: 'array', items: { $ref: '#/components/schemas/WorldSystem' } },
edges: {
type: 'array',
description: 'Undirected jump routes as [fromId, toId] pairs (sorted, deduped)',
items: {
type: 'array',
items: { type: 'integer' },
minItems: 2,
maxItems: 2,
},
},
turn: { type: 'integer', description: 'Turn counter — one per jump' },
},
required: ['systems', 'edges', 'turn'],
},
JumpRequest: {
type: 'object',
properties: {
systemId: { type: 'integer', description: 'solar_systems.id of the jump target' },
},
required: ['systemId'],
},
Error: {
type: 'object',
properties: {
error: { type: 'string' },
},
required: ['error'],
},
},
},
};