volleyballsimtypes 0.0.524 → 0.0.525

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.
Files changed (75) hide show
  1. package/dist/cjs/src/api/index.d.ts +16 -0
  2. package/dist/cjs/src/data/init-models.js +32 -0
  3. package/dist/cjs/src/data/models/competition.d.ts +1 -1
  4. package/dist/cjs/src/data/models/competition.js +1 -1
  5. package/dist/cjs/src/data/models/index.d.ts +5 -0
  6. package/dist/cjs/src/data/models/index.js +5 -0
  7. package/dist/cjs/src/data/models/jersey-badge.d.ts +1 -1
  8. package/dist/cjs/src/data/models/jersey-badge.js +1 -1
  9. package/dist/cjs/src/data/models/national-team-claim.d.ts +21 -0
  10. package/dist/cjs/src/data/models/national-team-claim.js +36 -0
  11. package/dist/cjs/src/data/models/national-team.d.ts +22 -0
  12. package/dist/cjs/src/data/models/national-team.js +31 -0
  13. package/dist/cjs/src/data/models/wnl-callup.d.ts +31 -0
  14. package/dist/cjs/src/data/models/wnl-callup.js +45 -0
  15. package/dist/cjs/src/data/models/wnl-season.d.ts +24 -0
  16. package/dist/cjs/src/data/models/wnl-season.js +34 -0
  17. package/dist/cjs/src/data/models/wnl-squad.d.ts +40 -0
  18. package/dist/cjs/src/data/models/wnl-squad.js +59 -0
  19. package/dist/cjs/src/service/match/index.d.ts +1 -0
  20. package/dist/cjs/src/service/match/index.js +8 -0
  21. package/dist/cjs/src/service/match/match-generator.d.ts +5 -1
  22. package/dist/cjs/src/service/match/match-generator.js +6 -4
  23. package/dist/cjs/src/service/notification/catalog/en.json +29 -0
  24. package/dist/cjs/src/service/notification/catalog/es.json +29 -0
  25. package/dist/cjs/src/service/notification/catalog/fr.json +29 -0
  26. package/dist/cjs/src/service/notification/catalog/it.json +29 -0
  27. package/dist/cjs/src/service/notification/catalog/pl.json +29 -0
  28. package/dist/cjs/src/service/notification/catalog/pt-BR.json +29 -0
  29. package/dist/cjs/src/service/notification/catalog/tr.json +29 -0
  30. package/dist/cjs/src/service/notification/notification-type.d.ts +1 -1
  31. package/dist/cjs/src/service/notification/notification-type.js +8 -1
  32. package/dist/cjs/src/service/notification/notification.test.js +18 -0
  33. package/dist/cjs/src/service/notification/payloads.d.ts +7 -1
  34. package/dist/cjs/src/service/notification/registry.d.ts +5 -1
  35. package/dist/cjs/src/service/notification/registry.js +90 -3
  36. package/dist/cjs/src/service/premium/premium-tier.d.ts +2 -0
  37. package/dist/cjs/src/service/premium/premium-tier.js +8 -1
  38. package/dist/esm/src/api/index.d.ts +16 -0
  39. package/dist/esm/src/data/init-models.js +33 -1
  40. package/dist/esm/src/data/models/competition.d.ts +1 -1
  41. package/dist/esm/src/data/models/competition.js +1 -1
  42. package/dist/esm/src/data/models/index.d.ts +5 -0
  43. package/dist/esm/src/data/models/index.js +5 -0
  44. package/dist/esm/src/data/models/jersey-badge.d.ts +1 -1
  45. package/dist/esm/src/data/models/jersey-badge.js +1 -1
  46. package/dist/esm/src/data/models/national-team-claim.d.ts +21 -0
  47. package/dist/esm/src/data/models/national-team-claim.js +32 -0
  48. package/dist/esm/src/data/models/national-team.d.ts +22 -0
  49. package/dist/esm/src/data/models/national-team.js +27 -0
  50. package/dist/esm/src/data/models/wnl-callup.d.ts +31 -0
  51. package/dist/esm/src/data/models/wnl-callup.js +41 -0
  52. package/dist/esm/src/data/models/wnl-season.d.ts +24 -0
  53. package/dist/esm/src/data/models/wnl-season.js +30 -0
  54. package/dist/esm/src/data/models/wnl-squad.d.ts +40 -0
  55. package/dist/esm/src/data/models/wnl-squad.js +55 -0
  56. package/dist/esm/src/service/match/index.d.ts +1 -0
  57. package/dist/esm/src/service/match/index.js +3 -0
  58. package/dist/esm/src/service/match/match-generator.d.ts +5 -1
  59. package/dist/esm/src/service/match/match-generator.js +6 -4
  60. package/dist/esm/src/service/notification/catalog/en.json +29 -0
  61. package/dist/esm/src/service/notification/catalog/es.json +29 -0
  62. package/dist/esm/src/service/notification/catalog/fr.json +29 -0
  63. package/dist/esm/src/service/notification/catalog/it.json +29 -0
  64. package/dist/esm/src/service/notification/catalog/pl.json +29 -0
  65. package/dist/esm/src/service/notification/catalog/pt-BR.json +29 -0
  66. package/dist/esm/src/service/notification/catalog/tr.json +29 -0
  67. package/dist/esm/src/service/notification/notification-type.d.ts +1 -1
  68. package/dist/esm/src/service/notification/notification-type.js +8 -1
  69. package/dist/esm/src/service/notification/notification.test.js +19 -1
  70. package/dist/esm/src/service/notification/payloads.d.ts +7 -1
  71. package/dist/esm/src/service/notification/registry.d.ts +5 -1
  72. package/dist/esm/src/service/notification/registry.js +88 -3
  73. package/dist/esm/src/service/premium/premium-tier.d.ts +2 -0
  74. package/dist/esm/src/service/premium/premium-tier.js +6 -0
  75. package/package.json +1 -1
