@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.
Files changed (225) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +103 -0
  3. package/dist/__playground.d.ts +7 -0
  4. package/dist/achievement/getAchievementUnlocks.d.ts +45 -0
  5. package/dist/achievement/index.d.ts +2 -0
  6. package/dist/achievement/models/achievement-unlock-entity.model.d.ts +6 -0
  7. package/dist/achievement/models/get-achievement-unlocks-response.model.d.ts +8 -0
  8. package/dist/achievement/models/index.d.ts +2 -0
  9. package/dist/api.cjs.development.js +2363 -0
  10. package/dist/api.cjs.development.js.map +1 -0
  11. package/dist/api.cjs.production.min.js +2 -0
  12. package/dist/api.cjs.production.min.js.map +1 -0
  13. package/dist/api.esm.js +2333 -0
  14. package/dist/api.esm.js.map +1 -0
  15. package/dist/console/getConsoleIds.d.ts +22 -0
  16. package/dist/console/getGameList.d.ts +52 -0
  17. package/dist/console/index.d.ts +3 -0
  18. package/dist/console/models/console-id.model.d.ts +4 -0
  19. package/dist/console/models/game-list.model.d.ts +15 -0
  20. package/dist/console/models/get-console-ids-response.model.d.ts +4 -0
  21. package/dist/console/models/get-game-list-response.model.d.ts +15 -0
  22. package/dist/console/models/index.d.ts +4 -0
  23. package/dist/feed/getAchievementOfTheWeek.d.ts +48 -0
  24. package/dist/feed/getActiveClaims.d.ts +38 -0
  25. package/dist/feed/getTicketData.d.ts +158 -0
  26. package/dist/feed/getTopTenUsers.d.ts +24 -0
  27. package/dist/feed/index.d.ts +5 -0
  28. package/dist/feed/models/achievement-of-the-week.model.d.ts +32 -0
  29. package/dist/feed/models/achievement-ticket-stats-response.model.d.ts +7 -0
  30. package/dist/feed/models/achievement-ticket-stats.model.d.ts +7 -0
  31. package/dist/feed/models/active-claim.model.d.ts +49 -0
  32. package/dist/feed/models/game-ticket-stats.model.d.ts +9 -0
  33. package/dist/feed/models/game-tickets-response.model.d.ts +7 -0
  34. package/dist/feed/models/get-achievement-of-the-week-response.model.d.ts +32 -0
  35. package/dist/feed/models/get-active-claims-response.model.d.ts +19 -0
  36. package/dist/feed/models/get-top-ten-users-response.model.d.ts +10 -0
  37. package/dist/feed/models/index.d.ts +19 -0
  38. package/dist/feed/models/most-ticketed-games-response.model.d.ts +12 -0
  39. package/dist/feed/models/most-ticketed-games.model.d.ts +12 -0
  40. package/dist/feed/models/recent-tickets-response.model.d.ts +6 -0
  41. package/dist/feed/models/recent-tickets.model.d.ts +6 -0
  42. package/dist/feed/models/response-ticket-entity.model.d.ts +24 -0
  43. package/dist/feed/models/ticket-entity.model.d.ts +24 -0
  44. package/dist/feed/models/tickets-by-user-response.model.d.ts +8 -0
  45. package/dist/feed/models/top-ten-users-entity.model.d.ts +5 -0
  46. package/dist/feed/models/top-ten-users.model.d.ts +2 -0
  47. package/dist/feed/models/user-ticket-stats.model.d.ts +8 -0
  48. package/dist/game/getAchievementCount.d.ts +31 -0
  49. package/dist/game/getAchievementDistribution.d.ts +57 -0
  50. package/dist/game/getGame.d.ts +48 -0
  51. package/dist/game/getGameExtended.d.ts +68 -0
  52. package/dist/game/getGameRankAndScore.d.ts +38 -0
  53. package/dist/game/getGameRating.d.ts +38 -0
  54. package/dist/game/index.d.ts +7 -0
  55. package/dist/game/models/achievement-count.model.d.ts +4 -0
  56. package/dist/game/models/achievement-distribution-flags.model.d.ts +4 -0
  57. package/dist/game/models/game-extended-achievement-entity.model.d.ts +15 -0
  58. package/dist/game/models/game-extended-claim-entity.model.d.ts +7 -0
  59. package/dist/game/models/game-extended.model.d.ts +25 -0
  60. package/dist/game/models/game-rank-and-score-entity.model.d.ts +6 -0
  61. package/dist/game/models/game-rating.model.d.ts +9 -0
  62. package/dist/game/models/game.model.d.ts +19 -0
  63. package/dist/game/models/get-achievement-count-response.model.d.ts +4 -0
  64. package/dist/game/models/get-achievement-distribution-response.model.d.ts +1 -0
  65. package/dist/game/models/get-game-extended-response.model.d.ts +50 -0
  66. package/dist/game/models/get-game-rank-and-score-response.model.d.ts +8 -0
  67. package/dist/game/models/get-game-rating-response.model.d.ts +9 -0
  68. package/dist/game/models/get-game-response.model.d.ts +19 -0
  69. package/dist/game/models/index.d.ts +14 -0
  70. package/dist/index.d.ts +6 -0
  71. package/dist/index.js +8 -0
  72. package/dist/user/getAchievementsEarnedBetween.d.ts +59 -0
  73. package/dist/user/getAchievementsEarnedOnDay.d.ts +57 -0
  74. package/dist/user/getGameInfoAndUserProgress.d.ts +80 -0
  75. package/dist/user/getUserGameRankAndScore.d.ts +44 -0
  76. package/dist/user/getUserPoints.d.ts +30 -0
  77. package/dist/user/getUserProgress.d.ts +49 -0
  78. package/dist/user/getUserRecentlyPlayedGames.d.ts +50 -0
  79. package/dist/user/getUserSummary.d.ts +32 -0
  80. package/dist/user/index.d.ts +9 -0
  81. package/dist/user/models/dated-user-achievement.model.d.ts +17 -0
  82. package/dist/user/models/dated-user-achievements-response.model.d.ts +19 -0
  83. package/dist/user/models/game-info-and-user-progress.model.d.ts +12 -0
  84. package/dist/user/models/get-game-info-and-user-progress-response.model.d.ts +14 -0
  85. package/dist/user/models/get-user-game-rank-and-score-response.model.d.ts +8 -0
  86. package/dist/user/models/get-user-points-response.model.d.ts +4 -0
  87. package/dist/user/models/get-user-progress-response.model.d.ts +10 -0
  88. package/dist/user/models/get-user-recently-played-games-response.model.d.ts +16 -0
  89. package/dist/user/models/get-user-summary-response.model.d.ts +82 -0
  90. package/dist/user/models/index.d.ts +14 -0
  91. package/dist/user/models/user-game-rank-and-score.model.d.ts +8 -0
  92. package/dist/user/models/user-points.model.d.ts +4 -0
  93. package/dist/user/models/user-progress.model.d.ts +10 -0
  94. package/dist/user/models/user-recently-played-games.model.d.ts +16 -0
  95. package/dist/user/models/user-summary.model.d.ts +83 -0
  96. package/dist/utils/internal/apiBaseUrl.d.ts +1 -0
  97. package/dist/utils/internal/buildRequestUrl.d.ts +2 -0
  98. package/dist/utils/internal/call.d.ts +20 -0
  99. package/dist/utils/internal/index.d.ts +4 -0
  100. package/dist/utils/internal/serializeProperties.d.ts +4 -0
  101. package/dist/utils/public/buildAuthorization.d.ts +22 -0
  102. package/dist/utils/public/index.d.ts +3 -0
  103. package/dist/utils/public/models/auth-object.model.d.ts +19 -0
  104. package/dist/utils/public/models/index.d.ts +1 -0
  105. package/package.json +117 -0
  106. package/src/__playground.ts +27 -0
  107. package/src/achievement/getAchievementUnlocks.test.ts +71 -0
  108. package/src/achievement/getAchievementUnlocks.ts +80 -0
  109. package/src/achievement/index.ts +2 -0
  110. package/src/achievement/models/achievement-unlock-entity.model.ts +6 -0
  111. package/src/achievement/models/get-achievement-unlocks-response.model.ts +8 -0
  112. package/src/achievement/models/index.ts +2 -0
  113. package/src/console/getConsoleIds.test.ts +53 -0
  114. package/src/console/getConsoleIds.ts +43 -0
  115. package/src/console/getGameList.test.ts +82 -0
  116. package/src/console/getGameList.ts +94 -0
  117. package/src/console/index.ts +3 -0
  118. package/src/console/models/console-id.model.ts +4 -0
  119. package/src/console/models/game-list.model.ts +16 -0
  120. package/src/console/models/get-console-ids-response.model.ts +1 -0
  121. package/src/console/models/get-game-list-response.model.ts +16 -0
  122. package/src/console/models/index.ts +4 -0
  123. package/src/feed/getAchievementOfTheWeek.test.ts +167 -0
  124. package/src/feed/getAchievementOfTheWeek.ts +80 -0
  125. package/src/feed/getActiveClaims.test.ts +81 -0
  126. package/src/feed/getActiveClaims.ts +68 -0
  127. package/src/feed/getTicketData.test.ts +349 -0
  128. package/src/feed/getTicketData.ts +286 -0
  129. package/src/feed/getTopTenUsers.test.ts +101 -0
  130. package/src/feed/getTopTenUsers.ts +51 -0
  131. package/src/feed/index.ts +5 -0
  132. package/src/feed/models/achievement-of-the-week.model.ts +27 -0
  133. package/src/feed/models/achievement-ticket-stats-response.model.ts +7 -0
  134. package/src/feed/models/achievement-ticket-stats.model.ts +7 -0
  135. package/src/feed/models/active-claim.model.ts +66 -0
  136. package/src/feed/models/game-ticket-stats.model.ts +11 -0
  137. package/src/feed/models/game-tickets-response.model.ts +7 -0
  138. package/src/feed/models/get-achievement-of-the-week-response.model.ts +27 -0
  139. package/src/feed/models/get-active-claims-response.model.ts +19 -0
  140. package/src/feed/models/get-top-ten-users-response.model.ts +12 -0
  141. package/src/feed/models/index.ts +19 -0
  142. package/src/feed/models/most-ticketed-games-response.model.ts +12 -0
  143. package/src/feed/models/most-ticketed-games.model.ts +12 -0
  144. package/src/feed/models/recent-tickets-response.model.ts +7 -0
  145. package/src/feed/models/recent-tickets.model.ts +7 -0
  146. package/src/feed/models/response-ticket-entity.model.ts +25 -0
  147. package/src/feed/models/ticket-entity.model.ts +24 -0
  148. package/src/feed/models/tickets-by-user-response.model.ts +8 -0
  149. package/src/feed/models/top-ten-users-entity.model.ts +5 -0
  150. package/src/feed/models/top-ten-users.model.ts +3 -0
  151. package/src/feed/models/user-ticket-stats.model.ts +8 -0
  152. package/src/game/getAchievementCount.test.ts +49 -0
  153. package/src/game/getAchievementCount.ts +52 -0
  154. package/src/game/getAchievementDistribution.test.ts +187 -0
  155. package/src/game/getAchievementDistribution.ts +88 -0
  156. package/src/game/getGame.test.ts +81 -0
  157. package/src/game/getGame.ts +74 -0
  158. package/src/game/getGameExtended.test.ts +121 -0
  159. package/src/game/getGameExtended.ts +103 -0
  160. package/src/game/getGameRankAndScore.test.ts +62 -0
  161. package/src/game/getGameRankAndScore.ts +66 -0
  162. package/src/game/getGameRating.test.ts +59 -0
  163. package/src/game/getGameRating.ts +59 -0
  164. package/src/game/index.ts +7 -0
  165. package/src/game/models/achievement-count.model.ts +4 -0
  166. package/src/game/models/achievement-distribution-flags.model.ts +4 -0
  167. package/src/game/models/game-extended-achievement-entity.model.ts +15 -0
  168. package/src/game/models/game-extended-claim-entity.model.ts +7 -0
  169. package/src/game/models/game-extended.model.ts +26 -0
  170. package/src/game/models/game-rank-and-score-entity.model.ts +6 -0
  171. package/src/game/models/game-rating.model.ts +9 -0
  172. package/src/game/models/game.model.ts +19 -0
  173. package/src/game/models/get-achievement-count-response.model.ts +4 -0
  174. package/src/game/models/get-achievement-distribution-response.model.ts +1 -0
  175. package/src/game/models/get-game-extended-response.model.ts +56 -0
  176. package/src/game/models/get-game-rank-and-score-response.model.ts +8 -0
  177. package/src/game/models/get-game-rating-response.model.ts +9 -0
  178. package/src/game/models/get-game-response.model.ts +19 -0
  179. package/src/game/models/index.ts +14 -0
  180. package/src/index.ts +8 -0
  181. package/src/user/getAchievementsEarnedBetween.test.ts +84 -0
  182. package/src/user/getAchievementsEarnedBetween.ts +88 -0
  183. package/src/user/getAchievementsEarnedOnDay.test.ts +83 -0
  184. package/src/user/getAchievementsEarnedOnDay.ts +87 -0
  185. package/src/user/getGameInfoAndUserProgress.test.ts +135 -0
  186. package/src/user/getGameInfoAndUserProgress.ts +118 -0
  187. package/src/user/getUserGameRankAndScore.test.ts +60 -0
  188. package/src/user/getUserGameRankAndScore.ts +69 -0
  189. package/src/user/getUserPoints.test.ts +49 -0
  190. package/src/user/getUserPoints.ts +51 -0
  191. package/src/user/getUserProgress.test.ts +80 -0
  192. package/src/user/getUserProgress.ts +78 -0
  193. package/src/user/getUserRecentlyPlayedGames.test.ts +76 -0
  194. package/src/user/getUserRecentlyPlayedGames.ts +93 -0
  195. package/src/user/getUserSummary.test.ts +251 -0
  196. package/src/user/getUserSummary.ts +96 -0
  197. package/src/user/index.ts +9 -0
  198. package/src/user/models/dated-user-achievement.model.ts +17 -0
  199. package/src/user/models/dated-user-achievements-response.model.ts +20 -0
  200. package/src/user/models/game-info-and-user-progress.model.ts +19 -0
  201. package/src/user/models/get-game-info-and-user-progress-response.model.ts +28 -0
  202. package/src/user/models/get-user-game-rank-and-score-response.model.ts +9 -0
  203. package/src/user/models/get-user-points-response.model.ts +4 -0
  204. package/src/user/models/get-user-progress-response.model.ts +13 -0
  205. package/src/user/models/get-user-recently-played-games-response.model.ts +17 -0
  206. package/src/user/models/get-user-summary-response.model.ts +92 -0
  207. package/src/user/models/index.ts +14 -0
  208. package/src/user/models/user-game-rank-and-score.model.ts +8 -0
  209. package/src/user/models/user-points.model.ts +4 -0
  210. package/src/user/models/user-progress.model.ts +10 -0
  211. package/src/user/models/user-recently-played-games.model.ts +16 -0
  212. package/src/user/models/user-summary.model.ts +92 -0
  213. package/src/utils/internal/apiBaseUrl.ts +1 -0
  214. package/src/utils/internal/buildRequestUrl.test.ts +51 -0
  215. package/src/utils/internal/buildRequestUrl.ts +32 -0
  216. package/src/utils/internal/call.test.ts +39 -0
  217. package/src/utils/internal/call.ts +29 -0
  218. package/src/utils/internal/index.ts +4 -0
  219. package/src/utils/internal/serializeProperties.test.ts +141 -0
  220. package/src/utils/internal/serializeProperties.ts +75 -0
  221. package/src/utils/public/buildAuthorization.test.ts +36 -0
  222. package/src/utils/public/buildAuthorization.ts +40 -0
  223. package/src/utils/public/index.ts +3 -0
  224. package/src/utils/public/models/auth-object.model.ts +20 -0
  225. 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
+ };