@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 +29 -0
- package/dist/index.js +34 -0
- package/package.json +22 -7
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
|
+
"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": [
|
|
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": [
|
|
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": {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"
|
|
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
|
}
|