@@ -62,5 +62,34 @@
62
62
  "regionRelocation": {
63
63
  "title": "Tu equipo se traslada",
64
64
  "body": "Tu equipo ha sido elegido para trasladarse a la nueva región: Kyorin. No cambia nada en cuanto al equipo que gestionas, tus jugadores ni nada más."
65
+ },
66
+ "wnlCallupOpen": {
67
+ "title": "Convocatoria nacional abierta",
68
+ "body": "¡La fase de convocatoria nacional ha comenzado! Tienes hasta el {{date}} para seleccionar tu equipo y participar en la próxima edición de la WNL."
69
+ },
70
+ "wnlCallupDeadline": {
71
+ "title": "La convocatoria cierra hoy",
72
+ "body": "El plazo de la convocatoria nacional termina hoy. Asegúrate de haber seleccionado a los jugadores que participarán en la próxima edición de la WNL."
73
+ },
74
+ "wnlCallupClosed": {
75
+ "title": "Convocatoria nacional cerrada",
76
+ "body": "La fase de convocatoria nacional ha terminado. ¡Puedes editar tu alineación para preparar la WNL que empieza el próximo lunes!"
77
+ },
78
+ "wnlLeagueStart": {
79
+ "title": "La liga WNL ha empezado",
80
+ "body": "¡La fase de liga de la WNL ha comenzado!"
81
+ },
82
+ "wnlFinalsStart": {
83
+ "title": "Las finales de la WNL han empezado",
84
+ "body": "¡Las finales de la WNL han comenzado!"
85
+ },
86
+ "wnlChampion": {
87
+ "title": "Campeones de la WNL",
88
+ "body": "La edición de la WNL ha terminado. ¡{{team}} son los campeones de la WNL!",
89
+ "bodyUnnamed": "La edición de la WNL ha terminado. ¡Ya hay campeones!"
90
+ },
91
+ "wnlPlayerCalledUp": {
92
+ "title": "Jugadores convocados",
93
+ "body": "¡Uno o más de tus jugadores han sido convocados por su selección nacional!"
65
94
  }
66
95
  }
@@ -62,5 +62,34 @@
62
62
  "regionRelocation": {
63
63
  "title": "Votre équipe déménage",
64
64
  "body": "Votre équipe a été choisie pour être transférée vers la nouvelle région : Kyorin. Rien ne change concernant l'équipe que vous gérez, vos joueurs ni quoi que ce soit d'autre."
65
+ },
66
+ "wnlCallupOpen": {
67
+ "title": "Convocation nationale ouverte",
68
+ "body": "La phase de convocation nationale a commencé ! Vous avez jusqu'au {{date}} pour sélectionner votre équipe et participer à la prochaine édition de la WNL."
69
+ },
70
+ "wnlCallupDeadline": {
71
+ "title": "La convocation se termine aujourd'hui",
72
+ "body": "La date limite de la convocation nationale est aujourd'hui. Assurez-vous d'avoir sélectionné les joueurs qui participeront à la prochaine édition de la WNL."
73
+ },
74
+ "wnlCallupClosed": {
75
+ "title": "Convocation nationale terminée",
76
+ "body": "La phase de convocation nationale est terminée. Vous pouvez modifier votre composition pour préparer la WNL qui commence lundi prochain !"
77
+ },
78
+ "wnlLeagueStart": {
79
+ "title": "La ligue WNL a commencé",
80
+ "body": "La phase de ligue de la WNL a commencé !"
81
+ },
82
+ "wnlFinalsStart": {
83
+ "title": "Les finales de la WNL ont commencé",
84
+ "body": "Les finales de la WNL ont commencé !"
85
+ },
86
+ "wnlChampion": {
87
+ "title": "Champions de la WNL",
88
+ "body": "L'édition de la WNL est terminée. {{team}} sont les champions de la WNL !",
89
+ "bodyUnnamed": "L'édition de la WNL est terminée. Les champions sont couronnés !"
90
+ },
91
+ "wnlPlayerCalledUp": {
92
+ "title": "Joueurs convoqués",
93
+ "body": "Un ou plusieurs de vos joueurs ont été convoqués par leur équipe nationale !"
65
94
  }
66
95
  }
@@ -62,5 +62,34 @@
62
62
  "regionRelocation": {
63
63
  "title": "La tua squadra si trasferisce",
64
64
  "body": "La tua squadra è stata scelta per essere spostata nella nuova regione: Kyorin. Non cambia nulla riguardo alla squadra che gestisci, ai tuoi giocatori o a qualsiasi altra cosa."
65
+ },
66
+ "wnlCallupOpen": {
67
+ "title": "Convocazione nazionale aperta",
68
+ "body": "La fase di convocazione nazionale è iniziata! Hai tempo fino al {{date}} per selezionare la tua squadra e partecipare alla prossima edizione della WNL."
69
+ },
70
+ "wnlCallupDeadline": {
71
+ "title": "La convocazione scade oggi",
72
+ "body": "Il termine della convocazione nazionale è oggi. Assicurati di aver selezionato i giocatori che parteciperanno alla prossima edizione della WNL."
73
+ },
74
+ "wnlCallupClosed": {
75
+ "title": "Convocazione nazionale chiusa",
76
+ "body": "La fase di convocazione nazionale è terminata. Puoi modificare la tua formazione per preparare la WNL che inizia lunedì prossimo!"
77
+ },
78
+ "wnlLeagueStart": {
79
+ "title": "La lega WNL è iniziata",
80
+ "body": "La fase di lega della WNL è iniziata!"
81
+ },
82
+ "wnlFinalsStart": {
83
+ "title": "Le finali della WNL sono iniziate",
84
+ "body": "Le finali della WNL sono iniziate!"
85
+ },
86
+ "wnlChampion": {
87
+ "title": "Campioni della WNL",
88
+ "body": "L'edizione della WNL è terminata. {{team}} sono i campioni della WNL!",
89
+ "bodyUnnamed": "L'edizione della WNL è terminata. I campioni sono stati incoronati!"
90
+ },
91
+ "wnlPlayerCalledUp": {
92
+ "title": "Giocatori convocati",
93
+ "body": "Uno o più dei tuoi giocatori sono stati convocati dalla loro nazionale!"
65
94
  }
66
95
  }
