halo-infinite-api 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,11 +6,11 @@ import { Playlist } from "../models/halo-infinite/playlist";
6
6
  import { PlaylistCsrContainer } from "../models/halo-infinite/playlist-csr-container";
7
7
  import { ServiceRecord } from "../models/halo-infinite/service-record";
8
8
  import { UserInfo } from "../models/halo-infinite/user-info";
9
- import { MapAsset, UgcGameVariantAsset } from "../models/halo-infinite/asset";
9
+ import { MapAsset, PlaylistAsset, UgcGameVariantAsset } from "../models/halo-infinite/asset";
10
10
  import { AssetKind } from "../models/halo-infinite/asset-kind";
11
11
  interface ResultContainer<TValue> {
12
12
  Id: string;
13
- ResultCode: number;
13
+ ResultCode: 0 | 1;
14
14
  Result: TValue;
15
15
  }
16
16
  interface TokenPersister {
@@ -20,6 +20,7 @@ interface TokenPersister {
20
20
  type AssetKindTypeMap = {
21
21
  [AssetKind.Map]: MapAsset;
22
22
  [AssetKind.UgcGameVariant]: UgcGameVariantAsset;
23
+ [AssetKind.Playlist]: PlaylistAsset;
23
24
  };
24
25
  export declare class HaloInfiniteClient {
25
26
  private readonly haloAuthClient;
@@ -46,7 +47,7 @@ export declare class HaloInfiniteClient {
46
47
  getPlaylist: (playlistId: string) => Promise<Playlist>;
47
48
  getPlayerMatches: (playerXuid: string, type?: MatchType, count?: number, start?: number) => Promise<PlayerMatchHistory[]>;
48
49
  getMatchStats: (matchId: string) => Promise<MatchStats<import("..").GameVariantCategory>>;
49
- getMatchSkill: (matchId: string, playerIds: string[]) => Promise<ResultContainer<MatchSkill>[]>;
50
+ getMatchSkill: (matchId: string, playerIds: string[]) => Promise<ResultContainer<MatchSkill<0>>[]>;
50
51
  /** Gets authoring metadata about a specific asset. */
51
52
  getAsset: <TAssetType extends keyof AssetKindTypeMap>(assetType: TAssetType, assetId: string) => Promise<AssetKindTypeMap[TAssetType]>;
52
53
  /** Gets metadata related to a concrete version of a specified asset. */
@@ -1,4 +1,4 @@
1
- import axios, { AxiosHeaders } from "axios";
1
+ import axios, { AxiosError, AxiosHeaders } from "axios";
2
2
  import { HaloAuthenticationClient } from "../authentication/halo-authentication-client";
3
3
  import { RelyingParty, XboxAuthenticationClient, } from "../authentication/xbox-authentication-client";
4
4
  import { HaloCoreEndpoints } from "../endpoints/halo-core-endpoints";
@@ -8,7 +8,17 @@ import { AssetKind } from "../models/halo-infinite/asset-kind";
8
8
  const assetKindUrlMap = {
9
9
  [AssetKind.Map]: "Maps",
10
10
  [AssetKind.UgcGameVariant]: "UgcGameVariants",
11
+ [AssetKind.Playlist]: "Playlists",
11
12
  };
13
+ function wrapPlayerId(playerId) {
14
+ if (/^\w+(\d+)/) {
15
+ return playerId;
16
+ }
17
+ else {
18
+ // Assume xuid
19
+ return `xuid(${playerId})`;
20
+ }
21
+ }
12
22
  export class HaloInfiniteClient {
13
23
  haloAuthClient;
14
24
  constructor(clientId, redirectUri, getAuthCode, tokenPersister) {
@@ -77,7 +87,9 @@ export class HaloInfiniteClient {
77
87
  * @param playlistId - Unique ID for the playlist.
78
88
  * @param playerIds - Array of player xuids.
79
89
  */
80
- getPlaylistCsr = (playlistId, playerIds) => this.executeResultsRequest(`https://${HaloCoreEndpoints.SkillOrigin}.${HaloCoreEndpoints.ServiceDomain}/hi/playlist/${playlistId}/csrs?players=xuid(${playerIds.join("),xuid(")})`, "get");
90
+ getPlaylistCsr = (playlistId, playerIds) => this.executeResultsRequest(`https://${HaloCoreEndpoints.SkillOrigin}.${HaloCoreEndpoints.ServiceDomain}/hi/playlist/${playlistId}/csrs?players=${playerIds
91
+ .map(wrapPlayerId)
92
+ .join(",")}`, "get");
81
93
  /** Get gamertag info for a player.
82
94
  * @param gamerTag - Gamertag to lookup.
83
95
  */
@@ -95,10 +107,24 @@ export class HaloInfiniteClient {
95
107
  if (type !== MatchType.All) {
96
108
  params.type = type.toString();
97
109
  }
98
- return this.executePaginationRequest(count, start, params, `https://${HaloCoreEndpoints.StatsOrigin}.${HaloCoreEndpoints.ServiceDomain}/hi/players/xuid(${playerXuid})/matches`, "get");
110
+ return this.executePaginationRequest(count, start, params, `https://${HaloCoreEndpoints.StatsOrigin}.${HaloCoreEndpoints.ServiceDomain}/hi/players/xuid(${wrapPlayerId(playerXuid)})/matches`, "get");
99
111
  };
100
112
  getMatchStats = (matchId) => this.executeRequest(`https://${HaloCoreEndpoints.StatsOrigin}.${HaloCoreEndpoints.ServiceDomain}/hi/matches/${matchId}/stats`, "get");
101
- getMatchSkill = (matchId, playerIds) => this.executeResultsRequest(`https://${HaloCoreEndpoints.SkillOrigin}.${HaloCoreEndpoints.ServiceDomain}/hi/matches/${matchId}/skill?players=xuid(${playerIds.join("),xuid(")})`, "get");
113
+ getMatchSkill = async (matchId, playerIds) => {
114
+ try {
115
+ return await this.executeResultsRequest(`https://${HaloCoreEndpoints.SkillOrigin}.${HaloCoreEndpoints.ServiceDomain}/hi/matches/${matchId}/skill?players=${playerIds
116
+ .map(wrapPlayerId)
117
+ .join(",")}`, "get");
118
+ }
119
+ catch (e) {
120
+ if (e instanceof AxiosError && e.status === 404 && e.response?.data) {
121
+ return e.response.data.Value;
122
+ }
123
+ else {
124
+ throw e;
125
+ }
126
+ }
127
+ };
102
128
  /** Gets authoring metadata about a specific asset. */
103
129
  getAsset = (assetType, assetId) => this.executeRequest(`https://${HaloCoreEndpoints.DiscoveryOrigin}.${HaloCoreEndpoints.ServiceDomain}/hi/${assetKindUrlMap[assetType]}/${assetId}`, "get");
104
130
  /** Gets metadata related to a concrete version of a specified asset. */
@@ -1 +1 @@
1
- {"version":3,"file":"halo-infinite-client.js","sourceRoot":"","sources":["../../src/core/halo-infinite-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"halo-infinite-client.js","sourceRoot":"","sources":["../../src/core/halo-infinite-client.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -10,3 +10,4 @@ export { PlayerMatchHistory } from "./models/halo-infinite/player-match-history"
10
10
  export { Stats } from "./models/halo-infinite/stats";
11
11
  export { MapAsset, UgcGameVariantAsset } from "./models/halo-infinite/asset";
12
12
  export { AssetKind } from "./models/halo-infinite/asset-kind";
13
+ export { MatchOutcome } from "./models/halo-infinite/match-outcome";
package/dist/index.js CHANGED
@@ -2,4 +2,5 @@ export { HaloInfiniteClient } from "./core/halo-infinite-client";
2
2
  export { MatchType } from "./models/halo-infinite/match-type";
3
3
  export { GameVariantCategory } from "./models/halo-infinite/game-variant-category";
4
4
  export { AssetKind } from "./models/halo-infinite/asset-kind";
5
+ export { MatchOutcome } from "./models/halo-infinite/match-outcome";
5
6
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAKjE,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8CAA8C,CAAC;AAKnF,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAKjE,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8CAA8C,CAAC;AAKnF,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC"}
@@ -54,3 +54,31 @@ export interface UgcGameVariantAsset extends Asset {
54
54
  };
55
55
  EngineGameVariantLink?: Asset;
56
56
  }
57
+ export interface PlaylistAsset extends Asset {
58
+ CustomData: {
59
+ PlaylistEntries: Array<{
60
+ MapModePairAssetId: string;
61
+ Metadata: {
62
+ Weight: number;
63
+ };
64
+ }>;
65
+ Strategy: number;
66
+ MinTeams: number;
67
+ MinTeamSize: number;
68
+ MaxTeams: number;
69
+ MaxTeamSize: number;
70
+ MaxTeamImbalance: number;
71
+ MaxSplitscreenPlayersAllowed: number;
72
+ AllowFriendJoinInProgress: boolean;
73
+ AllowMatchmakingJoinInProgress: boolean;
74
+ AllowBotJoinInProgress: boolean;
75
+ ExitExperienceDurationSec: number;
76
+ FireteamLeaderKickAllowed: boolean;
77
+ DisableMidgameChat: boolean;
78
+ AllowedDeviceInputs: Array<number>;
79
+ BotDifficulty: number;
80
+ MinFireteamSize: number;
81
+ MaxFireteamSize: number;
82
+ };
83
+ RotationEntries: Asset[];
84
+ }
@@ -1,7 +1,7 @@
1
1
  import { AssetVersionLink } from "./asset-version-link";
2
2
  import { GameVariantCategory } from "./game-variant-category";
3
3
  import { PlaylistExperience } from "./playlist-experience";
4
- export interface MatchInfo<TCategory extends GameVariantCategory = GameVariantCategory> {
4
+ export interface MatchInfo<TCategory extends GameVariantCategory = GameVariantCategory, TResult extends 1 | 0 = 0> {
5
5
  StartTime: string;
6
6
  EndTime: string;
7
7
  Duration: string;
@@ -11,10 +11,10 @@ export interface MatchInfo<TCategory extends GameVariantCategory = GameVariantCa
11
11
  MapVariant: AssetVersionLink;
12
12
  UgcGameVariant: AssetVersionLink;
13
13
  ClearanceId: string;
14
- Playlist: AssetVersionLink;
15
- PlaylistExperience: PlaylistExperience;
16
- PlaylistMapModePair: AssetVersionLink;
17
- SeasonId: string;
14
+ Playlist: AssetVersionLink | null;
15
+ PlaylistExperience: TResult extends 0 ? PlaylistExperience : null;
16
+ PlaylistMapModePair: TResult extends 0 ? AssetVersionLink : null;
17
+ SeasonId: TResult extends 0 ? string : null;
18
18
  PlayableDuration: string;
19
19
  TeamsEnabled: boolean;
20
20
  TeamScoringEnabled: boolean;
@@ -17,7 +17,7 @@ interface Counterfactual {
17
17
  Kills: number;
18
18
  Deaths: number;
19
19
  }
20
- export interface MatchSkill {
20
+ export interface MatchSkill<TResult extends 1 | 0 = 0> {
21
21
  TeamId: number;
22
22
  TeamMmr: number;
23
23
  TeamMmrs: {
@@ -27,12 +27,12 @@ export interface MatchSkill {
27
27
  PreMatchCsr: CsrObject;
28
28
  PostMatchCsr: CsrObject;
29
29
  };
30
- StatPerformances: {
30
+ StatPerformances: TResult extends 0 ? {
31
31
  Kills: StatPerformance;
32
32
  Deaths: StatPerformance;
33
- };
34
- Counterfactuals: {
35
- SelfCounterfactual: Counterfactual;
33
+ } : {};
34
+ Counterfactuals: TResult extends 0 ? {
35
+ SelfCounterfactuals: Counterfactual;
36
36
  TierCounterfactuals: {
37
37
  Bronze: Counterfactual;
38
38
  Silver: Counterfactual;
@@ -41,6 +41,6 @@ export interface MatchSkill {
41
41
  Diamond: Counterfactual;
42
42
  Onyx: Counterfactual;
43
43
  };
44
- };
44
+ } : null;
45
45
  }
46
46
  export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "halo-infinite-api",
3
3
  "type": "module",
4
- "version": "1.1.0",
4
+ "version": "1.2.0",
5
5
  "description": "An NPM package for accessing the official Halo Infinite API.",
6
6
  "main": "dist/index.js",
7
7
  "scripts": {
@@ -1,4 +1,4 @@
1
- import axios, { AxiosHeaders, Method } from "axios";
1
+ import axios, { AxiosError, AxiosHeaders, Method } from "axios";
2
2
  import { HaloAuthenticationClient } from "../authentication/halo-authentication-client";
3
3
  import {
4
4
  RelyingParty,
@@ -14,12 +14,16 @@ import { PlaylistCsrContainer } from "../models/halo-infinite/playlist-csr-conta
14
14
  import { ServiceRecord } from "../models/halo-infinite/service-record";
15
15
  import { UserInfo } from "../models/halo-infinite/user-info";
16
16
  import { GlobalConstants } from "../util/global-contants";
17
- import { MapAsset, UgcGameVariantAsset } from "../models/halo-infinite/asset";
17
+ import {
18
+ MapAsset,
19
+ PlaylistAsset,
20
+ UgcGameVariantAsset,
21
+ } from "../models/halo-infinite/asset";
18
22
  import { AssetKind } from "../models/halo-infinite/asset-kind";
19
23
 
20
24
  interface ResultContainer<TValue> {
21
25
  Id: string;
22
- ResultCode: number;
26
+ ResultCode: 0 | 1;
23
27
  Result: TValue;
24
28
  }
25
29
 
@@ -42,15 +46,26 @@ interface TokenPersister {
42
46
  type AssetKindTypeMap = {
43
47
  [AssetKind.Map]: MapAsset;
44
48
  [AssetKind.UgcGameVariant]: UgcGameVariantAsset;
49
+ [AssetKind.Playlist]: PlaylistAsset;
45
50
  };
46
51
 
47
52
  const assetKindUrlMap = {
48
53
  [AssetKind.Map]: "Maps",
49
54
  [AssetKind.UgcGameVariant]: "UgcGameVariants",
55
+ [AssetKind.Playlist]: "Playlists",
50
56
  } satisfies {
51
57
  [key in keyof AssetKindTypeMap]: string;
52
58
  };
53
59
 
60
+ function wrapPlayerId(playerId: string) {
61
+ if (/^\w+(\d+)/) {
62
+ return playerId;
63
+ } else {
64
+ // Assume xuid
65
+ return `xuid(${playerId})`;
66
+ }
67
+ }
68
+
54
69
  export class HaloInfiniteClient {
55
70
  private readonly haloAuthClient: HaloAuthenticationClient;
56
71
 
@@ -169,9 +184,9 @@ export class HaloInfiniteClient {
169
184
  this.executeResultsRequest<PlaylistCsrContainer>(
170
185
  `https://${HaloCoreEndpoints.SkillOrigin}.${
171
186
  HaloCoreEndpoints.ServiceDomain
172
- }/hi/playlist/${playlistId}/csrs?players=xuid(${playerIds.join(
173
- "),xuid("
174
- )})`,
187
+ }/hi/playlist/${playlistId}/csrs?players=${playerIds
188
+ .map(wrapPlayerId)
189
+ .join(",")}`,
175
190
  "get"
176
191
  );
177
192
 
@@ -216,7 +231,9 @@ export class HaloInfiniteClient {
216
231
  count,
217
232
  start,
218
233
  params,
219
- `https://${HaloCoreEndpoints.StatsOrigin}.${HaloCoreEndpoints.ServiceDomain}/hi/players/xuid(${playerXuid})/matches`,
234
+ `https://${HaloCoreEndpoints.StatsOrigin}.${
235
+ HaloCoreEndpoints.ServiceDomain
236
+ }/hi/players/xuid(${wrapPlayerId(playerXuid)})/matches`,
220
237
  "get"
221
238
  );
222
239
  };
@@ -227,13 +244,24 @@ export class HaloInfiniteClient {
227
244
  "get"
228
245
  );
229
246
 
230
- public getMatchSkill = (matchId: string, playerIds: string[]) =>
231
- this.executeResultsRequest<MatchSkill>(
232
- `https://${HaloCoreEndpoints.SkillOrigin}.${
233
- HaloCoreEndpoints.ServiceDomain
234
- }/hi/matches/${matchId}/skill?players=xuid(${playerIds.join("),xuid(")})`,
235
- "get"
236
- );
247
+ public getMatchSkill = async (matchId: string, playerIds: string[]) => {
248
+ try {
249
+ return await this.executeResultsRequest<MatchSkill>(
250
+ `https://${HaloCoreEndpoints.SkillOrigin}.${
251
+ HaloCoreEndpoints.ServiceDomain
252
+ }/hi/matches/${matchId}/skill?players=${playerIds
253
+ .map(wrapPlayerId)
254
+ .join(",")}`,
255
+ "get"
256
+ );
257
+ } catch (e) {
258
+ if (e instanceof AxiosError && e.status === 404 && e.response?.data) {
259
+ return (e.response.data as ResultsContainer<MatchSkill<0 | 1>>).Value;
260
+ } else {
261
+ throw e;
262
+ }
263
+ }
264
+ };
237
265
 
238
266
  /** Gets authoring metadata about a specific asset. */
239
267
  public getAsset = <TAssetType extends keyof AssetKindTypeMap>(
package/src/index.ts CHANGED
@@ -10,3 +10,4 @@ export { PlayerMatchHistory } from "./models/halo-infinite/player-match-history"
10
10
  export { Stats } from "./models/halo-infinite/stats";
11
11
  export { MapAsset, UgcGameVariantAsset } from "./models/halo-infinite/asset";
12
12
  export { AssetKind } from "./models/halo-infinite/asset-kind";
13
+ export { MatchOutcome } from "./models/halo-infinite/match-outcome";
@@ -57,3 +57,32 @@ export interface UgcGameVariantAsset extends Asset {
57
57
  };
58
58
  EngineGameVariantLink?: Asset;
59
59
  }
60
+
61
+ export interface PlaylistAsset extends Asset {
62
+ CustomData: {
63
+ PlaylistEntries: Array<{
64
+ MapModePairAssetId: string;
65
+ Metadata: {
66
+ Weight: number;
67
+ };
68
+ }>;
69
+ Strategy: number;
70
+ MinTeams: number;
71
+ MinTeamSize: number;
72
+ MaxTeams: number;
73
+ MaxTeamSize: number;
74
+ MaxTeamImbalance: number;
75
+ MaxSplitscreenPlayersAllowed: number;
76
+ AllowFriendJoinInProgress: boolean;
77
+ AllowMatchmakingJoinInProgress: boolean;
78
+ AllowBotJoinInProgress: boolean;
79
+ ExitExperienceDurationSec: number;
80
+ FireteamLeaderKickAllowed: boolean;
81
+ DisableMidgameChat: boolean;
82
+ AllowedDeviceInputs: Array<number>;
83
+ BotDifficulty: number;
84
+ MinFireteamSize: number;
85
+ MaxFireteamSize: number;
86
+ };
87
+ RotationEntries: Asset[]; // TODO: Some sort of map-mode pair asset
88
+ }
@@ -2,7 +2,8 @@ import { AssetVersionLink } from "./asset-version-link";
2
2
  import { GameVariantCategory } from "./game-variant-category";
3
3
  import { PlaylistExperience } from "./playlist-experience";
4
4
  export interface MatchInfo<
5
- TCategory extends GameVariantCategory = GameVariantCategory
5
+ TCategory extends GameVariantCategory = GameVariantCategory,
6
+ TResult extends 1 | 0 = 0
6
7
  > {
7
8
  StartTime: string;
8
9
  EndTime: string;
@@ -13,10 +14,10 @@ export interface MatchInfo<
13
14
  MapVariant: AssetVersionLink;
14
15
  UgcGameVariant: AssetVersionLink;
15
16
  ClearanceId: string;
16
- Playlist: AssetVersionLink;
17
- PlaylistExperience: PlaylistExperience;
18
- PlaylistMapModePair: AssetVersionLink;
19
- SeasonId: string;
17
+ Playlist: AssetVersionLink | null;
18
+ PlaylistExperience: TResult extends 0 ? PlaylistExperience : null;
19
+ PlaylistMapModePair: TResult extends 0 ? AssetVersionLink : null;
20
+ SeasonId: TResult extends 0 ? string : null;
20
21
  PlayableDuration: string;
21
22
  TeamsEnabled: boolean;
22
23
  TeamScoringEnabled: boolean;
@@ -20,7 +20,7 @@ interface Counterfactual {
20
20
  Deaths: number;
21
21
  }
22
22
 
23
- export interface MatchSkill {
23
+ export interface MatchSkill<TResult extends 1 | 0 = 0> {
24
24
  TeamId: number;
25
25
  TeamMmr: number;
26
26
  TeamMmrs: {
@@ -30,19 +30,23 @@ export interface MatchSkill {
30
30
  PreMatchCsr: CsrObject;
31
31
  PostMatchCsr: CsrObject;
32
32
  };
33
- StatPerformances: {
34
- Kills: StatPerformance;
35
- Deaths: StatPerformance;
36
- };
37
- Counterfactuals: {
38
- SelfCounterfactual: Counterfactual;
39
- TierCounterfactuals: {
40
- Bronze: Counterfactual;
41
- Silver: Counterfactual;
42
- Gold: Counterfactual;
43
- Platinum: Counterfactual;
44
- Diamond: Counterfactual;
45
- Onyx: Counterfactual;
46
- };
47
- };
33
+ StatPerformances: TResult extends 0
34
+ ? {
35
+ Kills: StatPerformance;
36
+ Deaths: StatPerformance;
37
+ }
38
+ : {};
39
+ Counterfactuals: TResult extends 0
40
+ ? {
41
+ SelfCounterfactuals: Counterfactual;
42
+ TierCounterfactuals: {
43
+ Bronze: Counterfactual;
44
+ Silver: Counterfactual;
45
+ Gold: Counterfactual;
46
+ Platinum: Counterfactual;
47
+ Diamond: Counterfactual;
48
+ Onyx: Counterfactual;
49
+ };
50
+ }
51
+ : null;
48
52
  }