@retroachievements/api 0.0.0-development → 1.0.0-rc.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.
@@ -1,6 +1,8 @@
1
1
  export * from "./getAchievementsEarnedBetween";
2
2
  export * from "./getAchievementsEarnedOnDay";
3
3
  export * from "./getGameInfoAndUserProgress";
4
+ export * from "./getUserClaims";
5
+ export * from "./getUserCompletedGames";
4
6
  export * from "./getUserGameRankAndScore";
5
7
  export * from "./getUserPoints";
6
8
  export * from "./getUserProgress";
@@ -0,0 +1,13 @@
1
+ interface UserCompletedGamesResponseEntity {
2
+ GameID: string;
3
+ Title: string;
4
+ ImageIcon: string;
5
+ ConsoleID: string;
6
+ ConsoleName: string;
7
+ MaxPossible: string;
8
+ NumAwarded: string;
9
+ PctWon: string;
10
+ HardcoreMode: "0" | "1";
11
+ }
12
+ export declare type GetUserCompletedGamesResponse = UserCompletedGamesResponseEntity[];
13
+ export {};
@@ -2,11 +2,15 @@ export * from "./dated-user-achievement.model";
2
2
  export * from "./dated-user-achievements-response.model";
3
3
  export * from "./game-info-and-user-progress.model";
4
4
  export * from "./get-game-info-and-user-progress-response.model";
5
+ export * from "./get-user-completed-games-response.model";
5
6
  export * from "./get-user-game-rank-and-score-response.model";
6
7
  export * from "./get-user-points-response.model";
7
8
  export * from "./get-user-progress-response.model";
8
9
  export * from "./get-user-recently-played-games-response.model";
9
10
  export * from "./get-user-summary-response.model";
11
+ export * from "./user-claims.model";
12
+ export * from "./user-claims-response.model";
13
+ export * from "./user-completed-games.model";
10
14
  export * from "./user-game-rank-and-score.model";
11
15
  export * from "./user-points.model";
12
16
  export * from "./user-progress.model";
@@ -0,0 +1,19 @@
1
+ interface UserClaimsResponseEntity {
2
+ ID: string;
3
+ User: string;
4
+ GameID: string;
5
+ GameTitle: string;
6
+ GameIcon: string;
7
+ ConsoleName: string;
8
+ ClaimType: string;
9
+ SetType: string;
10
+ Status: string;
11
+ Extension: string;
12
+ Special: string;
13
+ Created: string;
14
+ DoneTime: string;
15
+ Updated: string;
16
+ MinutesLeft: string;
17
+ }
18
+ export declare type GetUserClaimsResponse = UserClaimsResponseEntity[];
19
+ export {};
@@ -0,0 +1,19 @@
1
+ interface UserClaim {
2
+ id: number;
3
+ user: string;
4
+ gameId: number;
5
+ gameTitle: string;
6
+ gameIcon: string;
7
+ consoleName: string;
8
+ claimType: number;
9
+ setType: number;
10
+ status: number;
11
+ extension: number;
12
+ special: number;
13
+ created: string;
14
+ doneTime: string;
15
+ updated: string;
16
+ minutesLeft: number;
17
+ }
18
+ export declare type UserClaims = UserClaim[];
19
+ export {};
@@ -0,0 +1,13 @@
1
+ interface UserCompletedGame {
2
+ gameId: number;
3
+ title: string;
4
+ imageIcon: string;
5
+ consoleId: number;
6
+ consoleName: string;
7
+ maxPossible: number;
8
+ numAwarded: number;
9
+ pctWon: number;
10
+ hardcoreMode: boolean;
11
+ }
12
+ export declare type UserCompletedGames = UserCompletedGame[];
13
+ export {};
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "raweb",
9
9
  "retro gaming"
10
10
  ],
11
- "version": "0.0.0-development",
11
+ "version": "1.0.0-rc.0",
12
12
  "main": "dist/index.js",
13
13
  "module": "dist/api.esm.js",
14
14
  "typings": "dist/index.d.ts",
@@ -7,7 +7,7 @@
7
7
 
