Use SplatNet 3 types from splatnet3-types

This commit is contained in:
Samuel Elliott 2022-10-20 22:57:35 +01:00
parent dda504b50c
commit 04e6a80496
No known key found for this signature in database
GPG Key ID: 8420C7CDE43DC4D6
10 changed files with 85 additions and 1313 deletions

11
package-lock.json generated
View File

@ -21,6 +21,7 @@
"node-notifier": "^10.0.1",
"node-persist": "^3.1.0",
"read": "^1.0.7",
"splatnet3-types": "^0.1.20221020213035",
"supports-color": "^8.1.1",
"tslib": "^2.4.0",
"uuid": "^8.3.2",
@ -4360,6 +4361,11 @@
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
"dev": true
},
"node_modules/splatnet3-types": {
"version": "0.1.20221020213035",
"resolved": "https://registry.npmjs.org/splatnet3-types/-/splatnet3-types-0.1.20221020213035.tgz",
"integrity": "sha512-IjetRtZCcr4kKVdKGVsmiqAHt8b6WqyOJB+8+2pj5imDiAXBWqTKeKp9++CkdIpNPRBO4BLpWUwM5wHaYI0YGA=="
},
"node_modules/sprintf-js": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
@ -8386,6 +8392,11 @@
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
"dev": true
},
"splatnet3-types": {
"version": "0.1.20221020213035",
"resolved": "https://registry.npmjs.org/splatnet3-types/-/splatnet3-types-0.1.20221020213035.tgz",
"integrity": "sha512-IjetRtZCcr4kKVdKGVsmiqAHt8b6WqyOJB+8+2pj5imDiAXBWqTKeKp9++CkdIpNPRBO4BLpWUwM5wHaYI0YGA=="
},
"sprintf-js": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",

View File