@@ -62,5 +62,34 @@
62
62
  "regionRelocation": {
63
63
  "title": "Twoja drużyna się przenosi",
64
64
  "body": "Twoja drużyna została wybrana do przeniesienia do nowego regionu: Kyorin. Nic się nie zmienia, jeśli chodzi o zarządzaną przez ciebie drużynę, twoich zawodników ani cokolwiek innego."
65
+ },
66
+ "wnlCallupOpen": {
67
+ "title": "Powołania do reprezentacji otwarte",
68
+ "body": "Faza powołań do reprezentacji rozpoczęła się! Masz czas do {{date}}, aby wybrać swoją drużynę do udziału w następnej edycji WNL."
69
+ },
70
+ "wnlCallupDeadline": {
71
+ "title": "Termin powołań mija dzisiaj",
72
+ "body": "Termin powołań do reprezentacji mija dzisiaj. Upewnij się, że wybrałeś zawodników, którzy wezmą udział w następnej edycji WNL."
73
+ },
74
+ "wnlCallupClosed": {
75
+ "title": "Powołania do reprezentacji zamknięte",
76
+ "body": "Faza powołań do reprezentacji zakończyła się. Możesz edytować swój skład, aby przygotować się do WNL, która zaczyna się w najbliższy poniedziałek!"
77
+ },
78
+ "wnlLeagueStart": {
79
+ "title": "Liga WNL rozpoczęta",
80
+ "body": "Faza ligowa WNL rozpoczęła się!"
81
+ },
82
+ "wnlFinalsStart": {
83
+ "title": "Finały WNL rozpoczęte",
84
+ "body": "Finały WNL rozpoczęły się!"
85
+ },
86
+ "wnlChampion": {
87
+ "title": "Mistrzowie WNL",
88
+ "body": "Edycja WNL zakończyła się. {{team}} to mistrzowie WNL!",
89
+ "bodyUnnamed": "Edycja WNL zakończyła się. Mistrzowie zostali wyłonieni!"
90
+ },
91
+ "wnlPlayerCalledUp": {
92
+ "title": "Zawodnicy powołani",
93
+ "body": "Co najmniej jeden z twoich zawodników został powołany do swojej reprezentacji!"
65
94
  }
66
95
  }
@@ -62,5 +62,34 @@
62
62
  "regionRelocation": {
63
63
  "title": "Seu time está mudando",
64
64
  "body": "Seu time foi escolhido para ser movido para a nova região: Kyorin. Nada muda em relação ao time que você gerencia, seus jogadores ou qualquer outra coisa."
65
+ },
66
+ "wnlCallupOpen": {
67
+ "title": "Convocação nacional aberta",
68
+ "body": "A fase de convocação nacional começou! Você tem até {{date}} para selecionar seu time e participar da próxima edição da WNL."
69
+ },
70
+ "wnlCallupDeadline": {
71
+ "title": "A convocação termina hoje",
72
+ "body": "O prazo da convocação nacional termina hoje. Verifique se você selecionou os jogadores que participarão da próxima edição da WNL."
73
+ },
74
+ "wnlCallupClosed": {
75
+ "title": "Convocação nacional encerrada",
76
+ "body": "A fase de convocação nacional terminou. Você pode editar sua escalação para se preparar para a WNL que começa na próxima segunda-feira!"
77
+ },
78
+ "wnlLeagueStart": {
79
+ "title": "A liga WNL começou",
80
+ "body": "A fase de liga da WNL começou!"
81
+ },
82
+ "wnlFinalsStart": {
83
+ "title": "As finais da WNL começaram",
84
+ "body": "As finais da WNL começaram!"
85
+ },
86
+ "wnlChampion": {
87
+ "title": "Campeões da WNL",
88
+ "body": "A edição da WNL terminou. {{team}} são os campeões da WNL!",
89
+ "bodyUnnamed": "A edição da WNL terminou. Os campeões foram coroados!"
90
+ },
91
+ "wnlPlayerCalledUp": {
92
+ "title": "Jogadores convocados",
93
+ "body": "Um ou mais dos seus jogadores foram convocados pela sua seleção nacional!"
65
94
  }
66
95
  }
@@ -62,5 +62,34 @@
62
62
  "regionRelocation": {
63
63
  "title": "Takımın taşınıyor",
64
64
  "body": "Takımın yeni bölgeye, Kyorin'e taşınmak üzere seçildi. Yönettiğin takım, oyuncuların ya da başka hiçbir şey açısından hiçbir şey değişmiyor."
65
+ },
66
+ "wnlCallupOpen": {
67
+ "title": "Milli takım kadro çağrısı açıldı",
68
+ "body": "Milli takım kadro çağrısı başladı! Bir sonraki WNL sezonuna katılacak takımını seçmek için {{date}} tarihine kadar vaktin var."
69
+ },
70
+ "wnlCallupDeadline": {
71
+ "title": "Kadro çağrısı bugün sona eriyor",
72
+ "body": "Milli takım kadro çağrısının son günü bugün. Bir sonraki WNL sezonunda oynayacak oyuncuları seçtiğinden emin ol."
73
+ },
74
+ "wnlCallupClosed": {
75
+ "title": "Kadro çağrısı kapandı",
76
+ "body": "Milli takım kadro çağrısı sona erdi. Önümüzdeki pazartesi başlayacak WNL için dizilişini düzenleyebilirsin!"
77
+ },
78
+ "wnlLeagueStart": {
79
+ "title": "WNL ligi başladı",
80
+ "body": "WNL lig aşaması başladı!"
81
+ },
82
+ "wnlFinalsStart": {
83
+ "title": "WNL finalleri başladı",
84
+ "body": "WNL finalleri başladı!"
85
+ },
86
+ "wnlChampion": {
87
+ "title": "WNL şampiyonları",
88
+ "body": "WNL sezonu sona erdi. {{team}} WNL şampiyonu oldu!",
89
+ "bodyUnnamed": "WNL sezonu sona erdi. Şampiyonlar belli oldu!"
90
+ },
91
+ "wnlPlayerCalledUp": {
92
+ "title": "Oyuncular milli takıma çağrıldı",
93
+ "body": "Bir veya daha fazla oyuncun milli takımına çağrıldı!"
65
94
  }
66
95
  }
