@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,187 @@
|
|
|
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 { getAchievementDistribution } from "./getAchievementDistribution";
|
|
7
|
+
import {
|
|
8
|
+
type GetAchievementDistributionResponse,
|
|
9
|
+
AchievementDistributionFlags
|
|
10
|
+
} from "./models";
|
|
11
|
+
|
|
12
|
+
const server = setupServer();
|
|
13
|
+
|
|
14
|
+
describe("Function: getAchievementDistribution", () => {
|
|
15
|
+
// MSW Setup
|
|
16
|
+
beforeAll(() => server.listen());
|
|
17
|
+
afterEach(() => server.resetHandlers());
|
|
18
|
+
afterAll(() => server.close());
|
|
19
|
+
|
|
20
|
+
it("is defined #sanity", () => {
|
|
21
|
+
// ASSERT
|
|
22
|
+
expect(getAchievementDistribution).toBeDefined();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("given a game ID, retrieves the achievement distribution associated with the game", async () => {
|
|
26
|
+
// ARRANGE
|
|
27
|
+
const authorization = buildAuthorization({
|
|
28
|
+
userName: "mockUserName",
|
|
29
|
+
webApiKey: "mockWebApiKey"
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const mockResponse: GetAchievementDistributionResponse = {
|
|
33
|
+
"1": 20,
|
|
34
|
+
"2": 10,
|
|
35
|
+
"3": 8,
|
|
36
|
+
"4": 4,
|
|
37
|
+
"5": 1
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
let detectedSearchParams: URLSearchParams;
|
|
41
|
+
|
|
42
|
+
server.use(
|
|
43
|
+
rest.get(
|
|
44
|
+
`${apiBaseUrl}/API_GetAchievementDistribution.php`,
|
|
45
|
+
(req, res, ctx) => {
|
|
46
|
+
detectedSearchParams = req.url.searchParams;
|
|
47
|
+
return res(ctx.json(mockResponse));
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
// ACT
|
|
53
|
+
const response = await getAchievementDistribution(authorization, {
|
|
54
|
+
gameId: 14_402
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// ASSERT
|
|
58
|
+
expect(response).toEqual(mockResponse);
|
|
59
|
+
|
|
60
|
+
expect(detectedSearchParams!.get("i")).toEqual("14402");
|
|
61
|
+
expect(detectedSearchParams!.has("f")).toBeFalsy();
|
|
62
|
+
expect(detectedSearchParams!.has("h")).toBeFalsy();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("given flags, successfully attaches the option to the call", async () => {
|
|
66
|
+
// ARRANGE
|
|
67
|
+
const authorization = buildAuthorization({
|
|
68
|
+
userName: "mockUserName",
|
|
69
|
+
webApiKey: "mockWebApiKey"
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const mockResponse: GetAchievementDistributionResponse = {
|
|
73
|
+
"1": 20,
|
|
74
|
+
"2": 10,
|
|
75
|
+
"3": 8,
|
|
76
|
+
"4": 4,
|
|
77
|
+
"5": 1
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
let detectedSearchParams: URLSearchParams;
|
|
81
|
+
|
|
82
|
+
server.use(
|
|
83
|
+
rest.get(
|
|
84
|
+
`${apiBaseUrl}/API_GetAchievementDistribution.php`,
|
|
85
|
+
(req, res, ctx) => {
|
|
86
|
+
detectedSearchParams = req.url.searchParams;
|
|
87
|
+
return res(ctx.json(mockResponse));
|
|
88
|
+
}
|
|
89
|
+
)
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
// ACT
|
|
93
|
+
const response = await getAchievementDistribution(authorization, {
|
|
94
|
+
gameId: 14_402,
|
|
95
|
+
flags: AchievementDistributionFlags.UnofficialAchievements
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// ASSERT
|
|
99
|
+
expect(response).toEqual(mockResponse);
|
|
100
|
+
|
|
101
|
+
expect(detectedSearchParams!.get("i")).toEqual("14402");
|
|
102
|
+
expect(detectedSearchParams!.get("f")).toEqual(
|
|
103
|
+
String(AchievementDistributionFlags.UnofficialAchievements)
|
|
104
|
+
);
|
|
105
|
+
expect(detectedSearchParams!.has("h")).toBeFalsy();
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("given a truthy hardcore value, successfully attaches the option to the call", async () => {
|
|
109
|
+
// ARRANGE
|
|
110
|
+
const authorization = buildAuthorization({
|
|
111
|
+
userName: "mockUserName",
|
|
112
|
+
webApiKey: "mockWebApiKey"
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const mockResponse: GetAchievementDistributionResponse = {
|
|
116
|
+
"1": 20,
|
|
117
|
+
"2": 10,
|
|
118
|
+
"3": 8,
|
|
119
|
+
"4": 4,
|
|
120
|
+
"5": 1
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
let detectedSearchParams: URLSearchParams;
|
|
124
|
+
|
|
125
|
+
server.use(
|
|
126
|
+
rest.get(
|
|
127
|
+
`${apiBaseUrl}/API_GetAchievementDistribution.php`,
|
|
128
|
+
(req, res, ctx) => {
|
|
129
|
+
detectedSearchParams = req.url.searchParams;
|
|
130
|
+
return res(ctx.json(mockResponse));
|
|
131
|
+
}
|
|
132
|
+
)
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
// ACT
|
|
136
|
+
const response = await getAchievementDistribution(authorization, {
|
|
137
|
+
gameId: 14_402,
|
|
138
|
+
hardcore: true
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// ASSERT
|
|
142
|
+
expect(response).toEqual(mockResponse);
|
|
143
|
+
|
|
144
|
+
expect(detectedSearchParams!.get("i")).toEqual("14402");
|
|
145
|
+
expect(detectedSearchParams!.get("h")).toEqual("1");
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it("given a falsy hardcore value, successfully attaches the option to the call", async () => {
|
|
149
|
+
// ARRANGE
|
|
150
|
+
const authorization = buildAuthorization({
|
|
151
|
+
userName: "mockUserName",
|
|
152
|
+
webApiKey: "mockWebApiKey"
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
const mockResponse: GetAchievementDistributionResponse = {
|
|
156
|
+
"1": 20,
|
|
157
|
+
"2": 10,
|
|
158
|
+
"3": 8,
|
|
159
|
+
"4": 4,
|
|
160
|
+
"5": 1
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
let detectedSearchParams: URLSearchParams;
|
|
164
|
+
|
|
165
|
+
server.use(
|
|
166
|
+
rest.get(
|
|
167
|
+
`${apiBaseUrl}/API_GetAchievementDistribution.php`,
|
|
168
|
+
(req, res, ctx) => {
|
|
169
|
+
detectedSearchParams = req.url.searchParams;
|
|
170
|
+
return res(ctx.json(mockResponse));
|
|
171
|
+
}
|
|
172
|
+
)
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
// ACT
|
|
176
|
+
const response = await getAchievementDistribution(authorization, {
|
|
177
|
+
gameId: 14_402,
|
|
178
|
+
hardcore: false
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// ASSERT
|
|
182
|
+
expect(response).toEqual(mockResponse);
|
|
183
|
+
|
|
184
|
+
expect(detectedSearchParams!.get("i")).toEqual("14402");
|
|
185
|
+
expect(detectedSearchParams!.get("h")).toEqual("0");
|
|
186
|
+
});
|
|
187
|
+
});
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { apiBaseUrl, buildRequestUrl, call } from "../utils/internal";
|
|
2
|
+
import type { AuthObject } from "../utils/public";
|
|
3
|
+
import type {
|
|
4
|
+
AchievementDistributionFlags,
|
|
5
|
+
GetAchievementDistributionResponse
|
|
6
|
+
} from "./models";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A call to this function will retrieve a dictionary
|
|
10
|
+
* of the number of players who have earned a specific
|
|
11
|
+
* number of achievements for a given game ID.
|
|
12
|
+
*
|
|
13
|
+
* @param authorization An object containing your userName and webApiKey.
|
|
14
|
+
* This can be constructed with `buildAuthorization()`.
|
|
15
|
+
*
|
|
16
|
+
* @param payload.gameId The unique game ID. If you are unsure, open the
|
|
17
|
+
* game's page on the RetroAchievements.org website. For example, Dragster's
|
|
18
|
+
* URL is https://retroachievements.org/game/14402. We can see from the
|
|
19
|
+
* URL that the game ID is "14402".
|
|
20
|
+
*
|
|
21
|
+
* @param payload.flags Optional. By default, only official achievement
|
|
22
|
+
* tallies are returned in the response. Import the `AchievementDistributionFlags`
|
|
23
|
+
* enum for possible values. This lets you see the count of players who have
|
|
24
|
+
* unlocked unofficial achievements.
|
|
25
|
+
*
|
|
26
|
+
* @param payload.hardcore Optional. By default, set to false, with both
|
|
27
|
+
* softcore and hardcore tallies returned in the response. If this option
|
|
28
|
+
* is set to true, only hardcore unlocks will be included in the totals.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```
|
|
32
|
+
* const achievementDistribution = await getAchievementDistribution(
|
|
33
|
+
* authorization,
|
|
34
|
+
* { gameId: 14402, hardcore: true }
|
|
35
|
+
* );
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @returns A dictionary where the keys represent the earned achievement
|
|
39
|
+
* count and the values represent the number of players who have unlocked
|
|
40
|
+
* that many achievements.
|
|
41
|
+
* ```
|
|
42
|
+
* {
|
|
43
|
+
* '1': 64,
|
|
44
|
+
* '2': 19,
|
|
45
|
+
* '3': 11,
|
|
46
|
+
* '4': 18,
|
|
47
|
+
* '5': 25,
|
|
48
|
+
* '6': 20,
|
|
49
|
+
* '7': 26,
|
|
50
|
+
* '8': 29,
|
|
51
|
+
* '9': 54,
|
|
52
|
+
* '10': 17,
|
|
53
|
+
* '11': 29,
|
|
54
|
+
* '12': 4
|
|
55
|
+
* }
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export const getAchievementDistribution = async (
|
|
59
|
+
authorization: AuthObject,
|
|
60
|
+
payload: {
|
|
61
|
+
gameId: number;
|
|
62
|
+
flags?: AchievementDistributionFlags;
|
|
63
|
+
hardcore?: boolean;
|
|
64
|
+
}
|
|
65
|
+
) => {
|
|
66
|
+
const { gameId, flags, hardcore } = payload;
|
|
67
|
+
|
|
68
|
+
const queryParams: Record<string, any> = { i: gameId };
|
|
69
|
+
|
|
70
|
+
if (flags !== undefined) {
|
|
71
|
+
queryParams["f"] = flags;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (hardcore !== undefined) {
|
|
75
|
+
queryParams["h"] = hardcore === true ? 1 : 0;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const url = buildRequestUrl(
|
|
79
|
+
apiBaseUrl,
|
|
80
|
+
"/API_GetAchievementDistribution.php",
|
|
81
|
+
authorization,
|
|
82
|
+
queryParams
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
return await call<GetAchievementDistributionResponse>({
|
|
86
|
+
url
|
|
87
|
+
});
|
|
88
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
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 { getGame } from "./getGame";
|
|
9
|
+
import type { GetGameResponse } from "./models";
|
|
10
|
+
|
|
11
|
+
const server = setupServer();
|
|
12
|
+
|
|
13
|
+
describe("Function: getGame", () => {
|
|
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(getGame).toBeDefined();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("given a game ID, retrieves basic metadata about the game", async () => {
|
|
25
|
+
// ARRANGE
|
|
26
|
+
const authorization = buildAuthorization({
|
|
27
|
+
userName: "mockUserName",
|
|
28
|
+
webApiKey: "mockWebApiKey"
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const mockResponse: GetGameResponse = {
|
|
32
|
+
ID: "14402",
|
|
33
|
+
Title: "Dragster",
|
|
34
|
+
ForumTopicID: "9145",
|
|
35
|
+
ConsoleID: "25",
|
|
36
|
+
ConsoleName: "Atari 2600",
|
|
37
|
+
Flags: "0",
|
|
38
|
+
ImageIcon: "/Images/026368.png",
|
|
39
|
+
GameIcon: "/Images/026368.png",
|
|
40
|
+
ImageTitle: "/Images/026366.png",
|
|
41
|
+
ImageIngame: "/Images/026367.png",
|
|
42
|
+
ImageBoxArt: "/Images/026365.png",
|
|
43
|
+
Publisher: "Activision ",
|
|
44
|
+
Developer: "David Crane",
|
|
45
|
+
Genre: "Racing",
|
|
46
|
+
Released: "1980",
|
|
47
|
+
GameTitle: "Dragster",
|
|
48
|
+
Console: "Atari 2600"
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
server.use(
|
|
52
|
+
rest.get(`${apiBaseUrl}/API_GetGame.php`, (_, res, ctx) =>
|
|
53
|
+
res(ctx.json(mockResponse))
|
|
54
|
+
)
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
// ACT
|
|
58
|
+
const response = await getGame(authorization, { gameId: 14_402 });
|
|
59
|
+
|
|
60
|
+
// ASSERT
|
|
61
|
+
expect(response).toEqual({
|
|
62
|
+
id: 14_402,
|
|
63
|
+
title: "Dragster",
|
|
64
|
+
forumTopicId: 9145,
|
|
65
|
+
consoleId: 25,
|
|
66
|
+
consoleName: "Atari 2600",
|
|
67
|
+
flags: 0,
|
|
68
|
+
imageIcon: "/Images/026368.png",
|
|
69
|
+
gameIcon: "/Images/026368.png",
|
|
70
|
+
imageTitle: "/Images/026366.png",
|
|
71
|
+
imageIngame: "/Images/026367.png",
|
|
72
|
+
imageBoxArt: "/Images/026365.png",
|
|
73
|
+
publisher: "Activision ",
|
|
74
|
+
developer: "David Crane",
|
|
75
|
+
genre: "Racing",
|
|
76
|
+
released: 1980,
|
|
77
|
+
gameTitle: "Dragster",
|
|
78
|
+
console: "Atari 2600"
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import {
|
|
2
|
+
apiBaseUrl,
|
|
3
|
+
buildRequestUrl,
|
|
4
|
+
call,
|
|
5
|
+
serializeProperties
|
|
6
|
+
} from "../utils/internal";
|
|
7
|
+
import type { AuthObject } from "../utils/public";
|
|
8
|
+
import type { Game, GetGameResponse } from "./models";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A call to this function will retrieve basic metadata about
|
|
12
|
+
* a game, targeted via its unique ID.
|
|
13
|
+
*
|
|
14
|
+
* @param authorization An object containing your userName and webApiKey.
|
|
15
|
+
* This can be constructed with `buildAuthorization()`.
|
|
16
|
+
*
|
|
17
|
+
* @param payload.gameId The unique game ID. If you are unsure, open the
|
|
18
|
+
* game's page on the RetroAchievements.org website. For example, Dragster's
|
|
19
|
+
* URL is https://retroachievements.org/game/14402. We can see from the
|
|
20
|
+
* URL that the game ID is "14402".
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```
|
|
24
|
+
* const game = await getGame(
|
|
25
|
+
* authorization,
|
|
26
|
+
* { gameId: 14402 }
|
|
27
|
+
* );
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @returns An object containing basic metadata about a target game.
|
|
31
|
+
* ```json
|
|
32
|
+
* {
|
|
33
|
+
* id: 14402,
|
|
34
|
+
* title: "Dragster",
|
|
35
|
+
* forumTopicId: 9145,
|
|
36
|
+
* consoleId: 25,
|
|
37
|
+
* consoleName: "Atari 2600",
|
|
38
|
+
* flags: 0,
|
|
39
|
+
* imageIcon: "/Images/026368.png",
|
|
40
|
+
* gameIcon: "/Images/026368.png",
|
|
41
|
+
* imageTitle: "/Images/026366.png",
|
|
42
|
+
* imageIngame: "/Images/026367.png",
|
|
43
|
+
* imageBoxArt: "/Images/026365.png",
|
|
44
|
+
* publisher: "Activision",
|
|
45
|
+
* developer: "David Crane",
|
|
46
|
+
* genre: "Racing",
|
|
47
|
+
* released: 1980,
|
|
48
|
+
* gameTitle: "Dragster",
|
|
49
|
+
* console: "Atari 2600"
|
|
50
|
+
* }
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export const getGame = async (
|
|
54
|
+
authorization: AuthObject,
|
|
55
|
+
payload: { gameId: number }
|
|
56
|
+
): Promise<Game> => {
|
|
57
|
+
const { gameId } = payload;
|
|
58
|
+
|
|
59
|
+
const url = buildRequestUrl(apiBaseUrl, "/API_GetGame.php", authorization, {
|
|
60
|
+
i: gameId
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const rawResponse = await call<GetGameResponse>({ url });
|
|
64
|
+
|
|
65
|
+
return serializeProperties(rawResponse, {
|
|
66
|
+
shouldCastToNumbers: [
|
|
67
|
+
"ID",
|
|
68
|
+
"ForumTopicID",
|
|
69
|
+
"ConsoleID",
|
|
70
|
+
"Flags",
|
|
71
|
+
"Released"
|
|
72
|
+
]
|
|
73
|
+
});
|
|
74
|
+
};
|
|
@@ -0,0 +1,121 @@
|
|
|
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 { getGameExtended } from "./getGameExtended";
|
|
9
|
+
import type { GetGameExtendedResponse } from "./models";
|
|
10
|
+
|
|
11
|
+
const server = setupServer();
|
|
12
|
+
|
|
13
|
+
describe("Function: getGameExtended", () => {
|
|
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(getGameExtended).toBeDefined();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("given a game ID, retrieves extended metadata about the game", async () => {
|
|
25
|
+
// ARRANGE
|
|
26
|
+
const authorization = buildAuthorization({
|
|
27
|
+
userName: "mockUserName",
|
|
28
|
+
webApiKey: "mockWebApiKey"
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const mockResponse: GetGameExtendedResponse = {
|
|
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
|
+
Claims: [],
|
|
52
|
+
Achievements: {
|
|
53
|
+
"79434": {
|
|
54
|
+
ID: "79434",
|
|
55
|
+
NumAwarded: "338",
|
|
56
|
+
NumAwardedHardcore: "253",
|
|
57
|
+
Title: "Novice Dragster Driver 1",
|
|
58
|
+
Description: "Complete your very first race in game 1.",
|
|
59
|
+
Points: "1",
|
|
60
|
+
TrueRatio: "1",
|
|
61
|
+
Author: "Boldewin",
|
|
62
|
+
DateModified: "2019-08-01 19:03:46",
|
|
63
|
+
DateCreated: "2019-07-31 18:49:57",
|
|
64
|
+
BadgeName: "85541",
|
|
65
|
+
DisplayOrder: "0",
|
|
66
|
+
MemAddr: "f5c41fa0b5fa0d5fbb8a74c598f18582"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
server.use(
|
|
72
|
+
rest.get(`${apiBaseUrl}/API_GetGameExtended.php`, (_, res, ctx) =>
|
|
73
|
+
res(ctx.json(mockResponse))
|
|
74
|
+
)
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
// ACT
|
|
78
|
+
const response = await getGameExtended(authorization, { gameId: 14_402 });
|
|
79
|
+
|
|
80
|
+
// ASSERT
|
|
81
|
+
expect(response).toEqual({
|
|
82
|
+
id: 14_402,
|
|
83
|
+
title: "Dragster",
|
|
84
|
+
consoleId: 25,
|
|
85
|
+
forumTopicId: 9145,
|
|
86
|
+
flags: 0,
|
|
87
|
+
imageIcon: "/Images/026368.png",
|
|
88
|
+
imageTitle: "/Images/026366.png",
|
|
89
|
+
imageIngame: "/Images/026367.png",
|
|
90
|
+
imageBoxArt: "/Images/026365.png",
|
|
91
|
+
publisher: "Activision ",
|
|
92
|
+
developer: "David Crane",
|
|
93
|
+
genre: "Racing",
|
|
94
|
+
released: 1980,
|
|
95
|
+
isFinal: false,
|
|
96
|
+
consoleName: "Atari 2600",
|
|
97
|
+
richPresencePatch: "2b92fa1bf9635c303b3b7f8feea3ed3c",
|
|
98
|
+
numAchievements: 12,
|
|
99
|
+
numDistinctPlayersCasual: 454,
|
|
100
|
+
numDistinctPlayersHardcore: 323,
|
|
101
|
+
claims: [],
|
|
102
|
+
achievements: {
|
|
103
|
+
"79434": {
|
|
104
|
+
id: 79_434,
|
|
105
|
+
numAwarded: 338,
|
|
106
|
+
numAwardedHardcore: 253,
|
|
107
|
+
title: "Novice Dragster Driver 1",
|
|
108
|
+
description: "Complete your very first race in game 1.",
|
|
109
|
+
points: 1,
|
|
110
|
+
trueRatio: 1,
|
|
111
|
+
author: "Boldewin",
|
|
112
|
+
dateModified: "2019-08-01 19:03:46",
|
|
113
|
+
dateCreated: "2019-07-31 18:49:57",
|
|
114
|
+
badgeName: "85541",
|
|
115
|
+
displayOrder: 0,
|
|
116
|
+
memAddr: "f5c41fa0b5fa0d5fbb8a74c598f18582"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
});
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import {
|
|
2
|
+
apiBaseUrl,
|
|
3
|
+
buildRequestUrl,
|
|
4
|
+
call,
|
|
5
|
+
serializeProperties
|
|
6
|
+
} from "../utils/internal";
|
|
7
|
+
import type { AuthObject } from "../utils/public";
|
|
8
|
+
import type { GameExtended, GetGameExtendedResponse } from "./models";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A call to this function will retrieve extended metadata
|
|
12
|
+
* about a game, targeted via its unique ID.
|
|
13
|
+
*
|
|
14
|
+
* @param authorization An object containing your userName and webApiKey.
|
|
15
|
+
* This can be constructed with `buildAuthorization()`.
|
|
16
|
+
*
|
|
17
|
+
* @param payload.gameId The unique game ID. If you are unsure, open the
|
|
18
|
+
* game's page on the RetroAchievements.org website. For example, Dragster's
|
|
19
|
+
* URL is https://retroachievements.org/game/14402. We can see from the
|
|
20
|
+
* URL that the game ID is "14402".
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```
|
|
24
|
+
* const gameExtended = await getGameExtended(
|
|
25
|
+
* authorization,
|
|
26
|
+
* { gameId: 14402 }
|
|
27
|
+
* );
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @returns An object containing extended metadata about a target game.
|
|
31
|
+
* ```json
|
|
32
|
+
* {
|
|
33
|
+
* id: 14402,
|
|
34
|
+
* title: "Dragster",
|
|
35
|
+
* consoleId: 25,
|
|
36
|
+
* forumTopicId: 9145,
|
|
37
|
+
* flags: 0,
|
|
38
|
+
* imageIcon: "/Images/026368.png",
|
|
39
|
+
* imageTitle: "/Images/026366.png",
|
|
40
|
+
* imageIngame: "/Images/026367.png",
|
|
41
|
+
* imageBoxArt: "/Images/026365.png",
|
|
42
|
+
* publisher: "Activision",
|
|
43
|
+
* developer: "David Crane",
|
|
44
|
+
* genre: "Racing",
|
|
45
|
+
* released: 1980,
|
|
46
|
+
* isFinal: false,
|
|
47
|
+
* consoleName: "Atari 2600",
|
|
48
|
+
* richPresencePatch: "2b92fa1bf9635c303b3b7f8feea3ed3c",
|
|
49
|
+
* numAchievements: 12,
|
|
50
|
+
* numDistinctPlayersCasual: 454,
|
|
51
|
+
* numDistinctPlayersHardcore, 323
|
|
52
|
+
* claims: [],
|
|
53
|
+
* achievements: {
|
|
54
|
+
* '79434': {
|
|
55
|
+
* id: 79434,
|
|
56
|
+
* numAwarded: 338,
|
|
57
|
+
* numAwardedHardcore: 253,
|
|
58
|
+
* title: "Novice Dragster Driver 1",
|
|
59
|
+
* description: "Complete your very first race in game 1.",
|
|
60
|
+
* points: 1,
|
|
61
|
+
* trueRatio: 1,
|
|
62
|
+
* author: "Boldewin",
|
|
63
|
+
* dateModified: "2019-08-01 19:03:46",
|
|
64
|
+
* dateCreated: "2019-07-31 18:49:57",
|
|
65
|
+
* badgeName: "85541",
|
|
66
|
+
* displayOrder: 0,
|
|
67
|
+
* memAddr: "f5c41fa0b5fa0d5fbb8a74c598f18582"
|
|
68
|
+
* }
|
|
69
|
+
* }
|
|
70
|
+
* }
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export const getGameExtended = async (
|
|
74
|
+
authorization: AuthObject,
|
|
75
|
+
payload: { gameId: number }
|
|
76
|
+
): Promise<GameExtended> => {
|
|
77
|
+
const { gameId } = payload;
|
|
78
|
+
|
|
79
|
+
const url = buildRequestUrl(
|
|
80
|
+
apiBaseUrl,
|
|
81
|
+
"/API_GetGameExtended.php",
|
|
82
|
+
authorization,
|
|
83
|
+
{
|
|
84
|
+
i: gameId
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const rawResponse = await call<GetGameExtendedResponse>({ url });
|
|
89
|
+
|
|
90
|
+
return serializeProperties(rawResponse, {
|
|
91
|
+
shouldCastToNumbers: [
|
|
92
|
+
"ID",
|
|
93
|
+
"NumAwarded",
|
|
94
|
+
"NumAwardedHardcore",
|
|
95
|
+
"Points",
|
|
96
|
+
"TrueRatio",
|
|
97
|
+
"DisplayOrder",
|
|
98
|
+
"NumDistinctPlayersCasual",
|
|
99
|
+
"NumDistinctPlayersHardcore",
|
|
100
|
+
"Released"
|
|
101
|
+
]
|
|
102
|
+
});
|
|
103
|
+
};
|