8
8
  // If you can't import what you want from "./index", users won't
9
9
  // be able to import it either.
10
- import { buildAuthorization, getTicketData } from "./index";
10
+ // import { buildAuthorization, getAchievementCount } from "./index";
11
11
 
12
12
  const main = async () => {
13
13
  console.log("retroachievements-api-js playground is running.");
@@ -15,13 +15,15 @@ const main = async () => {
15
15
 
16
16
  // -- Start testing stuff here --
17
17
 
18
+ /*
18
19
  const authorization = buildAuthorization({
19
- userName: "WCopeland",
20
- webApiKey: "gYPwmMOAIiGkOmk1qpNDrTfqBiGIeh7X"
21
- });
20
+ userName: 'myUserName',
21
+ webApiKey: 'myWebApiKey'
22
+ })
22
23
 
23
- const ticketData = await getTicketData(authorization, {});
24
- console.log(ticketData);
24
+ const achievementCount = await getAchievementCount(authorization, 14_402);
25
+ console.log(achievementCount);
26
+ */
25
27
  };
26
28
 
27
29
  main();
@@ -0,0 +1,82 @@
1
+ /* eslint-disable sonarjs/no-duplicate-string */
2
+
3
+ import { rest } from "msw";
4
+ import { setupServer } from "msw/node";
5
+
6
+ import { apiBaseUrl } from "../utils/internal";
7
+ import { buildAuthorization } from "../utils/public";
8
+ import { getUserClaims } from "./getUserClaims";
9
+ import type { GetUserClaimsResponse } from "./models";
10
+
11
+ const server = setupServer();
12
+
13
+ describe("Function: getUserClaims", () => {
14
+ // MSW Setup
15
+ beforeAll(() => server.listen());
16
+ afterEach(() => server.resetHandlers());
17
+ afterAll(() => server.close());
18
+
19
+ it("is defined #sanity", () => {
20
+ // ASSERT
21
+ expect(getUserClaims).toBeDefined();
22
+ });
23
+
24
+ it("given a username, retrieves a list of achievement set claims for the user", async () => {
25
+ const authorization = buildAuthorization({
26
+ userName: "mockUserName",
27
+ webApiKey: "mockWebApiKey"
28
+ });
29
+
30
+ const mockResponse: GetUserClaimsResponse = [
31
+ {
32
+ ID: "1685",
33
+ User: "Jamiras",
34
+ GameID: "1492",
35
+ GameTitle: "Pinball Quest",
36
+ GameIcon: "/Images/011326.png",
37
+ ConsoleName: "NES",
38
+ ClaimType: "0",
39
+ SetType: "0",
40
+ Status: "1",
41
+ Extension: "0",
42
+ Special: "0",
43
+ Created: "2017-08-20 00:00:00",
44
+ DoneTime: "2017-08-20 00:00:00",
45
+ Updated: "2022-06-28 17:15:59",
46
+ MinutesLeft: "-2862348"
47
+ }
48
+ ];
49
+
50
+ server.use(
51
+ rest.get(`${apiBaseUrl}/API_GetUserClaims.php`, (_, res, ctx) =>
52
+ res(ctx.json(mockResponse))
53
+ )
54
+ );
55
+
56
+ // ACT
57
+ const response = await getUserClaims(authorization, {
58
+ userName: "Jamiras"
59
+ });
60
+
61
+ // ASSERT
62
+ expect(response).toEqual([
63
+ {
64
+ id: 1685,
65
+ user: "Jamiras",
66
+ gameId: 1492,
67
+ gameTitle: "Pinball Quest",
68
+ gameIcon: "/Images/011326.png",
69
+ consoleName: "NES",
70
+ claimType: 0,
71
+ setType: 0,
72
+ status: 1,
73
+ extension: 0,
74
+ special: 0,
75
+ created: "2017-08-20 00:00:00",
76
+ doneTime: "2017-08-20 00:00:00",
77
+ updated: "2022-06-28 17:15:59",
78
+ minutesLeft: -2_862_348
79
+ }
80
+ ]);
81
+ });
82
+ });
@@ -0,0 +1,59 @@
1
+ import {
2
+ apiBaseUrl,
3
+ buildRequestUrl,
4
+ call,
5
+ serializeProperties
6
+ } from "../utils/internal";
7
+ import type { AuthObject } from "../utils/public";
8
+ import type { GetUserClaimsResponse, UserClaims } from "./models";
9
+
10
+ /**
11
+ * A call to this function will retrieve a list of
12
+ * achievement set claims made over the lifetime of a given
13
+ * user, targeted by their username.
14
+ *
15
+ * @param authorization An object containing your userName and webApiKey.
16
+ * This can be constructed with `buildAuthorization()`.
17
+ *
18
+ * @param payload.userName The user for which to retrieve the historical
19
+ * achievement set claims list for.
20
+ *
21
+ * @example
22
+ * ```
23
+ * const userClaims = await getUserClaims(
24
+ * authorization,
25
+ * { userName: "xelnia" }
26
+ * );
27
+ * ```
28
+ *
29
+ * @returns An array containing all the achievement set claims
30
+ * made over the lifetime of the given user.
31
+ */
32
+ export const getUserClaims = async (
33
+ authorization: AuthObject,
34
+ payload: { userName: string }
35
+ ): Promise<UserClaims> => {
36
+ const { userName } = payload;
37
+
38
+ const url = buildRequestUrl(
39
+ apiBaseUrl,
40
+ "/API_GetUserClaims.php",
41
+ authorization,
42
+ { u: userName }
43
+ );
44
+
45
+ const rawResponse = await call<GetUserClaimsResponse>({ url });
46
+
47
+ return serializeProperties(rawResponse, {
48
+ shouldCastToNumbers: [
49
+ "ID",
50
+ "GameID",
51
+ "ClaimType",
52
+ "SetType",
53
+ "Status",
54
+ "Extension",
55
+ "Special",
56
+ "MinutesLeft"
57
+ ]
58
+ });
59
+ };
@@ -0,0 +1,93 @@
1
+ /* eslint-disable sonarjs/no-duplicate-string */
2
+
3
+ import { rest } from "msw";
4
+ import { setupServer } from "msw/node";
5
+
6
+ import { apiBaseUrl } from "../utils/internal";
7
+ import { buildAuthorization } from "../utils/public";
8
+ import { getUserCompletedGames } from "./getUserCompletedGames";
9
+ import type { GetUserCompletedGamesResponse } from "./models";
10
+
11
+ const server = setupServer();
12
+
13
+ describe("Function: getUserCompletedGames", () => {
14
+ // MSW Setup
15
+ beforeAll(() => server.listen());
16
+ afterEach(() => server.resetHandlers());
17
+ afterAll(() => server.close());
18
+
19
+ it("is defined #sanity", () => {
20
+ // ASSERT
21
+ expect(getUserCompletedGames).toBeDefined();
22
+ });
23
+
24
+ it("given a username, returns completion metadata", async () => {
25
+ // ARRANGE
26
+ const authorization = buildAuthorization({
27
+ userName: "mockUserName",
28
+ webApiKey: "mockWebApiKey"
29
+ });
30
+
31
+ const mockResponse: GetUserCompletedGamesResponse = [
32
+ {
33
+ GameID: "1881",
34
+ Title: "Popeye",
35
+ ImageIcon: "/Images/065073.png",
36
+ ConsoleID: "7",
37
+ ConsoleName: "NES",
38
+ MaxPossible: "26",
39
+ NumAwarded: "12",
40
+ PctWon: "0.4615",
41
+ HardcoreMode: "0"
42
+ },
43
+ {
44
+ GameID: "1881",
45
+ Title: "Popeye",
46
+ ImageIcon: "/Images/065073.png",
47
+ ConsoleID: "7",
48
+ ConsoleName: "NES",
49
+ MaxPossible: "26",
50
+ NumAwarded: "12",
51
+ PctWon: "0.4615",
52
+ HardcoreMode: "1"
53
+ }
54
+ ];
55
+
56
+ server.use(
57
+ rest.get(`${apiBaseUrl}/API_GetUserCompletedGames.php`, (_, res, ctx) =>
58
+ res(ctx.json(mockResponse))
59
+ )
60
+ );
61
+
62
+ // ACT
63
+ const response = await getUserCompletedGames(authorization, {
64
+ userName: "xelnia"
65
+ });
66
+
67
+ // ASSERT
68
+ expect(response).toEqual([
69
+ {
70
+ gameId: 1881,
71
+ title: "Popeye",
72
+ imageIcon: "/Images/065073.png",
73
+ consoleId: 7,
74
+ consoleName: "NES",
75
+ maxPossible: 26,
76
+ numAwarded: 12,
77
+ pctWon: 0.4615,
78
+ hardcoreMode: false
79
+ },
80
+ {
81
+ gameId: 1881,
82
+ title: "Popeye",
83
+ imageIcon: "/Images/065073.png",
84
+ consoleId: 7,
85
+ consoleName: "NES",
86
+ maxPossible: 26,
87
+ numAwarded: 12,
88
+ pctWon: 0.4615,
89
+ hardcoreMode: true
90
+ }
91
+ ]);
92
+ });
93
+ });
@@ -0,0 +1,89 @@
1
+ import {
2
+ apiBaseUrl,
3
+ buildRequestUrl,
4
+ call,
5
+ serializeProperties
6
+ } from "../utils/internal";
7
+ import type { AuthObject } from "../utils/public";
8
+ import type {
9
+ GetUserCompletedGamesResponse,
10
+ UserCompletedGames
11
+ } from "./models";
12
+
13
+ /**
14
+ * A call to this function will retrieve completion metadata
15
+ * about the games a given user has played. It returns two
16
+ * entries per each game: one for the softcore completion and
17
+ * one for the hardcore completion. These are designated by
18
+ * the `hardcoreMode` property on the completion object.
19
+ *
20
+ * @param authorization An object containing your userName and webApiKey.
21
+ * This can be constructed with `buildAuthorization()`.
22
+ *
23
+ * @param payload.userName The user for which to retrieve the
24
+ * completion metadata for.
25
+ *
26
+ * @example
27
+ * ```
28
+ * const userCompletedGames = await getUserCompletedGames(
29
+ * authorization,
30
+ * { userName: "xelnia" }
31
+ * );
32
+ * ```
33
+ *
34
+ * @returns An array containing completion metadata objects
35
+ * for a given user. Each game contains two completion records,
36
+ * one for softcore and another for hardcore.
37
+ * ```json
38
+ * [
39
+ * {
40
+ * gameId: 14976,
41
+ * title: 'Mortal Kombat',
42
+ * imageIcon: '/Images/036812.png',
43
+ * consoleId: 27,
44
+ * consoleName: 'Arcade',
45
+ * maxPossible: 35,
46
+ * numAwarded: 13,
47
+ * pctWon: 0.3714,
48
+ * hardcoreMode: false
49
+ * },
50
+ * {
51
+ * gameId: 14976,
52
+ * title: 'Mortal Kombat',
53
+ * imageIcon: '/Images/036812.png',
54
+ * consoleId: 27,
55
+ * consoleName: 'Arcade',
56
+ * maxPossible: 35,
57
+ * numAwarded: 13,
58
+ * pctWon: 0.3714,
59
+ * hardcoreMode: true
60
+ * },
61
+ * ]
62
+ * ```
63
+ */
64
+ export const getUserCompletedGames = async (
65
+ authorization: AuthObject,
66
+ payload: { userName: string }
67
+ ): Promise<UserCompletedGames> => {
68
+ const { userName } = payload;
69
+
70
+ const url = buildRequestUrl(
71
+ apiBaseUrl,
72
+ "/API_GetUserCompletedGames.php",
73
+ authorization,
74
+ { u: userName }
75
+ );
76
+
77
+ const rawResponse = await call<GetUserCompletedGamesResponse>({ url });
78
+
79
+ return serializeProperties(rawResponse, {
80
+ shouldCastToNumbers: [
81
+ "GameID",
82
+ "ConsoleID",
83
+ "MaxPossible",
84
+ "NumAwarded",
85
+ "PctWon"
86
+ ],
87
+ shouldMapToBooleans: ["HardcoreMode"]
88
+ });
89
+ };
@@ -37,7 +37,7 @@ import type {
37
37
  * @returns An array containing metadata about the user's
38
38
  * rank and score for the target game ID. If metadata
39
39
  * cannot be found, the array is empty.
40
- * ```
40
+ * ```json
41
41
  * [
42
42
  * {
43
43
  * user: "xelnia",
package/src/user/index.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  export * from "./getAchievementsEarnedBetween";
2
2
  export * from "./getAchievementsEarnedOnDay";
3
3
  export * from "./getGameInfoAndUserProgress";
4
+ export * from "./getUserClaims";
5
+ export * from "./getUserCompletedGames";
4
6
  export * from "./getUserGameRankAndScore";
5
7
  export * from "./getUserPoints";
6
8
  export * from "./getUserProgress";
@@ -0,0 +1,13 @@
1
+ interface UserCompletedGamesResponseEntity {
2
+ GameID: string;
3
+ Title: string;
4
+ ImageIcon: string;
5
+ ConsoleID: string;
6
+ ConsoleName: string;
7
+ MaxPossible: string;
8
+ NumAwarded: string;
9
+ PctWon: string;
10
+ HardcoreMode: "0" | "1";
11
+ }
12
+
13
+ export type GetUserCompletedGamesResponse = UserCompletedGamesResponseEntity[];
@@ -2,11 +2,15 @@ export * from "./dated-user-achievement.model";
2
2
  export * from "./dated-user-achievements-response.model";
3
3
  export * from "./game-info-and-user-progress.model";
4
4
  export * from "./get-game-info-and-user-progress-response.model";
5
+ export * from "./get-user-completed-games-response.model";
5
6
  export * from "./get-user-game-rank-and-score-response.model";
6
7
  export * from "./get-user-points-response.model";
7
8
  export * from "./get-user-progress-response.model";
8
9
  export * from "./get-user-recently-played-games-response.model";
9
10
  export * from "./get-user-summary-response.model";
11
+ export * from "./user-claims.model";
12
+ export * from "./user-claims-response.model";
13
+ export * from "./user-completed-games.model";
10
14
  export * from "./user-game-rank-and-score.model";
11
15
  export * from "./user-points.model";
12
16
  export * from "./user-progress.model";
@@ -0,0 +1,19 @@
1
+ interface UserClaimsResponseEntity {
2
+ ID: string;
3
+ User: string;
4
+ GameID: string;
5
+ GameTitle: string;
6
+ GameIcon: string;
7
+ ConsoleName: string;
8
+ ClaimType: string;
9
+ SetType: string;
10
+ Status: string;
11
+ Extension: string;
12
+ Special: string;
13
+ Created: string;
14
+ DoneTime: string;
15
+ Updated: string;
16
+ MinutesLeft: string;
17
+ }
18
+
19
+ export type GetUserClaimsResponse = UserClaimsResponseEntity[];
@@ -0,0 +1,19 @@
1
+ interface UserClaim {
2
+ id: number;
3
+ user: string;
4
+ gameId: number;
5
+ gameTitle: string;
6
+ gameIcon: string;
7
+ consoleName: string;
8
+ claimType: number;
9
+ setType: number;
10
+ status: number;
11
+ extension: number;
12
+ special: number;
13
+ created: string;
14
+ doneTime: string;
15
+ updated: string;
16
+ minutesLeft: number;
17
+ }
18
+
19
+ export type UserClaims = UserClaim[];
@@ -0,0 +1,13 @@
1
+ interface UserCompletedGame {
2
+ gameId: number;
3
+ title: string;
4
+ imageIcon: string;
5
+ consoleId: number;
6
+ consoleName: string;
7
+ maxPossible: number;
8
+ numAwarded: number;
9
+ pctWon: number;
10
+ hardcoreMode: boolean;
11
+ }
12
+
13
+ export type UserCompletedGames = UserCompletedGame[];