@@ -1,4 +1,4 @@
1
- export declare const NOTIFICATION_TYPES: readonly ["MATCH_RESULT", "INJURY", "INJURY_RECOVERED", "SEASON_END", "GRANT_RECEIVED", "PROMOTION", "DAILY_LOGIN", "WELCOME", "COMPENSATION", "EVENT_REGISTRATION_OPEN", "EVENT_REGISTRATION_CLOSING", "EVENT_STARTED", "EVENT_FINAL_ROUND", "EVENT_FINISHED", "REGION_RELOCATION"];
1
+ export declare const NOTIFICATION_TYPES: readonly ["MATCH_RESULT", "INJURY", "INJURY_RECOVERED", "SEASON_END", "GRANT_RECEIVED", "PROMOTION", "DAILY_LOGIN", "WELCOME", "COMPENSATION", "EVENT_REGISTRATION_OPEN", "EVENT_REGISTRATION_CLOSING", "EVENT_STARTED", "EVENT_FINAL_ROUND", "EVENT_FINISHED", "REGION_RELOCATION", "WNL_CALLUP_OPEN", "WNL_CALLUP_DEADLINE", "WNL_CALLUP_CLOSED", "WNL_LEAGUE_START", "WNL_FINALS_START", "WNL_CHAMPION", "WNL_PLAYER_CALLED_UP"];
2
2
  export type NotificationType = typeof NOTIFICATION_TYPES[number];
3
3
  export declare const NOTIFICATION_LOCALES: readonly ["en", "es", "fr", "it", "pl", "pt-BR", "tr"];
4
4
  export type NotificationLocale = typeof NOTIFICATION_LOCALES[number];
@@ -22,7 +22,14 @@ exports.NOTIFICATION_TYPES = [
22
22
  'EVENT_STARTED',
23
23
  'EVENT_FINAL_ROUND',
24
24
  'EVENT_FINISHED',
25
- 'REGION_RELOCATION'
25
+ 'REGION_RELOCATION',
26
+ 'WNL_CALLUP_OPEN',
27
+ 'WNL_CALLUP_DEADLINE',
28
+ 'WNL_CALLUP_CLOSED',
29
+ 'WNL_LEAGUE_START',
30
+ 'WNL_FINALS_START',
31
+ 'WNL_CHAMPION',
32
+ 'WNL_PLAYER_CALLED_UP'
26
33
  ];
27
34
  // The 7 supported locales. Must stay in sync with the API VALID_LOCALES set and the UI src/locales/*.json.
28
35
  exports.NOTIFICATION_LOCALES = ['en', 'es', 'fr', 'it', 'pl', 'pt-BR', 'tr'];
@@ -145,4 +145,22 @@ function flattenStrings(node, prefix = '') {
145
145
  // disabling one type does not affect another
146
146
  (0, globals_1.expect)((0, notification_type_1.pushEnabledFor)({ MATCH_RESULT: false }, 'INJURY')).toBe(true);
147
147
  });
148
+ (0, globals_1.it)('groups the WNL types under the single WNL preference key', () => {
149
+ // Every WNL type resolves to the shared toggle; ungrouped types resolve to themselves.
150
+ for (const type of notification_type_1.NOTIFICATION_TYPES.filter((t) => t.startsWith('WNL_'))) {
151
+ (0, globals_1.expect)((0, registry_1.pushPrefKeyFor)(type)).toBe('WNL');
152
+ }
153
+ (0, globals_1.expect)((0, registry_1.pushPrefKeyFor)('MATCH_RESULT')).toBe('MATCH_RESULT');
154
+ (0, globals_1.expect)((0, registry_1.pushPrefKeyFor)('UNKNOWN_TYPE')).toBe('UNKNOWN_TYPE');
155
+ // The one WNL toggle gates every WNL type's push; individual WNL type keys are never consulted.
156
+ (0, globals_1.expect)((0, registry_1.pushEnabledForType)({ WNL: false }, 'WNL_CALLUP_OPEN')).toBe(false);
157
+ (0, globals_1.expect)((0, registry_1.pushEnabledForType)({ WNL: false }, 'WNL_CHAMPION')).toBe(false);
158
+ (0, globals_1.expect)((0, registry_1.pushEnabledForType)({}, 'WNL_CHAMPION')).toBe(true);
159
+ (0, globals_1.expect)((0, registry_1.pushEnabledForType)({ WNL_CHAMPION: false }, 'WNL_CHAMPION')).toBe(true);
160
+ (0, globals_1.expect)((0, registry_1.pushEnabledForType)({ MATCH_RESULT: false }, 'MATCH_RESULT')).toBe(false);
161
+ // The toggleable key set collapses the seven WNL types into one 'WNL' entry and keeps the rest per-type.
162
+ (0, globals_1.expect)(registry_1.PUSH_PREF_KEYS.filter((k) => k === 'WNL')).toHaveLength(1);
163
+ (0, globals_1.expect)(registry_1.PUSH_PREF_KEYS).not.toContain('WNL_CALLUP_OPEN');
164
+ (0, globals_1.expect)(registry_1.PUSH_PREF_KEYS).toContain('MATCH_RESULT');
165
+ });
148
166
  });
@@ -31,4 +31,10 @@ export interface PromotionPayload {
31
31
  teamId?: string;
32
32
  amount?: number;
33
33
  }
34
- export type NotificationPayload = MatchResultPayload | InjuryPayload | InjuryRecoveredPayload | SeasonEndPayload | PromotionPayload | Record<string, unknown>;
34
+ export interface WnlCallupOpenPayload {
35
+ deadline?: string;
36
+ }
37
+ export interface WnlChampionPayload {
38
+ team?: string;
39
+ }
40
+ export type NotificationPayload = MatchResultPayload | InjuryPayload | InjuryRecoveredPayload | SeasonEndPayload | PromotionPayload | WnlCallupOpenPayload | WnlChampionPayload | Record<string, unknown>;
@@ -1,7 +1,8 @@
1
- import { type NotificationType } from './notification-type';
1
+ import { type NotificationPreferences, type NotificationType } from './notification-type';
2
2
  export type CatalogKeyResolver = string | ((payload: Record<string, unknown>) => string);
