xpt-shared-types 1.18.0 → 1.19.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.
@@ -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;
@@ -427,6 +435,9 @@ export interface UserInput {
427
435
  export interface UserGameAccountInput {
428
436
  accountId?: string;
429
437
  isPrivate?: boolean;
438
+ verifiedAt?: string;
439
+ verificationMethod?: UserGameAccountVerificationMethod;
440
+ providerAccountId?: string;
430
441
  users_permissions_user?: RelationInput;
431
442
  game_account?: RelationInput;
432
443
  }
@@ -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;
@@ -427,6 +435,9 @@ export interface User extends StrapiDocument {
427
435
  export interface UserGameAccount extends StrapiDocument {
428
436
  accountId?: string | null;
429
437
  isPrivate?: boolean | null;
438
+ verifiedAt?: string | null;
439
+ verificationMethod?: UserGameAccountVerificationMethod | null;
440
+ providerAccountId?: string | null;
430
441
  users_permissions_user?: User | null;
431
442
  game_account?: GameAccount | null;
432
443
  }
@@ -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 and a rule exists for its code,
73
- * otherwise the generic one.
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 and a rule exists for its code,
160
- * otherwise the generic one.
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
- if ((network === null || network === void 0 ? void 0 : network.verification) !== 'format' || !network.code) {
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xpt-shared-types",
3
- "version": "1.18.0",
3
+ "version": "1.19.0",
4
4
  "description": "Shared types and data for XPT projects",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -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"
@@ -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;
@@ -512,6 +522,9 @@ export interface UserInput {
512
522
  export interface UserGameAccountInput {
513
523
  accountId?: string;
514
524
  isPrivate?: boolean;
525
+ verifiedAt?: string;
526
+ verificationMethod?: UserGameAccountVerificationMethod;
527
+ providerAccountId?: string;
515
528
  users_permissions_user?: RelationInput;
516
529
  game_account?: RelationInput;
517
530
  }
@@ -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;
@@ -513,6 +523,9 @@ export interface User extends StrapiDocument {
513
523
  export interface UserGameAccount extends StrapiDocument {
514
524
  accountId?: string | null;
515
525
  isPrivate?: boolean | null;
526
+ verifiedAt?: string | null;
527
+ verificationMethod?: UserGameAccountVerificationMethod | null;
528
+ providerAccountId?: string | null;
516
529
  users_permissions_user?: User | null;
517
530
  game_account?: GameAccount | null;
518
531
  }
@@ -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 = 'HandleInvalid' | 'HandleTaken';
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 and a rule exists for its code,
191
- * otherwise the generic one.
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
- if (network?.verification !== 'format' || !network.code) {
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;