xpt-shared-types 1.18.0 → 1.20.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.
- package/README.md +7 -0
- package/dist/generated/enums.d.ts +3 -1
- package/dist/generated/inputs.d.ts +13 -1
- package/dist/generated/models.d.ts +13 -1
- package/dist/manual/gameAccountHandle.d.ts +41 -3
- package/dist/manual/gameAccountHandle.js +22 -4
- package/dist/manual/tournamentEntry.d.ts +5 -1
- package/package.json +1 -1
- package/src/generated/enums.ts +6 -1
- package/src/generated/inputs.ts +14 -0
- package/src/generated/models.ts +14 -0
- package/src/manual/gameAccountHandle.ts +60 -4
- package/src/manual/tournamentEntry.ts +5 -1
package/README.md
CHANGED
|
@@ -117,6 +117,13 @@ using npm trusted publishing, so no npm token or 2FA prompt is involved.
|
|
|
117
117
|
2. `yarn version --patch` (or `--minor`), which commits and tags `vX.Y.Z`
|
|
118
118
|
3. `git push --follow-tags`
|
|
119
119
|
|
|
120
|
+
If the version was bumped by hand instead, commit it and tag with
|
|
121
|
+
`git tag -a vX.Y.Z -m vX.Y.Z` before pushing: `--follow-tags` only sends
|
|
122
|
+
annotated tags, so a plain `git tag vX.Y.Z` (or no tag at all) pushes nothing
|
|
123
|
+
and prints "Everything up-to-date". `git push origin vX.Y.Z` also works.
|
|
124
|
+
After the run succeeds the registry can lag a minute or two; confirm with
|
|
125
|
+
`npm view xpt-shared-types dist-tags.latest` before installing.
|
|
126
|
+
|
|
120
127
|
The workflow fires on the `v*` tag, refuses to run if the tag and
|
|
121
128
|
`package.json` version disagree, then builds and publishes.
|
|
122
129
|
|
|
@@ -7,7 +7,7 @@ export type FriendshipStatus = "pending" | "accepted";
|
|
|
7
7
|
/** `GameAccount.code` */
|
|
8
8
|
export type GameAccountCode = "steam" | "psn" | "xbox" | "battlenet" | "riot" | "epic" | "ea" | "activision" | "ubisoft" | "nintendo" | "fightcade" | "apple" | "googleplay";
|
|
9
9
|
/** `GameAccount.verification` */
|
|
10
|
-
export type GameAccountVerification = "none" | "format";
|
|
10
|
+
export type GameAccountVerification = "none" | "format" | "linked";
|
|
11
11
|
/** `Game.genre` */
|
|
12
12
|
export type GameGenre = "FPS" | "MOBA" | "Battle Royale" | "Fighting (FGC)" | "Sports" | "Strategy/RTS" | "Sim Racing" | "Card Game" | "Retro" | "Other";
|
|
13
13
|
/** `GameRequest.customLobbies` */
|
|
@@ -66,6 +66,8 @@ export type TournamentTeamSize = "one" | "two" | "three" | "four" | "five";
|
|
|
66
66
|
export type TournamentType = "Single Elimination" | "League" | "Double Elimination";
|
|
67
67
|
/** `Tournament.visibility` */
|
|
68
68
|
export type TournamentVisibility = "public" | "unlisted";
|
|
69
|
+
/** `UserGameAccount.verificationMethod` */
|
|
70
|
+
export type UserGameAccountVerificationMethod = "linked";
|
|
69
71
|
/** `UserTransaction.stripeStatus` */
|
|
70
72
|
export type UserTransactionStripeStatus = "pending" | "completed" | "failed" | "refunded" | "internal";
|
|
71
73
|
/** `UserTransaction.type` */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BlocksContent, MediaInput, RelationInput } from '../contracts';
|
|
2
|
-
import type { AdminActionTargetType, FaqCategory, FriendshipStatus, GameAccountCode, GameAccountVerification, GameGenre, GameRequestCustomLobbies, GameRequestGenre, GameRequestTeamPlay, GameVisibility, MatchDisputeReason, MatchLobbyStatus, MatchResultType, MatchRound, MatchStreamPlatform, MatchWinnerSlot, PlatformCode, PlayerBanScope, ReferralStatus, TeamCurrentStatus, TeamInviteStatus, TeamInviteTeamRole, TeamPlayerTeamRole, TournamentAccess, TournamentCurrentStatus, TournamentInviteStatus, TournamentJoinRequestEntryType, TournamentJoinRequestStatus, TournamentParticipantEntryType, TournamentParticipantStatus, TournamentRoleRole, TournamentTeamSize, TournamentType, TournamentVisibility, UserTransactionStripeStatus, UserTransactionType } from './enums';
|
|
2
|
+
import type { AdminActionTargetType, FaqCategory, FriendshipStatus, GameAccountCode, GameAccountVerification, GameGenre, GameRequestCustomLobbies, GameRequestGenre, GameRequestTeamPlay, GameVisibility, MatchDisputeReason, MatchLobbyStatus, MatchResultType, MatchRound, MatchStreamPlatform, MatchWinnerSlot, PlatformCode, PlayerBanScope, ReferralStatus, TeamCurrentStatus, TeamInviteStatus, TeamInviteTeamRole, TeamPlayerTeamRole, TournamentAccess, TournamentCurrentStatus, TournamentInviteStatus, TournamentJoinRequestEntryType, TournamentJoinRequestStatus, TournamentParticipantEntryType, TournamentParticipantStatus, TournamentRoleRole, TournamentTeamSize, TournamentType, TournamentVisibility, UserGameAccountVerificationMethod, UserTransactionStripeStatus, UserTransactionType } from './enums';
|
|
3
3
|
/** Write payload for `about`. */
|
|
4
4
|
export interface AboutInput {
|
|
5
5
|
heroTitle?: string;
|
|
@@ -83,6 +83,14 @@ export interface GameAccountInput {
|
|
|
83
83
|
games?: RelationInput | RelationInput[];
|
|
84
84
|
platforms?: RelationInput | RelationInput[];
|
|
85
85
|
}
|
|
86
|
+
/** Write payload for `game-account-link`. */
|
|
87
|
+
export interface GameAccountLinkInput {
|
|
88
|
+
token?: string;
|
|
89
|
+
users_permissions_user?: RelationInput;
|
|
90
|
+
game_account?: RelationInput;
|
|
91
|
+
expiresAt?: string;
|
|
92
|
+
returnTo?: string;
|
|
93
|
+
}
|
|
86
94
|
/** Write payload for `game-request`. */
|
|
87
95
|
export interface GameRequestInput {
|
|
88
96
|
gameTitle?: string;
|
|
@@ -328,6 +336,7 @@ export interface TournamentInput {
|
|
|
328
336
|
rules?: string;
|
|
329
337
|
hasThirdPlace?: boolean;
|
|
330
338
|
hasMatchLobby?: boolean;
|
|
339
|
+
requireVerifiedAccounts?: boolean;
|
|
331
340
|
visibility?: TournamentVisibility;
|
|
332
341
|
access?: TournamentAccess;
|
|
333
342
|
checkInTime?: number;
|
|
@@ -427,6 +436,9 @@ export interface UserInput {
|
|
|
427
436
|
export interface UserGameAccountInput {
|
|
428
437
|
accountId?: string;
|
|
429
438
|
isPrivate?: boolean;
|
|
439
|
+
verifiedAt?: string;
|
|
440
|
+
verificationMethod?: UserGameAccountVerificationMethod;
|
|
441
|
+
providerAccountId?: string;
|
|
430
442
|
users_permissions_user?: RelationInput;
|
|
431
443
|
game_account?: RelationInput;
|
|
432
444
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BlocksContent, StrapiDocument, StrapiMedia, UserRole } from '../contracts';
|
|
2
|
-
import type { AdminActionTargetType, FaqCategory, FriendshipStatus, GameAccountCode, GameAccountVerification, GameGenre, GameRequestCustomLobbies, GameRequestGenre, GameRequestTeamPlay, GameVisibility, MatchDisputeReason, MatchLobbyStatus, MatchResultType, MatchRound, MatchStreamPlatform, MatchWinnerSlot, PlatformCode, PlayerBanScope, ReferralStatus, TeamCurrentStatus, TeamInviteStatus, TeamInviteTeamRole, TeamPlayerTeamRole, TournamentAccess, TournamentCurrentStatus, TournamentInviteStatus, TournamentJoinRequestEntryType, TournamentJoinRequestStatus, TournamentParticipantEntryType, TournamentParticipantStatus, TournamentRoleRole, TournamentTeamSize, TournamentType, TournamentVisibility, UserTransactionStripeStatus, UserTransactionType } from './enums';
|
|
2
|
+
import type { AdminActionTargetType, FaqCategory, FriendshipStatus, GameAccountCode, GameAccountVerification, GameGenre, GameRequestCustomLobbies, GameRequestGenre, GameRequestTeamPlay, GameVisibility, MatchDisputeReason, MatchLobbyStatus, MatchResultType, MatchRound, MatchStreamPlatform, MatchWinnerSlot, PlatformCode, PlayerBanScope, ReferralStatus, TeamCurrentStatus, TeamInviteStatus, TeamInviteTeamRole, TeamPlayerTeamRole, TournamentAccess, TournamentCurrentStatus, TournamentInviteStatus, TournamentJoinRequestEntryType, TournamentJoinRequestStatus, TournamentParticipantEntryType, TournamentParticipantStatus, TournamentRoleRole, TournamentTeamSize, TournamentType, TournamentVisibility, UserGameAccountVerificationMethod, UserTransactionStripeStatus, UserTransactionType } from './enums';
|
|
3
3
|
/** `about` */
|
|
4
4
|
export interface About extends StrapiDocument {
|
|
5
5
|
heroTitle?: string | null;
|
|
@@ -83,6 +83,14 @@ export interface GameAccount extends StrapiDocument {
|
|
|
83
83
|
games?: Game[];
|
|
84
84
|
platforms?: Platform[];
|
|
85
85
|
}
|
|
86
|
+
/** `game-account-link` */
|
|
87
|
+
export interface GameAccountLink extends StrapiDocument {
|
|
88
|
+
token?: string | null;
|
|
89
|
+
users_permissions_user?: User | null;
|
|
90
|
+
game_account?: GameAccount | null;
|
|
91
|
+
expiresAt?: string | null;
|
|
92
|
+
returnTo?: string | null;
|
|
93
|
+
}
|
|
86
94
|
/** `game-request` */
|
|
87
95
|
export interface GameRequest extends StrapiDocument {
|
|
88
96
|
gameTitle?: string | null;
|
|
@@ -328,6 +336,7 @@ export interface Tournament extends StrapiDocument {
|
|
|
328
336
|
rules?: string | null;
|
|
329
337
|
hasThirdPlace?: boolean | null;
|
|
330
338
|
hasMatchLobby?: boolean | null;
|
|
339
|
+
requireVerifiedAccounts?: boolean | null;
|
|
331
340
|
visibility?: TournamentVisibility | null;
|
|
332
341
|
access?: TournamentAccess | null;
|
|
333
342
|
checkInTime?: number | null;
|
|
@@ -427,6 +436,9 @@ export interface User extends StrapiDocument {
|
|
|
427
436
|
export interface UserGameAccount extends StrapiDocument {
|
|
428
437
|
accountId?: string | null;
|
|
429
438
|
isPrivate?: boolean | null;
|
|
439
|
+
verifiedAt?: string | null;
|
|
440
|
+
verificationMethod?: UserGameAccountVerificationMethod | null;
|
|
441
|
+
providerAccountId?: string | null;
|
|
430
442
|
users_permissions_user?: User | null;
|
|
431
443
|
game_account?: GameAccount | null;
|
|
432
444
|
}
|
|
@@ -51,7 +51,44 @@ export type HandleCheck = {
|
|
|
51
51
|
message: string;
|
|
52
52
|
};
|
|
53
53
|
/** `error.details.name` values the game-account write endpoints raise. */
|
|
54
|
-
export type GameAccountErrorName = 'HandleInvalid' | 'HandleTaken'
|
|
54
|
+
export type GameAccountErrorName = 'HandleInvalid' | 'HandleTaken'
|
|
55
|
+
/** The row is verified by a link; unlink before changing the ID. */
|
|
56
|
+
| 'HandleLocked'
|
|
57
|
+
/** No configured link provider for this network. */
|
|
58
|
+
| 'LinkUnavailable'
|
|
59
|
+
/** The provider account is already linked to another XPT user. */
|
|
60
|
+
| 'LinkConflict';
|
|
61
|
+
/**
|
|
62
|
+
* Networks whose handles can be verified by signing in to the network. The
|
|
63
|
+
* catalogue's `verification: 'linked'` is only valid for these; whether a
|
|
64
|
+
* provider is actually configured on a given environment is answered at
|
|
65
|
+
* runtime by `GET /user-game-accounts/link/providers`.
|
|
66
|
+
*/
|
|
67
|
+
export declare const LINK_PROVIDER_CODES: readonly ["steam", "battlenet"];
|
|
68
|
+
export type LinkProviderCode = (typeof LINK_PROVIDER_CODES)[number];
|
|
69
|
+
export declare function isLinkableCode(code: string | null | undefined): code is LinkProviderCode;
|
|
70
|
+
/**
|
|
71
|
+
* Why a link attempt came back without a verified account — the `linkError`
|
|
72
|
+
* query value the callback redirects to the settings page with.
|
|
73
|
+
*/
|
|
74
|
+
export type AccountLinkError =
|
|
75
|
+
/** The attempt was unknown, already used, or older than its window. */
|
|
76
|
+
'expired'
|
|
77
|
+
/** The player cancelled at the provider. */
|
|
78
|
+
| 'denied'
|
|
79
|
+
/** The provider's answer did not verify. */
|
|
80
|
+
| 'invalid'
|
|
81
|
+
/** That provider account is already linked to another XPT user. */
|
|
82
|
+
| 'taken'
|
|
83
|
+
/** The provider is not configured, or the network is not linkable. */
|
|
84
|
+
| 'unavailable'
|
|
85
|
+
/** Accounts are frozen while the player is in a running tournament. */
|
|
86
|
+
| 'activeTournament';
|
|
87
|
+
/** True when a row's handle was proved by signing in to the network. */
|
|
88
|
+
export declare function isVerifiedAccount(row: {
|
|
89
|
+
verifiedAt?: string | Date | null;
|
|
90
|
+
verificationMethod?: string | null;
|
|
91
|
+
} | null | undefined): boolean;
|
|
55
92
|
/**
|
|
56
93
|
* The rule every network gets when it has no stricter one. Also the backstop
|
|
57
94
|
* the backend applies to every write regardless of network, so every rule
|
|
@@ -69,8 +106,9 @@ export declare const GENERIC_HANDLE_RULE: HandleRule;
|
|
|
69
106
|
export declare const HANDLE_RULES: Partial<Record<GameAccountCode, HandleRule>>;
|
|
70
107
|
/**
|
|
71
108
|
* The rule a network's handles are checked against: its own when the
|
|
72
|
-
* catalogue row asks for format checks
|
|
73
|
-
* otherwise the
|
|
109
|
+
* catalogue row asks for format checks (or is linkable, which implies them
|
|
110
|
+
* for anything typed by hand) and a rule exists for its code, otherwise the
|
|
111
|
+
* generic one.
|
|
74
112
|
*/
|
|
75
113
|
export declare function handleRuleFor(network: {
|
|
76
114
|
code?: GameAccountCode | string | null;
|
|
@@ -24,11 +24,27 @@
|
|
|
24
24
|
* `tests/unit/utils/gameAccountHandle.test.ts`).
|
|
25
25
|
*/
|
|
26
26
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
-
exports.HANDLE_RULES = exports.GENERIC_HANDLE_RULE = void 0;
|
|
27
|
+
exports.HANDLE_RULES = exports.GENERIC_HANDLE_RULE = exports.LINK_PROVIDER_CODES = void 0;
|
|
28
|
+
exports.isLinkableCode = isLinkableCode;
|
|
29
|
+
exports.isVerifiedAccount = isVerifiedAccount;
|
|
28
30
|
exports.handleRuleFor = handleRuleFor;
|
|
29
31
|
exports.hasHandleRule = hasHandleRule;
|
|
30
32
|
exports.checkHandle = checkHandle;
|
|
31
33
|
exports.normalizeHandleKey = normalizeHandleKey;
|
|
34
|
+
/**
|
|
35
|
+
* Networks whose handles can be verified by signing in to the network. The
|
|
36
|
+
* catalogue's `verification: 'linked'` is only valid for these; whether a
|
|
37
|
+
* provider is actually configured on a given environment is answered at
|
|
38
|
+
* runtime by `GET /user-game-accounts/link/providers`.
|
|
39
|
+
*/
|
|
40
|
+
exports.LINK_PROVIDER_CODES = ['steam', 'battlenet'];
|
|
41
|
+
function isLinkableCode(code) {
|
|
42
|
+
return exports.LINK_PROVIDER_CODES.includes(code !== null && code !== void 0 ? code : '');
|
|
43
|
+
}
|
|
44
|
+
/** True when a row's handle was proved by signing in to the network. */
|
|
45
|
+
function isVerifiedAccount(row) {
|
|
46
|
+
return !!(row === null || row === void 0 ? void 0 : row.verifiedAt) && row.verificationMethod === 'linked';
|
|
47
|
+
}
|
|
32
48
|
/**
|
|
33
49
|
* The rule every network gets when it has no stricter one. Also the backstop
|
|
34
50
|
* the backend applies to every write regardless of network, so every rule
|
|
@@ -156,12 +172,14 @@ exports.HANDLE_RULES = {
|
|
|
156
172
|
};
|
|
157
173
|
/**
|
|
158
174
|
* The rule a network's handles are checked against: its own when the
|
|
159
|
-
* catalogue row asks for format checks
|
|
160
|
-
* otherwise the
|
|
175
|
+
* catalogue row asks for format checks (or is linkable, which implies them
|
|
176
|
+
* for anything typed by hand) and a rule exists for its code, otherwise the
|
|
177
|
+
* generic one.
|
|
161
178
|
*/
|
|
162
179
|
function handleRuleFor(network) {
|
|
163
180
|
var _a;
|
|
164
|
-
|
|
181
|
+
const checked = (network === null || network === void 0 ? void 0 : network.verification) === 'format' || (network === null || network === void 0 ? void 0 : network.verification) === 'linked';
|
|
182
|
+
if (!checked || !(network === null || network === void 0 ? void 0 : network.code)) {
|
|
165
183
|
return exports.GENERIC_HANDLE_RULE;
|
|
166
184
|
}
|
|
167
185
|
return (_a = exports.HANDLE_RULES[network.code]) !== null && _a !== void 0 ? _a : exports.GENERIC_HANDLE_RULE;
|
|
@@ -33,4 +33,8 @@ export interface TournamentTeamJoinInput {
|
|
|
33
33
|
* `error.details.name` values the entry endpoints raise that a client is
|
|
34
34
|
* expected to branch on. Anything else is a plain message.
|
|
35
35
|
*/
|
|
36
|
-
export type TournamentEntryErrorName = 'NotEntryLeader' | 'MembersMissingGameAccount' | 'InsufficientCoins' | 'GameAccountRequired' | 'TeamEntryRequired'
|
|
36
|
+
export type TournamentEntryErrorName = 'NotEntryLeader' | 'MembersMissingGameAccount' | 'InsufficientCoins' | 'GameAccountRequired' | 'TeamEntryRequired'
|
|
37
|
+
/** The tournament admits only accounts verified by signing in; yours is typed. */
|
|
38
|
+
| 'GameAccountUnverified'
|
|
39
|
+
/** Same, for the named players on a team roster. */
|
|
40
|
+
| 'MembersUnverifiedGameAccount';
|
package/package.json
CHANGED
package/src/generated/enums.ts
CHANGED
|
@@ -41,7 +41,8 @@ export type GameAccountCode =
|
|
|
41
41
|
/** `GameAccount.verification` */
|
|
42
42
|
export type GameAccountVerification =
|
|
43
43
|
| "none"
|
|
44
|
-
| "format"
|
|
44
|
+
| "format"
|
|
45
|
+
| "linked";
|
|
45
46
|
|
|
46
47
|
/** `Game.genre` */
|
|
47
48
|
export type GameGenre =
|
|
@@ -254,6 +255,10 @@ export type TournamentVisibility =
|
|
|
254
255
|
| "public"
|
|
255
256
|
| "unlisted";
|
|
256
257
|
|
|
258
|
+
/** `UserGameAccount.verificationMethod` */
|
|
259
|
+
export type UserGameAccountVerificationMethod =
|
|
260
|
+
| "linked";
|
|
261
|
+
|
|
257
262
|
/** `UserTransaction.stripeStatus` */
|
|
258
263
|
export type UserTransactionStripeStatus =
|
|
259
264
|
| "pending"
|
package/src/generated/inputs.ts
CHANGED
|
@@ -42,6 +42,7 @@ import type {
|
|
|
42
42
|
TournamentTeamSize,
|
|
43
43
|
TournamentType,
|
|
44
44
|
TournamentVisibility,
|
|
45
|
+
UserGameAccountVerificationMethod,
|
|
45
46
|
UserTransactionStripeStatus,
|
|
46
47
|
UserTransactionType,
|
|
47
48
|
} from './enums';
|
|
@@ -138,6 +139,15 @@ export interface GameAccountInput {
|
|
|
138
139
|
platforms?: RelationInput | RelationInput[];
|
|
139
140
|
}
|
|
140
141
|
|
|
142
|
+
/** Write payload for `game-account-link`. */
|
|
143
|
+
export interface GameAccountLinkInput {
|
|
144
|
+
token?: string;
|
|
145
|
+
users_permissions_user?: RelationInput;
|
|
146
|
+
game_account?: RelationInput;
|
|
147
|
+
expiresAt?: string;
|
|
148
|
+
returnTo?: string;
|
|
149
|
+
}
|
|
150
|
+
|
|
141
151
|
/** Write payload for `game-request`. */
|
|
142
152
|
export interface GameRequestInput {
|
|
143
153
|
gameTitle?: string;
|
|
@@ -406,6 +416,7 @@ export interface TournamentInput {
|
|
|
406
416
|
rules?: string;
|
|
407
417
|
hasThirdPlace?: boolean;
|
|
408
418
|
hasMatchLobby?: boolean;
|
|
419
|
+
requireVerifiedAccounts?: boolean;
|
|
409
420
|
visibility?: TournamentVisibility;
|
|
410
421
|
access?: TournamentAccess;
|
|
411
422
|
checkInTime?: number;
|
|
@@ -512,6 +523,9 @@ export interface UserInput {
|
|
|
512
523
|
export interface UserGameAccountInput {
|
|
513
524
|
accountId?: string;
|
|
514
525
|
isPrivate?: boolean;
|
|
526
|
+
verifiedAt?: string;
|
|
527
|
+
verificationMethod?: UserGameAccountVerificationMethod;
|
|
528
|
+
providerAccountId?: string;
|
|
515
529
|
users_permissions_user?: RelationInput;
|
|
516
530
|
game_account?: RelationInput;
|
|
517
531
|
}
|
package/src/generated/models.ts
CHANGED
|
@@ -43,6 +43,7 @@ import type {
|
|
|
43
43
|
TournamentTeamSize,
|
|
44
44
|
TournamentType,
|
|
45
45
|
TournamentVisibility,
|
|
46
|
+
UserGameAccountVerificationMethod,
|
|
46
47
|
UserTransactionStripeStatus,
|
|
47
48
|
UserTransactionType,
|
|
48
49
|
} from './enums';
|
|
@@ -139,6 +140,15 @@ export interface GameAccount extends StrapiDocument {
|
|
|
139
140
|
platforms?: Platform[];
|
|
140
141
|
}
|
|
141
142
|
|
|
143
|
+
/** `game-account-link` */
|
|
144
|
+
export interface GameAccountLink extends StrapiDocument {
|
|
145
|
+
token?: string | null;
|
|
146
|
+
users_permissions_user?: User | null;
|
|
147
|
+
game_account?: GameAccount | null;
|
|
148
|
+
expiresAt?: string | null;
|
|
149
|
+
returnTo?: string | null;
|
|
150
|
+
}
|
|
151
|
+
|
|
142
152
|
/** `game-request` */
|
|
143
153
|
export interface GameRequest extends StrapiDocument {
|
|
144
154
|
gameTitle?: string | null;
|
|
@@ -407,6 +417,7 @@ export interface Tournament extends StrapiDocument {
|
|
|
407
417
|
rules?: string | null;
|
|
408
418
|
hasThirdPlace?: boolean | null;
|
|
409
419
|
hasMatchLobby?: boolean | null;
|
|
420
|
+
requireVerifiedAccounts?: boolean | null;
|
|
410
421
|
visibility?: TournamentVisibility | null;
|
|
411
422
|
access?: TournamentAccess | null;
|
|
412
423
|
checkInTime?: number | null;
|
|
@@ -513,6 +524,9 @@ export interface User extends StrapiDocument {
|
|
|
513
524
|
export interface UserGameAccount extends StrapiDocument {
|
|
514
525
|
accountId?: string | null;
|
|
515
526
|
isPrivate?: boolean | null;
|
|
527
|
+
verifiedAt?: string | null;
|
|
528
|
+
verificationMethod?: UserGameAccountVerificationMethod | null;
|
|
529
|
+
providerAccountId?: string | null;
|
|
516
530
|
users_permissions_user?: User | null;
|
|
517
531
|
game_account?: GameAccount | null;
|
|
518
532
|
}
|
|
@@ -54,7 +54,60 @@ export type HandleCheck =
|
|
|
54
54
|
| { ok: false; message: string };
|
|
55
55
|
|
|
56
56
|
/** `error.details.name` values the game-account write endpoints raise. */
|
|
57
|
-
export type GameAccountErrorName =
|
|
57
|
+
export type GameAccountErrorName =
|
|
58
|
+
| 'HandleInvalid'
|
|
59
|
+
| 'HandleTaken'
|
|
60
|
+
/** The row is verified by a link; unlink before changing the ID. */
|
|
61
|
+
| 'HandleLocked'
|
|
62
|
+
/** No configured link provider for this network. */
|
|
63
|
+
| 'LinkUnavailable'
|
|
64
|
+
/** The provider account is already linked to another XPT user. */
|
|
65
|
+
| 'LinkConflict';
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Networks whose handles can be verified by signing in to the network. The
|
|
69
|
+
* catalogue's `verification: 'linked'` is only valid for these; whether a
|
|
70
|
+
* provider is actually configured on a given environment is answered at
|
|
71
|
+
* runtime by `GET /user-game-accounts/link/providers`.
|
|
72
|
+
*/
|
|
73
|
+
export const LINK_PROVIDER_CODES = ['steam', 'battlenet'] as const satisfies
|
|
74
|
+
readonly GameAccountCode[];
|
|
75
|
+
|
|
76
|
+
export type LinkProviderCode = (typeof LINK_PROVIDER_CODES)[number];
|
|
77
|
+
|
|
78
|
+
export function isLinkableCode(
|
|
79
|
+
code: string | null | undefined
|
|
80
|
+
): code is LinkProviderCode {
|
|
81
|
+
return (LINK_PROVIDER_CODES as readonly string[]).includes(code ?? '');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Why a link attempt came back without a verified account — the `linkError`
|
|
86
|
+
* query value the callback redirects to the settings page with.
|
|
87
|
+
*/
|
|
88
|
+
export type AccountLinkError =
|
|
89
|
+
/** The attempt was unknown, already used, or older than its window. */
|
|
90
|
+
| 'expired'
|
|
91
|
+
/** The player cancelled at the provider. */
|
|
92
|
+
| 'denied'
|
|
93
|
+
/** The provider's answer did not verify. */
|
|
94
|
+
| 'invalid'
|
|
95
|
+
/** That provider account is already linked to another XPT user. */
|
|
96
|
+
| 'taken'
|
|
97
|
+
/** The provider is not configured, or the network is not linkable. */
|
|
98
|
+
| 'unavailable'
|
|
99
|
+
/** Accounts are frozen while the player is in a running tournament. */
|
|
100
|
+
| 'activeTournament';
|
|
101
|
+
|
|
102
|
+
/** True when a row's handle was proved by signing in to the network. */
|
|
103
|
+
export function isVerifiedAccount(
|
|
104
|
+
row:
|
|
105
|
+
| { verifiedAt?: string | Date | null; verificationMethod?: string | null }
|
|
106
|
+
| null
|
|
107
|
+
| undefined
|
|
108
|
+
): boolean {
|
|
109
|
+
return !!row?.verifiedAt && row.verificationMethod === 'linked';
|
|
110
|
+
}
|
|
58
111
|
|
|
59
112
|
/**
|
|
60
113
|
* The rule every network gets when it has no stricter one. Also the backstop
|
|
@@ -187,8 +240,9 @@ export const HANDLE_RULES: Partial<Record<GameAccountCode, HandleRule>> = {
|
|
|
187
240
|
|
|
188
241
|
/**
|
|
189
242
|
* The rule a network's handles are checked against: its own when the
|
|
190
|
-
* catalogue row asks for format checks
|
|
191
|
-
* otherwise the
|
|
243
|
+
* catalogue row asks for format checks (or is linkable, which implies them
|
|
244
|
+
* for anything typed by hand) and a rule exists for its code, otherwise the
|
|
245
|
+
* generic one.
|
|
192
246
|
*/
|
|
193
247
|
export function handleRuleFor(
|
|
194
248
|
network:
|
|
@@ -199,7 +253,9 @@ export function handleRuleFor(
|
|
|
199
253
|
| null
|
|
200
254
|
| undefined
|
|
201
255
|
): HandleRule {
|
|
202
|
-
|
|
256
|
+
const checked =
|
|
257
|
+
network?.verification === 'format' || network?.verification === 'linked';
|
|
258
|
+
if (!checked || !network?.code) {
|
|
203
259
|
return GENERIC_HANDLE_RULE;
|
|
204
260
|
}
|
|
205
261
|
return HANDLE_RULES[network.code as GameAccountCode] ?? GENERIC_HANDLE_RULE;
|
|
@@ -51,4 +51,8 @@ export type TournamentEntryErrorName =
|
|
|
51
51
|
| 'MembersMissingGameAccount'
|
|
52
52
|
| 'InsufficientCoins'
|
|
53
53
|
| 'GameAccountRequired'
|
|
54
|
-
| 'TeamEntryRequired'
|
|
54
|
+
| 'TeamEntryRequired'
|
|
55
|
+
/** The tournament admits only accounts verified by signing in; yours is typed. */
|
|
56
|
+
| 'GameAccountUnverified'
|
|
57
|
+
/** Same, for the named players on a team roster. */
|
|
58
|
+
| 'MembersUnverifiedGameAccount';
|