@openleaderboard/sdk 0.3.0 → 0.4.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/dist/index.d.ts CHANGED
@@ -16,6 +16,14 @@ export interface RankEntry {
16
16
  score: number;
17
17
  rank: number;
18
18
  exact: boolean;
19
+ nickname?: string;
20
+ }
21
+ /** A registered player: server-minted id + nickname unique per app (case-insensitive). */
22
+ export interface User {
23
+ user_id: string;
24
+ nickname: string;
25
+ created_at?: string;
26
+ updated_at?: string;
19
27
  }
20
28
  export interface SubmitResult {
21
29
  accepted: boolean;
@@ -78,6 +86,10 @@ export declare class LeaderboardError extends Error {
78
86
  export declare class NotFoundError extends LeaderboardError {
79
87
  constructor(message: string);
80
88
  }
89
+ /** Thrown when a nickname is already claimed in this app (HTTP 409). */
90
+ export declare class NicknameTakenError extends LeaderboardError {
91
+ constructor(message: string);
92
+ }
81
93
  export declare class LeaderboardClient {
82
94
  private readonly apiKey;
83
95
  private readonly opts;
@@ -105,6 +117,23 @@ export declare class LeaderboardClient {
105
117
  getNeighbors(board: string, member: string, k: number, q?: QueryOpts): Promise<RankEntry[]>;
106
118
  /** Rank an explicit set of members against each other (a friend leaderboard). */
107
119
  getFriends(board: string, members: string[], q?: QueryOpts): Promise<RankEntry[]>;
120
+ /**
121
+ * Register a player: mints a `plr_...` user id and claims a nickname
122
+ * (unique per app, case-insensitive). Submit scores with `user_id` as the
123
+ * member; reads then include the nickname. Throws {@link NicknameTakenError}
124
+ * if the name is claimed.
125
+ */
126
+ registerUser(nickname: string): Promise<User>;
127
+ /** Fetch a registered player by id. Throws {@link NotFoundError} if absent. */
128
+ getUser(userId: string): Promise<User>;
129
+ /** Resolve a nickname (case-insensitive) to its player. */
130
+ getUserByNickname(nickname: string): Promise<User>;
131
+ /**
132
+ * Change a player's nickname. The user id — and therefore board data and
133
+ * HMAC signatures — is unaffected. Throws {@link NicknameTakenError} on
134
+ * conflict.
135
+ */
136
+ renameUser(userId: string, nickname: string): Promise<User>;
108
137
  private send;
109
138
  }
110
139
  /**
package/dist/index.js CHANGED
@@ -26,6 +26,13 @@ export class NotFoundError extends LeaderboardError {
26
26
  this.name = "NotFoundError";
27
27
  }
28
28
  }
29
+ /** Thrown when a nickname is already claimed in this app (HTTP 409). */
30
+ export class NicknameTakenError extends LeaderboardError {
31
+ constructor(message) {
32
+ super(409, message);
33
+ this.name = "NicknameTakenError";
34
+ }
35
+ }
29
36
  export class LeaderboardClient {
30
37
  constructor(baseUrl, apiKey, opts = {}) {
31
38
  this.apiKey = apiKey;
@@ -103,6 +110,31 @@ export class LeaderboardClient {
103
110
  const r = await this.send("POST", `/v1/boards/${enc(board)}/friends${qs({ ...q })}`, { members });
104
111
  return r.entries ?? [];
105
112
  }
113
+ /**
114
+ * Register a player: mints a `plr_...` user id and claims a nickname
115
+ * (unique per app, case-insensitive). Submit scores with `user_id` as the
116
+ * member; reads then include the nickname. Throws {@link NicknameTakenError}
117
+ * if the name is claimed.
118
+ */
119
+ async registerUser(nickname) {
120
+ return this.send("POST", "/v1/users", { nickname });
121
+ }
122
+ /** Fetch a registered player by id. Throws {@link NotFoundError} if absent. */
123
+ async getUser(userId) {
124
+ return this.send("GET", `/v1/users/${enc(userId)}`);
125
+ }
126
+ /** Resolve a nickname (case-insensitive) to its player. */
127
+ async getUserByNickname(nickname) {
128
+ return this.send("GET", `/v1/users${qs({ nickname })}`);
129
+ }
130
+ /**
131
+ * Change a player's nickname. The user id — and therefore board data and
132
+ * HMAC signatures — is unaffected. Throws {@link NicknameTakenError} on
133
+ * conflict.
134
+ */
135
+ async renameUser(userId, nickname) {
136
+ return this.send("PATCH", `/v1/users/${enc(userId)}`, { nickname });
137
+ }
106
138
  async send(method, path, body) {
107
139
  const headers = { Authorization: `Bearer ${this.apiKey}` };
108
140
  let bodyStr;
@@ -114,6 +146,8 @@ export class LeaderboardClient {
114
146
  const text = await resp.text();
115
147
  if (resp.status === 404)
116
148
  throw new NotFoundError(text);
149
+ if (resp.status === 409)
150
+ throw new NicknameTakenError(text);
117
151
  if (!resp.ok)
118
152
  throw new LeaderboardError(resp.status, `${method} ${path} -> ${resp.status}: ${text}`);
119
153
  return text ? JSON.parse(text) : {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openleaderboard/sdk",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "TypeScript client for the OpenLeaderboard API (browser + Node 18+).",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -12,7 +12,9 @@
12
12
  "import": "./dist/index.js"
13
13
  }
14
14
  },
15
- "files": ["dist"],
15
+ "files": [
16
+ "dist"
17
+ ],
16
18
  "scripts": {
17
19
  "build": "tsc -p tsconfig.json",
18
20
  "typecheck": "tsc -p tsconfig.json --noEmit",
@@ -20,7 +22,12 @@
20
22
  "test:hmac": "node test/hmac.mjs",
21
23
  "prepublishOnly": "npm run build"
22
24
  },
23
- "keywords": ["leaderboard", "gaming", "ranking", "api"],
25
+ "keywords": [
26
+ "leaderboard",
27
+ "gaming",
28
+ "ranking",
29
+ "api"
30
+ ],
24
31
  "license": "Apache-2.0",
25
32
  "repository": {
26
33
  "type": "git",
@@ -28,8 +35,16 @@
28
35
  "directory": "sdk/typescript"
29
36
  },
30
37
  "homepage": "https://github.com/kodeni-am/leaderboard/tree/main/sdk/typescript#readme",
31
- "bugs": { "url": "https://github.com/kodeni-am/leaderboard/issues" },
32
- "publishConfig": { "access": "public" },
33
- "engines": { "node": ">=18" },
34
- "devDependencies": { "typescript": "^5.5.0" }
38
+ "bugs": {
39
+ "url": "https://github.com/kodeni-am/leaderboard/issues"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "engines": {
45
+ "node": ">=18"
46
+ },
47
+ "devDependencies": {
48
+ "typescript": "^5.5.0"
49
+ }
35
50
  }