@retroachievements/api 0.0.0-development
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/LICENSE.md +21 -0
- package/README.md +103 -0
- package/dist/__playground.d.ts +7 -0
- package/dist/achievement/getAchievementUnlocks.d.ts +45 -0
- package/dist/achievement/index.d.ts +2 -0
- package/dist/achievement/models/achievement-unlock-entity.model.d.ts +6 -0
- package/dist/achievement/models/get-achievement-unlocks-response.model.d.ts +8 -0
- package/dist/achievement/models/index.d.ts +2 -0
- package/dist/api.cjs.development.js +2363 -0
- package/dist/api.cjs.development.js.map +1 -0
- package/dist/api.cjs.production.min.js +2 -0
- package/dist/api.cjs.production.min.js.map +1 -0
- package/dist/api.esm.js +2333 -0
- package/dist/api.esm.js.map +1 -0
- package/dist/console/getConsoleIds.d.ts +22 -0
- package/dist/console/getGameList.d.ts +52 -0
- package/dist/console/index.d.ts +3 -0
- package/dist/console/models/console-id.model.d.ts +4 -0
- package/dist/console/models/game-list.model.d.ts +15 -0
- package/dist/console/models/get-console-ids-response.model.d.ts +4 -0
- package/dist/console/models/get-game-list-response.model.d.ts +15 -0
- package/dist/console/models/index.d.ts +4 -0
- package/dist/feed/getAchievementOfTheWeek.d.ts +48 -0
- package/dist/feed/getActiveClaims.d.ts +38 -0
- package/dist/feed/getTicketData.d.ts +158 -0
- package/dist/feed/getTopTenUsers.d.ts +24 -0
- package/dist/feed/index.d.ts +5 -0
- package/dist/feed/models/achievement-of-the-week.model.d.ts +32 -0
- package/dist/feed/models/achievement-ticket-stats-response.model.d.ts +7 -0
- package/dist/feed/models/achievement-ticket-stats.model.d.ts +7 -0
- package/dist/feed/models/active-claim.model.d.ts +49 -0
- package/dist/feed/models/game-ticket-stats.model.d.ts +9 -0
- package/dist/feed/models/game-tickets-response.model.d.ts +7 -0
- package/dist/feed/models/get-achievement-of-the-week-response.model.d.ts +32 -0
- package/dist/feed/models/get-active-claims-response.model.d.ts +19 -0
- package/dist/feed/models/get-top-ten-users-response.model.d.ts +10 -0
- package/dist/feed/models/index.d.ts +19 -0
- package/dist/feed/models/most-ticketed-games-response.model.d.ts +12 -0
- package/dist/feed/models/most-ticketed-games.model.d.ts +12 -0
- package/dist/feed/models/recent-tickets-response.model.d.ts +6 -0
- package/dist/feed/models/recent-tickets.model.d.ts +6 -0
- package/dist/feed/models/response-ticket-entity.model.d.ts +24 -0
- package/dist/feed/models/ticket-entity.model.d.ts +24 -0
- package/dist/feed/models/tickets-by-user-response.model.d.ts +8 -0
- package/dist/feed/models/top-ten-users-entity.model.d.ts +5 -0
- package/dist/feed/models/top-ten-users.model.d.ts +2 -0
- package/dist/feed/models/user-ticket-stats.model.d.ts +8 -0
- package/dist/game/getAchievementCount.d.ts +31 -0
- package/dist/game/getAchievementDistribution.d.ts +57 -0
- package/dist/game/getGame.d.ts +48 -0
- package/dist/game/getGameExtended.d.ts +68 -0
- package/dist/game/getGameRankAndScore.d.ts +38 -0
- package/dist/game/getGameRating.d.ts +38 -0
- package/dist/game/index.d.ts +7 -0
- package/dist/game/models/achievement-count.model.d.ts +4 -0
- package/dist/game/models/achievement-distribution-flags.model.d.ts +4 -0
- package/dist/game/models/game-extended-achievement-entity.model.d.ts +15 -0
- package/dist/game/models/game-extended-claim-entity.model.d.ts +7 -0
- package/dist/game/models/game-extended.model.d.ts +25 -0
- package/dist/game/models/game-rank-and-score-entity.model.d.ts +6 -0
- package/dist/game/models/game-rating.model.d.ts +9 -0
- package/dist/game/models/game.model.d.ts +19 -0
- package/dist/game/models/get-achievement-count-response.model.d.ts +4 -0
- package/dist/game/models/get-achievement-distribution-response.model.d.ts +1 -0
- package/dist/game/models/get-game-extended-response.model.d.ts +50 -0
- package/dist/game/models/get-game-rank-and-score-response.model.d.ts +8 -0
- package/dist/game/models/get-game-rating-response.model.d.ts +9 -0
- package/dist/game/models/get-game-response.model.d.ts +19 -0
- package/dist/game/models/index.d.ts +14 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +8 -0
- package/dist/user/getAchievementsEarnedBetween.d.ts +59 -0
- package/dist/user/getAchievementsEarnedOnDay.d.ts +57 -0
- package/dist/user/getGameInfoAndUserProgress.d.ts +80 -0
- package/dist/user/getUserGameRankAndScore.d.ts +44 -0
- package/dist/user/getUserPoints.d.ts +30 -0
- package/dist/user/getUserProgress.d.ts +49 -0
- package/dist/user/getUserRecentlyPlayedGames.d.ts +50 -0
- package/dist/user/getUserSummary.d.ts +32 -0
- package/dist/user/index.d.ts +9 -0
- package/dist/user/models/dated-user-achievement.model.d.ts +17 -0
- package/dist/user/models/dated-user-achievements-response.model.d.ts +19 -0
- package/dist/user/models/game-info-and-user-progress.model.d.ts +12 -0
- package/dist/user/models/get-game-info-and-user-progress-response.model.d.ts +14 -0
- package/dist/user/models/get-user-game-rank-and-score-response.model.d.ts +8 -0
- package/dist/user/models/get-user-points-response.model.d.ts +4 -0
- package/dist/user/models/get-user-progress-response.model.d.ts +10 -0
- package/dist/user/models/get-user-recently-played-games-response.model.d.ts +16 -0
- package/dist/user/models/get-user-summary-response.model.d.ts +82 -0
- package/dist/user/models/index.d.ts +14 -0
- package/dist/user/models/user-game-rank-and-score.model.d.ts +8 -0
- package/dist/user/models/user-points.model.d.ts +4 -0
- package/dist/user/models/user-progress.model.d.ts +10 -0
- package/dist/user/models/user-recently-played-games.model.d.ts +16 -0
- package/dist/user/models/user-summary.model.d.ts +83 -0
- package/dist/utils/internal/apiBaseUrl.d.ts +1 -0
- package/dist/utils/internal/buildRequestUrl.d.ts +2 -0
- package/dist/utils/internal/call.d.ts +20 -0
- package/dist/utils/internal/index.d.ts +4 -0
- package/dist/utils/internal/serializeProperties.d.ts +4 -0
- package/dist/utils/public/buildAuthorization.d.ts +22 -0
- package/dist/utils/public/index.d.ts +3 -0
- package/dist/utils/public/models/auth-object.model.d.ts +19 -0
- package/dist/utils/public/models/index.d.ts +1 -0
- package/package.json +117 -0
- package/src/__playground.ts +27 -0
- package/src/achievement/getAchievementUnlocks.test.ts +71 -0
- package/src/achievement/getAchievementUnlocks.ts +80 -0
- package/src/achievement/index.ts +2 -0
- package/src/achievement/models/achievement-unlock-entity.model.ts +6 -0
- package/src/achievement/models/get-achievement-unlocks-response.model.ts +8 -0
- package/src/achievement/models/index.ts +2 -0
- package/src/console/getConsoleIds.test.ts +53 -0
- package/src/console/getConsoleIds.ts +43 -0
- package/src/console/getGameList.test.ts +82 -0
- package/src/console/getGameList.ts +94 -0
- package/src/console/index.ts +3 -0
- package/src/console/models/console-id.model.ts +4 -0
- package/src/console/models/game-list.model.ts +16 -0
- package/src/console/models/get-console-ids-response.model.ts +1 -0
- package/src/console/models/get-game-list-response.model.ts +16 -0
- package/src/console/models/index.ts +4 -0
- package/src/feed/getAchievementOfTheWeek.test.ts +167 -0
- package/src/feed/getAchievementOfTheWeek.ts +80 -0
- package/src/feed/getActiveClaims.test.ts +81 -0
- package/src/feed/getActiveClaims.ts +68 -0
- package/src/feed/getTicketData.test.ts +349 -0
- package/src/feed/getTicketData.ts +286 -0
- package/src/feed/getTopTenUsers.test.ts +101 -0
- package/src/feed/getTopTenUsers.ts +51 -0
- package/src/feed/index.ts +5 -0
- package/src/feed/models/achievement-of-the-week.model.ts +27 -0
- package/src/feed/models/achievement-ticket-stats-response.model.ts +7 -0
- package/src/feed/models/achievement-ticket-stats.model.ts +7 -0
- package/src/feed/models/active-claim.model.ts +66 -0
- package/src/feed/models/game-ticket-stats.model.ts +11 -0
- package/src/feed/models/game-tickets-response.model.ts +7 -0
- package/src/feed/models/get-achievement-of-the-week-response.model.ts +27 -0
- package/src/feed/models/get-active-claims-response.model.ts +19 -0
- package/src/feed/models/get-top-ten-users-response.model.ts +12 -0
- package/src/feed/models/index.ts +19 -0
- package/src/feed/models/most-ticketed-games-response.model.ts +12 -0
- package/src/feed/models/most-ticketed-games.model.ts +12 -0
- package/src/feed/models/recent-tickets-response.model.ts +7 -0
- package/src/feed/models/recent-tickets.model.ts +7 -0
- package/src/feed/models/response-ticket-entity.model.ts +25 -0
- package/src/feed/models/ticket-entity.model.ts +24 -0
- package/src/feed/models/tickets-by-user-response.model.ts +8 -0
- package/src/feed/models/top-ten-users-entity.model.ts +5 -0
- package/src/feed/models/top-ten-users.model.ts +3 -0
- package/src/feed/models/user-ticket-stats.model.ts +8 -0
- package/src/game/getAchievementCount.test.ts +49 -0
- package/src/game/getAchievementCount.ts +52 -0
- package/src/game/getAchievementDistribution.test.ts +187 -0
- package/src/game/getAchievementDistribution.ts +88 -0
- package/src/game/getGame.test.ts +81 -0
- package/src/game/getGame.ts +74 -0
- package/src/game/getGameExtended.test.ts +121 -0
- package/src/game/getGameExtended.ts +103 -0
- package/src/game/getGameRankAndScore.test.ts +62 -0
- package/src/game/getGameRankAndScore.ts +66 -0
- package/src/game/getGameRating.test.ts +59 -0
- package/src/game/getGameRating.ts +59 -0
- package/src/game/index.ts +7 -0
- package/src/game/models/achievement-count.model.ts +4 -0
- package/src/game/models/achievement-distribution-flags.model.ts +4 -0
- package/src/game/models/game-extended-achievement-entity.model.ts +15 -0
- package/src/game/models/game-extended-claim-entity.model.ts +7 -0
- package/src/game/models/game-extended.model.ts +26 -0
- package/src/game/models/game-rank-and-score-entity.model.ts +6 -0
- package/src/game/models/game-rating.model.ts +9 -0
- package/src/game/models/game.model.ts +19 -0
- package/src/game/models/get-achievement-count-response.model.ts +4 -0
- package/src/game/models/get-achievement-distribution-response.model.ts +1 -0
- package/src/game/models/get-game-extended-response.model.ts +56 -0
- package/src/game/models/get-game-rank-and-score-response.model.ts +8 -0
- package/src/game/models/get-game-rating-response.model.ts +9 -0
- package/src/game/models/get-game-response.model.ts +19 -0
- package/src/game/models/index.ts +14 -0
- package/src/index.ts +8 -0
- package/src/user/getAchievementsEarnedBetween.test.ts +84 -0
- package/src/user/getAchievementsEarnedBetween.ts +88 -0
- package/src/user/getAchievementsEarnedOnDay.test.ts +83 -0
- package/src/user/getAchievementsEarnedOnDay.ts +87 -0
- package/src/user/getGameInfoAndUserProgress.test.ts +135 -0
- package/src/user/getGameInfoAndUserProgress.ts +118 -0
- package/src/user/getUserGameRankAndScore.test.ts +60 -0
- package/src/user/getUserGameRankAndScore.ts +69 -0
- package/src/user/getUserPoints.test.ts +49 -0
- package/src/user/getUserPoints.ts +51 -0
- package/src/user/getUserProgress.test.ts +80 -0
- package/src/user/getUserProgress.ts +78 -0
- package/src/user/getUserRecentlyPlayedGames.test.ts +76 -0
- package/src/user/getUserRecentlyPlayedGames.ts +93 -0
- package/src/user/getUserSummary.test.ts +251 -0
- package/src/user/getUserSummary.ts +96 -0
- package/src/user/index.ts +9 -0
- package/src/user/models/dated-user-achievement.model.ts +17 -0
- package/src/user/models/dated-user-achievements-response.model.ts +20 -0
- package/src/user/models/game-info-and-user-progress.model.ts +19 -0
- package/src/user/models/get-game-info-and-user-progress-response.model.ts +28 -0
- package/src/user/models/get-user-game-rank-and-score-response.model.ts +9 -0
- package/src/user/models/get-user-points-response.model.ts +4 -0
- package/src/user/models/get-user-progress-response.model.ts +13 -0
- package/src/user/models/get-user-recently-played-games-response.model.ts +17 -0
- package/src/user/models/get-user-summary-response.model.ts +92 -0
- package/src/user/models/index.ts +14 -0
- package/src/user/models/user-game-rank-and-score.model.ts +8 -0
- package/src/user/models/user-points.model.ts +4 -0
- package/src/user/models/user-progress.model.ts +10 -0
- package/src/user/models/user-recently-played-games.model.ts +16 -0
- package/src/user/models/user-summary.model.ts +92 -0
- package/src/utils/internal/apiBaseUrl.ts +1 -0
- package/src/utils/internal/buildRequestUrl.test.ts +51 -0
- package/src/utils/internal/buildRequestUrl.ts +32 -0
- package/src/utils/internal/call.test.ts +39 -0
- package/src/utils/internal/call.ts +29 -0
- package/src/utils/internal/index.ts +4 -0
- package/src/utils/internal/serializeProperties.test.ts +141 -0
- package/src/utils/internal/serializeProperties.ts +75 -0
- package/src/utils/public/buildAuthorization.test.ts +36 -0
- package/src/utils/public/buildAuthorization.ts +40 -0
- package/src/utils/public/index.ts +3 -0
- package/src/utils/public/models/auth-object.model.ts +20 -0
- package/src/utils/public/models/index.ts +1 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { rest } from "msw";
|
|
2
|
+
import { setupServer } from "msw/node";
|
|
3
|
+
|
|
4
|
+
import { apiBaseUrl } from "../utils/internal";
|
|
5
|
+
import { buildAuthorization } from "../utils/public";
|
|
6
|
+
import { getAchievementsEarnedOnDay } from "./getAchievementsEarnedOnDay";
|
|
7
|
+
import type { DatedUserAchievementsResponse } from "./models";
|
|
8
|
+
|
|
9
|
+
const server = setupServer();
|
|
10
|
+
|
|
11
|
+
describe("Function: getAchievementsEarnedOnDay", () => {
|
|
12
|
+
// MSW Setup
|
|
13
|
+
beforeAll(() => server.listen());
|
|
14
|
+
afterEach(() => server.resetHandlers());
|
|
15
|
+
afterAll(() => server.close());
|
|
16
|
+
|
|
17
|
+
it("is defined #sanity", () => {
|
|
18
|
+
// ASSERT
|
|
19
|
+
expect(getAchievementsEarnedOnDay).toBeDefined();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("retrieves a list of user achievements earned on a specified date", async () => {
|
|
23
|
+
// ARRANGE
|
|
24
|
+
const authorization = buildAuthorization({
|
|
25
|
+
userName: "mockUserName",
|
|
26
|
+
webApiKey: "mockWebApiKey"
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const mockResponse: DatedUserAchievementsResponse = [
|
|
30
|
+
{
|
|
31
|
+
Date: "2022-10-12 07:36:31",
|
|
32
|
+
HardcoreMode: "1",
|
|
33
|
+
AchievementID: "173356",
|
|
34
|
+
Title: "Wind Beneath My Wings",
|
|
35
|
+
Description: "Collect all objects in the Wings Category.",
|
|
36
|
+
BadgeName: "193797",
|
|
37
|
+
Points: "10",
|
|
38
|
+
Author: "blendedsea",
|
|
39
|
+
GameTitle: "Me & My Katamari",
|
|
40
|
+
GameIcon: "/Images/047357.png",
|
|
41
|
+
GameID: "3571",
|
|
42
|
+
ConsoleName: "PlayStation Portable",
|
|
43
|
+
CumulScore: 40,
|
|
44
|
+
BadgeURL: "/Badge/193797.png",
|
|
45
|
+
GameURL: "/game/3571"
|
|
46
|
+
}
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
server.use(
|
|
50
|
+
rest.get(
|
|
51
|
+
`${apiBaseUrl}/API_GetAchievementsEarnedOnDay.php`,
|
|
52
|
+
(_, res, ctx) => res(ctx.json(mockResponse))
|
|
53
|
+
)
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
// ACT
|
|
57
|
+
const response = await getAchievementsEarnedOnDay(authorization, {
|
|
58
|
+
userName: "xelnia",
|
|
59
|
+
onDate: new Date("2022-10-12")
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// ASSERT
|
|
63
|
+
expect(response).toEqual([
|
|
64
|
+
{
|
|
65
|
+
date: "2022-10-12 07:36:31",
|
|
66
|
+
hardcoreMode: true,
|
|
67
|
+
achievementId: 173_356,
|
|
68
|
+
title: "Wind Beneath My Wings",
|
|
69
|
+
description: "Collect all objects in the Wings Category.",
|
|
70
|
+
badgeName: "193797",
|
|
71
|
+
points: 10,
|
|
72
|
+
author: "blendedsea",
|
|
73
|
+
gameTitle: "Me & My Katamari",
|
|
74
|
+
gameIcon: "/Images/047357.png",
|
|
75
|
+
gameId: 3571,
|
|
76
|
+
consoleName: "PlayStation Portable",
|
|
77
|
+
cumulScore: 40,
|
|
78
|
+
badgeUrl: "/Badge/193797.png",
|
|
79
|
+
gameUrl: "/game/3571"
|
|
80
|
+
}
|
|
81
|
+
]);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
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
|
+
DatedUserAchievement,
|
|
10
|
+
DatedUserAchievementsResponse
|
|
11
|
+
} from "./models";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A call to this function will retrieve a list of achievements
|
|
15
|
+
* earned by a given user on a specified date.
|
|
16
|
+
*
|
|
17
|
+
* @param authorization An object containing your userName and webApiKey.
|
|
18
|
+
* This can be constructed with `buildAuthorization()`.
|
|
19
|
+
*
|
|
20
|
+
* @param payload.userName The user for which to retrieve the
|
|
21
|
+
* list of achievements for.
|
|
22
|
+
*
|
|
23
|
+
* @param payload.fromDate A Date object specifying when
|
|
24
|
+
* the list itself should begin.
|
|
25
|
+
*
|
|
26
|
+
* @param payload.onDate A Date object specifying the day
|
|
27
|
+
* to query for a user's earned achievements.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```
|
|
31
|
+
* const achievementsEarnedOnDay = await getAchievementsEarnedOnDay(
|
|
32
|
+
* authorization,
|
|
33
|
+
* {
|
|
34
|
+
* userName: "xelnia",
|
|
35
|
+
* onDate: new Date("2022-10-13")
|
|
36
|
+
* }
|
|
37
|
+
* );
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @returns An array containing metadata about the user
|
|
41
|
+
* achievements earned on the specified day.
|
|
42
|
+
* ```
|
|
43
|
+
* [
|
|
44
|
+
* {
|
|
45
|
+
* date: '2022-10-12 07:58:05',
|
|
46
|
+
* hardcoreMode: true,
|
|
47
|
+
* achievementId: 173315,
|
|
48
|
+
* title: 'Your Puny Human Weapons',
|
|
49
|
+
* description: 'Collect all objects in the Weapons Category.',
|
|
50
|
+
* badgeName: '193756',
|
|
51
|
+
* points: 10,
|
|
52
|
+
* author: 'blendedsea',
|
|
53
|
+
* gameTitle: 'Me & My Katamari',
|
|
54
|
+
* gameIcon: '/Images/047357.png',
|
|
55
|
+
* gameId: 3571,
|
|
56
|
+
* consoleName: 'PlayStation Portable',
|
|
57
|
+
* cumulScore: 120,
|
|
58
|
+
* badgeUrl: '/Badge/193756.png',
|
|
59
|
+
* gameUrl: '/game/3571'
|
|
60
|
+
* }
|
|
61
|
+
* ]
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export const getAchievementsEarnedOnDay = async (
|
|
65
|
+
authorization: AuthObject,
|
|
66
|
+
payload: { userName: string; onDate: Date }
|
|
67
|
+
): Promise<DatedUserAchievement[]> => {
|
|
68
|
+
const { userName, onDate } = payload;
|
|
69
|
+
|
|
70
|
+
const url = buildRequestUrl(
|
|
71
|
+
apiBaseUrl,
|
|
72
|
+
"/API_GetAchievementsEarnedOnDay.php",
|
|
73
|
+
authorization,
|
|
74
|
+
{
|
|
75
|
+
u: userName,
|
|
76
|
+
// YYYY-MM-DD
|
|
77
|
+
d: `${onDate.getFullYear()}-${onDate.getMonth() + 1}-${onDate.getDate()}`
|
|
78
|
+
}
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const rawResponse = await call<DatedUserAchievementsResponse>({ url });
|
|
82
|
+
|
|
83
|
+
return serializeProperties(rawResponse, {
|
|
84
|
+
shouldCastToNumbers: ["AchievementID", "Points", "GameID"],
|
|
85
|
+
shouldMapToBooleans: ["HardcoreMode"]
|
|
86
|
+
});
|
|
87
|
+
};
|
|
@@ -0,0 +1,135 @@
|
|
|
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 { getGameInfoAndUserProgress } from "./getGameInfoAndUserProgress";
|
|
9
|
+
import type { GetGameInfoAndUserProgressResponse } from "./models";
|
|
10
|
+
|
|
11
|
+
const server = setupServer();
|
|
12
|
+
|
|
13
|
+
describe("Function: getGameInfoAndUserProgress", () => {
|
|
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(getGameInfoAndUserProgress).toBeDefined();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("given a game ID and a username, retrieves extended metadata about the game and that user`s progress", async () => {
|
|
25
|
+
// ARRANGE
|
|
26
|
+
const authorization = buildAuthorization({
|
|
27
|
+
userName: "mockUserName",
|
|
28
|
+
webApiKey: "mockWebApiKey"
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const mockResponse: GetGameInfoAndUserProgressResponse = {
|
|
32
|
+
ID: 14_402,
|
|
33
|
+
Title: "Dragster",
|
|
34
|
+
ConsoleID: 25,
|
|
35
|
+
ForumTopicID: 9145,
|
|
36
|
+
Flags: 0,
|
|
37
|
+
ImageIcon: "/Images/026368.png",
|
|
38
|
+
ImageTitle: "/Images/026366.png",
|
|
39
|
+
ImageIngame: "/Images/026367.png",
|
|
40
|
+
ImageBoxArt: "/Images/026365.png",
|
|
41
|
+
Publisher: "Activision ",
|
|
42
|
+
Developer: "David Crane",
|
|
43
|
+
Genre: "Racing",
|
|
44
|
+
Released: "1980",
|
|
45
|
+
IsFinal: false,
|
|
46
|
+
ConsoleName: "Atari 2600",
|
|
47
|
+
RichPresencePatch: "2b92fa1bf9635c303b3b7f8feea3ed3c",
|
|
48
|
+
NumAchievements: 12,
|
|
49
|
+
NumDistinctPlayersCasual: "454",
|
|
50
|
+
NumDistinctPlayersHardcore: "323",
|
|
51
|
+
Achievements: {
|
|
52
|
+
"79434": {
|
|
53
|
+
ID: "79434",
|
|
54
|
+
NumAwarded: "338",
|
|
55
|
+
NumAwardedHardcore: "253",
|
|
56
|
+
Title: "Novice Dragster Driver 1",
|
|
57
|
+
Description: "Complete your very first race in game 1.",
|
|
58
|
+
Points: "1",
|
|
59
|
+
TrueRatio: "1",
|
|
60
|
+
Author: "Boldewin",
|
|
61
|
+
DateModified: "2019-08-01 19:03:46",
|
|
62
|
+
DateCreated: "2019-07-31 18:49:57",
|
|
63
|
+
BadgeName: "85541",
|
|
64
|
+
DisplayOrder: "0",
|
|
65
|
+
MemAddr: "f5c41fa0b5fa0d5fbb8a74c598f18582",
|
|
66
|
+
DateEarned: "2022-08-23 22:56:38",
|
|
67
|
+
DateEarnedHardcore: "2022-08-23 22:56:38"
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
NumAwardedToUser: 12,
|
|
71
|
+
NumAwardedToUserHardcore: 12,
|
|
72
|
+
UserCompletion: "100.00%",
|
|
73
|
+
UserCompletionHardcore: "100.00%"
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
server.use(
|
|
77
|
+
rest.get(
|
|
78
|
+
`${apiBaseUrl}/API_GetGameInfoAndUserProgress.php`,
|
|
79
|
+
(_, res, ctx) => res(ctx.json(mockResponse))
|
|
80
|
+
)
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
// ACT
|
|
84
|
+
const response = await getGameInfoAndUserProgress(authorization, {
|
|
85
|
+
gameId: 14_402,
|
|
86
|
+
userName: "xelnia"
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// ASSERT
|
|
90
|
+
expect(response).toEqual({
|
|
91
|
+
id: 14_402,
|
|
92
|
+
title: "Dragster",
|
|
93
|
+
consoleId: 25,
|
|
94
|
+
forumTopicId: 9145,
|
|
95
|
+
flags: 0,
|
|
96
|
+
imageIcon: "/Images/026368.png",
|
|
97
|
+
imageTitle: "/Images/026366.png",
|
|
98
|
+
imageIngame: "/Images/026367.png",
|
|
99
|
+
imageBoxArt: "/Images/026365.png",
|
|
100
|
+
publisher: "Activision ",
|
|
101
|
+
developer: "David Crane",
|
|
102
|
+
genre: "Racing",
|
|
103
|
+
released: 1980,
|
|
104
|
+
isFinal: false,
|
|
105
|
+
consoleName: "Atari 2600",
|
|
106
|
+
richPresencePatch: "2b92fa1bf9635c303b3b7f8feea3ed3c",
|
|
107
|
+
numAchievements: 12,
|
|
108
|
+
numDistinctPlayersCasual: 454,
|
|
109
|
+
numDistinctPlayersHardcore: 323,
|
|
110
|
+
achievements: {
|
|
111
|
+
"79434": {
|
|
112
|
+
id: 79_434,
|
|
113
|
+
numAwarded: 338,
|
|
114
|
+
numAwardedHardcore: 253,
|
|
115
|
+
title: "Novice Dragster Driver 1",
|
|
116
|
+
description: "Complete your very first race in game 1.",
|
|
117
|
+
points: 1,
|
|
118
|
+
trueRatio: 1,
|
|
119
|
+
author: "Boldewin",
|
|
120
|
+
dateModified: "2019-08-01 19:03:46",
|
|
121
|
+
dateCreated: "2019-07-31 18:49:57",
|
|
122
|
+
badgeName: "85541",
|
|
123
|
+
displayOrder: 0,
|
|
124
|
+
memAddr: "f5c41fa0b5fa0d5fbb8a74c598f18582",
|
|
125
|
+
dateEarned: "2022-08-23 22:56:38",
|
|
126
|
+
dateEarnedHardcore: "2022-08-23 22:56:38"
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
numAwardedToUser: 12,
|
|
130
|
+
numAwardedToUserHardcore: 12,
|
|
131
|
+
userCompletion: "100.00%",
|
|
132
|
+
userCompletionHardcore: "100.00%"
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
});
|
|
@@ -0,0 +1,118 @@
|
|
|
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
|
+
GameInfoAndUserProgress,
|
|
10
|
+
GetGameInfoAndUserProgressResponse
|
|
11
|
+
} from "./models";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A call to this function will retrieve extended metadata
|
|
15
|
+
* about a game, in addition to a user's progress about a game.
|
|
16
|
+
* This is targeted via a game's unique ID and a given username.
|
|
17
|
+
*
|
|
18
|
+
* @param authorization An object containing your userName and webApiKey.
|
|
19
|
+
* This can be constructed with `buildAuthorization()`.
|
|
20
|
+
*
|
|
21
|
+
* @param payload.gameId The unique game ID. If you are unsure, open the
|
|
22
|
+
* game's page on the RetroAchievements.org website. For example, Dragster's
|
|
23
|
+
* URL is https://retroachievements.org/game/14402. We can see from the
|
|
24
|
+
* URL that the game ID is "14402".
|
|
25
|
+
*
|
|
26
|
+
* @param payload.userName The user for which to retrieve the
|
|
27
|
+
* game progress for.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```
|
|
31
|
+
* const gameInfoAndUserProgress = await getGameInfoAndUserProgress(
|
|
32
|
+
* authorization,
|
|
33
|
+
* { gameId: 14402, userName: "wv_pinball" }
|
|
34
|
+
* );
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @returns An object containing extended metadata about a target game,
|
|
38
|
+
* with attached progress for a target username.
|
|
39
|
+
* ```json
|
|
40
|
+
* {
|
|
41
|
+
* id: 14402,
|
|
42
|
+
* title: "Dragster",
|
|
43
|
+
* consoleId: 25,
|
|
44
|
+
* forumTopicId: 9145,
|
|
45
|
+
* flags: 0,
|
|
46
|
+
* imageIcon: "/Images/026368.png",
|
|
47
|
+
* imageTitle: "/Images/026366.png",
|
|
48
|
+
* imageIngame: "/Images/026367.png",
|
|
49
|
+
* imageBoxArt: "/Images/026365.png",
|
|
50
|
+
* publisher: "Activision",
|
|
51
|
+
* developer: "David Crane",
|
|
52
|
+
* genre: "Racing",
|
|
53
|
+
* released: 1980,
|
|
54
|
+
* isFinal: false,
|
|
55
|
+
* consoleName: "Atari 2600",
|
|
56
|
+
* richPresencePatch: "2b92fa1bf9635c303b3b7f8feea3ed3c",
|
|
57
|
+
* numAchievements: 12,
|
|
58
|
+
* numDistinctPlayersCasual: 454,
|
|
59
|
+
* numDistinctPlayersHardcore, 323
|
|
60
|
+
* claims: [],
|
|
61
|
+
* achievements: {
|
|
62
|
+
* '79434': {
|
|
63
|
+
* id: 79434,
|
|
64
|
+
* numAwarded: 338,
|
|
65
|
+
* numAwardedHardcore: 253,
|
|
66
|
+
* title: "Novice Dragster Driver 1",
|
|
67
|
+
* description: "Complete your very first race in game 1.",
|
|
68
|
+
* points: 1,
|
|
69
|
+
* trueRatio: 1,
|
|
70
|
+
* author: "Boldewin",
|
|
71
|
+
* dateModified: "2019-08-01 19:03:46",
|
|
72
|
+
* dateCreated: "2019-07-31 18:49:57",
|
|
73
|
+
* badgeName: "85541",
|
|
74
|
+
* displayOrder: 0,
|
|
75
|
+
* memAddr: "f5c41fa0b5fa0d5fbb8a74c598f18582",
|
|
76
|
+
* dateEarned: '2022-08-23 22:56:38',
|
|
77
|
+
* dateEarnedHardcore: '2022-08-23 22:56:38'
|
|
78
|
+
* }
|
|
79
|
+
* },
|
|
80
|
+
* numAwardedToUser: 12,
|
|
81
|
+
* numAwardedToUserHardcore: 12,
|
|
82
|
+
* userCompletion: "100.00%",
|
|
83
|
+
* userCompletionHardcore: "100.00%"
|
|
84
|
+
* }
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export const getGameInfoAndUserProgress = async (
|
|
88
|
+
authorization: AuthObject,
|
|
89
|
+
payload: { gameId: number; userName: string }
|
|
90
|
+
): Promise<GameInfoAndUserProgress> => {
|
|
91
|
+
const { gameId, userName } = payload;
|
|
92
|
+
|
|
93
|
+
const url = buildRequestUrl(
|
|
94
|
+
apiBaseUrl,
|
|
95
|
+
"/API_GetGameInfoAndUserProgress.php",
|
|
96
|
+
authorization,
|
|
97
|
+
{
|
|
98
|
+
g: gameId,
|
|
99
|
+
u: userName
|
|
100
|
+
}
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
const rawResponse = await call<GetGameInfoAndUserProgressResponse>({ url });
|
|
104
|
+
|
|
105
|
+
return serializeProperties(rawResponse, {
|
|
106
|
+
shouldCastToNumbers: [
|
|
107
|
+
"ID",
|
|
108
|
+
"NumAwarded",
|
|
109
|
+
"NumAwardedHardcore",
|
|
110
|
+
"Points",
|
|
111
|
+
"TrueRatio",
|
|
112
|
+
"DisplayOrder",
|
|
113
|
+
"NumDistinctPlayersCasual",
|
|
114
|
+
"NumDistinctPlayersHardcore",
|
|
115
|
+
"Released"
|
|
116
|
+
]
|
|
117
|
+
});
|
|
118
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { rest } from "msw";
|
|
2
|
+
import { setupServer } from "msw/node";
|
|
3
|
+
|
|
4
|
+
import { apiBaseUrl } from "../utils/internal";
|
|
5
|
+
import { buildAuthorization } from "../utils/public";
|
|
6
|
+
import { getUserGameRankAndScore } from "./getUserGameRankAndScore";
|
|
7
|
+
import type { GetUserGameRankAndScoreResponse } from "./models";
|
|
8
|
+
|
|
9
|
+
const server = setupServer();
|
|
10
|
+
|
|
11
|
+
describe("Function: getUserGameRankAndScore", () => {
|
|
12
|
+
// MSW Setup
|
|
13
|
+
beforeAll(() => server.listen());
|
|
14
|
+
afterEach(() => server.resetHandlers());
|
|
15
|
+
afterAll(() => server.close());
|
|
16
|
+
|
|
17
|
+
it("is defined #sanity", () => {
|
|
18
|
+
// ASSERT
|
|
19
|
+
expect(getUserGameRankAndScore).toBeDefined();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("given a game ID and a user name, retrieves metadata about how that user ranks on the given game", async () => {
|
|
23
|
+
// ARRANGE
|
|
24
|
+
const authorization = buildAuthorization({
|
|
25
|
+
userName: "mockUserName",
|
|
26
|
+
webApiKey: "mockWebApiKey"
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const mockResponse: GetUserGameRankAndScoreResponse = [
|
|
30
|
+
{
|
|
31
|
+
User: "xelnia",
|
|
32
|
+
TotalScore: "1000",
|
|
33
|
+
LastAward: "2022-09-01 21:51:23",
|
|
34
|
+
UserRank: "4"
|
|
35
|
+
}
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
server.use(
|
|
39
|
+
rest.get(`${apiBaseUrl}/API_GetUserGameRankAndScore.php`, (_, res, ctx) =>
|
|
40
|
+
res(ctx.json(mockResponse))
|
|
41
|
+
)
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
// ACT
|
|
45
|
+
const response = await getUserGameRankAndScore(authorization, {
|
|
46
|
+
userName: "xelnia",
|
|
47
|
+
gameId: 14_402
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// ASSERT
|
|
51
|
+
expect(response).toEqual([
|
|
52
|
+
{
|
|
53
|
+
user: "xelnia",
|
|
54
|
+
totalScore: 1000,
|
|
55
|
+
lastAward: "2022-09-01 21:51:23",
|
|
56
|
+
userRank: 4
|
|
57
|
+
}
|
|
58
|
+
]);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
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
|
+
GetUserGameRankAndScoreResponse,
|
|
10
|
+
UserGameRankAndScore
|
|
11
|
+
} from "./models";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A call to this function will retrieve metadata about
|
|
15
|
+
* how a particular user has performed/ranked on a particular
|
|
16
|
+
* game, targeted by game ID.
|
|
17
|
+
*
|
|
18
|
+
* @param authorization An object containing your userName and webApiKey.
|
|
19
|
+
* This can be constructed with `buildAuthorization()`.
|
|
20
|
+
*
|
|
21
|
+
* @param payload.gameId The unique game ID. If you are unsure, open the
|
|
22
|
+
* game's page on the RetroAchievements.org website. For example, Dragster's
|
|
23
|
+
* URL is https://retroachievements.org/game/14402. We can see from the
|
|
24
|
+
* URL that the game ID is "14402".
|
|
25
|
+
*
|
|
26
|
+
* @param payload.userName The user for which to retrieve the
|
|
27
|
+
* game ranking metadata for.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```
|
|
31
|
+
* const userGameRankAndScore = await getUserGameRankAndScore(
|
|
32
|
+
* authorization,
|
|
33
|
+
* { gameId: 14402, userName: "xelnia" }
|
|
34
|
+
* );
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @returns An array containing metadata about the user's
|
|
38
|
+
* rank and score for the target game ID. If metadata
|
|
39
|
+
* cannot be found, the array is empty.
|
|
40
|
+
* ```
|
|
41
|
+
* [
|
|
42
|
+
* {
|
|
43
|
+
* user: "xelnia",
|
|
44
|
+
* totalScore: 378,
|
|
45
|
+
* lastAward: "2022-09-01 21:51:23",
|
|
46
|
+
* userRank: 3
|
|
47
|
+
* }
|
|
48
|
+
* ]
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export const getUserGameRankAndScore = async (
|
|
52
|
+
authorization: AuthObject,
|
|
53
|
+
payload: { gameId: number; userName: string }
|
|
54
|
+
): Promise<UserGameRankAndScore> => {
|
|
55
|
+
const { gameId, userName } = payload;
|
|
56
|
+
|
|
57
|
+
const url = buildRequestUrl(
|
|
58
|
+
apiBaseUrl,
|
|
59
|
+
"/API_GetUserGameRankAndScore.php",
|
|
60
|
+
authorization,
|
|
61
|
+
{ g: gameId, u: userName }
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const rawResponse = await call<GetUserGameRankAndScoreResponse>({ url });
|
|
65
|
+
|
|
66
|
+
return serializeProperties(rawResponse, {
|
|
67
|
+
shouldCastToNumbers: ["TotalScore", "UserRank"]
|
|
68
|
+
});
|
|
69
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { rest } from "msw";
|
|
2
|
+
import { setupServer } from "msw/node";
|
|
3
|
+
|
|
4
|
+
import { apiBaseUrl } from "../utils/internal";
|
|
5
|
+
import { buildAuthorization } from "../utils/public";
|
|
6
|
+
import { getUserPoints } from "./getUserPoints";
|
|
7
|
+
import type { GetUserPointsResponse } from "./models";
|
|
8
|
+
|
|
9
|
+
const server = setupServer();
|
|
10
|
+
|
|
11
|
+
describe("Function: getUserPoints", () => {
|
|
12
|
+
// MSW Setup
|
|
13
|
+
beforeAll(() => server.listen());
|
|
14
|
+
afterEach(() => server.resetHandlers());
|
|
15
|
+
afterAll(() => server.close());
|
|
16
|
+
|
|
17
|
+
it("is defined #sanity", () => {
|
|
18
|
+
// ASSERT
|
|
19
|
+
expect(getUserPoints).toBeDefined();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("given a username, retrieves the point values associated with the user", async () => {
|
|
23
|
+
// ARRANGE
|
|
24
|
+
const authorization = buildAuthorization({
|
|
25
|
+
userName: "mockUserName",
|
|
26
|
+
webApiKey: "mockWebApiKey"
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const mockResponse: GetUserPointsResponse = {
|
|
30
|
+
Points: 10_000,
|
|
31
|
+
SoftcorePoints: 5400
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
server.use(
|
|
35
|
+
rest.get(`${apiBaseUrl}/API_GetUserPoints.php`, (_, res, ctx) =>
|
|
36
|
+
res(ctx.json(mockResponse))
|
|
37
|
+
)
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
// ACT
|
|
41
|
+
const response = await getUserPoints(authorization, { userName: "xelnia" });
|
|
42
|
+
|
|
43
|
+
// ASSERT
|
|
44
|
+
expect(response).toEqual({
|
|
45
|
+
points: 10_000,
|
|
46
|
+
softcorePoints: 5400
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {
|
|
2
|
+
apiBaseUrl,
|
|
3
|
+
buildRequestUrl,
|
|
4
|
+
call,
|
|
5
|
+
serializeProperties
|
|
6
|
+
} from "../utils/internal";
|
|
7
|
+
import type { AuthObject } from "../utils/public";
|
|
8
|
+
import type { GetUserPointsResponse, UserPoints } from "./models";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A call to this function will retrieve a given user's hardcore
|
|
12
|
+
* and softcore points.
|
|
13
|
+
*
|
|
14
|
+
* @param authorization An object containing your userName and webApiKey.
|
|
15
|
+
* This can be constructed with `buildAuthorization()`.
|
|
16
|
+
*
|
|
17
|
+
* @param payload.userName The user for which to retrieve the points for.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```
|
|
21
|
+
* const userPoints = await getUserPoints(
|
|
22
|
+
* authorization,
|
|
23
|
+
* { userName: "xelnia" }
|
|
24
|
+
* );
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @returns An object containing metadata about a target user's points.
|
|
28
|
+
* ```json
|
|
29
|
+
* {
|
|
30
|
+
* points: 7640,
|
|
31
|
+
* softcorePoints: 25
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export const getUserPoints = async (
|
|
36
|
+
authorization: AuthObject,
|
|
37
|
+
payload: { userName: string }
|
|
38
|
+
): Promise<UserPoints> => {
|
|
39
|
+
const { userName } = payload;
|
|
40
|
+
|
|
41
|
+
const url = buildRequestUrl(
|
|
42
|
+
apiBaseUrl,
|
|
43
|
+
"/API_GetUserPoints.php",
|
|
44
|
+
authorization,
|
|
45
|
+
{ u: userName }
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const rawResponse = await call<GetUserPointsResponse>({ url });
|
|
49
|
+
|
|
50
|
+
return serializeProperties(rawResponse);
|
|
51
|
+
};
|