volleyballsimtypes 0.0.478 → 0.0.480
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/cjs/src/api/index.d.ts +1 -0
- package/dist/cjs/src/data/models/tactics.d.ts +1 -0
- package/dist/cjs/src/data/transformers/rally-event-tempo.test.d.ts +1 -0
- package/dist/cjs/src/data/transformers/rally-event-tempo.test.js +40 -0
- package/dist/cjs/src/data/transformers/rally-event.d.ts +1 -0
- package/dist/cjs/src/data/transformers/rally-event.js +5 -1
- package/dist/cjs/src/data/transformers/tactics.js +8 -4
- package/dist/cjs/src/data/transformers/tactics.test.js +13 -0
- package/dist/cjs/src/service/event/schemas/set.z.d.ts +1 -0
- package/dist/cjs/src/service/event/schemas/set.z.js +4 -1
- package/dist/cjs/src/service/event/schemas/set.z.test.d.ts +1 -0
- package/dist/cjs/src/service/event/schemas/set.z.test.js +29 -0
- package/dist/cjs/src/service/event/set.d.ts +7 -0
- package/dist/cjs/src/service/event/set.js +15 -3
- package/dist/cjs/src/service/index.d.ts +1 -0
- package/dist/cjs/src/service/index.js +1 -0
- package/dist/cjs/src/service/notification/catalog/en.json +41 -0
- package/dist/cjs/src/service/notification/catalog/es.json +41 -0
- package/dist/cjs/src/service/notification/catalog/fr.json +41 -0
- package/dist/cjs/src/service/notification/catalog/index.d.ts +3 -0
- package/dist/cjs/src/service/notification/catalog/index.js +22 -0
- package/dist/cjs/src/service/notification/catalog/it.json +41 -0
- package/dist/cjs/src/service/notification/catalog/pl.json +41 -0
- package/dist/cjs/src/service/notification/catalog/pt-BR.json +41 -0
- package/dist/cjs/src/service/notification/catalog/tr.json +41 -0
- package/dist/cjs/src/service/notification/index.d.ts +5 -0
- package/dist/cjs/src/service/notification/index.js +23 -0
- package/dist/cjs/src/service/notification/notification-type.d.ts +6 -0
- package/dist/cjs/src/service/notification/notification-type.js +30 -0
- package/dist/cjs/src/service/notification/notification.test.d.ts +1 -0
- package/dist/cjs/src/service/notification/notification.test.js +128 -0
- package/dist/cjs/src/service/notification/payloads.d.ts +34 -0
- package/dist/cjs/src/service/notification/payloads.js +5 -0
- package/dist/cjs/src/service/notification/registry.d.ts +13 -0
- package/dist/cjs/src/service/notification/registry.js +112 -0
- package/dist/cjs/src/service/notification/render.d.ts +10 -0
- package/dist/cjs/src/service/notification/render.js +64 -0
- package/dist/cjs/src/service/team/offensive-preference.d.ts +2 -0
- package/dist/cjs/src/service/team/schemas/tactics.z.d.ts +8 -0
- package/dist/cjs/src/service/team/schemas/tactics.z.js +12 -2
- package/dist/cjs/src/service/team/schemas/tactics.z.test.js +24 -0
- package/dist/cjs/src/service/team/schemas/team.z.d.ts +8 -0
- package/dist/esm/src/api/index.d.ts +1 -0
- package/dist/esm/src/data/models/tactics.d.ts +1 -0
- package/dist/esm/src/data/transformers/rally-event-tempo.test.d.ts +1 -0
- package/dist/esm/src/data/transformers/rally-event-tempo.test.js +38 -0
- package/dist/esm/src/data/transformers/rally-event.d.ts +1 -0
- package/dist/esm/src/data/transformers/rally-event.js +5 -1
- package/dist/esm/src/data/transformers/tactics.js +8 -4
- package/dist/esm/src/data/transformers/tactics.test.js +13 -0
- package/dist/esm/src/service/event/schemas/set.z.d.ts +1 -0
- package/dist/esm/src/service/event/schemas/set.z.js +4 -1
- package/dist/esm/src/service/event/schemas/set.z.test.d.ts +1 -0
- package/dist/esm/src/service/event/schemas/set.z.test.js +27 -0
- package/dist/esm/src/service/event/set.d.ts +7 -0
- package/dist/esm/src/service/event/set.js +14 -2
- package/dist/esm/src/service/index.d.ts +1 -0
- package/dist/esm/src/service/index.js +1 -0
- package/dist/esm/src/service/notification/catalog/en.json +41 -0
- package/dist/esm/src/service/notification/catalog/es.json +41 -0
- package/dist/esm/src/service/notification/catalog/fr.json +41 -0
- package/dist/esm/src/service/notification/catalog/index.d.ts +3 -0
- package/dist/esm/src/service/notification/catalog/index.js +16 -0
- package/dist/esm/src/service/notification/catalog/it.json +41 -0
- package/dist/esm/src/service/notification/catalog/pl.json +41 -0
- package/dist/esm/src/service/notification/catalog/pt-BR.json +41 -0
- package/dist/esm/src/service/notification/catalog/tr.json +41 -0
- package/dist/esm/src/service/notification/index.d.ts +5 -0
- package/dist/esm/src/service/notification/index.js +5 -0
- package/dist/esm/src/service/notification/notification-type.d.ts +6 -0
- package/dist/esm/src/service/notification/notification-type.js +26 -0
- package/dist/esm/src/service/notification/notification.test.d.ts +1 -0
- package/dist/esm/src/service/notification/notification.test.js +126 -0
- package/dist/esm/src/service/notification/payloads.d.ts +34 -0
- package/dist/esm/src/service/notification/payloads.js +4 -0
- package/dist/esm/src/service/notification/registry.d.ts +13 -0
- package/dist/esm/src/service/notification/registry.js +109 -0
- package/dist/esm/src/service/notification/render.d.ts +10 -0
- package/dist/esm/src/service/notification/render.js +58 -0
- package/dist/esm/src/service/team/offensive-preference.d.ts +2 -0
- package/dist/esm/src/service/team/schemas/tactics.z.d.ts +8 -0
- package/dist/esm/src/service/team/schemas/tactics.z.js +12 -2
- package/dist/esm/src/service/team/schemas/tactics.z.test.js +24 -0
- package/dist/esm/src/service/team/schemas/team.z.d.ts +8 -0
- package/package.json +6 -1
|
@@ -86,7 +86,8 @@ function transformToAttributes(tactics, teamId) {
|
|
|
86
86
|
designated_setters: tactics.designatedSetters.map((s) => s.id),
|
|
87
87
|
offensive_preferences: tactics.offensivePreferences.map(p => ({
|
|
88
88
|
rotation: p.rotation,
|
|
89
|
-
order: p.order.map((a) => a.id)
|
|
89
|
+
order: p.order.map((a) => a.id),
|
|
90
|
+
tempos: p.tempos
|
|
90
91
|
})),
|
|
91
92
|
system_sets: tactics.systemSets?.map(s => ({
|
|
92
93
|
rotationSystem: s.rotationSystem,
|
|
@@ -94,7 +95,8 @@ function transformToAttributes(tactics, teamId) {
|
|
|
94
95
|
})),
|
|
95
96
|
offensive_preference_sets: tactics.offensivePreferenceSets?.map(prefs => prefs.map(p => ({
|
|
96
97
|
rotation: p.rotation,
|
|
97
|
-
order: p.order.map((a) => a.id)
|
|
98
|
+
order: p.order.map((a) => a.id),
|
|
99
|
+
tempos: p.tempos
|
|
98
100
|
}))),
|
|
99
101
|
replace_knocked_immediately: tactics.replaceKnockedImmediately,
|
|
100
102
|
injury_replacements: tactics.injuryReplacements.map(ir => ({
|
|
@@ -184,7 +186,8 @@ function transformToObject(model, roster) {
|
|
|
184
186
|
designatedSetters: (model.designated_setters ?? []).map((id) => findPlayer(id, roster)),
|
|
185
187
|
offensivePreferences: (model.offensive_preferences ?? []).map(p => ({
|
|
186
188
|
rotation: p.rotation,
|
|
187
|
-
order: p.order.map((id) => findPlayer(id, roster))
|
|
189
|
+
order: p.order.map((id) => findPlayer(id, roster)),
|
|
190
|
+
tempos: p.tempos
|
|
188
191
|
})),
|
|
189
192
|
systemSets: model.system_sets?.map(s => ({
|
|
190
193
|
rotationSystem: s.rotationSystem,
|
|
@@ -192,7 +195,8 @@ function transformToObject(model, roster) {
|
|
|
192
195
|
})),
|
|
193
196
|
offensivePreferenceSets: model.offensive_preference_sets?.map(prefs => prefs.map(p => ({
|
|
194
197
|
rotation: p.rotation,
|
|
195
|
-
order: p.order.map((id) => findPlayer(id, roster))
|
|
198
|
+
order: p.order.map((id) => findPlayer(id, roster)),
|
|
199
|
+
tempos: p.tempos
|
|
196
200
|
}))),
|
|
197
201
|
// LENIENT: keep only boolean entries keyed by a court starter or, when a second libero exists, the starting
|
|
198
202
|
// libero (the libero knock toggle is an L2-only feature, owner 2026-07-06) so stale jsonb (an ex-starter's
|
|
@@ -182,6 +182,19 @@ describe('per-set tactics — service <-> row round-trip', () => {
|
|
|
182
182
|
expect(back.systemSets).toBeUndefined();
|
|
183
183
|
expect(back.offensivePreferenceSets).toBeUndefined();
|
|
184
184
|
});
|
|
185
|
+
it('round-trips a per-starter tempos map on offensive preferences', () => {
|
|
186
|
+
const withTempos = Tactics.create({
|
|
187
|
+
lineup: { 4: p4, 3: p3, 2: p2, 5: p5, 6: p6, 1: p1, bench: [] },
|
|
188
|
+
liberoReplacements: [],
|
|
189
|
+
offensivePreferences: [{ rotation: 1, order: [p2, p3], tempos: { [p2.id]: 'FAST', [p3.id]: 'HIGH' } }]
|
|
190
|
+
});
|
|
191
|
+
const attrs = transformFromTactics(withTempos, 'team-1');
|
|
192
|
+
expect(attrs.offensive_preferences).toEqual([
|
|
193
|
+
{ rotation: 1, order: [p2.id, p3.id], tempos: { [p2.id]: 'FAST', [p3.id]: 'HIGH' } }
|
|
194
|
+
]);
|
|
195
|
+
const back = transformToTactics(attrs, roster);
|
|
196
|
+
expect(back.offensivePreferences[0].tempos).toEqual({ [p2.id]: 'FAST', [p3.id]: 'HIGH' });
|
|
197
|
+
});
|
|
185
198
|
});
|
|
186
199
|
describe('libero injuries — service <-> row round-trip + lenient heal', () => {
|
|
187
200
|
const country = makeCountry();
|
|
@@ -3,6 +3,7 @@ import { TraitEnum } from '../../player';
|
|
|
3
3
|
import { EventIncidentSchema } from './incident.z';
|
|
4
4
|
const setTypeValues = [0, 1];
|
|
5
5
|
const setFailureValues = [0, 1, 2, 3, 4];
|
|
6
|
+
const setTempoValues = [0, 1, 2];
|
|
6
7
|
const courtTargetValues = Array.from({ length: 13 }, (_, i) => i);
|
|
7
8
|
export const SetInputSchema = z.object({
|
|
8
9
|
playerId: z.uuid(),
|
|
@@ -11,5 +12,7 @@ export const SetInputSchema = z.object({
|
|
|
11
12
|
activeTraits: z.array(z.enum(Object.values(TraitEnum))).default([]),
|
|
12
13
|
failure: z.number().int().refine((v) => setFailureValues.includes(v), { message: 'INVALID_SET_FAILURE' }),
|
|
13
14
|
type: z.number().int().refine((v) => setTypeValues.includes(v), { message: 'INVALID_SET_TYPE' }),
|
|
14
|
-
incident: EventIncidentSchema.optional()
|
|
15
|
+
incident: EventIncidentSchema.optional(),
|
|
16
|
+
// Set tempo (FIRST=0, SECOND=1, HIGH=2). Optional: absent on dumps, failed sets, and every pre-tempo event.
|
|
17
|
+
tempo: z.number().int().refine((v) => setTempoValues.includes(v), { message: 'INVALID_SET_TEMPO' }).optional()
|
|
15
18
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { describe, it, expect } from '@jest/globals';
|
|
2
|
+
import { SetInputSchema } from './set.z';
|
|
3
|
+
const base = {
|
|
4
|
+
playerId: '11111111-1111-4111-8111-111111111111',
|
|
5
|
+
score: 90,
|
|
6
|
+
target: 4,
|
|
7
|
+
activeTraits: [],
|
|
8
|
+
failure: 0,
|
|
9
|
+
type: 0
|
|
10
|
+
};
|
|
11
|
+
describe('SetInputSchema — tempo', () => {
|
|
12
|
+
it('accepts every tempo 0-2 (FIRST / SECOND / HIGH)', () => {
|
|
13
|
+
for (const tempo of [0, 1, 2]) {
|
|
14
|
+
expect(SetInputSchema.safeParse({ ...base, tempo }).success).toBe(true);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
it('accepts an absent tempo (Auto, dumps, failed sets)', () => {
|
|
18
|
+
expect(SetInputSchema.safeParse(base).success).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
it('rejects an out-of-range tempo', () => {
|
|
21
|
+
expect(SetInputSchema.safeParse({ ...base, tempo: 3 }).success).toBe(false);
|
|
22
|
+
expect(SetInputSchema.safeParse({ ...base, tempo: -1 }).success).toBe(false);
|
|
23
|
+
});
|
|
24
|
+
it('rejects a non-integer tempo', () => {
|
|
25
|
+
expect(SetInputSchema.safeParse({ ...base, tempo: 1.5 }).success).toBe(false);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -4,6 +4,12 @@ export declare enum SetTypeEnum {
|
|
|
4
4
|
DUMP = 1
|
|
5
5
|
}
|
|
6
6
|
export type SetType = SetTypeEnum.OVERHAND | SetTypeEnum.DUMP;
|
|
7
|
+
export declare enum SetTempoEnum {
|
|
8
|
+
FIRST = 0,
|
|
9
|
+
SECOND = 1,
|
|
10
|
+
HIGH = 2
|
|
11
|
+
}
|
|
12
|
+
export type SetTempo = SetTempoEnum.FIRST | SetTempoEnum.SECOND | SetTempoEnum.HIGH;
|
|
7
13
|
export declare enum SetFailureEnum {
|
|
8
14
|
NO_FAILURE = 0,
|
|
9
15
|
FAULT = 1,
|
|
@@ -15,6 +21,7 @@ export type SetFailure = SetFailureEnum.NO_FAILURE | SetFailureEnum.FAULT | SetF
|
|
|
15
21
|
export declare class Set extends InPlayEvent<SetFailure, SetType> {
|
|
16
22
|
readonly failure: SetFailure;
|
|
17
23
|
readonly type: SetType;
|
|
24
|
+
readonly tempo?: SetTempo;
|
|
18
25
|
static create(input: unknown): Set;
|
|
19
26
|
private constructor();
|
|
20
27
|
toString(): string;
|
|
@@ -6,6 +6,16 @@ export var SetTypeEnum;
|
|
|
6
6
|
SetTypeEnum[SetTypeEnum["OVERHAND"] = 0] = "OVERHAND";
|
|
7
7
|
SetTypeEnum[SetTypeEnum["DUMP"] = 1] = "DUMP";
|
|
8
8
|
})(SetTypeEnum || (SetTypeEnum = {}));
|
|
9
|
+
// The tempo of a set (set-tempo rework). Decided by the simulator (pass quality + target lane + setter skill)
|
|
10
|
+
// or forced by a per-player offensive preference. FIRST = quick (swings the `quick` stat, hardest to nail,
|
|
11
|
+
// hardest to block); SECOND = second tempo; HIGH = high ball (the fallback, easiest to block). Only present on
|
|
12
|
+
// a successful overhand set; absent for dumps, failed sets, and free-ball/scramble attacks.
|
|
13
|
+
export var SetTempoEnum;
|
|
14
|
+
(function (SetTempoEnum) {
|
|
15
|
+
SetTempoEnum[SetTempoEnum["FIRST"] = 0] = "FIRST";
|
|
16
|
+
SetTempoEnum[SetTempoEnum["SECOND"] = 1] = "SECOND";
|
|
17
|
+
SetTempoEnum[SetTempoEnum["HIGH"] = 2] = "HIGH";
|
|
18
|
+
})(SetTempoEnum || (SetTempoEnum = {}));
|
|
9
19
|
export var SetFailureEnum;
|
|
10
20
|
(function (SetFailureEnum) {
|
|
11
21
|
SetFailureEnum[SetFailureEnum["NO_FAILURE"] = 0] = "NO_FAILURE";
|
|
@@ -28,14 +38,16 @@ export class Set extends InPlayEvent {
|
|
|
28
38
|
}
|
|
29
39
|
return new Set(result.data);
|
|
30
40
|
}
|
|
31
|
-
constructor({ score, playerId, target, failure, type, activeTraits, incident }) {
|
|
41
|
+
constructor({ score, playerId, target, failure, type, activeTraits, incident, tempo }) {
|
|
32
42
|
super({ score, playerId, target, activeTraits, incident, eventType });
|
|
33
43
|
this.type = type;
|
|
34
44
|
this.failure = failure;
|
|
45
|
+
this.tempo = tempo;
|
|
35
46
|
}
|
|
36
47
|
toString() {
|
|
37
48
|
const failure = `"failure":${this.failure}`;
|
|
38
49
|
const type = `"type":${this.type}`;
|
|
39
|
-
|
|
50
|
+
const tempo = this.tempo !== undefined ? `,"tempo":${this.tempo}` : '';
|
|
51
|
+
return `{${this._toString()},${failure},${type}${tempo}}`;
|
|
40
52
|
}
|
|
41
53
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"matchResult": {
|
|
3
|
+
"title": "Match result",
|
|
4
|
+
"wonNamed": "You won against {{opponent}}",
|
|
5
|
+
"wonUnnamed": "You won your match",
|
|
6
|
+
"lostNamed": "You lost against {{opponent}}",
|
|
7
|
+
"lostUnnamed": "You lost your match"
|
|
8
|
+
},
|
|
9
|
+
"injury": {
|
|
10
|
+
"title": "Player injured",
|
|
11
|
+
"body": "{{name}} has been injured during the last match. Check the infirmary for their recovery time."
|
|
12
|
+
},
|
|
13
|
+
"injuryRecovered": {
|
|
14
|
+
"title": "Player recovered",
|
|
15
|
+
"body": "{{name}} has recovered from their injury and is ready to play!"
|
|
16
|
+
},
|
|
17
|
+
"seasonEnd": {
|
|
18
|
+
"title": "Season complete",
|
|
19
|
+
"body": "Your final league position is ready."
|
|
20
|
+
},
|
|
21
|
+
"grant": {
|
|
22
|
+
"title": "Recruit received",
|
|
23
|
+
"body": "A new recruit reward is available."
|
|
24
|
+
},
|
|
25
|
+
"promotion": {
|
|
26
|
+
"title": "Promotion",
|
|
27
|
+
"body": "Your team has been promoted to a higher division."
|
|
28
|
+
},
|
|
29
|
+
"dailyLogin": {
|
|
30
|
+
"title": "Daily reward claimed",
|
|
31
|
+
"body": "Your daily login reward was added."
|
|
32
|
+
},
|
|
33
|
+
"welcome": {
|
|
34
|
+
"title": "Welcome to World Aces",
|
|
35
|
+
"body": "Your welcome recruit is ready."
|
|
36
|
+
},
|
|
37
|
+
"generic": {
|
|
38
|
+
"title": "World Aces",
|
|
39
|
+
"body": "You have a new notification."
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"matchResult": {
|
|
3
|
+
"title": "Resultado del partido",
|
|
4
|
+
"wonNamed": "Ganaste contra {{opponent}}",
|
|
5
|
+
"wonUnnamed": "Ganaste tu partido",
|
|
6
|
+
"lostNamed": "Perdiste contra {{opponent}}",
|
|
7
|
+
"lostUnnamed": "Perdiste tu partido"
|
|
8
|
+
},
|
|
9
|
+
"injury": {
|
|
10
|
+
"title": "Jugador lesionado",
|
|
11
|
+
"body": "{{name}} se ha lesionado durante el último partido. Consulta la enfermería para ver su tiempo de recuperación."
|
|
12
|
+
},
|
|
13
|
+
"injuryRecovered": {
|
|
14
|
+
"title": "Jugador recuperado",
|
|
15
|
+
"body": "¡{{name}} se ha recuperado de su lesión y está listo para jugar!"
|
|
16
|
+
},
|
|
17
|
+
"seasonEnd": {
|
|
18
|
+
"title": "Temporada completada",
|
|
19
|
+
"body": "Tu posición final en la liga está lista."
|
|
20
|
+
},
|
|
21
|
+
"grant": {
|
|
22
|
+
"title": "Reclutamiento recibido",
|
|
23
|
+
"body": "Hay una nueva recompensa de reclutamiento disponible."
|
|
24
|
+
},
|
|
25
|
+
"promotion": {
|
|
26
|
+
"title": "Ascenso",
|
|
27
|
+
"body": "Tu equipo ha ascendido a una división superior."
|
|
28
|
+
},
|
|
29
|
+
"dailyLogin": {
|
|
30
|
+
"title": "Recompensa diaria reclamada",
|
|
31
|
+
"body": "Tu recompensa por inicio de sesión diario se ha añadido."
|
|
32
|
+
},
|
|
33
|
+
"welcome": {
|
|
34
|
+
"title": "Te damos la bienvenida a World Aces",
|
|
35
|
+
"body": "Tu reclutamiento de bienvenida ya está disponible."
|
|
36
|
+
},
|
|
37
|
+
"generic": {
|
|
38
|
+
"title": "World Aces",
|
|
39
|
+
"body": "Tienes una nueva notificación."
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"matchResult": {
|
|
3
|
+
"title": "Résultat du match",
|
|
4
|
+
"wonNamed": "Vous avez gagné contre {{opponent}}",
|
|
5
|
+
"wonUnnamed": "Vous avez gagné votre match",
|
|
6
|
+
"lostNamed": "Vous avez perdu contre {{opponent}}",
|
|
7
|
+
"lostUnnamed": "Vous avez perdu votre match"
|
|
8
|
+
},
|
|
9
|
+
"injury": {
|
|
10
|
+
"title": "Joueur blessé",
|
|
11
|
+
"body": "{{name}} s'est blessé lors du dernier match. Consultez l'infirmerie pour connaître son temps de récupération."
|
|
12
|
+
},
|
|
13
|
+
"injuryRecovered": {
|
|
14
|
+
"title": "Joueur rétabli",
|
|
15
|
+
"body": "{{name}} est remis de sa blessure et est prêt à jouer !"
|
|
16
|
+
},
|
|
17
|
+
"seasonEnd": {
|
|
18
|
+
"title": "Saison terminée",
|
|
19
|
+
"body": "Votre classement final dans la ligue est disponible."
|
|
20
|
+
},
|
|
21
|
+
"grant": {
|
|
22
|
+
"title": "Recrutement reçu",
|
|
23
|
+
"body": "Une nouvelle récompense de recrutement est disponible."
|
|
24
|
+
},
|
|
25
|
+
"promotion": {
|
|
26
|
+
"title": "Promotion",
|
|
27
|
+
"body": "Votre équipe a été promue dans une division supérieure."
|
|
28
|
+
},
|
|
29
|
+
"dailyLogin": {
|
|
30
|
+
"title": "Récompense quotidienne récupérée",
|
|
31
|
+
"body": "Votre récompense de connexion quotidienne a été ajoutée."
|
|
32
|
+
},
|
|
33
|
+
"welcome": {
|
|
34
|
+
"title": "Bienvenue sur World Aces",
|
|
35
|
+
"body": "Votre recrutement de bienvenue est prêt."
|
|
36
|
+
},
|
|
37
|
+
"generic": {
|
|
38
|
+
"title": "World Aces",
|
|
39
|
+
"body": "Vous avez une nouvelle notification."
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import en from './en.json';
|
|
2
|
+
import es from './es.json';
|
|
3
|
+
import fr from './fr.json';
|
|
4
|
+
import it from './it.json';
|
|
5
|
+
import pl from './pl.json';
|
|
6
|
+
import ptBR from './pt-BR.json';
|
|
7
|
+
import tr from './tr.json';
|
|
8
|
+
export const NOTIFICATION_CATALOG = {
|
|
9
|
+
en,
|
|
10
|
+
es,
|
|
11
|
+
fr,
|
|
12
|
+
it,
|
|
13
|
+
pl,
|
|
14
|
+
'pt-BR': ptBR,
|
|
15
|
+
tr
|
|
16
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"matchResult": {
|
|
3
|
+
"title": "Risultato della partita",
|
|
4
|
+
"wonNamed": "Hai vinto contro {{opponent}}",
|
|
5
|
+
"wonUnnamed": "Hai vinto la partita",
|
|
6
|
+
"lostNamed": "Hai perso contro {{opponent}}",
|
|
7
|
+
"lostUnnamed": "Hai perso la partita"
|
|
8
|
+
},
|
|
9
|
+
"injury": {
|
|
10
|
+
"title": "Giocatore infortunato",
|
|
11
|
+
"body": "{{name}} si è infortunato durante l'ultima partita. Controlla l'infermeria per conoscere i suoi tempi di recupero."
|
|
12
|
+
},
|
|
13
|
+
"injuryRecovered": {
|
|
14
|
+
"title": "Giocatore recuperato",
|
|
15
|
+
"body": "{{name}} si è ripreso dall'infortunio ed è pronto a giocare!"
|
|
16
|
+
},
|
|
17
|
+
"seasonEnd": {
|
|
18
|
+
"title": "Stagione completata",
|
|
19
|
+
"body": "La tua posizione finale in campionato è pronta."
|
|
20
|
+
},
|
|
21
|
+
"grant": {
|
|
22
|
+
"title": "Reclutamento ricevuto",
|
|
23
|
+
"body": "È disponibile una nuova ricompensa di reclutamento."
|
|
24
|
+
},
|
|
25
|
+
"promotion": {
|
|
26
|
+
"title": "Promozione",
|
|
27
|
+
"body": "La tua squadra è stata promossa in una divisione superiore."
|
|
28
|
+
},
|
|
29
|
+
"dailyLogin": {
|
|
30
|
+
"title": "Ricompensa giornaliera riscattata",
|
|
31
|
+
"body": "La tua ricompensa di accesso giornaliero è stata aggiunta."
|
|
32
|
+
},
|
|
33
|
+
"welcome": {
|
|
34
|
+
"title": "Benvenuto in World Aces",
|
|
35
|
+
"body": "La tua recluta di benvenuto è pronta."
|
|
36
|
+
},
|
|
37
|
+
"generic": {
|
|
38
|
+
"title": "World Aces",
|
|
39
|
+
"body": "Hai una nuova notifica."
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"matchResult": {
|
|
3
|
+
"title": "Wynik meczu",
|
|
4
|
+
"wonNamed": "Wygrana z {{opponent}}",
|
|
5
|
+
"wonUnnamed": "Wygrana w meczu",
|
|
6
|
+
"lostNamed": "Porażka z {{opponent}}",
|
|
7
|
+
"lostUnnamed": "Porażka w meczu"
|
|
8
|
+
},
|
|
9
|
+
"injury": {
|
|
10
|
+
"title": "Zawodnik kontuzjowany",
|
|
11
|
+
"body": "{{name}} doznał kontuzji w ostatnim meczu. Sprawdź ambulatorium, aby poznać czas powrotu do zdrowia."
|
|
12
|
+
},
|
|
13
|
+
"injuryRecovered": {
|
|
14
|
+
"title": "Zawodnik wyzdrowiał",
|
|
15
|
+
"body": "{{name}} wrócił do zdrowia po kontuzji i jest gotowy do gry!"
|
|
16
|
+
},
|
|
17
|
+
"seasonEnd": {
|
|
18
|
+
"title": "Sezon zakończony",
|
|
19
|
+
"body": "Twoja końcowa pozycja w lidze jest gotowa."
|
|
20
|
+
},
|
|
21
|
+
"grant": {
|
|
22
|
+
"title": "Otrzymano rekrutację",
|
|
23
|
+
"body": "Dostępna jest nowa nagroda rekrutacyjna."
|
|
24
|
+
},
|
|
25
|
+
"promotion": {
|
|
26
|
+
"title": "Awans",
|
|
27
|
+
"body": "Twoja drużyna awansowała do wyższej dywizji."
|
|
28
|
+
},
|
|
29
|
+
"dailyLogin": {
|
|
30
|
+
"title": "Odebrano codzienną nagrodę",
|
|
31
|
+
"body": "Twoja codzienna nagroda za logowanie została dodana."
|
|
32
|
+
},
|
|
33
|
+
"welcome": {
|
|
34
|
+
"title": "Witaj w World Aces",
|
|
35
|
+
"body": "Twoja powitalna rekrutacja jest gotowa."
|
|
36
|
+
},
|
|
37
|
+
"generic": {
|
|
38
|
+
"title": "World Aces",
|
|
39
|
+
"body": "Masz nowe powiadomienie."
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"matchResult": {
|
|
3
|
+
"title": "Resultado da partida",
|
|
4
|
+
"wonNamed": "Você venceu {{opponent}}",
|
|
5
|
+
"wonUnnamed": "Você venceu sua partida",
|
|
6
|
+
"lostNamed": "Você perdeu para {{opponent}}",
|
|
7
|
+
"lostUnnamed": "Você perdeu sua partida"
|
|
8
|
+
},
|
|
9
|
+
"injury": {
|
|
10
|
+
"title": "Jogador lesionado",
|
|
11
|
+
"body": "{{name}} se lesionou durante a última partida. Confira a enfermaria para ver o tempo de recuperação."
|
|
12
|
+
},
|
|
13
|
+
"injuryRecovered": {
|
|
14
|
+
"title": "Jogador recuperado",
|
|
15
|
+
"body": "{{name}} se recuperou da lesão e está pronto para jogar!"
|
|
16
|
+
},
|
|
17
|
+
"seasonEnd": {
|
|
18
|
+
"title": "Temporada concluída",
|
|
19
|
+
"body": "Sua colocação final na liga já está disponível."
|
|
20
|
+
},
|
|
21
|
+
"grant": {
|
|
22
|
+
"title": "Recrutamento recebido",
|
|
23
|
+
"body": "Uma nova recompensa de recrutamento está disponível."
|
|
24
|
+
},
|
|
25
|
+
"promotion": {
|
|
26
|
+
"title": "Promoção",
|
|
27
|
+
"body": "Seu time foi promovido para uma divisão superior."
|
|
28
|
+
},
|
|
29
|
+
"dailyLogin": {
|
|
30
|
+
"title": "Recompensa diária coletada",
|
|
31
|
+
"body": "Sua recompensa de login diário foi adicionada."
|
|
32
|
+
},
|
|
33
|
+
"welcome": {
|
|
34
|
+
"title": "Boas-vindas ao World Aces",
|
|
35
|
+
"body": "Seu recrutamento de boas-vindas está pronto."
|
|
36
|
+
},
|
|
37
|
+
"generic": {
|
|
38
|
+
"title": "World Aces",
|
|
39
|
+
"body": "Você tem uma nova notificação."
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"matchResult": {
|
|
3
|
+
"title": "Maç sonucu",
|
|
4
|
+
"wonNamed": "{{opponent}} karşısında kazandın",
|
|
5
|
+
"wonUnnamed": "Maçını kazandın",
|
|
6
|
+
"lostNamed": "{{opponent}} karşısında kaybettin",
|
|
7
|
+
"lostUnnamed": "Maçını kaybettin"
|
|
8
|
+
},
|
|
9
|
+
"injury": {
|
|
10
|
+
"title": "Oyuncu sakatlandı",
|
|
11
|
+
"body": "{{name}} son maçta sakatlandı. İyileşme süresini görmek için reviri kontrol edin."
|
|
12
|
+
},
|
|
13
|
+
"injuryRecovered": {
|
|
14
|
+
"title": "Oyuncu iyileşti",
|
|
15
|
+
"body": "{{name}} sakatlığını atlattı ve oynamaya hazır!"
|
|
16
|
+
},
|
|
17
|
+
"seasonEnd": {
|
|
18
|
+
"title": "Sezon tamamlandı",
|
|
19
|
+
"body": "Ligdeki nihai sıralaman hazır."
|
|
20
|
+
},
|
|
21
|
+
"grant": {
|
|
22
|
+
"title": "Transfer alındı",
|
|
23
|
+
"body": "Yeni bir transfer ödülü mevcut."
|
|
24
|
+
},
|
|
25
|
+
"promotion": {
|
|
26
|
+
"title": "Terfi",
|
|
27
|
+
"body": "Takımın bir üst gruba terfi etti."
|
|
28
|
+
},
|
|
29
|
+
"dailyLogin": {
|
|
30
|
+
"title": "Günlük ödül alındı",
|
|
31
|
+
"body": "Günlük giriş ödülün eklendi."
|
|
32
|
+
},
|
|
33
|
+
"welcome": {
|
|
34
|
+
"title": "World Aces'e hoş geldin",
|
|
35
|
+
"body": "Hoş geldin transferin hazır."
|
|
36
|
+
},
|
|
37
|
+
"generic": {
|
|
38
|
+
"title": "World Aces",
|
|
39
|
+
"body": "Yeni bir bildirimin var."
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const NOTIFICATION_TYPES: readonly ["MATCH_RESULT", "INJURY", "INJURY_RECOVERED", "SEASON_END", "GRANT_RECEIVED", "PROMOTION", "DAILY_LOGIN", "WELCOME", "COMPENSATION"];
|
|
2
|
+
export type NotificationType = typeof NOTIFICATION_TYPES[number];
|
|
3
|
+
export declare const NOTIFICATION_LOCALES: readonly ["en", "es", "fr", "it", "pl", "pt-BR", "tr"];
|
|
4
|
+
export type NotificationLocale = typeof NOTIFICATION_LOCALES[number];
|
|
5
|
+
export declare const DEFAULT_NOTIFICATION_LOCALE: NotificationLocale;
|
|
6
|
+
export declare function normalizeNotificationLocale(locale: string | null | undefined): NotificationLocale;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Single source of truth for the set of notification types and the locales the catalog ships.
|
|
2
|
+
// Adding a notification type: add it here, add a NOTIFICATION_REGISTRY entry, and add its catalog
|
|
3
|
+
// strings to every locale file. The completeness test (notification.test.ts) fails the build if any
|
|
4
|
+
// of those three is missing. See README.md in this folder.
|
|
5
|
+
export const NOTIFICATION_TYPES = [
|
|
6
|
+
'MATCH_RESULT',
|
|
7
|
+
'INJURY',
|
|
8
|
+
'INJURY_RECOVERED',
|
|
9
|
+
'SEASON_END',
|
|
10
|
+
'GRANT_RECEIVED',
|
|
11
|
+
'PROMOTION',
|
|
12
|
+
'DAILY_LOGIN',
|
|
13
|
+
'WELCOME',
|
|
14
|
+
'COMPENSATION'
|
|
15
|
+
];
|
|
16
|
+
// The 7 supported locales. Must stay in sync with the API VALID_LOCALES set and the UI src/locales/*.json.
|
|
17
|
+
export const NOTIFICATION_LOCALES = ['en', 'es', 'fr', 'it', 'pl', 'pt-BR', 'tr'];
|
|
18
|
+
export const DEFAULT_NOTIFICATION_LOCALE = 'en';
|
|
19
|
+
// Coalesce an arbitrary/untrusted locale string (e.g. UserSettings.locale, which is nullable) to a
|
|
20
|
+
// supported locale, defaulting to English. Push senders MUST call this before renderPush.
|
|
21
|
+
export function normalizeNotificationLocale(locale) {
|
|
22
|
+
if (locale != null && NOTIFICATION_LOCALES.includes(locale)) {
|
|
23
|
+
return locale;
|
|
24
|
+
}
|
|
25
|
+
return DEFAULT_NOTIFICATION_LOCALE;
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|