@ -45,6 +45,7 @@
"node-notifier": "^10.0.1",
"node-persist": "^3.1.0",
"read": "^1.0.7",
"splatnet3-types": "^0.1.20221020213035",
"supports-color": "^8.1.1",
"tslib": "^2.4.0",
"uuid": "^8.3.2",

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,12 @@
import fetch, { Response } from 'node-fetch';
import createDebug from 'debug';
import { GraphQLRequest, GraphQLResponse, KnownRequestId, RequestId, RequestParametersFor, RequestResultFor } from 'splatnet3-types/splatnet3';
import { WebServiceToken } from './coral-types.js';
import { NintendoAccountUser } from './na.js';
import { defineResponse, ErrorResponse, HasResponse } from './util.js';
import CoralApi from './coral.js';
import { timeoutSignal } from '../util/misc.js';
import { BankaraBattleHistoriesResult, BattleHistoryCurrentPlayerResult, BulletToken, CurrentFestResult, FriendListResult, GraphQLRequest, GraphQLResponse, HistoryRecordResult, HomeResult, LatestBattleHistoriesResult, PrivateBattleHistoriesResult, RegularBattleHistoriesResult, RequestId, SettingResult, StageScheduleResult, VsHistoryDetailResult, CoopHistoryResult, CoopHistoryDetailResult, FestRecordResult, FestRecordRefetchResult, DetailFestRecordDetailResult, DetailVotingStatusResult, DetailFestVotingStatusRefetchResult, VotesUpdateFestVoteResult, VsHistoryDetailPagerRefetchResult } from './splatnet3-types.js';
import { BulletToken } from './splatnet3-types.js';
const debug = createDebug('nxapi:api:splatnet3');
@ -107,7 +108,11 @@ export default class SplatNet3Api {
return defineResponse(data, response);
}
async persistedQuery<T = unknown, V = unknown>(id: string, variables: V) {
async persistedQuery<
I extends string,
T = I extends KnownRequestId ? RequestResultFor<I> : unknown,
V = I extends KnownRequestId ? RequestParametersFor<I> : unknown,
>(id: I, variables: V) {
const req: GraphQLRequest<V> = {
variables,
extensions: {
@ -125,11 +130,11 @@ export default class SplatNet3Api {
}
async getHome() {
return this.persistedQuery<HomeResult>(RequestId.HomeQuery, {});
return this.persistedQuery(RequestId.HomeQuery, {});
}
async getCurrentFest() {
return this.persistedQuery<CurrentFestResult>(RequestId.CurrentFestQuery, {});
return this.persistedQuery(RequestId.CurrentFestQuery, {});
}
async getConfigureAnalytics() {
@ -137,102 +142,102 @@ export default class SplatNet3Api {
}
async getSettings() {
return this.persistedQuery<SettingResult>(RequestId.SettingQuery, {});
return this.persistedQuery(RequestId.SettingQuery, {});
}
async getFestRecords() {
return this.persistedQuery<FestRecordResult>(RequestId.FestRecordQuery, {});
return this.persistedQuery(RequestId.FestRecordQuery, {});
}
async getFestRecordsRefetch() {
return this.persistedQuery<FestRecordRefetchResult>(RequestId.FestRecordRefetchQuery, {});
return this.persistedQuery(RequestId.FestRecordRefetchQuery, {});
}
async getFestDetail(id: string) {
return this.persistedQuery<DetailFestRecordDetailResult>(RequestId.DetailFestRecordDetailQuery, {
return this.persistedQuery(RequestId.DetailFestRecordDetailQuery, {
festId: id,
});
}
async getFestDetailRefetch(id: string) {
return this.persistedQuery<FestRecordRefetchResult>(RequestId.DetailFestRefethQuery, {
return this.persistedQuery(RequestId.DetailFestRefethQuery, {
festId: id,
});
}
async getFestVotingStatus(id: string) {
return this.persistedQuery<DetailVotingStatusResult>(RequestId.DetailVotingStatusQuery, {
return this.persistedQuery(RequestId.DetailVotingStatusQuery, {
festId: id,
});
}
async getFestVotingStatusRefetch(id: string) {
return this.persistedQuery<DetailFestVotingStatusRefetchResult>(RequestId.DetailFestVotingStatusRefethQuery, {
return this.persistedQuery(RequestId.DetailFestVotingStatusRefethQuery, {
festId: id,
});
}
async updateFestPoll(id: string) {
return this.persistedQuery<VotesUpdateFestVoteResult>(RequestId.VotesUpdateFestVoteMutation, {
return this.persistedQuery(RequestId.VotesUpdateFestVoteMutation, {
teamId: id,
});
}
async getFriends() {
return this.persistedQuery<FriendListResult>(RequestId.FriendListQuery, {});
return this.persistedQuery(RequestId.FriendListQuery, {});
}
async getFriendsRefetch() {
return this.persistedQuery<FriendListResult>(RequestId.FriendListRefetchQuery, {});
return this.persistedQuery(RequestId.FriendListRefetchQuery, {});
}
async getHistoryRecords() {
return this.persistedQuery<HistoryRecordResult>(RequestId.HistoryRecordQuery, {});
return this.persistedQuery(RequestId.HistoryRecordQuery, {});
}
async getSchedules() {
return this.persistedQuery<StageScheduleResult>(RequestId.StageScheduleQuery, {});
return this.persistedQuery(RequestId.StageScheduleQuery, {});
}
async getBattleHistoryCurrentPlayer() {
return this.persistedQuery<BattleHistoryCurrentPlayerResult>(RequestId.BattleHistoryCurrentPlayerQuery, {});
return this.persistedQuery(RequestId.BattleHistoryCurrentPlayerQuery, {});
}
async getLatestBattleHistories() {
return this.persistedQuery<LatestBattleHistoriesResult>(RequestId.LatestBattleHistoriesQuery, {});
return this.persistedQuery(RequestId.LatestBattleHistoriesQuery, {});
}
async getRegularBattleHistories() {
return this.persistedQuery<RegularBattleHistoriesResult>(RequestId.RegularBattleHistoriesQuery, {});
return this.persistedQuery(RequestId.RegularBattleHistoriesQuery, {});
}
async getBankaraBattleHistories() {
return this.persistedQuery<BankaraBattleHistoriesResult>(RequestId.BankaraBattleHistoriesQuery, {});
return this.persistedQuery(RequestId.BankaraBattleHistoriesQuery, {});
}
async getPrivateBattleHistories() {
return this.persistedQuery<PrivateBattleHistoriesResult>(RequestId.PrivateBattleHistoriesQuery, {});
return this.persistedQuery(RequestId.PrivateBattleHistoriesQuery, {});
}
async getBattleHistoryDetail(id: string) {
return this.persistedQuery<VsHistoryDetailResult>(RequestId.VsHistoryDetailQuery, {
return this.persistedQuery(RequestId.VsHistoryDetailQuery, {
vsResultId: id,
});
}
async getBattleHistoryDetailPagerRefetch(id: string) {
return this.persistedQuery<VsHistoryDetailPagerRefetchResult>(RequestId.VsHistoryDetailPagerRefetchQuery, {
return this.persistedQuery(RequestId.VsHistoryDetailPagerRefetchQuery, {
vsResultId: id,
});
}
async getCoopHistory() {
return this.persistedQuery<CoopHistoryResult>(RequestId.CoopHistoryQuery, {});
return this.persistedQuery(RequestId.CoopHistoryQuery, {});
}
async getCoopHistoryDetail(id: string) {
return this.persistedQuery<CoopHistoryDetailResult>(RequestId.CoopHistoryDetailQuery, {
coopHistoryDetailId: id
return this.persistedQuery(RequestId.CoopHistoryDetailQuery, {
coopHistoryDetailId: id,
});
}

View File

@ -1,11 +1,11 @@
import * as net from 'node:net';
import createDebug from 'debug';
import express, { Request, Response } from 'express';
import express from 'express';
import * as persist from 'node-persist';
import { BankaraMatchMode, BankaraMatchSetting, CoopSetting, DetailVotingStatusResult, FestMatchSetting, FestState, FestTeam_schedule, FestTeam_votingStatus, FestVoteState, Fest_schedule, Friend as SplatNetFriend, FriendListResult, FriendOnlineState, GraphQLResponse, LeagueMatchSetting, RegularMatchSetting, StageScheduleResult, XMatchSetting } from 'splatnet3-types/splatnet3';
import type { Arguments as ParentArguments } from '../cli.js';
import { ArgumentsCamelCase, Argv, YargsArguments } from '../util/yargs.js';
import { initStorage } from '../util/storage.js';
import { SavedToken } from '../common/auth/coral.js';
import { addCliFeatureUserAgent } from '../util/useragent.js';
import { parseListenAddress } from '../util/net.js';
import { product } from '../util/product.js';
@ -13,7 +13,6 @@ import Users, { CoralUser } from '../common/users.js';
import { Friend } from '../api/coral-types.js';
import { getBulletToken, SavedBulletToken } from '../common/auth/splatnet3.js';
import SplatNet3Api from '../api/splatnet3.js';
import { BankaraMatchMode, DetailVotingStatusResult, FestState, FestVoteState, FriendListResult, FriendOnlineState, GraphQLResponse, StageScheduleResult } from '../api/splatnet3-types.js';
const debug = createDebug('cli:presence-server');
@ -131,12 +130,12 @@ export class SplatNet3User {
}
}
async getFriends(): Promise<FriendListResult['friends']> {
async getFriends(): Promise<SplatNetFriend[]> {
await this.update('friends', async () => {
this.friends = await this.splatnet.getFriendsRefetch();
}, this.update_interval);
return this.friends.data.friends;
return this.friends.data.friends.nodes;
}
async getSchedules(): Promise<StageScheduleResult> {
@ -145,7 +144,7 @@ export class SplatNet3User {
if (this.schedules && this.schedules.data.currentFest) {
const tricolour_open = new Date(this.schedules.data.currentFest.midtermTime).getTime() <= Date.now();
const should_refresh_fest = tricolour_open &&
![FestState.SECOND_HALF, FestState.CLOSED].includes(this.schedules.data.currentFest.state);
![FestState.SECOND_HALF, FestState.CLOSED].includes(this.schedules.data.currentFest.state as FestState);
if (should_refresh_fest) update_interval = this.update_interval;
}
@ -207,8 +206,8 @@ function createApp(
const include_splatnet3 = splatnet3_users && req.query['include-splatoon3'] === '1';
const result: (Friend & {
splatoon3?: FriendListResult['friends']['nodes'][0] | null;
splatoon3_fest_team?: Exclude<DetailVotingStatusResult['fest'], null>['teams'][0] | null;
splatoon3?: SplatNetFriend | null;
splatoon3_fest_team?: FestTeam_votingStatus | null;
})[] = [];
const users = await Promise.all(user_ids.map(async id => {
@ -248,7 +247,7 @@ function createApp(
const friends = await user.getFriends();
const fest_vote_status = await user.getCurrentFestVotes();
for (const friend of friends.nodes) {
for (const friend of friends) {
const friend_nsaid = Buffer.from(friend.id, 'base64').toString()
.replace(/^Friend-([0-9a-f]{16})$/, '$1');
const match = result.find(f => f.nsaId === friend_nsaid);
@ -303,23 +302,16 @@ function createApp(
let match_coral: Friend | null = null;
let match_user_id: string | null = null;
let match_splatnet3: FriendListResult['friends']['nodes'][0] | null = null;
let match_splatnet3_fest_team:
Exclude<StageScheduleResult['currentFest'], null>['teams'][0] | null | undefined = undefined;
let match_splatnet3_fest_team_vote_status:
Exclude<DetailVotingStatusResult['fest'], null>['teams'][0] | null | undefined = undefined;
let match_splatnet3: SplatNetFriend | null = null;
let match_splatnet3_fest_team: FestTeam_schedule | null | undefined = undefined;
let match_splatnet3_fest_team_vote_status: FestTeam_votingStatus | null | undefined = undefined;
const additional_response_data: {
splatoon3_vs_setting?:
StageScheduleResult['regularSchedules']['nodes'][0]['regularMatchSetting'] |
Exclude<StageScheduleResult['bankaraSchedules']['nodes'][0]['bankaraMatchSettings'], null>[0] |
StageScheduleResult['festSchedules']['nodes'][0]['festMatchSetting'] |
StageScheduleResult['leagueSchedules']['nodes'][0]['leagueMatchSetting'] |
StageScheduleResult['xSchedules']['nodes'][0]['xMatchSetting'] |
null;
splatoon3_coop_setting?:
StageScheduleResult['coopGroupingSchedule']['regularSchedules']['nodes'][0]['setting'] | null;
splatoon3_fest?: StageScheduleResult['currentFest'] | null;
RegularMatchSetting | BankaraMatchSetting | FestMatchSetting |
LeagueMatchSetting | XMatchSetting | null;
splatoon3_coop_setting?: CoopSetting | null;
splatoon3_fest?: Fest_schedule | null;
} = {};
for (const user_naid of user_ids) {
@ -356,7 +348,7 @@ function createApp(
const friends = await user.getFriends();
const fest_vote_status = await user.getCurrentFestVotes();
for (const friend of friends.nodes) {
for (const friend of friends) {
const friend_nsaid = Buffer.from(friend.id, 'base64').toString()
.replace(/^Friend-([0-9a-f]{16})$/, '$1');
if (match_coral.nsaId !== friend_nsaid) continue;
@ -462,9 +454,8 @@ function createApp(
}
function createScheduleFest(
fest: Exclude<StageScheduleResult['currentFest'], null>,
vote_team?: string, state?: FestVoteState | null
): Exclude<StageScheduleResult['currentFest'], null> {
fest: Fest_schedule, vote_team?: string, state?: FestVoteState | null
): Fest_schedule {
return {
...fest,
teams: fest.teams.map(t => createFestScheduleTeam(t, t.id === vote_team ? state : null)),
@ -472,9 +463,8 @@ function createScheduleFest(
}
function createFestScheduleTeam(
team: Exclude<StageScheduleResult['currentFest'], null>['teams'][0],
state: FestVoteState | null = null
): Exclude<StageScheduleResult['currentFest'], null>['teams'][0] {
team: FestTeam_schedule, state: FestVoteState | null = null
): FestTeam_schedule {
return {
id: team.id,
color: team.color,
@ -484,9 +474,8 @@ function createFestScheduleTeam(
}
function createFestVoteTeam(
team: Exclude<DetailVotingStatusResult['fest'], null>['teams'][0],
state?: FestVoteState | null
): Exclude<DetailVotingStatusResult['fest'], null>['teams'][0] {
team: FestTeam_votingStatus, state: FestVoteState | null
): FestTeam_votingStatus {
return {
id: team.id,
teamName: team.teamName,

View File

@ -1,10 +1,10 @@
import createDebug from 'debug';
import { Judgement } from 'splatnet3-types/splatnet3';
import Table from '../util/table.js';
import type { Arguments as ParentArguments } from '../splatnet3.js';
import { ArgumentsCamelCase, Argv, YargsArguments } from '../../util/yargs.js';
import { initStorage } from '../../util/storage.js';
import { getBulletToken } from '../../common/auth/splatnet3.js';
import { Judgement } from '../../api/splatnet3-types.js';
const debug = createDebug('cli:splatnet3:battles');

View File

@ -1,10 +1,10 @@
import createDebug from 'debug';
import { FestState } from 'splatnet3-types/splatnet3';
import Table from '../util/table.js';
import type { Arguments as ParentArguments } from '../splatnet3.js';
import { ArgumentsCamelCase, Argv, YargsArguments } from '../../util/yargs.js';
import { initStorage } from '../../util/storage.js';
import { getBulletToken } from '../../common/auth/splatnet3.js';
import { FestState } from '../../api/splatnet3-types.js';
const debug = createDebug('cli:splatnet3:festival');

View File

@ -1,10 +1,10 @@
import createDebug from 'debug';
import { FriendOnlineState } from 'splatnet3-types/splatnet3';
import Table from '../util/table.js';
import type { Arguments as ParentArguments } from '../splatnet3.js';
import { ArgumentsCamelCase, Argv, YargsArguments } from '../../util/yargs.js';
import { initStorage } from '../../util/storage.js';
import { getBulletToken } from '../../common/auth/splatnet3.js';
import { FriendOnlineState } from '../../api/splatnet3-types.js';
const debug = createDebug('cli:splatnet3:friends');

View File

@ -1,8 +1,8 @@
import createDebug from 'debug';
import persist from 'node-persist';
import DiscordRPC from 'discord-rpc';
import { BankaraMatchMode, BankaraMatchSetting, CoopSchedule, CoopSetting, DetailVotingStatusResult, FestMatchSetting, FestState, FestTeamRole, FestTeam_schedule, FestTeam_votingStatus, Fest_schedule, FriendListResult, FriendOnlineState, GraphQLResponse, LeagueMatchSetting, RegularMatchSetting, StageScheduleResult, VsSchedule_bankara, VsSchedule_fest, VsSchedule_league, VsSchedule_regular, VsSchedule_xMatch, XMatchSetting } from 'splatnet3-types/splatnet3';
import { Game } from '../../../api/coral-types.js';
import { BankaraMatchMode, DetailVotingStatusResult, FestState, FestTeamRole, FriendListResult, FriendOnlineState, GraphQLResponse, StageScheduleResult } from '../../../api/splatnet3-types.js';
import SplatNet3Api from '../../../api/splatnet3.js';
import { DiscordPresenceExternalMonitorsConfiguration } from '../../../app/common/types.js';
import { Arguments } from '../../../cli/nso/presence.js';
@ -27,15 +27,15 @@ export default class SplatNet3Monitor extends EmbeddedLoop {
friend: FriendListResult['friends']['nodes'][0] | null = null;
regular_schedule: StageScheduleResult['regularSchedules']['nodes'][0] | null = null;
anarchy_schedule: StageScheduleResult['bankaraSchedules']['nodes'][0] | null = null;
fest_schedule: StageScheduleResult['festSchedules']['nodes'][0] | null = null;
league_schedule: StageScheduleResult['leagueSchedules']['nodes'][0] | null = null;
x_schedule: StageScheduleResult['xSchedules']['nodes'][0] | null = null;
coop_schedule: StageScheduleResult['coopGroupingSchedule']['regularSchedules']['nodes'][0] | null = null;
fest: StageScheduleResult['currentFest'] | null = null;
fest_team_voting_status: Exclude<DetailVotingStatusResult['fest'], null>['teams'][0] | null = null;
fest_team: Exclude<StageScheduleResult['currentFest'], null>['teams'][0] | null = null;
regular_schedule: VsSchedule_regular | null = null;
anarchy_schedule: VsSchedule_bankara | null = null;
fest_schedule: VsSchedule_fest | null = null;
league_schedule: VsSchedule_league | null = null;
x_schedule: VsSchedule_xMatch | null = null;
coop_schedule: CoopSchedule | null = null;
fest: Fest_schedule | null = null;
fest_team_voting_status: FestTeam_votingStatus | null = null;
fest_team: FestTeam_schedule | null = null;
constructor(
readonly discord_presence: ExternalMonitorPresenceInterface,
@ -119,7 +119,7 @@ export default class SplatNet3Monitor extends EmbeddedLoop {
// to check if the player may join a Tricolour battle
const tricolour_open = this.fest && new Date(this.fest.midtermTime).getTime() < Date.now();
const should_refresh_fest = this.fest && tricolour_open &&
![FestState.SECOND_HALF, FestState.CLOSED].includes(this.fest.state);
![FestState.SECOND_HALF, FestState.CLOSED].includes(this.fest.state as FestState);
this.regular_schedule = this.getSchedule(this.cached_schedules?.data.regularSchedules.nodes ?? []);
@ -220,19 +220,12 @@ export function getConfigFromAppConfig(
interface PresenceUrlResponse {
splatoon3?: FriendListResult['friends']['nodes'][0] | null;
splatoon3_fest_team?:
(Exclude<DetailVotingStatusResult['fest'], null>['teams'][0] &
Exclude<StageScheduleResult['currentFest'], null>['teams'][0]) | null;
splatoon3_fest_team?: (FestTeam_votingStatus & FestTeam_schedule) | null;
splatoon3_vs_setting?:
StageScheduleResult['regularSchedules']['nodes'][0]['regularMatchSetting'] |
Exclude<StageScheduleResult['bankaraSchedules']['nodes'][0]['bankaraMatchSettings'], null>[0] |
StageScheduleResult['festSchedules']['nodes'][0]['festMatchSetting'] |
StageScheduleResult['leagueSchedules']['nodes'][0]['leagueMatchSetting'] |
StageScheduleResult['xSchedules']['nodes'][0]['xMatchSetting'] |
null;
splatoon3_coop_setting?:
StageScheduleResult['coopGroupingSchedule']['regularSchedules']['nodes'][0]['setting'] | null;
splatoon3_fest?: StageScheduleResult['currentFest'] | null;
RegularMatchSetting | BankaraMatchSetting | FestMatchSetting |
LeagueMatchSetting | XMatchSetting | null;
splatoon3_coop_setting?: CoopSetting | null;
splatoon3_fest?: Fest_schedule | null;
}
export function callback(activity: DiscordRPC.Presence, game: Game, context?: DiscordPresenceContext) {

View File

@ -3,4 +3,4 @@ export {
SplatNet3AuthData,
} from '../api/splatnet3.js';
export * from '../api/splatnet3-types.js';
// export * from '../api/splatnet3-types.js';