3
3
  export interface NotificationDescriptor {
4
4
  emitsPush: boolean;
5
+ prefKey?: string;
5
6
  deepLink?: (payload: Record<string, unknown>) => string;
6
7
  pushTitleKey?: CatalogKeyResolver;
7
8
  pushBodyKey?: CatalogKeyResolver;
@@ -12,3 +13,6 @@ export interface NotificationDescriptor {
12
13
  }
13
14
  export declare const NOTIFICATION_REGISTRY: Record<NotificationType, NotificationDescriptor>;
14
15
  export declare const PUSH_NOTIFICATION_TYPES: NotificationType[];
16
+ export declare function pushPrefKeyFor(type: string): string;
17
+ export declare function pushEnabledForType(prefs: NotificationPreferences | null | undefined, type: string): boolean;
18
+ export declare const PUSH_PREF_KEYS: string[];
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PUSH_NOTIFICATION_TYPES = exports.NOTIFICATION_REGISTRY = void 0;
3
+ exports.PUSH_PREF_KEYS = exports.PUSH_NOTIFICATION_TYPES = exports.NOTIFICATION_REGISTRY = void 0;
4
+ exports.pushPrefKeyFor = pushPrefKeyFor;
5
+ exports.pushEnabledForType = pushEnabledForType;
4
6
  const notification_type_1 = require("./notification-type");
5
7
  function readString(value) {
6
8
  return typeof value === 'string' && value !== '' ? value : null;
@@ -171,9 +173,94 @@ exports.NOTIFICATION_REGISTRY = {
171
173
  pushBodyKey: 'regionRelocation.body',
172
174
  inAppMessageKey: 'regionRelocation.body',
173
175
  catalogKeys: ['regionRelocation.title', 'regionRelocation.body']
176
+ },
177
+ // World Nations League (owner 2026-08-28). All seven share the single 'WNL' preference toggle. The three callup
178
+ // types go to national team managers, LEAGUE_START/FINALS_START/CHAMPION are broadcast to every active user, and
179
+ // PLAYER_CALLED_UP goes to club owners with at least one player in a finalized squad.
180
+ WNL_CALLUP_OPEN: {
181
+ emitsPush: true,
182
+ prefKey: 'WNL',
183
+ deepLink: () => '/wnl/callup',
184
+ pushTitleKey: 'wnlCallupOpen.title',
185
+ pushBodyKey: 'wnlCallupOpen.body',
186
+ inAppMessageKey: 'wnlCallupOpen.body',
187
+ // The deadline arrives pre-formatted (locale-neutral 'YYYY-MM-DD HH:mm UTC') because the stored payload is
188
+ // shared by the push and the in-app bell and cannot be re-localised per render.
189
+ params: (p) => ({ date: readString(p.deadline) ?? '' }),
190
+ catalogKeys: ['wnlCallupOpen.title', 'wnlCallupOpen.body']
191
+ },
192
+ WNL_CALLUP_DEADLINE: {
193
+ emitsPush: true,
194
+ prefKey: 'WNL',
195
+ deepLink: () => '/wnl/callup',
196
+ pushTitleKey: 'wnlCallupDeadline.title',
197
+ pushBodyKey: 'wnlCallupDeadline.body',
198
+ inAppMessageKey: 'wnlCallupDeadline.body',
199
+ catalogKeys: ['wnlCallupDeadline.title', 'wnlCallupDeadline.body']
200
+ },
201
+ WNL_CALLUP_CLOSED: {
202
+ emitsPush: true,
203
+ prefKey: 'WNL',
204
+ deepLink: () => '/wnl/manage/lineup',
205
+ pushTitleKey: 'wnlCallupClosed.title',
206
+ pushBodyKey: 'wnlCallupClosed.body',
207
+ inAppMessageKey: 'wnlCallupClosed.body',
208
+ catalogKeys: ['wnlCallupClosed.title', 'wnlCallupClosed.body']
209
+ },
210
+ WNL_LEAGUE_START: {
211
+ emitsPush: true,
212
+ prefKey: 'WNL',
213
+ deepLink: () => '/wnl',
214
+ pushTitleKey: 'wnlLeagueStart.title',
215
+ pushBodyKey: 'wnlLeagueStart.body',
216
+ inAppMessageKey: 'wnlLeagueStart.body',
217
+ catalogKeys: ['wnlLeagueStart.title', 'wnlLeagueStart.body']
218
+ },
219
+ WNL_FINALS_START: {
220
+ emitsPush: true,
221
+ prefKey: 'WNL',
222
+ deepLink: () => '/wnl/finals',
223
+ pushTitleKey: 'wnlFinalsStart.title',
224
+ pushBodyKey: 'wnlFinalsStart.body',
225
+ inAppMessageKey: 'wnlFinalsStart.body',
226
+ catalogKeys: ['wnlFinalsStart.title', 'wnlFinalsStart.body']
227
+ },
228
+ WNL_CHAMPION: {
229
+ emitsPush: true,
230
+ prefKey: 'WNL',
231
+ deepLink: () => '/wnl/finals',
232
+ pushTitleKey: 'wnlChampion.title',
233
+ // A missing team name never renders a subjectless sentence (mirrors the MATCH_RESULT named/unnamed split).
234
+ pushBodyKey: (p) => readString(p.team) != null ? 'wnlChampion.body' : 'wnlChampion.bodyUnnamed',
235
+ inAppMessageKey: (p) => readString(p.team) != null ? 'wnlChampion.body' : 'wnlChampion.bodyUnnamed',
236
+ params: (p) => ({ team: readString(p.team) ?? '' }),
237
+ catalogKeys: ['wnlChampion.title', 'wnlChampion.body', 'wnlChampion.bodyUnnamed']
238
+ },
239
+ WNL_PLAYER_CALLED_UP: {
240
+ emitsPush: true,
241
+ prefKey: 'WNL',
242
+ deepLink: () => '/wnl/teams',
243
+ pushTitleKey: 'wnlPlayerCalledUp.title',
244
+ pushBodyKey: 'wnlPlayerCalledUp.body',
245
+ inAppMessageKey: 'wnlPlayerCalledUp.body',
246
+ catalogKeys: ['wnlPlayerCalledUp.title', 'wnlPlayerCalledUp.body']
174
247
  }
175
248
  };
176
249
  // The notification types that emit a mobile push (everything except COMPENSATION). Source of truth = each
177
- // descriptor's emitsPush, so this cannot drift. This is the user-toggleable set surfaced in the mobile app's
178
- // notification settings and validated by the API before persisting a preference.
250
+ // descriptor's emitsPush, so this cannot drift.
179
251
  exports.PUSH_NOTIFICATION_TYPES = notification_type_1.NOTIFICATION_TYPES.filter((type) => exports.NOTIFICATION_REGISTRY[type].emitsPush);
252
+ // The preference-map key a type's push toggle lives under: the descriptor's prefKey (group toggle) or the type
253
+ // itself. Unknown types resolve to themselves, mirroring pushEnabledFor's loose-string tolerance.
254
+ function pushPrefKeyFor(type) {
255
+ const descriptor = exports.NOTIFICATION_REGISTRY[type];
256
+ return descriptor?.prefKey ?? type;
257
+ }
258
+ // Group-aware push gate: like pushEnabledFor, but resolves the type's preference GROUP first, so muting the one
259
+ // 'WNL' toggle suppresses every WNL type's push. Senders (Sim/API insertNotification) use THIS, not pushEnabledFor.
260
+ function pushEnabledForType(prefs, type) {
261
+ return (0, notification_type_1.pushEnabledFor)(prefs, pushPrefKeyFor(type));
262
+ }
263
+ // The user-toggleable keys surfaced in the mobile app's notification settings and validated by the API before
264
+ // persisting a preference: one entry per DISTINCT pref key (individual types plus each group toggle once),
265
+ // in first-appearance order.
266
+ exports.PUSH_PREF_KEYS = [...new Set(exports.PUSH_NOTIFICATION_TYPES.map((type) => pushPrefKeyFor(type)))];
@@ -8,3 +8,5 @@ export declare const PREMIUM_TIERS: PremiumTierDef[];
8
8
  export declare const MAX_PREMIUM_TIER: number;
9
9
  export declare function premiumTierDef(tier: number): PremiumTierDef | undefined;
10
10
  export declare function hasTier(effectiveTier: number, required: number): boolean;
11
+ export declare const TIER_NATIONAL = 2;
12
+ export declare function canManageNationalTeam(effectiveTier: number): boolean;
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MAX_PREMIUM_TIER = exports.PREMIUM_TIERS = exports.NO_PREMIUM = void 0;
3
+ exports.TIER_NATIONAL = exports.MAX_PREMIUM_TIER = exports.PREMIUM_TIERS = exports.NO_PREMIUM = void 0;
4
4
  exports.premiumTierDef = premiumTierDef;
5
5
  exports.hasTier = hasTier;
6
+ exports.canManageNationalTeam = canManageNationalTeam;
6
7
  // Hierarchical premium tiers (owner 2026-08-17): tier N grants everything below it, so a feature gate is just
7
8
  // `effectiveTier >= required`. Tiers are NUMERIC and code-defined here (the DB stores only the number), so adding a
8
9
  // tier needs no migration. Names/keys are display + gating helpers. Keep PREMIUM_TIERS ascending by tier. See
@@ -22,3 +23,9 @@ function premiumTierDef(tier) {
22
23
  function hasTier(effectiveTier, required) {
23
24
  return effectiveTier >= required;
24
25
  }
26
+ // Tier 2 (NATIONAL) unlocks World Cup / national-team management (claiming and managing a national team, the WNL
27
+ // callup, lineup and kit). Gate every national-team write on this.
28
+ exports.TIER_NATIONAL = 2;
29
+ function canManageNationalTeam(effectiveTier) {
30
+ return hasTier(effectiveTier, exports.TIER_NATIONAL);
31
+ }
@@ -70,6 +70,8 @@ export type ChampionBadgeSpec = {
70
70
  region: ChampionRegion;
71
71
  } | {
72
72
  type: 'wcc';
73
+ } | {
74
+ type: 'wnl';
73
75
  };
74
76
  export type Player = Omit<DataProps<_Player>, 'stats' | 'birthAge' | 'birthIteration' | 'declineProfile' | 'nickname' | 'injuryProneProfile' | 'injury'> & {
75
77
  -readonly [K in 'birthAge' | 'birthIteration']?: DataProps<_Player>[K];
@@ -83,6 +85,7 @@ export type Player = Omit<DataProps<_Player>, 'stats' | 'birthAge' | 'birthItera
83
85
  nickname?: string;
84
86
  jerseyConfig?: JerseyConfig;
85
87
  championBadge?: ChampionBadgeSpec;
88
+ nationalFlagAlpha2?: string;
86
89
  };
87
90
  export interface StartingLineup {
88
91
  [CourtPosition.LEFT_FRONT]: string;
@@ -189,6 +192,12 @@ export type Team = Omit<DataProps<_Team>, 'roster' | '_rating' | 'rating' | 'tac
189
192
  };
190
193
  nationalCountryName?: string;
191
194
  isEvent?: boolean;
195
+ isNational?: boolean;
196
+ nationalManager?: {
197
+ displayName: string;
198
+ teamId: string;
199
+ teamShortName: string;
200
+ };
192
201
  };
193
202
  export type Standing = DataProps<_Standing> & {
194
203
  position: number;
@@ -255,4 +264,11 @@ export type TotalBoxScore = Omit<DataProps<BoxScore>, 'misc' | 'playerId' | 'mat
255
264
  setsPlayed: number;
256
265
  matchesPlayed: number;
257
266
  };
267
+ national?: {
268
+ alpha2: string;
269
+ matchesPlayed: number;
270
+ matchesWon: number;
271
+ pointsPlayed: number;
272
+ pointsWon: number;
273
+ };
258
274
  };
