@volorio/games-node 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # @volorio/games-node
2
+
3
+ Server-side Volorio Games SDK.
4
+
5
+ Use this package only in your backend. It sends your Volorio server API key to `api.volor.io` and creates short-lived game sessions/tokens for browser and mobile clients.
6
+
7
+ ```ts
8
+ import { VolorioGamesNodeClient } from "@volorio/games-node";
9
+
10
+ const games = new VolorioGamesNodeClient({
11
+ apiBaseUrl: "https://api.volor.io",
12
+ apiKey: process.env.VOLORIO_API_KEY!,
13
+ });
14
+
15
+ const session = await games.createGameSession({
16
+ projectId: "proj_123",
17
+ roomId: "room_123",
18
+ gameId: "dice",
19
+ gameVersion: "1.0.0",
20
+ createdBy: "user_123",
21
+ });
22
+ ```
23
+
24
+ Never put the server API key in browser or mobile code.
25
+
@@ -0,0 +1,85 @@
1
+ import type { VolorioGameManifest, VolorioGameRole, VolorioGameSessionStatus } from "@volorio/games-core";
2
+ export interface VolorioGamesNodeClientOptions {
3
+ apiBaseUrl: string;
4
+ apiKey: string;
5
+ fetch?: typeof fetch;
6
+ }
7
+ export interface CreateGameSessionInput {
8
+ projectId: string;
9
+ roomId: string;
10
+ gameId: string;
11
+ gameVersion?: string;
12
+ createdBy: string;
13
+ maxPlayers?: number;
14
+ spectatorSupport?: boolean;
15
+ idempotencyKey?: string;
16
+ }
17
+ export interface JoinGameSessionInput {
18
+ gameInstanceId: string;
19
+ identity: string;
20
+ displayName?: string;
21
+ role?: VolorioGameRole;
22
+ lastKnownStateVersion?: number;
23
+ }
24
+ export interface StartGameSessionInput {
25
+ gameInstanceId: string;
26
+ startedBy: string;
27
+ idempotencyKey?: string;
28
+ }
29
+ export interface FinishGameSessionInput {
30
+ gameInstanceId: string;
31
+ finishedBy: string;
32
+ reason?: string;
33
+ idempotencyKey?: string;
34
+ }
35
+ export interface CreateGameTokenInput {
36
+ gameInstanceId: string;
37
+ identity: string;
38
+ role?: VolorioGameRole;
39
+ ttlSeconds?: number;
40
+ permissions?: string[];
41
+ }
42
+ export interface VolorioGameSessionDescriptor {
43
+ gameInstanceId: string;
44
+ projectId: string;
45
+ roomId: string;
46
+ gameId: string;
47
+ gameVersion: string;
48
+ status: VolorioGameSessionStatus;
49
+ gatewayUrl?: string;
50
+ }
51
+ export interface VolorioGameJoinResult {
52
+ gameInstanceId: string;
53
+ identity: string;
54
+ role: VolorioGameRole;
55
+ status: VolorioGameSessionStatus;
56
+ token?: string;
57
+ gatewayUrl?: string;
58
+ stateVersion?: number;
59
+ }
60
+ export interface VolorioGameTokenResult {
61
+ token: string;
62
+ expiresAt: string;
63
+ gatewayUrl: string;
64
+ }
65
+ export interface VolorioLeaderboardEntry {
66
+ rank: number;
67
+ identity: string;
68
+ score: number;
69
+ metadata?: Record<string, unknown>;
70
+ }
71
+ export declare class VolorioGamesNodeClient {
72
+ private readonly options;
73
+ private readonly apiBaseUrl;
74
+ private readonly fetchImpl;
75
+ constructor(options: VolorioGamesNodeClientOptions);
76
+ listCatalog(projectId: string): Promise<VolorioGameManifest[]>;
77
+ createGameSession(input: CreateGameSessionInput): Promise<VolorioGameSessionDescriptor>;
78
+ getGameSession(gameInstanceId: string): Promise<VolorioGameSessionDescriptor>;
79
+ joinGameSession(input: JoinGameSessionInput): Promise<VolorioGameJoinResult>;
80
+ startGameSession(input: StartGameSessionInput): Promise<VolorioGameSessionDescriptor>;
81
+ finishGameSession(input: FinishGameSessionInput): Promise<VolorioGameSessionDescriptor>;
82
+ createGameToken(input: CreateGameTokenInput): Promise<VolorioGameTokenResult>;
83
+ getLeaderboard(projectId: string, gameId: string, limit?: number): Promise<VolorioLeaderboardEntry[]>;
84
+ private request;
85
+ }
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VolorioGamesNodeClient = void 0;
4
+ class VolorioGamesNodeClient {
5
+ options;
6
+ apiBaseUrl;
7
+ fetchImpl;
8
+ constructor(options) {
9
+ this.options = options;
10
+ this.apiBaseUrl = options.apiBaseUrl.replace(/\/+$/, "");
11
+ this.fetchImpl = options.fetch ?? ((input, init) => fetch(input, init));
12
+ if (options.apiKey.trim().length === 0) {
13
+ throw new Error("volorio_games_api_key_required");
14
+ }
15
+ }
16
+ listCatalog(projectId) {
17
+ return this.request(`/v1/games/catalog?projectId=${encodeURIComponent(projectId)}`, { method: "GET" });
18
+ }
19
+ createGameSession(input) {
20
+ return this.request("/v1/games/sessions", { method: "POST", body: input });
21
+ }
22
+ getGameSession(gameInstanceId) {
23
+ return this.request(`/v1/games/sessions/${encodeURIComponent(gameInstanceId)}`, { method: "GET" });
24
+ }
25
+ joinGameSession(input) {
26
+ return this.request(`/v1/games/sessions/${encodeURIComponent(input.gameInstanceId)}/join`, { method: "POST", body: input });
27
+ }
28
+ startGameSession(input) {
29
+ return this.request(`/v1/games/sessions/${encodeURIComponent(input.gameInstanceId)}/start`, { method: "POST", body: input });
30
+ }
31
+ finishGameSession(input) {
32
+ return this.request(`/v1/games/sessions/${encodeURIComponent(input.gameInstanceId)}/finish`, { method: "POST", body: input });
33
+ }
34
+ createGameToken(input) {
35
+ return this.request(`/v1/games/sessions/${encodeURIComponent(input.gameInstanceId)}/tokens`, { method: "POST", body: input });
36
+ }
37
+ getLeaderboard(projectId, gameId, limit = 100) {
38
+ const params = new URLSearchParams({ projectId, limit: String(limit) });
39
+ return this.request(`/v1/games/leaderboards/${encodeURIComponent(gameId)}?${params.toString()}`, { method: "GET" });
40
+ }
41
+ async request(path, init) {
42
+ const response = await this.fetchImpl(`${this.apiBaseUrl}${path}`, {
43
+ method: init.method,
44
+ headers: {
45
+ "authorization": `Bearer ${this.options.apiKey}`,
46
+ "content-type": "application/json",
47
+ },
48
+ body: init.body === undefined ? undefined : JSON.stringify(init.body),
49
+ });
50
+ const body = await response.json().catch(() => undefined);
51
+ if (!response.ok) {
52
+ throw new Error(readErrorMessage(body, response.status));
53
+ }
54
+ return body;
55
+ }
56
+ }
57
+ exports.VolorioGamesNodeClient = VolorioGamesNodeClient;
58
+ function readErrorMessage(body, status) {
59
+ if (typeof body === "object" && body !== null && "message" in body) {
60
+ return String(body.message);
61
+ }
62
+ return `volorio_games_request_failed_${status}`;
63
+ }
64
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@volorio/games-node",
3
+ "version": "0.2.0",
4
+ "private": false,
5
+ "description": "Server-side Volorio Games client for game catalog, session, token, and leaderboard control-plane APIs.",
6
+ "main": "dist/src/index.js",
7
+ "types": "dist/src/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/src/index.d.ts",
11
+ "default": "./dist/src/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist/src",
16
+ "README.md"
17
+ ],
18
+ "publishConfig": {
19
+ "access": "public",
20
+ "registry": "https://registry.npmjs.org/"
21
+ },
22
+ "scripts": {
23
+ "build": "tsc -p tsconfig.build.json",
24
+ "test": "pnpm build && tsc -p tsconfig.json && node --test dist/test/*.js",
25
+ "pack:local": "pnpm build && npm pack --pack-destination dist"
26
+ },
27
+ "dependencies": {
28
+ "@volorio/games-core": "^0.2.0"
29
+ }
30
+ }