@game-infra/api-schemas-core
@game-infra/api-schemas-core
Generic service API contract: valibot schemas plus toad-contracts defineApiContract definitions for auth, savegame, game-entity CRUD, admin backup, feedback, and heartbeat. This is the base contract every game backend and frontend shares; the event-editor, balance, file-storage, and progress-tracker contracts build on it.
Published to npm. Also consumable as sibling source (exports points at src/).
Install
// pnpm sibling checkout
"@game-infra/api-schemas-core": "link:../../game-infra/packages/schemas/api-schemas-core"
// or from npm
"@game-infra/api-schemas-core": "^0.1.0"
valibot is a peer dependency (^1.4.0); the consumer provides it.
Usage
Contracts carry method, path, params, and request/response schemas in one object. Build a URL with pathResolver, derive the route pattern with mapApiContractToPath:
import {
authLoginContract,
gameEntityLoadContract,
LoginRequestSchema,
} from "@game-infra/api-schemas-core";
import { mapApiContractToPath } from "@toad-contracts/valibot";
authLoginContract.pathResolver(); // '/auth/login'
gameEntityLoadContract.pathResolver({ gameId: "g1", entityType: "item", entityId: "e1" });
// '/games/g1/entities/item/e1'
mapApiContractToPath(gameEntityLoadContract); // '/games/:gameId/entities/:entityType/:entityId'
Register on a Hono service with @toad-contracts/hono (buildHonoRoute) and call from a frontend with @toad-contracts/frontend-http-client (sendByApiContract) — both drive off the same contract objects.
The API URL is not hardcoded. Build a resolver per deployment:
import { createApiUrlResolver } from "@game-infra/api-schemas-core";
const { getApiUrl } = createApiUrlResolver({ productionUrl: "https://api.example.com" });
getApiUrl(window.location.hostname); // dev URL on localhost, prod otherwise
Extension points
- Entity types:
entityTypeis a plainstring(). The oldEntityTypesenum (spell/item/persona/secret) was dropped; games re-tighten it via their own config/validation. - AI provider:
AI_PROVIDERS/AIProviderSchemaare the single source of truth for theproviderfield used across AI endpoints.
Migrating from golem-forge
The old ApiPaths constants and PathResolvers / resolve*Path helpers are gone. Get a URL from the contract itself with contract.pathResolver(params) and the :param route pattern with mapApiContractToPath(contract). Prefer driving requests through @toad-contracts/frontend-http-client (sendByApiContract) and routes through @toad-contracts/hono (buildHonoRoute), which consume the contract directly so you never touch a raw path. Event-editor and hex routes moved to their own packages.
Dependencies
@toad-contracts/core, @toad-contracts/valibot; peer valibot. No internal @game-infra/* deps.
Consumers
core-service (auth/feedback/backup/heartbeat endpoints), game frontends (shared-fe), and the other *-schemas packages, which re-use createSuccessResponseSchema and AIProviderSchema.