xpt-shared-types 1.12.1 → 1.13.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/dist/generated/enums.d.ts +2 -0
- package/dist/generated/inputs.d.ts +17 -1
- package/dist/generated/models.d.ts +17 -1
- package/dist/manual/index.d.ts +1 -0
- package/dist/manual/index.js +1 -0
- package/dist/manual/notification.d.ts +40 -0
- package/dist/manual/notification.js +93 -0
- package/package.json +26 -26
- package/src/generated/enums.ts +7 -0
- package/src/generated/inputs.ts +18 -0
- package/src/generated/models.ts +18 -0
- package/src/manual/index.ts +1 -0
- package/src/manual/notification.ts +117 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** `AdminAction.targetType` */
|
|
2
|
+
export type AdminActionTargetType = "user" | "tournament" | "match" | "transaction";
|
|
1
3
|
/** `Faq.category` */
|
|
2
4
|
export type FaqCategory = "gettingStarted" | "tournamentsMatches" | "hosting" | "walletCoins" | "account";
|
|
3
5
|
/** `Friendship.status` */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BlocksContent, MediaInput, RelationInput } from '../contracts';
|
|
2
|
-
import type { FaqCategory, FriendshipStatus, GameGenre, GameRequestCustomLobbies, GameRequestGenre, GameRequestTeamPlay, GameVisibility, MatchDisputeReason, MatchLobbyStatus, MatchResultType, MatchRound, MatchStreamPlatform, MatchWinnerSlot, PlatformCode, 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, GameGenre, GameRequestCustomLobbies, GameRequestGenre, GameRequestTeamPlay, GameVisibility, MatchDisputeReason, MatchLobbyStatus, MatchResultType, MatchRound, MatchStreamPlatform, MatchWinnerSlot, PlatformCode, ReferralStatus, TeamCurrentStatus, TeamInviteStatus, TeamInviteTeamRole, TeamPlayerTeamRole, TournamentAccess, TournamentCurrentStatus, TournamentInviteStatus, TournamentJoinRequestEntryType, TournamentJoinRequestStatus, TournamentParticipantEntryType, TournamentParticipantStatus, TournamentRoleRole, TournamentTeamSize, TournamentType, TournamentVisibility, UserTransactionStripeStatus, UserTransactionType } from './enums';
|
|
3
3
|
/** Write payload for `about`. */
|
|
4
4
|
export interface AboutInput {
|
|
5
5
|
heroTitle?: string;
|
|
@@ -7,6 +7,20 @@ export interface AboutInput {
|
|
|
7
7
|
aboutInfo?: unknown;
|
|
8
8
|
gameIcons?: MediaInput[];
|
|
9
9
|
}
|
|
10
|
+
/** Write payload for `admin-action`. */
|
|
11
|
+
export interface AdminActionInput {
|
|
12
|
+
action?: string;
|
|
13
|
+
adminId?: number;
|
|
14
|
+
adminUsername?: string;
|
|
15
|
+
targetType?: AdminActionTargetType;
|
|
16
|
+
targetId?: string;
|
|
17
|
+
targetLabel?: string;
|
|
18
|
+
contextId?: string;
|
|
19
|
+
reason?: string;
|
|
20
|
+
before?: unknown;
|
|
21
|
+
after?: unknown;
|
|
22
|
+
metadata?: unknown;
|
|
23
|
+
}
|
|
10
24
|
/** Write payload for `dm-message`. */
|
|
11
25
|
export interface DmMessageInput {
|
|
12
26
|
conversationId?: string;
|
|
@@ -383,6 +397,8 @@ export interface UserInput {
|
|
|
383
397
|
countryCode?: string;
|
|
384
398
|
dob?: string;
|
|
385
399
|
notifyUpdates?: boolean;
|
|
400
|
+
blockedReason?: string;
|
|
401
|
+
blockedAt?: string;
|
|
386
402
|
xptCoins?: number;
|
|
387
403
|
user_transactions?: RelationInput | RelationInput[];
|
|
388
404
|
dailyRewardStreak?: number;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BlocksContent, StrapiDocument, StrapiMedia, UserRole } from '../contracts';
|
|
2
|
-
import type { FaqCategory, FriendshipStatus, GameGenre, GameRequestCustomLobbies, GameRequestGenre, GameRequestTeamPlay, GameVisibility, MatchDisputeReason, MatchLobbyStatus, MatchResultType, MatchRound, MatchStreamPlatform, MatchWinnerSlot, PlatformCode, 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, GameGenre, GameRequestCustomLobbies, GameRequestGenre, GameRequestTeamPlay, GameVisibility, MatchDisputeReason, MatchLobbyStatus, MatchResultType, MatchRound, MatchStreamPlatform, MatchWinnerSlot, PlatformCode, ReferralStatus, TeamCurrentStatus, TeamInviteStatus, TeamInviteTeamRole, TeamPlayerTeamRole, TournamentAccess, TournamentCurrentStatus, TournamentInviteStatus, TournamentJoinRequestEntryType, TournamentJoinRequestStatus, TournamentParticipantEntryType, TournamentParticipantStatus, TournamentRoleRole, TournamentTeamSize, TournamentType, TournamentVisibility, UserTransactionStripeStatus, UserTransactionType } from './enums';
|
|
3
3
|
/** `about` */
|
|
4
4
|
export interface About extends StrapiDocument {
|
|
5
5
|
heroTitle?: string | null;
|
|
@@ -7,6 +7,20 @@ export interface About extends StrapiDocument {
|
|
|
7
7
|
aboutInfo?: unknown | null;
|
|
8
8
|
gameIcons?: StrapiMedia[];
|
|
9
9
|
}
|
|
10
|
+
/** `admin-action` */
|
|
11
|
+
export interface AdminAction extends StrapiDocument {
|
|
12
|
+
action?: string | null;
|
|
13
|
+
adminId?: number | null;
|
|
14
|
+
adminUsername?: string | null;
|
|
15
|
+
targetType?: AdminActionTargetType | null;
|
|
16
|
+
targetId?: string | null;
|
|
17
|
+
targetLabel?: string | null;
|
|
18
|
+
contextId?: string | null;
|
|
19
|
+
reason?: string | null;
|
|
20
|
+
before?: unknown | null;
|
|
21
|
+
after?: unknown | null;
|
|
22
|
+
metadata?: unknown | null;
|
|
23
|
+
}
|
|
10
24
|
/** `dm-message` */
|
|
11
25
|
export interface DmMessage extends StrapiDocument {
|
|
12
26
|
conversationId?: string | null;
|
|
@@ -383,6 +397,8 @@ export interface User extends StrapiDocument {
|
|
|
383
397
|
countryCode?: string | null;
|
|
384
398
|
dob?: string | null;
|
|
385
399
|
notifyUpdates?: boolean | null;
|
|
400
|
+
blockedReason?: string | null;
|
|
401
|
+
blockedAt?: string | null;
|
|
386
402
|
xptCoins?: number | null;
|
|
387
403
|
user_transactions?: UserTransaction[];
|
|
388
404
|
dailyRewardStreak?: number | null;
|
package/dist/manual/index.d.ts
CHANGED
package/dist/manual/index.js
CHANGED
|
@@ -19,6 +19,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
19
19
|
*/
|
|
20
20
|
__exportStar(require("./country"), exports);
|
|
21
21
|
__exportStar(require("./lobby"), exports);
|
|
22
|
+
__exportStar(require("./notification"), exports);
|
|
22
23
|
__exportStar(require("./tournamentEntry"), exports);
|
|
23
24
|
__exportStar(require("./tournamentInvite"), exports);
|
|
24
25
|
__exportStar(require("./tournamentJoinRequest"), exports);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notification types — the contract between the server's writers and the
|
|
3
|
+
* client's bell.
|
|
4
|
+
*
|
|
5
|
+
* The `notification` content type stores `type` as a plain string (there is no
|
|
6
|
+
* enum on the schema), so the generated `Notification.type` is `string`. This
|
|
7
|
+
* is the closed list both sides agree on: the server refuses to write a type
|
|
8
|
+
* that is not here, the client switches on it for icons, actions and routes,
|
|
9
|
+
* and the preference page groups toggles by `NOTIFICATION_TYPE_GROUP`.
|
|
10
|
+
*
|
|
11
|
+
* Adding a type means adding it here, giving it a group, and then a writer
|
|
12
|
+
* on the server and a glyph on the client — the `Record`s below fail to
|
|
13
|
+
* compile until the group is chosen.
|
|
14
|
+
*/
|
|
15
|
+
export declare const NOTIFICATION_TYPES: readonly ["match_ready", "match_result", "match_dispute", "tournament_registered", "tournament_status", "tournament_eliminated", "tournament_placement", "tournament_withdrawn", "tournament_roster", "tournament_join_request", "tournament_join_approved", "tournament_join_declined", "tournament_join_expired", "team_invite", "team_kicked", "team_captaincy", "team_joined", "friend_request", "friend_request_accepted", "xp_earned", "wallet_credit", "wallet_debit"];
|
|
16
|
+
export type NotificationType = (typeof NOTIFICATION_TYPES)[number];
|
|
17
|
+
/** The in-app toggles on the notification settings page, one per group. */
|
|
18
|
+
export declare const NOTIFICATION_GROUPS: readonly ["matchAlerts", "tournamentUpdates", "teamSocial", "accountRewards"];
|
|
19
|
+
export type NotificationGroup = (typeof NOTIFICATION_GROUPS)[number];
|
|
20
|
+
/**
|
|
21
|
+
* Which toggle gates each type. Exhaustive: a new type must pick a group, or
|
|
22
|
+
* say `null` to mean it is always delivered.
|
|
23
|
+
*/
|
|
24
|
+
export declare const NOTIFICATION_TYPE_GROUP: Record<NotificationType, NotificationGroup | null>;
|
|
25
|
+
/**
|
|
26
|
+
* The stored preference blob on a user. The four groups gate in-app delivery;
|
|
27
|
+
* `emailNotifications` is the single email opt-out; `marketing` is stored for
|
|
28
|
+
* a future channel and read by nothing yet.
|
|
29
|
+
*/
|
|
30
|
+
export interface NotificationPreferences {
|
|
31
|
+
matchAlerts: boolean;
|
|
32
|
+
tournamentUpdates: boolean;
|
|
33
|
+
teamSocial: boolean;
|
|
34
|
+
accountRewards: boolean;
|
|
35
|
+
marketing: boolean;
|
|
36
|
+
emailNotifications: boolean;
|
|
37
|
+
}
|
|
38
|
+
/** Applied when a user has never saved preferences. */
|
|
39
|
+
export declare const DEFAULT_NOTIFICATION_PREFERENCES: NotificationPreferences;
|
|
40
|
+
export declare const isNotificationType: (value: unknown) => value is NotificationType;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Notification types — the contract between the server's writers and the
|
|
4
|
+
* client's bell.
|
|
5
|
+
*
|
|
6
|
+
* The `notification` content type stores `type` as a plain string (there is no
|
|
7
|
+
* enum on the schema), so the generated `Notification.type` is `string`. This
|
|
8
|
+
* is the closed list both sides agree on: the server refuses to write a type
|
|
9
|
+
* that is not here, the client switches on it for icons, actions and routes,
|
|
10
|
+
* and the preference page groups toggles by `NOTIFICATION_TYPE_GROUP`.
|
|
11
|
+
*
|
|
12
|
+
* Adding a type means adding it here, giving it a group, and then a writer
|
|
13
|
+
* on the server and a glyph on the client — the `Record`s below fail to
|
|
14
|
+
* compile until the group is chosen.
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.isNotificationType = exports.DEFAULT_NOTIFICATION_PREFERENCES = exports.NOTIFICATION_TYPE_GROUP = exports.NOTIFICATION_GROUPS = exports.NOTIFICATION_TYPES = void 0;
|
|
18
|
+
exports.NOTIFICATION_TYPES = [
|
|
19
|
+
// matchAlerts
|
|
20
|
+
'match_ready',
|
|
21
|
+
'match_result',
|
|
22
|
+
'match_dispute',
|
|
23
|
+
// tournamentUpdates
|
|
24
|
+
'tournament_registered',
|
|
25
|
+
'tournament_status',
|
|
26
|
+
'tournament_eliminated',
|
|
27
|
+
'tournament_placement',
|
|
28
|
+
'tournament_withdrawn',
|
|
29
|
+
'tournament_roster',
|
|
30
|
+
'tournament_join_request',
|
|
31
|
+
'tournament_join_approved',
|
|
32
|
+
'tournament_join_declined',
|
|
33
|
+
'tournament_join_expired',
|
|
34
|
+
// teamSocial
|
|
35
|
+
'team_invite',
|
|
36
|
+
'team_kicked',
|
|
37
|
+
'team_captaincy',
|
|
38
|
+
'team_joined',
|
|
39
|
+
'friend_request',
|
|
40
|
+
'friend_request_accepted',
|
|
41
|
+
// accountRewards
|
|
42
|
+
'xp_earned',
|
|
43
|
+
'wallet_credit',
|
|
44
|
+
// ungated — coins leaving an account cannot be muted
|
|
45
|
+
'wallet_debit',
|
|
46
|
+
];
|
|
47
|
+
/** The in-app toggles on the notification settings page, one per group. */
|
|
48
|
+
exports.NOTIFICATION_GROUPS = [
|
|
49
|
+
'matchAlerts',
|
|
50
|
+
'tournamentUpdates',
|
|
51
|
+
'teamSocial',
|
|
52
|
+
'accountRewards',
|
|
53
|
+
];
|
|
54
|
+
/**
|
|
55
|
+
* Which toggle gates each type. Exhaustive: a new type must pick a group, or
|
|
56
|
+
* say `null` to mean it is always delivered.
|
|
57
|
+
*/
|
|
58
|
+
exports.NOTIFICATION_TYPE_GROUP = {
|
|
59
|
+
match_ready: 'matchAlerts',
|
|
60
|
+
match_result: 'matchAlerts',
|
|
61
|
+
match_dispute: 'matchAlerts',
|
|
62
|
+
tournament_registered: 'tournamentUpdates',
|
|
63
|
+
tournament_status: 'tournamentUpdates',
|
|
64
|
+
tournament_eliminated: 'tournamentUpdates',
|
|
65
|
+
tournament_placement: 'tournamentUpdates',
|
|
66
|
+
tournament_withdrawn: 'tournamentUpdates',
|
|
67
|
+
tournament_roster: 'tournamentUpdates',
|
|
68
|
+
tournament_join_request: 'tournamentUpdates',
|
|
69
|
+
tournament_join_approved: 'tournamentUpdates',
|
|
70
|
+
tournament_join_declined: 'tournamentUpdates',
|
|
71
|
+
tournament_join_expired: 'tournamentUpdates',
|
|
72
|
+
team_invite: 'teamSocial',
|
|
73
|
+
team_kicked: 'teamSocial',
|
|
74
|
+
team_captaincy: 'teamSocial',
|
|
75
|
+
team_joined: 'teamSocial',
|
|
76
|
+
friend_request: 'teamSocial',
|
|
77
|
+
friend_request_accepted: 'teamSocial',
|
|
78
|
+
xp_earned: 'accountRewards',
|
|
79
|
+
wallet_credit: 'accountRewards',
|
|
80
|
+
wallet_debit: null,
|
|
81
|
+
};
|
|
82
|
+
/** Applied when a user has never saved preferences. */
|
|
83
|
+
exports.DEFAULT_NOTIFICATION_PREFERENCES = {
|
|
84
|
+
matchAlerts: true,
|
|
85
|
+
tournamentUpdates: true,
|
|
86
|
+
teamSocial: true,
|
|
87
|
+
accountRewards: true,
|
|
88
|
+
marketing: false,
|
|
89
|
+
emailNotifications: true,
|
|
90
|
+
};
|
|
91
|
+
const isNotificationType = (value) => typeof value === 'string' &&
|
|
92
|
+
exports.NOTIFICATION_TYPES.includes(value);
|
|
93
|
+
exports.isNotificationType = isNotificationType;
|
package/package.json
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "xpt-shared-types",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Shared types and data for XPT projects",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
7
|
-
"files": [
|
|
8
|
-
"dist",
|
|
9
|
-
"src",
|
|
10
|
-
"scripts"
|
|
11
|
-
],
|
|
12
|
-
"scripts": {
|
|
13
|
-
"sync": "node scripts/sync-from-strapi.js",
|
|
14
|
-
"build": "tsc",
|
|
15
|
-
"prepublishOnly": "yarn build"
|
|
16
|
-
},
|
|
17
|
-
"repository": {
|
|
18
|
-
"type": "git",
|
|
19
|
-
"url": "https://github.com/otemu/xpt-shared-types"
|
|
20
|
-
},
|
|
21
|
-
"author": "",
|
|
22
|
-
"license": "MIT",
|
|
23
|
-
"devDependencies": {
|
|
24
|
-
"typescript": "^5.0.0"
|
|
25
|
-
}
|
|
26
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "xpt-shared-types",
|
|
3
|
+
"version": "1.13.0",
|
|
4
|
+
"description": "Shared types and data for XPT projects",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"src",
|
|
10
|
+
"scripts"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"sync": "node scripts/sync-from-strapi.js",
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"prepublishOnly": "yarn build"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/otemu/xpt-shared-types"
|
|
20
|
+
},
|
|
21
|
+
"author": "",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"typescript": "^5.0.0"
|
|
25
|
+
}
|
|
26
|
+
}
|
package/src/generated/enums.ts
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
// Source: xpt-strapi/src/**/content-types/**/schema.json
|
|
3
3
|
// Regenerate with: yarn sync
|
|
4
4
|
|
|
5
|
+
/** `AdminAction.targetType` */
|
|
6
|
+
export type AdminActionTargetType =
|
|
7
|
+
| "user"
|
|
8
|
+
| "tournament"
|
|
9
|
+
| "match"
|
|
10
|
+
| "transaction";
|
|
11
|
+
|
|
5
12
|
/** `Faq.category` */
|
|
6
13
|
export type FaqCategory =
|
|
7
14
|
| "gettingStarted"
|
package/src/generated/inputs.ts
CHANGED
|
@@ -8,6 +8,7 @@ import type {
|
|
|
8
8
|
RelationInput,
|
|
9
9
|
} from '../contracts';
|
|
10
10
|
import type {
|
|
11
|
+
AdminActionTargetType,
|
|
11
12
|
FaqCategory,
|
|
12
13
|
FriendshipStatus,
|
|
13
14
|
GameGenre,
|
|
@@ -50,6 +51,21 @@ export interface AboutInput {
|
|
|
50
51
|
gameIcons?: MediaInput[];
|
|
51
52
|
}
|
|
52
53
|
|
|
54
|
+
/** Write payload for `admin-action`. */
|
|
55
|
+
export interface AdminActionInput {
|
|
56
|
+
action?: string;
|
|
57
|
+
adminId?: number;
|
|
58
|
+
adminUsername?: string;
|
|
59
|
+
targetType?: AdminActionTargetType;
|
|
60
|
+
targetId?: string;
|
|
61
|
+
targetLabel?: string;
|
|
62
|
+
contextId?: string;
|
|
63
|
+
reason?: string;
|
|
64
|
+
before?: unknown;
|
|
65
|
+
after?: unknown;
|
|
66
|
+
metadata?: unknown;
|
|
67
|
+
}
|
|
68
|
+
|
|
53
69
|
/** Write payload for `dm-message`. */
|
|
54
70
|
export interface DmMessageInput {
|
|
55
71
|
conversationId?: string;
|
|
@@ -461,6 +477,8 @@ export interface UserInput {
|
|
|
461
477
|
countryCode?: string;
|
|
462
478
|
dob?: string;
|
|
463
479
|
notifyUpdates?: boolean;
|
|
480
|
+
blockedReason?: string;
|
|
481
|
+
blockedAt?: string;
|
|
464
482
|
xptCoins?: number;
|
|
465
483
|
user_transactions?: RelationInput | RelationInput[];
|
|
466
484
|
dailyRewardStreak?: number;
|
package/src/generated/models.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
UserRole,
|
|
10
10
|
} from '../contracts';
|
|
11
11
|
import type {
|
|
12
|
+
AdminActionTargetType,
|
|
12
13
|
FaqCategory,
|
|
13
14
|
FriendshipStatus,
|
|
14
15
|
GameGenre,
|
|
@@ -51,6 +52,21 @@ export interface About extends StrapiDocument {
|
|
|
51
52
|
gameIcons?: StrapiMedia[];
|
|
52
53
|
}
|
|
53
54
|
|
|
55
|
+
/** `admin-action` */
|
|
56
|
+
export interface AdminAction extends StrapiDocument {
|
|
57
|
+
action?: string | null;
|
|
58
|
+
adminId?: number | null;
|
|
59
|
+
adminUsername?: string | null;
|
|
60
|
+
targetType?: AdminActionTargetType | null;
|
|
61
|
+
targetId?: string | null;
|
|
62
|
+
targetLabel?: string | null;
|
|
63
|
+
contextId?: string | null;
|
|
64
|
+
reason?: string | null;
|
|
65
|
+
before?: unknown | null;
|
|
66
|
+
after?: unknown | null;
|
|
67
|
+
metadata?: unknown | null;
|
|
68
|
+
}
|
|
69
|
+
|
|
54
70
|
/** `dm-message` */
|
|
55
71
|
export interface DmMessage extends StrapiDocument {
|
|
56
72
|
conversationId?: string | null;
|
|
@@ -462,6 +478,8 @@ export interface User extends StrapiDocument {
|
|
|
462
478
|
countryCode?: string | null;
|
|
463
479
|
dob?: string | null;
|
|
464
480
|
notifyUpdates?: boolean | null;
|
|
481
|
+
blockedReason?: string | null;
|
|
482
|
+
blockedAt?: string | null;
|
|
465
483
|
xptCoins?: number | null;
|
|
466
484
|
user_transactions?: UserTransaction[];
|
|
467
485
|
dailyRewardStreak?: number | null;
|
package/src/manual/index.ts
CHANGED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notification types — the contract between the server's writers and the
|
|
3
|
+
* client's bell.
|
|
4
|
+
*
|
|
5
|
+
* The `notification` content type stores `type` as a plain string (there is no
|
|
6
|
+
* enum on the schema), so the generated `Notification.type` is `string`. This
|
|
7
|
+
* is the closed list both sides agree on: the server refuses to write a type
|
|
8
|
+
* that is not here, the client switches on it for icons, actions and routes,
|
|
9
|
+
* and the preference page groups toggles by `NOTIFICATION_TYPE_GROUP`.
|
|
10
|
+
*
|
|
11
|
+
* Adding a type means adding it here, giving it a group, and then a writer
|
|
12
|
+
* on the server and a glyph on the client — the `Record`s below fail to
|
|
13
|
+
* compile until the group is chosen.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export const NOTIFICATION_TYPES = [
|
|
17
|
+
// matchAlerts
|
|
18
|
+
'match_ready',
|
|
19
|
+
'match_result',
|
|
20
|
+
'match_dispute',
|
|
21
|
+
// tournamentUpdates
|
|
22
|
+
'tournament_registered',
|
|
23
|
+
'tournament_status',
|
|
24
|
+
'tournament_eliminated',
|
|
25
|
+
'tournament_placement',
|
|
26
|
+
'tournament_withdrawn',
|
|
27
|
+
'tournament_roster',
|
|
28
|
+
'tournament_join_request',
|
|
29
|
+
'tournament_join_approved',
|
|
30
|
+
'tournament_join_declined',
|
|
31
|
+
'tournament_join_expired',
|
|
32
|
+
// teamSocial
|
|
33
|
+
'team_invite',
|
|
34
|
+
'team_kicked',
|
|
35
|
+
'team_captaincy',
|
|
36
|
+
'team_joined',
|
|
37
|
+
'friend_request',
|
|
38
|
+
'friend_request_accepted',
|
|
39
|
+
// accountRewards
|
|
40
|
+
'xp_earned',
|
|
41
|
+
'wallet_credit',
|
|
42
|
+
// ungated — coins leaving an account cannot be muted
|
|
43
|
+
'wallet_debit',
|
|
44
|
+
] as const;
|
|
45
|
+
|
|
46
|
+
export type NotificationType = (typeof NOTIFICATION_TYPES)[number];
|
|
47
|
+
|
|
48
|
+
/** The in-app toggles on the notification settings page, one per group. */
|
|
49
|
+
export const NOTIFICATION_GROUPS = [
|
|
50
|
+
'matchAlerts',
|
|
51
|
+
'tournamentUpdates',
|
|
52
|
+
'teamSocial',
|
|
53
|
+
'accountRewards',
|
|
54
|
+
] as const;
|
|
55
|
+
|
|
56
|
+
export type NotificationGroup = (typeof NOTIFICATION_GROUPS)[number];
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Which toggle gates each type. Exhaustive: a new type must pick a group, or
|
|
60
|
+
* say `null` to mean it is always delivered.
|
|
61
|
+
*/
|
|
62
|
+
export const NOTIFICATION_TYPE_GROUP: Record<
|
|
63
|
+
NotificationType,
|
|
64
|
+
NotificationGroup | null
|
|
65
|
+
> =
|
|
66
|
+
{
|
|
67
|
+
match_ready: 'matchAlerts',
|
|
68
|
+
match_result: 'matchAlerts',
|
|
69
|
+
match_dispute: 'matchAlerts',
|
|
70
|
+
tournament_registered: 'tournamentUpdates',
|
|
71
|
+
tournament_status: 'tournamentUpdates',
|
|
72
|
+
tournament_eliminated: 'tournamentUpdates',
|
|
73
|
+
tournament_placement: 'tournamentUpdates',
|
|
74
|
+
tournament_withdrawn: 'tournamentUpdates',
|
|
75
|
+
tournament_roster: 'tournamentUpdates',
|
|
76
|
+
tournament_join_request: 'tournamentUpdates',
|
|
77
|
+
tournament_join_approved: 'tournamentUpdates',
|
|
78
|
+
tournament_join_declined: 'tournamentUpdates',
|
|
79
|
+
tournament_join_expired: 'tournamentUpdates',
|
|
80
|
+
team_invite: 'teamSocial',
|
|
81
|
+
team_kicked: 'teamSocial',
|
|
82
|
+
team_captaincy: 'teamSocial',
|
|
83
|
+
team_joined: 'teamSocial',
|
|
84
|
+
friend_request: 'teamSocial',
|
|
85
|
+
friend_request_accepted: 'teamSocial',
|
|
86
|
+
xp_earned: 'accountRewards',
|
|
87
|
+
wallet_credit: 'accountRewards',
|
|
88
|
+
wallet_debit: null,
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The stored preference blob on a user. The four groups gate in-app delivery;
|
|
93
|
+
* `emailNotifications` is the single email opt-out; `marketing` is stored for
|
|
94
|
+
* a future channel and read by nothing yet.
|
|
95
|
+
*/
|
|
96
|
+
export interface NotificationPreferences {
|
|
97
|
+
matchAlerts: boolean;
|
|
98
|
+
tournamentUpdates: boolean;
|
|
99
|
+
teamSocial: boolean;
|
|
100
|
+
accountRewards: boolean;
|
|
101
|
+
marketing: boolean;
|
|
102
|
+
emailNotifications: boolean;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Applied when a user has never saved preferences. */
|
|
106
|
+
export const DEFAULT_NOTIFICATION_PREFERENCES: NotificationPreferences = {
|
|
107
|
+
matchAlerts: true,
|
|
108
|
+
tournamentUpdates: true,
|
|
109
|
+
teamSocial: true,
|
|
110
|
+
accountRewards: true,
|
|
111
|
+
marketing: false,
|
|
112
|
+
emailNotifications: true,
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export const isNotificationType = (value: unknown): value is NotificationType =>
|
|
116
|
+
typeof value === 'string' &&
|
|
117
|
+
(NOTIFICATION_TYPES as readonly string[]).includes(value);
|