@@ -1,4 +1,4 @@
1
- import { AuthIdentityModel, AuthSessionModel, AuthUserModel, BoxScoreModel, CoachModel, ScoutModel, PhysicianModel, PhysiotherapistModel, BoxScoreTotalsModel, CompetitionChampionModel, JerseyBadgeModel, CurrencyTransactionModel, GachaPityModel, GachaPullHistoryModel, WishlistModel, UserSettingsModel, UserAchievementsModel, UserDeviceTokenModel, BasePositionPresetModel, CompetitionMatchModel, CompetitionMVPModel, CompetitionModel, CompetitionStandingsMatchModel, CompetitionStandingsModel, CompetitionTeamsModel, CountryModel, DivisionModel, DivisionSeasonModel, IterationModel, LeagueModel, MatchModel, MatchRatingModel, MatchResultModel, MatchSetModel, PerformanceStatsModel, PlayerModel, PlayerImprovementLogModel, PlayerDeclineLogModel, PlayerTeamModel, RetiredPlayerModel, PromotionMatchModel, FriendlyModel, RegionQualifierModel, NationalCountryModel, RallyModel, MatchInputSnapshotModel, TacticsModel, TeamJerseyModel, LineupPresetModel, MatchPresetModel, EventModel, EventCompetitionModel, EventSquadModel, EventPackModel, EventPackPlayerModel, EventResultModel, EventBotTeamModel, TeamModel, TeamReplacementModel, UserCurrencyModel, UserPlayerProgressModel, UserPullGrantModel, PremiumGrantModel, UserTeamModel, VPERModel, NotificationModel, AppConfigModel, LegacyTeamFlagModel } from './models';
1
+ import { AuthIdentityModel, AuthSessionModel, AuthUserModel, BoxScoreModel, CoachModel, ScoutModel, PhysicianModel, PhysiotherapistModel, BoxScoreTotalsModel, CompetitionChampionModel, JerseyBadgeModel, CurrencyTransactionModel, GachaPityModel, GachaPullHistoryModel, WishlistModel, UserSettingsModel, UserAchievementsModel, UserDeviceTokenModel, BasePositionPresetModel, CompetitionMatchModel, CompetitionMVPModel, CompetitionModel, CompetitionStandingsMatchModel, CompetitionStandingsModel, CompetitionTeamsModel, CountryModel, DivisionModel, DivisionSeasonModel, IterationModel, LeagueModel, MatchModel, MatchRatingModel, MatchResultModel, MatchSetModel, PerformanceStatsModel, PlayerModel, PlayerImprovementLogModel, PlayerDeclineLogModel, PlayerTeamModel, RetiredPlayerModel, PromotionMatchModel, FriendlyModel, RegionQualifierModel, NationalCountryModel, NationalTeamModel, NationalTeamClaimModel, WnlSquadModel, WnlCallupModel, WnlSeasonModel, RallyModel, MatchInputSnapshotModel, TacticsModel, TeamJerseyModel, LineupPresetModel, MatchPresetModel, EventModel, EventCompetitionModel, EventSquadModel, EventPackModel, EventPackPlayerModel, EventResultModel, EventBotTeamModel, TeamModel, TeamReplacementModel, UserCurrencyModel, UserPlayerProgressModel, UserPullGrantModel, PremiumGrantModel, UserTeamModel, VPERModel, NotificationModel, AppConfigModel, LegacyTeamFlagModel } from './models';
2
2
  export function initModels(sequelize) {
3
3
  const Coach = CoachModel.initModel(sequelize);
4
4
  const Scout = ScoutModel.initModel(sequelize);
@@ -63,6 +63,11 @@ export function initModels(sequelize) {
63
63
  const Friendly = FriendlyModel.initModel(sequelize);
64
64
  const RegionQualifier = RegionQualifierModel.initModel(sequelize);
65
65
  const NationalCountry = NationalCountryModel.initModel(sequelize);
66
+ const NationalTeam = NationalTeamModel.initModel(sequelize);
67
+ const NationalTeamClaim = NationalTeamClaimModel.initModel(sequelize);
68
+ const WnlSquad = WnlSquadModel.initModel(sequelize);
69
+ const WnlCallup = WnlCallupModel.initModel(sequelize);
70
+ const WnlSeason = WnlSeasonModel.initModel(sequelize);
66
71
  const Team = TeamModel.initModel(sequelize);
67
72
  const TeamReplacement = TeamReplacementModel.initModel(sequelize);
68
73
  const LegacyTeamFlag = LegacyTeamFlagModel.initModel(sequelize);
@@ -228,6 +233,28 @@ export function initModels(sequelize) {
228
233
  Competition.hasOne(NationalCountry, { as: 'NationalCountry', foreignKey: 'competition_id' });
229
234
  Country.hasMany(NationalCountry, { as: 'NationalCountries', foreignKey: 'country_id' });
230
235
  Iteration.hasMany(NationalCountry, { as: 'NationalCountries', foreignKey: 'iteration' });
236
+ // National teams (WNL). The registry maps a country to its permanent active=false national Team; the claim links a
237
+ // Tier-2 manager to it; per-edition squad + callup + season rows hang off the WNL league Competition.
238
+ NationalTeam.belongsTo(Country, { as: 'country', foreignKey: 'country_id' });
239
+ NationalTeam.belongsTo(Team, { as: 'team', foreignKey: 'team_id' });
240
+ Country.hasOne(NationalTeam, { as: 'NationalTeam', foreignKey: 'country_id' });
241
+ Team.hasOne(NationalTeam, { as: 'NationalTeam', foreignKey: 'team_id' });
242
+ NationalTeam.hasOne(NationalTeamClaim, { as: 'claim', foreignKey: 'country_id' });
243
+ NationalTeamClaim.belongsTo(NationalTeam, { as: 'nationalTeam', foreignKey: 'country_id' });
244
+ NationalTeamClaim.belongsTo(AuthUser, { as: 'user', foreignKey: 'user_id' });
245
+ AuthUser.hasOne(NationalTeamClaim, { as: 'NationalTeamClaim', foreignKey: 'user_id' });
246
+ WnlSquad.belongsTo(Competition, { as: 'competition', foreignKey: 'competition_id' });
247
+ WnlSquad.belongsTo(Country, { as: 'country', foreignKey: 'country_id' });
248
+ WnlSquad.belongsTo(Team, { as: 'team', foreignKey: 'team_id' });
249
+ WnlSquad.belongsTo(AuthUser, { as: 'manager', foreignKey: 'manager_user_id' });
250
+ Competition.hasMany(WnlSquad, { as: 'WnlSquads', foreignKey: 'competition_id' });
251
+ WnlCallup.belongsTo(Competition, { as: 'competition', foreignKey: 'competition_id' });
252
+ WnlCallup.belongsTo(Player, { as: 'player', foreignKey: 'player_id' });
253
+ WnlCallup.belongsTo(Country, { as: 'country', foreignKey: 'country_id' });
254
+ Competition.hasMany(WnlCallup, { as: 'WnlCallups', foreignKey: 'competition_id' });
255
+ WnlSeason.belongsTo(Competition, { as: 'competition', foreignKey: 'competition_id' });
256
+ WnlSeason.belongsTo(Competition, { as: 'finalsCompetition', foreignKey: 'finals_competition_id' });
257
+ Competition.hasOne(WnlSeason, { as: 'WnlSeason', foreignKey: 'competition_id' });
231
258
  VPER.belongsTo(Player, { as: 'Player', foreignKey: 'player_id' });
232
259
  VPER.belongsTo(Match, { as: 'Match', foreignKey: 'match_id' });
233
260
  Team.hasOne(Coach, { as: 'Coach', foreignKey: 'team_id' });
@@ -351,6 +378,11 @@ export function initModels(sequelize) {
351
378
  Friendly,
352
379
  RegionQualifier,
353
380
  NationalCountry,
381
+ NationalTeam,
382
+ NationalTeamClaim,
383
+ WnlSquad,
384
+ WnlCallup,
385
+ WnlSeason,
354
386
  Rally,
355
387
  Team,
356
388
  TeamReplacement,
@@ -21,7 +21,7 @@ export interface CompetitionAttributes {
21
21
  LowerPromotionMatches?: PromotionMatchAttributes[];
22
22
  }
23
23
  export type CompetitionPk = 'competition_id';
24
- export type CompetitionType = 'LEAGUE' | 'TOURNAMENT' | 'QUALIFIER' | 'NATIONAL' | 'EVENT';
24
+ export type CompetitionType = 'LEAGUE' | 'TOURNAMENT' | 'QUALIFIER' | 'NATIONAL' | 'EVENT' | 'WNL' | 'WNLF';
25
25
  export type CompetitionId = CompetitionModel[CompetitionPk];
26
26
  export type CompetitionCreationAttributes = CompetitionAttributes;
27
27
  export declare class CompetitionModel extends Model<CompetitionAttributes, CompetitionCreationAttributes> implements CompetitionAttributes {
@@ -18,7 +18,7 @@ export class CompetitionModel extends Model {
18
18
  }
19
19
  },
20
20
  type: {
21
- type: DataTypes.ENUM('LEAGUE', 'TOURNAMENT', 'QUALIFIER', 'NATIONAL', 'EVENT'),
21
+ type: DataTypes.ENUM('LEAGUE', 'TOURNAMENT', 'QUALIFIER', 'NATIONAL', 'EVENT', 'WNL', 'WNLF'),
22
22
  allowNull: false
23
23
  },
24
24
  status: {
@@ -32,6 +32,11 @@ export * from './promotion-match';
32
32
  export * from './friendly';
33
33
  export * from './region-qualifier';
34
34
  export * from './national-country';
35
+ export * from './national-team';
36
+ export * from './national-team-claim';
37
+ export * from './wnl-squad';
38
+ export * from './wnl-callup';
39
+ export * from './wnl-season';
35
40
  export * from './coach';
36
41
  export * from './scout';
37
42
  export * from './physician';
@@ -32,6 +32,11 @@ export * from './promotion-match';
32
32
  export * from './friendly';
33
33
  export * from './region-qualifier';
34
34
  export * from './national-country';
35
+ export * from './national-team';
36
+ export * from './national-team-claim';
37
+ export * from './wnl-squad';
38
+ export * from './wnl-callup';
39
+ export * from './wnl-season';
35
40
  export * from './coach';
36
41
  export * from './scout';
37
42
  export * from './physician';
@@ -1,7 +1,7 @@
1
1
  import * as Sequelize from 'sequelize';
2
2
  import { Model } from 'sequelize';
3
3
  import { CompetitionId, CompetitionModel, TeamId, TeamModel } from '.';
4
- export type JerseyBadgeKind = 'LEAGUE' | 'NATIONALS' | 'REGIONALS' | 'WCC';
4
+ export type JerseyBadgeKind = 'LEAGUE' | 'NATIONALS' | 'REGIONALS' | 'WCC' | 'WNL';
5
5
  export interface JerseyBadgeAttributes {
6
6
  competition_id: string;
7
7
  team_id: string;
@@ -20,7 +20,7 @@ export class JerseyBadgeModel extends Model {
20
20
  }
21
21
  },
22
22
  badge: {
23
- type: DataTypes.ENUM('LEAGUE', 'NATIONALS', 'REGIONALS', 'WCC'),
23
+ type: DataTypes.ENUM('LEAGUE', 'NATIONALS', 'REGIONALS', 'WCC', 'WNL'),
24
24
  allowNull: false
25
25
  },
26
26
  region: {
@@ -0,0 +1,21 @@
1
+ import * as Sequelize from 'sequelize';
2
+ import { Model, Optional } from 'sequelize';
3
+ import { AuthUserId, AuthUserModel } from '.';
4
+ export interface NationalTeamClaimAttributes {
5
+ country_id: string;
6
+ user_id: string;
7
+ claimed_at: Date;
8
+ }
9
+ export type NationalTeamClaimPk = 'country_id';
10
+ export type NationalTeamClaimId = NationalTeamClaimModel[NationalTeamClaimPk];
11
+ export type NationalTeamClaimOptionalAttributes = 'claimed_at';
12
+ export type NationalTeamClaimCreationAttributes = Optional<NationalTeamClaimAttributes, NationalTeamClaimOptionalAttributes>;
13
+ export declare class NationalTeamClaimModel extends Model<NationalTeamClaimAttributes, NationalTeamClaimCreationAttributes> implements NationalTeamClaimAttributes {
14
+ country_id: string;
15
+ user_id: string;
16
+ claimed_at: Date;
17
+ user: AuthUserModel;
18
+ getUser: Sequelize.BelongsToGetAssociationMixin<AuthUserModel>;
19
+ setUser: Sequelize.BelongsToSetAssociationMixin<AuthUserModel, AuthUserId>;
20
+ static initModel(sequelize: Sequelize.Sequelize): typeof NationalTeamClaimModel;
21
+ }