volleyballsimtypes 0.0.470 → 0.0.471
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/data/transformers/rally-event-injury.test.js +52 -0
- package/dist/cjs/src/data/transformers/rally-event.d.ts +1 -0
- package/dist/cjs/src/data/transformers/rally-event.js +24 -5
- package/dist/cjs/src/service/event/block.js +2 -2
- package/dist/cjs/src/service/event/in-play-event.d.ts +7 -1
- package/dist/cjs/src/service/event/in-play-event.js +2 -1
- package/dist/cjs/src/service/event/reception.js +2 -2
- package/dist/cjs/src/service/event/schemas/block.z.d.ts +7 -0
- package/dist/cjs/src/service/event/schemas/block.z.js +3 -1
- package/dist/cjs/src/service/event/schemas/incident.z.d.ts +9 -0
- package/dist/cjs/src/service/event/schemas/incident.z.js +11 -0
- package/dist/cjs/src/service/event/schemas/reception.z.d.ts +7 -0
- package/dist/cjs/src/service/event/schemas/reception.z.js +3 -1
- package/dist/cjs/src/service/event/schemas/serve.z.d.ts +7 -0
- package/dist/cjs/src/service/event/schemas/serve.z.js +3 -1
- package/dist/cjs/src/service/event/schemas/set.z.d.ts +7 -0
- package/dist/cjs/src/service/event/schemas/set.z.js +3 -1
- package/dist/cjs/src/service/event/schemas/spike.z.d.ts +7 -0
- package/dist/cjs/src/service/event/schemas/spike.z.js +3 -1
- package/dist/cjs/src/service/event/serve.js +2 -2
- package/dist/cjs/src/service/event/set.js +2 -2
- package/dist/cjs/src/service/event/spike.js +2 -2
- package/dist/esm/src/data/transformers/rally-event-injury.test.js +54 -2
- package/dist/esm/src/data/transformers/rally-event.d.ts +1 -0
- package/dist/esm/src/data/transformers/rally-event.js +24 -5
- package/dist/esm/src/service/event/block.js +2 -2
- package/dist/esm/src/service/event/in-play-event.d.ts +7 -1
- package/dist/esm/src/service/event/in-play-event.js +2 -1
- package/dist/esm/src/service/event/reception.js +2 -2
- package/dist/esm/src/service/event/schemas/block.z.d.ts +7 -0
- package/dist/esm/src/service/event/schemas/block.z.js +3 -1
- package/dist/esm/src/service/event/schemas/incident.z.d.ts +9 -0
- package/dist/esm/src/service/event/schemas/incident.z.js +8 -0
- package/dist/esm/src/service/event/schemas/reception.z.d.ts +7 -0
- package/dist/esm/src/service/event/schemas/reception.z.js +3 -1
- package/dist/esm/src/service/event/schemas/serve.z.d.ts +7 -0
- package/dist/esm/src/service/event/schemas/serve.z.js +3 -1
- package/dist/esm/src/service/event/schemas/set.z.d.ts +7 -0
- package/dist/esm/src/service/event/schemas/set.z.js +3 -1
- package/dist/esm/src/service/event/schemas/spike.z.d.ts +7 -0
- package/dist/esm/src/service/event/schemas/spike.z.js +3 -1
- package/dist/esm/src/service/event/serve.js +2 -2
- package/dist/esm/src/service/event/set.js +2 -2
- package/dist/esm/src/service/event/spike.js +2 -2
- package/package.json +1 -1
|
@@ -31,3 +31,55 @@ const rally_event_1 = require("./rally-event");
|
|
|
31
31
|
(0, globals_1.expect)(decoded.injury).toBeUndefined();
|
|
32
32
|
});
|
|
33
33
|
});
|
|
34
|
+
(0, globals_1.describe)('rally-event compact round trip — incident marker on the causing event', () => {
|
|
35
|
+
const playerId = (0, uuid_1.v4)();
|
|
36
|
+
const roster = [playerId];
|
|
37
|
+
const playerIndex = new Map(roster.map((id, i) => [id, i]));
|
|
38
|
+
function makeSpike(incident) {
|
|
39
|
+
return service_1.Spike.create({
|
|
40
|
+
playerId,
|
|
41
|
+
score: 62.5,
|
|
42
|
+
target: 4,
|
|
43
|
+
failure: service_1.SpikeFailureEnum.NO_FAILURE,
|
|
44
|
+
type: service_1.SpikeTypeEnum.CROSS_SHOT,
|
|
45
|
+
...(incident != null ? { incident } : {})
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
(0, globals_1.it)('packs an INJURY incident as i = severity (1-4) and round-trips kind + severity', () => {
|
|
49
|
+
const compact = (0, rally_event_1.transformToCompact)(makeSpike({ kind: 'INJURY', severity: 4 }), playerIndex);
|
|
50
|
+
(0, globals_1.expect)(compact.i).toBe(4);
|
|
51
|
+
const decoded = (0, rally_event_1.transformToSpike)(compact, roster);
|
|
52
|
+
(0, globals_1.expect)(decoded.incident).toEqual({ kind: 'INJURY', severity: 4 });
|
|
53
|
+
});
|
|
54
|
+
(0, globals_1.it)('packs a KNOCK incident as i = 10 + tier and round-trips kind + severity', () => {
|
|
55
|
+
const serve = service_1.Serve.create({
|
|
56
|
+
playerId,
|
|
57
|
+
score: 55,
|
|
58
|
+
target: 6,
|
|
59
|
+
failure: service_1.ServeFailureEnum.NO_FAILURE,
|
|
60
|
+
type: service_1.ServeTypeEnum.JUMP_TOPSPIN,
|
|
61
|
+
incident: { kind: 'KNOCK', severity: 2 }
|
|
62
|
+
});
|
|
63
|
+
const compact = (0, rally_event_1.transformToCompact)(serve, playerIndex);
|
|
64
|
+
(0, globals_1.expect)(compact.i).toBe(12);
|
|
65
|
+
const decoded = (0, rally_event_1.transformToServe)(compact, roster);
|
|
66
|
+
(0, globals_1.expect)(decoded.incident).toEqual({ kind: 'KNOCK', severity: 2 });
|
|
67
|
+
});
|
|
68
|
+
(0, globals_1.it)('omits i entirely for an event without an incident', () => {
|
|
69
|
+
const compact = (0, rally_event_1.transformToCompact)(makeSpike(), playerIndex);
|
|
70
|
+
(0, globals_1.expect)('i' in compact).toBe(false);
|
|
71
|
+
const decoded = (0, rally_event_1.transformToSpike)(compact, roster);
|
|
72
|
+
(0, globals_1.expect)(decoded.incident).toBeUndefined();
|
|
73
|
+
});
|
|
74
|
+
(0, globals_1.it)('decodes a legacy compact event (no i key) with no incident', () => {
|
|
75
|
+
const legacy = { p: 0, e: service_1.EventTypeEnum.SPIKE, f: 0, t: 0, a: 4, s: 50 };
|
|
76
|
+
const decoded = (0, rally_event_1.transformToSpike)(legacy, roster);
|
|
77
|
+
(0, globals_1.expect)(decoded.incident).toBeUndefined();
|
|
78
|
+
});
|
|
79
|
+
(0, globals_1.it)('rejects an out-of-range or malformed incident at the schema', () => {
|
|
80
|
+
(0, globals_1.expect)(() => makeSpike({ kind: 'INJURY', severity: 5 })).toThrow(/INVALID_SPIKE/);
|
|
81
|
+
(0, globals_1.expect)(() => makeSpike({ kind: 'INJURY', severity: 0 })).toThrow(/INVALID_SPIKE/);
|
|
82
|
+
(0, globals_1.expect)(() => makeSpike({ kind: 'KNOCK', severity: 4 })).toThrow(/INVALID_SPIKE/);
|
|
83
|
+
(0, globals_1.expect)(() => makeSpike({ kind: 'BRUISE', severity: 1 })).toThrow(/INVALID_SPIKE/);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
@@ -10,6 +10,7 @@ export interface CompactEvent {
|
|
|
10
10
|
l?: number;
|
|
11
11
|
o?: number;
|
|
12
12
|
j?: number;
|
|
13
|
+
i?: number;
|
|
13
14
|
}
|
|
14
15
|
export declare function transformToCompact(evt: RallyEvent, playerIndex: Map<string, number>): CompactEvent;
|
|
15
16
|
export declare function transformToBlock(event: CompactEvent, roster: string[]): Block;
|
|
@@ -9,6 +9,17 @@ exports.transformToSet = transformToSet;
|
|
|
9
9
|
exports.transformToSpike = transformToSpike;
|
|
10
10
|
exports.transformToSubstitution = transformToSubstitution;
|
|
11
11
|
const service_1 = require("../../service");
|
|
12
|
+
// Incident packing for the compact key 'i': values below 10 are injury severities, 10+ are knock tiers.
|
|
13
|
+
function incidentToCompact(incident) {
|
|
14
|
+
if (incident == null)
|
|
15
|
+
return undefined;
|
|
16
|
+
return incident.kind === 'KNOCK' ? 10 + incident.severity : incident.severity;
|
|
17
|
+
}
|
|
18
|
+
function incidentFromCompact(i) {
|
|
19
|
+
if (i == null)
|
|
20
|
+
return undefined;
|
|
21
|
+
return i >= 10 ? { kind: 'KNOCK', severity: i - 10 } : { kind: 'INJURY', severity: i };
|
|
22
|
+
}
|
|
12
23
|
function transformToCompact(evt, playerIndex) {
|
|
13
24
|
const out = {
|
|
14
25
|
p: playerIndex.get(evt.playerId),
|
|
@@ -19,6 +30,9 @@ function transformToCompact(evt, playerIndex) {
|
|
|
19
30
|
out.t = evt.type;
|
|
20
31
|
out.a = evt.target;
|
|
21
32
|
out.s = evt.score;
|
|
33
|
+
const i = incidentToCompact(evt.incident);
|
|
34
|
+
if (i != null)
|
|
35
|
+
out.i = i;
|
|
22
36
|
if (evt instanceof service_1.Block) {
|
|
23
37
|
out.b = evt.blockers.map(id => playerIndex.get(id));
|
|
24
38
|
}
|
|
@@ -41,7 +55,8 @@ function transformToBlock(event, roster) {
|
|
|
41
55
|
playerId: roster[event.p],
|
|
42
56
|
target: event.a,
|
|
43
57
|
blockers: (event.b ?? []).map(i => roster[i]),
|
|
44
|
-
score: event.s
|
|
58
|
+
score: event.s,
|
|
59
|
+
incident: incidentFromCompact(event.i)
|
|
45
60
|
});
|
|
46
61
|
}
|
|
47
62
|
function transformToLiberoReplacement(event, roster) {
|
|
@@ -57,7 +72,8 @@ function transformToReception(event, roster) {
|
|
|
57
72
|
type: event.t,
|
|
58
73
|
playerId: roster[event.p],
|
|
59
74
|
target: event.a,
|
|
60
|
-
score: event.s
|
|
75
|
+
score: event.s,
|
|
76
|
+
incident: incidentFromCompact(event.i)
|
|
61
77
|
});
|
|
62
78
|
}
|
|
63
79
|
function transformToServe(event, roster) {
|
|
@@ -66,7 +82,8 @@ function transformToServe(event, roster) {
|
|
|
66
82
|
type: event.t,
|
|
67
83
|
playerId: roster[event.p],
|
|
68
84
|
target: event.a,
|
|
69
|
-
score: event.s
|
|
85
|
+
score: event.s,
|
|
86
|
+
incident: incidentFromCompact(event.i)
|
|
70
87
|
});
|
|
71
88
|
}
|
|
72
89
|
function transformToSet(event, roster) {
|
|
@@ -75,7 +92,8 @@ function transformToSet(event, roster) {
|
|
|
75
92
|
type: event.t,
|
|
76
93
|
playerId: roster[event.p],
|
|
77
94
|
target: event.a,
|
|
78
|
-
score: event.s
|
|
95
|
+
score: event.s,
|
|
96
|
+
incident: incidentFromCompact(event.i)
|
|
79
97
|
});
|
|
80
98
|
}
|
|
81
99
|
function transformToSpike(event, roster) {
|
|
@@ -84,7 +102,8 @@ function transformToSpike(event, roster) {
|
|
|
84
102
|
type: event.t,
|
|
85
103
|
playerId: roster[event.p],
|
|
86
104
|
target: event.a,
|
|
87
|
-
score: event.s
|
|
105
|
+
score: event.s,
|
|
106
|
+
incident: incidentFromCompact(event.i)
|
|
88
107
|
});
|
|
89
108
|
}
|
|
90
109
|
function transformToSubstitution(event, roster) {
|
|
@@ -34,8 +34,8 @@ class Block extends in_play_event_1.InPlayEvent {
|
|
|
34
34
|
}
|
|
35
35
|
return new Block(result.data);
|
|
36
36
|
}
|
|
37
|
-
constructor({ score, playerId, target, failure, type, blockers, activeTraits }) {
|
|
38
|
-
super({ score, playerId, target, activeTraits, eventType });
|
|
37
|
+
constructor({ score, playerId, target, failure, type, blockers, activeTraits, incident }) {
|
|
38
|
+
super({ score, playerId, target, activeTraits, incident, eventType });
|
|
39
39
|
this.type = type;
|
|
40
40
|
this.failure = failure;
|
|
41
41
|
this.blockers = blockers;
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { CourtTarget } from '../match';
|
|
2
2
|
import { RallyEvent, RallyEventOpts } from './rally-event';
|
|
3
3
|
import { Trait } from '../player';
|
|
4
|
+
export interface EventIncident {
|
|
5
|
+
readonly kind: 'KNOCK' | 'INJURY';
|
|
6
|
+
readonly severity: number;
|
|
7
|
+
}
|
|
4
8
|
export interface InPlayEventOpts extends RallyEventOpts {
|
|
5
9
|
readonly target: CourtTarget;
|
|
6
10
|
readonly score: number;
|
|
7
11
|
readonly activeTraits: Trait[];
|
|
12
|
+
readonly incident?: EventIncident;
|
|
8
13
|
}
|
|
9
14
|
export declare abstract class InPlayEvent<F, T> extends RallyEvent {
|
|
10
15
|
abstract failure: F;
|
|
@@ -12,6 +17,7 @@ export declare abstract class InPlayEvent<F, T> extends RallyEvent {
|
|
|
12
17
|
readonly target: CourtTarget;
|
|
13
18
|
readonly score: number;
|
|
14
19
|
readonly activeTraits: Trait[];
|
|
15
|
-
|
|
20
|
+
readonly incident?: EventIncident;
|
|
21
|
+
protected constructor({ eventType, playerId, target, score, activeTraits, incident }: InPlayEventOpts);
|
|
16
22
|
protected _toString(): string;
|
|
17
23
|
}
|
|
@@ -3,11 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.InPlayEvent = void 0;
|
|
4
4
|
const rally_event_1 = require("./rally-event");
|
|
5
5
|
class InPlayEvent extends rally_event_1.RallyEvent {
|
|
6
|
-
constructor({ eventType, playerId, target, score, activeTraits }) {
|
|
6
|
+
constructor({ eventType, playerId, target, score, activeTraits, incident }) {
|
|
7
7
|
super({ playerId, eventType });
|
|
8
8
|
this.target = target;
|
|
9
9
|
this.score = Number(score.toFixed(2));
|
|
10
10
|
this.activeTraits = activeTraits;
|
|
11
|
+
this.incident = incident;
|
|
11
12
|
}
|
|
12
13
|
_toString() {
|
|
13
14
|
const score = `"score":${this.score}`;
|
|
@@ -36,8 +36,8 @@ class Reception extends in_play_event_1.InPlayEvent {
|
|
|
36
36
|
}
|
|
37
37
|
return new Reception(result.data);
|
|
38
38
|
}
|
|
39
|
-
constructor({ score, playerId, target, failure, type, activeTraits }) {
|
|
40
|
-
super({ score, playerId, target, activeTraits, eventType });
|
|
39
|
+
constructor({ score, playerId, target, failure, type, activeTraits, incident }) {
|
|
40
|
+
super({ score, playerId, target, activeTraits, incident, eventType });
|
|
41
41
|
this.type = type;
|
|
42
42
|
this.failure = failure;
|
|
43
43
|
}
|
|
@@ -27,5 +27,12 @@ export declare const BlockInputSchema: z.ZodObject<{
|
|
|
27
27
|
failure: z.ZodNumber;
|
|
28
28
|
type: z.ZodNumber;
|
|
29
29
|
blockers: z.ZodArray<z.ZodUUID>;
|
|
30
|
+
incident: z.ZodOptional<z.ZodObject<{
|
|
31
|
+
kind: z.ZodEnum<{
|
|
32
|
+
KNOCK: "KNOCK";
|
|
33
|
+
INJURY: "INJURY";
|
|
34
|
+
}>;
|
|
35
|
+
severity: z.ZodNumber;
|
|
36
|
+
}, z.core.$strip>>;
|
|
30
37
|
}, z.core.$strip>;
|
|
31
38
|
export type BlockInput = z.infer<typeof BlockInputSchema>;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.BlockInputSchema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const player_1 = require("../../player");
|
|
6
|
+
const incident_z_1 = require("./incident.z");
|
|
6
7
|
const blockTypeValues = [0, 1, 2, 3];
|
|
7
8
|
const blockFailureValues = [0, 1, 2, 3, 4, 5];
|
|
8
9
|
const courtTargetValues = Array.from({ length: 13 }, (_, i) => i);
|
|
@@ -13,7 +14,8 @@ exports.BlockInputSchema = zod_1.z.object({
|
|
|
13
14
|
activeTraits: zod_1.z.array(zod_1.z.enum(Object.values(player_1.TraitEnum))).default([]),
|
|
14
15
|
failure: zod_1.z.number().int().refine((v) => blockFailureValues.includes(v), { message: 'INVALID_BLOCK_FAILURE' }),
|
|
15
16
|
type: zod_1.z.number().int().refine((v) => blockTypeValues.includes(v), { message: 'INVALID_BLOCK_TYPE' }),
|
|
16
|
-
blockers: zod_1.z.array(zod_1.z.uuid())
|
|
17
|
+
blockers: zod_1.z.array(zod_1.z.uuid()),
|
|
18
|
+
incident: incident_z_1.EventIncidentSchema.optional()
|
|
17
19
|
}).superRefine((data, ctx) => {
|
|
18
20
|
// The block type IS the blocker count (NO_BLOCKER=0, SINGLE=1, DOUBLE=2, TRIPLE=3), so the two must agree.
|
|
19
21
|
if (data.blockers.length !== data.type) {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const EventIncidentSchema: z.ZodObject<{
|
|
3
|
+
kind: z.ZodEnum<{
|
|
4
|
+
KNOCK: "KNOCK";
|
|
5
|
+
INJURY: "INJURY";
|
|
6
|
+
}>;
|
|
7
|
+
severity: z.ZodNumber;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
export type EventIncidentInput = z.infer<typeof EventIncidentSchema>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EventIncidentSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
// The moment a player got hurt, attached to the causing in-play event (owner 2026-07-05: EVERY knock and
|
|
6
|
+
// injury marks the action that produced it). KNOCK severity is the knock tier (1-3); INJURY severity is the
|
|
7
|
+
// InjurySeverityEnum value (1-4).
|
|
8
|
+
exports.EventIncidentSchema = zod_1.z.object({
|
|
9
|
+
kind: zod_1.z.enum(['KNOCK', 'INJURY']),
|
|
10
|
+
severity: zod_1.z.number().int().min(1).max(4)
|
|
11
|
+
}).refine(v => v.kind !== 'KNOCK' || v.severity <= 3, { message: 'INVALID_KNOCK_TIER' });
|
|
@@ -26,5 +26,12 @@ export declare const ReceptionInputSchema: z.ZodObject<{
|
|
|
26
26
|
}>>>;
|
|
27
27
|
failure: z.ZodNumber;
|
|
28
28
|
type: z.ZodNumber;
|
|
29
|
+
incident: z.ZodOptional<z.ZodObject<{
|
|
30
|
+
kind: z.ZodEnum<{
|
|
31
|
+
KNOCK: "KNOCK";
|
|
32
|
+
INJURY: "INJURY";
|
|
33
|
+
}>;
|
|
34
|
+
severity: z.ZodNumber;
|
|
35
|
+
}, z.core.$strip>>;
|
|
29
36
|
}, z.core.$strip>;
|
|
30
37
|
export type ReceptionInput = z.infer<typeof ReceptionInputSchema>;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ReceptionInputSchema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const player_1 = require("../../player");
|
|
6
|
+
const incident_z_1 = require("./incident.z");
|
|
6
7
|
const receptionTypeValues = [0, 1, 2, 3, 4];
|
|
7
8
|
const receptionFailureValues = [0, 1, 2, 3, 4];
|
|
8
9
|
const courtTargetValues = Array.from({ length: 13 }, (_, i) => i);
|
|
@@ -12,5 +13,6 @@ exports.ReceptionInputSchema = zod_1.z.object({
|
|
|
12
13
|
target: zod_1.z.number().int().refine((v) => courtTargetValues.includes(v), { message: 'INVALID_COURT_TARGET' }),
|
|
13
14
|
activeTraits: zod_1.z.array(zod_1.z.enum(Object.values(player_1.TraitEnum))).default([]),
|
|
14
15
|
failure: zod_1.z.number().int().refine((v) => receptionFailureValues.includes(v), { message: 'INVALID_RECEPTION_FAILURE' }),
|
|
15
|
-
type: zod_1.z.number().int().refine((v) => receptionTypeValues.includes(v), { message: 'INVALID_RECEPTION_TYPE' })
|
|
16
|
+
type: zod_1.z.number().int().refine((v) => receptionTypeValues.includes(v), { message: 'INVALID_RECEPTION_TYPE' }),
|
|
17
|
+
incident: incident_z_1.EventIncidentSchema.optional()
|
|
16
18
|
});
|
|
@@ -26,5 +26,12 @@ export declare const ServeInputSchema: z.ZodObject<{
|
|
|
26
26
|
}>>>;
|
|
27
27
|
failure: z.ZodNumber;
|
|
28
28
|
type: z.ZodNumber;
|
|
29
|
+
incident: z.ZodOptional<z.ZodObject<{
|
|
30
|
+
kind: z.ZodEnum<{
|
|
31
|
+
KNOCK: "KNOCK";
|
|
32
|
+
INJURY: "INJURY";
|
|
33
|
+
}>;
|
|
34
|
+
severity: z.ZodNumber;
|
|
35
|
+
}, z.core.$strip>>;
|
|
29
36
|
}, z.core.$strip>;
|
|
30
37
|
export type ServeInput = z.infer<typeof ServeInputSchema>;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ServeInputSchema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const player_1 = require("../../player");
|
|
6
|
+
const incident_z_1 = require("./incident.z");
|
|
6
7
|
const serveTypeValues = [0, 1, 2, 3];
|
|
7
8
|
const serveFailureValues = [0, 1, 2, 3, 4];
|
|
8
9
|
const courtTargetValues = Array.from({ length: 13 }, (_, i) => i);
|
|
@@ -12,5 +13,6 @@ exports.ServeInputSchema = zod_1.z.object({
|
|
|
12
13
|
target: zod_1.z.number().int().refine((v) => courtTargetValues.includes(v), { message: 'INVALID_COURT_TARGET' }),
|
|
13
14
|
activeTraits: zod_1.z.array(zod_1.z.enum(Object.values(player_1.TraitEnum))).default([]),
|
|
14
15
|
failure: zod_1.z.number().int().refine((v) => serveFailureValues.includes(v), { message: 'INVALID_SERVE_FAILURE' }),
|
|
15
|
-
type: zod_1.z.number().int().refine((v) => serveTypeValues.includes(v), { message: 'INVALID_SERVE_TYPE' })
|
|
16
|
+
type: zod_1.z.number().int().refine((v) => serveTypeValues.includes(v), { message: 'INVALID_SERVE_TYPE' }),
|
|
17
|
+
incident: incident_z_1.EventIncidentSchema.optional()
|
|
16
18
|
});
|
|
@@ -26,5 +26,12 @@ export declare const SetInputSchema: z.ZodObject<{
|
|
|
26
26
|
}>>>;
|
|
27
27
|
failure: z.ZodNumber;
|
|
28
28
|
type: z.ZodNumber;
|
|
29
|
+
incident: z.ZodOptional<z.ZodObject<{
|
|
30
|
+
kind: z.ZodEnum<{
|
|
31
|
+
KNOCK: "KNOCK";
|
|
32
|
+
INJURY: "INJURY";
|
|
33
|
+
}>;
|
|
34
|
+
severity: z.ZodNumber;
|
|
35
|
+
}, z.core.$strip>>;
|
|
29
36
|
}, z.core.$strip>;
|
|
30
37
|
export type SetInput = z.infer<typeof SetInputSchema>;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SetInputSchema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const player_1 = require("../../player");
|
|
6
|
+
const incident_z_1 = require("./incident.z");
|
|
6
7
|
const setTypeValues = [0, 1];
|
|
7
8
|
const setFailureValues = [0, 1, 2, 3, 4];
|
|
8
9
|
const courtTargetValues = Array.from({ length: 13 }, (_, i) => i);
|
|
@@ -12,5 +13,6 @@ exports.SetInputSchema = zod_1.z.object({
|
|
|
12
13
|
target: zod_1.z.number().int().refine((v) => courtTargetValues.includes(v), { message: 'INVALID_COURT_TARGET' }),
|
|
13
14
|
activeTraits: zod_1.z.array(zod_1.z.enum(Object.values(player_1.TraitEnum))).default([]),
|
|
14
15
|
failure: zod_1.z.number().int().refine((v) => setFailureValues.includes(v), { message: 'INVALID_SET_FAILURE' }),
|
|
15
|
-
type: zod_1.z.number().int().refine((v) => setTypeValues.includes(v), { message: 'INVALID_SET_TYPE' })
|
|
16
|
+
type: zod_1.z.number().int().refine((v) => setTypeValues.includes(v), { message: 'INVALID_SET_TYPE' }),
|
|
17
|
+
incident: incident_z_1.EventIncidentSchema.optional()
|
|
16
18
|
});
|
|
@@ -26,5 +26,12 @@ export declare const SpikeInputSchema: z.ZodObject<{
|
|
|
26
26
|
}>>>;
|
|
27
27
|
failure: z.ZodNumber;
|
|
28
28
|
type: z.ZodNumber;
|
|
29
|
+
incident: z.ZodOptional<z.ZodObject<{
|
|
30
|
+
kind: z.ZodEnum<{
|
|
31
|
+
KNOCK: "KNOCK";
|
|
32
|
+
INJURY: "INJURY";
|
|
33
|
+
}>;
|
|
34
|
+
severity: z.ZodNumber;
|
|
35
|
+
}, z.core.$strip>>;
|
|
29
36
|
}, z.core.$strip>;
|
|
30
37
|
export type SpikeInput = z.infer<typeof SpikeInputSchema>;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SpikeInputSchema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const player_1 = require("../../player");
|
|
6
|
+
const incident_z_1 = require("./incident.z");
|
|
6
7
|
const spikeTypeValues = [0, 1, 2, 3, 4, 5];
|
|
7
8
|
const spikeFailureValues = [0, 1, 2, 3, 4];
|
|
8
9
|
const courtTargetValues = Array.from({ length: 13 }, (_, i) => i);
|
|
@@ -12,5 +13,6 @@ exports.SpikeInputSchema = zod_1.z.object({
|
|
|
12
13
|
target: zod_1.z.number().int().refine((v) => courtTargetValues.includes(v), { message: 'INVALID_COURT_TARGET' }),
|
|
13
14
|
activeTraits: zod_1.z.array(zod_1.z.enum(Object.values(player_1.TraitEnum))).default([]),
|
|
14
15
|
failure: zod_1.z.number().int().refine((v) => spikeFailureValues.includes(v), { message: 'INVALID_SPIKE_FAILURE' }),
|
|
15
|
-
type: zod_1.z.number().int().refine((v) => spikeTypeValues.includes(v), { message: 'INVALID_SPIKE_TYPE' })
|
|
16
|
+
type: zod_1.z.number().int().refine((v) => spikeTypeValues.includes(v), { message: 'INVALID_SPIKE_TYPE' }),
|
|
17
|
+
incident: incident_z_1.EventIncidentSchema.optional()
|
|
16
18
|
});
|
|
@@ -33,8 +33,8 @@ class Serve extends in_play_event_1.InPlayEvent {
|
|
|
33
33
|
}
|
|
34
34
|
return new Serve(result.data);
|
|
35
35
|
}
|
|
36
|
-
constructor({ score, playerId, target, failure, type, activeTraits }) {
|
|
37
|
-
super({ score, playerId, target, activeTraits, eventType });
|
|
36
|
+
constructor({ score, playerId, target, failure, type, activeTraits, incident }) {
|
|
37
|
+
super({ score, playerId, target, activeTraits, incident, eventType });
|
|
38
38
|
this.type = type;
|
|
39
39
|
this.failure = failure;
|
|
40
40
|
}
|
|
@@ -31,8 +31,8 @@ class Set extends in_play_event_1.InPlayEvent {
|
|
|
31
31
|
}
|
|
32
32
|
return new Set(result.data);
|
|
33
33
|
}
|
|
34
|
-
constructor({ score, playerId, target, failure, type, activeTraits }) {
|
|
35
|
-
super({ score, playerId, target, activeTraits, eventType });
|
|
34
|
+
constructor({ score, playerId, target, failure, type, activeTraits, incident }) {
|
|
35
|
+
super({ score, playerId, target, activeTraits, incident, eventType });
|
|
36
36
|
this.type = type;
|
|
37
37
|
this.failure = failure;
|
|
38
38
|
}
|
|
@@ -35,8 +35,8 @@ class Spike extends in_play_event_1.InPlayEvent {
|
|
|
35
35
|
}
|
|
36
36
|
return new Spike(result.data);
|
|
37
37
|
}
|
|
38
|
-
constructor({ score, playerId, target, failure, type, activeTraits }) {
|
|
39
|
-
super({ score, playerId, target, activeTraits, eventType });
|
|
38
|
+
constructor({ score, playerId, target, failure, type, activeTraits, incident }) {
|
|
39
|
+
super({ score, playerId, target, activeTraits, incident, eventType });
|
|
40
40
|
this.type = type;
|
|
41
41
|
this.failure = failure;
|
|
42
42
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect } from '@jest/globals';
|
|
2
2
|
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
-
import { EventTypeEnum, Substitution } from '../../service';
|
|
4
|
-
import { transformToCompact, transformToSubstitution } from './rally-event';
|
|
3
|
+
import { EventTypeEnum, Serve, ServeFailureEnum, ServeTypeEnum, Spike, SpikeFailureEnum, SpikeTypeEnum, Substitution } from '../../service';
|
|
4
|
+
import { transformToCompact, transformToServe, transformToSpike, transformToSubstitution } from './rally-event';
|
|
5
5
|
describe('rally-event compact round trip — injury substitution marker', () => {
|
|
6
6
|
const playerIn = uuidv4();
|
|
7
7
|
const playerOut = uuidv4();
|
|
@@ -29,3 +29,55 @@ describe('rally-event compact round trip — injury substitution marker', () =>
|
|
|
29
29
|
expect(decoded.injury).toBeUndefined();
|
|
30
30
|
});
|
|
31
31
|
});
|
|
32
|
+
describe('rally-event compact round trip — incident marker on the causing event', () => {
|
|
33
|
+
const playerId = uuidv4();
|
|
34
|
+
const roster = [playerId];
|
|
35
|
+
const playerIndex = new Map(roster.map((id, i) => [id, i]));
|
|
36
|
+
function makeSpike(incident) {
|
|
37
|
+
return Spike.create({
|
|
38
|
+
playerId,
|
|
39
|
+
score: 62.5,
|
|
40
|
+
target: 4,
|
|
41
|
+
failure: SpikeFailureEnum.NO_FAILURE,
|
|
42
|
+
type: SpikeTypeEnum.CROSS_SHOT,
|
|
43
|
+
...(incident != null ? { incident } : {})
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
it('packs an INJURY incident as i = severity (1-4) and round-trips kind + severity', () => {
|
|
47
|
+
const compact = transformToCompact(makeSpike({ kind: 'INJURY', severity: 4 }), playerIndex);
|
|
48
|
+
expect(compact.i).toBe(4);
|
|
49
|
+
const decoded = transformToSpike(compact, roster);
|
|
50
|
+
expect(decoded.incident).toEqual({ kind: 'INJURY', severity: 4 });
|
|
51
|
+
});
|
|
52
|
+
it('packs a KNOCK incident as i = 10 + tier and round-trips kind + severity', () => {
|
|
53
|
+
const serve = Serve.create({
|
|
54
|
+
playerId,
|
|
55
|
+
score: 55,
|
|
56
|
+
target: 6,
|
|
57
|
+
failure: ServeFailureEnum.NO_FAILURE,
|
|
58
|
+
type: ServeTypeEnum.JUMP_TOPSPIN,
|
|
59
|
+
incident: { kind: 'KNOCK', severity: 2 }
|
|
60
|
+
});
|
|
61
|
+
const compact = transformToCompact(serve, playerIndex);
|
|
62
|
+
expect(compact.i).toBe(12);
|
|
63
|
+
const decoded = transformToServe(compact, roster);
|
|
64
|
+
expect(decoded.incident).toEqual({ kind: 'KNOCK', severity: 2 });
|
|
65
|
+
});
|
|
66
|
+
it('omits i entirely for an event without an incident', () => {
|
|
67
|
+
const compact = transformToCompact(makeSpike(), playerIndex);
|
|
68
|
+
expect('i' in compact).toBe(false);
|
|
69
|
+
const decoded = transformToSpike(compact, roster);
|
|
70
|
+
expect(decoded.incident).toBeUndefined();
|
|
71
|
+
});
|
|
72
|
+
it('decodes a legacy compact event (no i key) with no incident', () => {
|
|
73
|
+
const legacy = { p: 0, e: EventTypeEnum.SPIKE, f: 0, t: 0, a: 4, s: 50 };
|
|
74
|
+
const decoded = transformToSpike(legacy, roster);
|
|
75
|
+
expect(decoded.incident).toBeUndefined();
|
|
76
|
+
});
|
|
77
|
+
it('rejects an out-of-range or malformed incident at the schema', () => {
|
|
78
|
+
expect(() => makeSpike({ kind: 'INJURY', severity: 5 })).toThrow(/INVALID_SPIKE/);
|
|
79
|
+
expect(() => makeSpike({ kind: 'INJURY', severity: 0 })).toThrow(/INVALID_SPIKE/);
|
|
80
|
+
expect(() => makeSpike({ kind: 'KNOCK', severity: 4 })).toThrow(/INVALID_SPIKE/);
|
|
81
|
+
expect(() => makeSpike({ kind: 'BRUISE', severity: 1 })).toThrow(/INVALID_SPIKE/);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -10,6 +10,7 @@ export interface CompactEvent {
|
|
|
10
10
|
l?: number;
|
|
11
11
|
o?: number;
|
|
12
12
|
j?: number;
|
|
13
|
+
i?: number;
|
|
13
14
|
}
|
|
14
15
|
export declare function transformToCompact(evt: RallyEvent, playerIndex: Map<string, number>): CompactEvent;
|
|
15
16
|
export declare function transformToBlock(event: CompactEvent, roster: string[]): Block;
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
import { Block, InPlayEvent, LiberoReplacement, Reception, Serve, Set, Spike, Substitution } from '../../service';
|
|
2
|
+
// Incident packing for the compact key 'i': values below 10 are injury severities, 10+ are knock tiers.
|
|
3
|
+
function incidentToCompact(incident) {
|
|
4
|
+
if (incident == null)
|
|
5
|
+
return undefined;
|
|
6
|
+
return incident.kind === 'KNOCK' ? 10 + incident.severity : incident.severity;
|
|
7
|
+
}
|
|
8
|
+
function incidentFromCompact(i) {
|
|
9
|
+
if (i == null)
|
|
10
|
+
return undefined;
|
|
11
|
+
return i >= 10 ? { kind: 'KNOCK', severity: i - 10 } : { kind: 'INJURY', severity: i };
|
|
12
|
+
}
|
|
2
13
|
export function transformToCompact(evt, playerIndex) {
|
|
3
14
|
const out = {
|
|
4
15
|
p: playerIndex.get(evt.playerId),
|
|
@@ -9,6 +20,9 @@ export function transformToCompact(evt, playerIndex) {
|
|
|
9
20
|
out.t = evt.type;
|
|
10
21
|
out.a = evt.target;
|
|
11
22
|
out.s = evt.score;
|
|
23
|
+
const i = incidentToCompact(evt.incident);
|
|
24
|
+
if (i != null)
|
|
25
|
+
out.i = i;
|
|
12
26
|
if (evt instanceof Block) {
|
|
13
27
|
out.b = evt.blockers.map(id => playerIndex.get(id));
|
|
14
28
|
}
|
|
@@ -31,7 +45,8 @@ export function transformToBlock(event, roster) {
|
|
|
31
45
|
playerId: roster[event.p],
|
|
32
46
|
target: event.a,
|
|
33
47
|
blockers: (event.b ?? []).map(i => roster[i]),
|
|
34
|
-
score: event.s
|
|
48
|
+
score: event.s,
|
|
49
|
+
incident: incidentFromCompact(event.i)
|
|
35
50
|
});
|
|
36
51
|
}
|
|
37
52
|
export function transformToLiberoReplacement(event, roster) {
|
|
@@ -47,7 +62,8 @@ export function transformToReception(event, roster) {
|
|
|
47
62
|
type: event.t,
|
|
48
63
|
playerId: roster[event.p],
|
|
49
64
|
target: event.a,
|
|
50
|
-
score: event.s
|
|
65
|
+
score: event.s,
|
|
66
|
+
incident: incidentFromCompact(event.i)
|
|
51
67
|
});
|
|
52
68
|
}
|
|
53
69
|
export function transformToServe(event, roster) {
|
|
@@ -56,7 +72,8 @@ export function transformToServe(event, roster) {
|
|
|
56
72
|
type: event.t,
|
|
57
73
|
playerId: roster[event.p],
|
|
58
74
|
target: event.a,
|
|
59
|
-
score: event.s
|
|
75
|
+
score: event.s,
|
|
76
|
+
incident: incidentFromCompact(event.i)
|
|
60
77
|
});
|
|
61
78
|
}
|
|
62
79
|
export function transformToSet(event, roster) {
|
|
@@ -65,7 +82,8 @@ export function transformToSet(event, roster) {
|
|
|
65
82
|
type: event.t,
|
|
66
83
|
playerId: roster[event.p],
|
|
67
84
|
target: event.a,
|
|
68
|
-
score: event.s
|
|
85
|
+
score: event.s,
|
|
86
|
+
incident: incidentFromCompact(event.i)
|
|
69
87
|
});
|
|
70
88
|
}
|
|
71
89
|
export function transformToSpike(event, roster) {
|
|
@@ -74,7 +92,8 @@ export function transformToSpike(event, roster) {
|
|
|
74
92
|
type: event.t,
|
|
75
93
|
playerId: roster[event.p],
|
|
76
94
|
target: event.a,
|
|
77
|
-
score: event.s
|
|
95
|
+
score: event.s,
|
|
96
|
+
incident: incidentFromCompact(event.i)
|
|
78
97
|
});
|
|
79
98
|
}
|
|
80
99
|
export function transformToSubstitution(event, roster) {
|
|
@@ -31,8 +31,8 @@ export class Block extends InPlayEvent {
|
|
|
31
31
|
}
|
|
32
32
|
return new Block(result.data);
|
|
33
33
|
}
|
|
34
|
-
constructor({ score, playerId, target, failure, type, blockers, activeTraits }) {
|
|
35
|
-
super({ score, playerId, target, activeTraits, eventType });
|
|
34
|
+
constructor({ score, playerId, target, failure, type, blockers, activeTraits, incident }) {
|
|
35
|
+
super({ score, playerId, target, activeTraits, incident, eventType });
|
|
36
36
|
this.type = type;
|
|
37
37
|
this.failure = failure;
|
|
38
38
|
this.blockers = blockers;
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { CourtTarget } from '../match';
|
|
2
2
|
import { RallyEvent, RallyEventOpts } from './rally-event';
|
|
3
3
|
import { Trait } from '../player';
|
|
4
|
+
export interface EventIncident {
|
|
5
|
+
readonly kind: 'KNOCK' | 'INJURY';
|
|
6
|
+
readonly severity: number;
|
|
7
|
+
}
|
|
4
8
|
export interface InPlayEventOpts extends RallyEventOpts {
|
|
5
9
|
readonly target: CourtTarget;
|
|
6
10
|
readonly score: number;
|
|
7
11
|
readonly activeTraits: Trait[];
|
|
12
|
+
readonly incident?: EventIncident;
|
|
8
13
|
}
|
|
9
14
|
export declare abstract class InPlayEvent<F, T> extends RallyEvent {
|
|
10
15
|
abstract failure: F;
|
|
@@ -12,6 +17,7 @@ export declare abstract class InPlayEvent<F, T> extends RallyEvent {
|
|
|
12
17
|
readonly target: CourtTarget;
|
|
13
18
|
readonly score: number;
|
|
14
19
|
readonly activeTraits: Trait[];
|
|
15
|
-
|
|
20
|
+
readonly incident?: EventIncident;
|
|
21
|
+
protected constructor({ eventType, playerId, target, score, activeTraits, incident }: InPlayEventOpts);
|
|
16
22
|
protected _toString(): string;
|
|
17
23
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { RallyEvent } from './rally-event';
|
|
2
2
|
export class InPlayEvent extends RallyEvent {
|
|
3
|
-
constructor({ eventType, playerId, target, score, activeTraits }) {
|
|
3
|
+
constructor({ eventType, playerId, target, score, activeTraits, incident }) {
|
|
4
4
|
super({ playerId, eventType });
|
|
5
5
|
this.target = target;
|
|
6
6
|
this.score = Number(score.toFixed(2));
|
|
7
7
|
this.activeTraits = activeTraits;
|
|
8
|
+
this.incident = incident;
|
|
8
9
|
}
|
|
9
10
|
_toString() {
|
|
10
11
|
const score = `"score":${this.score}`;
|
|
@@ -33,8 +33,8 @@ export class Reception extends InPlayEvent {
|
|
|
33
33
|
}
|
|
34
34
|
return new Reception(result.data);
|
|
35
35
|
}
|
|
36
|
-
constructor({ score, playerId, target, failure, type, activeTraits }) {
|
|
37
|
-
super({ score, playerId, target, activeTraits, eventType });
|
|
36
|
+
constructor({ score, playerId, target, failure, type, activeTraits, incident }) {
|
|
37
|
+
super({ score, playerId, target, activeTraits, incident, eventType });
|
|
38
38
|
this.type = type;
|
|
39
39
|
this.failure = failure;
|
|
40
40
|
}
|
|
@@ -27,5 +27,12 @@ export declare const BlockInputSchema: z.ZodObject<{
|
|
|
27
27
|
failure: z.ZodNumber;
|
|
28
28
|
type: z.ZodNumber;
|
|
29
29
|
blockers: z.ZodArray<z.ZodUUID>;
|
|
30
|
+
incident: z.ZodOptional<z.ZodObject<{
|
|
31
|
+
kind: z.ZodEnum<{
|
|
32
|
+
KNOCK: "KNOCK";
|
|
33
|
+
INJURY: "INJURY";
|
|
34
|
+
}>;
|
|
35
|
+
severity: z.ZodNumber;
|
|
36
|
+
}, z.core.$strip>>;
|
|
30
37
|
}, z.core.$strip>;
|
|
31
38
|
export type BlockInput = z.infer<typeof BlockInputSchema>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { TraitEnum } from '../../player';
|
|
3
|
+
import { EventIncidentSchema } from './incident.z';
|
|
3
4
|
const blockTypeValues = [0, 1, 2, 3];
|
|
4
5
|
const blockFailureValues = [0, 1, 2, 3, 4, 5];
|
|
5
6
|
const courtTargetValues = Array.from({ length: 13 }, (_, i) => i);
|
|
@@ -10,7 +11,8 @@ export const BlockInputSchema = z.object({
|
|
|
10
11
|
activeTraits: z.array(z.enum(Object.values(TraitEnum))).default([]),
|
|
11
12
|
failure: z.number().int().refine((v) => blockFailureValues.includes(v), { message: 'INVALID_BLOCK_FAILURE' }),
|
|
12
13
|
type: z.number().int().refine((v) => blockTypeValues.includes(v), { message: 'INVALID_BLOCK_TYPE' }),
|
|
13
|
-
blockers: z.array(z.uuid())
|
|
14
|
+
blockers: z.array(z.uuid()),
|
|
15
|
+
incident: EventIncidentSchema.optional()
|
|
14
16
|
}).superRefine((data, ctx) => {
|
|
15
17
|
// The block type IS the blocker count (NO_BLOCKER=0, SINGLE=1, DOUBLE=2, TRIPLE=3), so the two must agree.
|
|
16
18
|
if (data.blockers.length !== data.type) {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const EventIncidentSchema: z.ZodObject<{
|
|
3
|
+
kind: z.ZodEnum<{
|
|
4
|
+
KNOCK: "KNOCK";
|
|
5
|
+
INJURY: "INJURY";
|
|
6
|
+
}>;
|
|
7
|
+
severity: z.ZodNumber;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
export type EventIncidentInput = z.infer<typeof EventIncidentSchema>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
// The moment a player got hurt, attached to the causing in-play event (owner 2026-07-05: EVERY knock and
|
|
3
|
+
// injury marks the action that produced it). KNOCK severity is the knock tier (1-3); INJURY severity is the
|
|
4
|
+
// InjurySeverityEnum value (1-4).
|
|
5
|
+
export const EventIncidentSchema = z.object({
|
|
6
|
+
kind: z.enum(['KNOCK', 'INJURY']),
|
|
7
|
+
severity: z.number().int().min(1).max(4)
|
|
8
|
+
}).refine(v => v.kind !== 'KNOCK' || v.severity <= 3, { message: 'INVALID_KNOCK_TIER' });
|
|
@@ -26,5 +26,12 @@ export declare const ReceptionInputSchema: z.ZodObject<{
|
|
|
26
26
|
}>>>;
|
|
27
27
|
failure: z.ZodNumber;
|
|
28
28
|
type: z.ZodNumber;
|
|
29
|
+
incident: z.ZodOptional<z.ZodObject<{
|
|
30
|
+
kind: z.ZodEnum<{
|
|
31
|
+
KNOCK: "KNOCK";
|
|
32
|
+
INJURY: "INJURY";
|
|
33
|
+
}>;
|
|
34
|
+
severity: z.ZodNumber;
|
|
35
|
+
}, z.core.$strip>>;
|
|
29
36
|
}, z.core.$strip>;
|
|
30
37
|
export type ReceptionInput = z.infer<typeof ReceptionInputSchema>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { TraitEnum } from '../../player';
|
|
3
|
+
import { EventIncidentSchema } from './incident.z';
|
|
3
4
|
const receptionTypeValues = [0, 1, 2, 3, 4];
|
|
4
5
|
const receptionFailureValues = [0, 1, 2, 3, 4];
|
|
5
6
|
const courtTargetValues = Array.from({ length: 13 }, (_, i) => i);
|
|
@@ -9,5 +10,6 @@ export const ReceptionInputSchema = z.object({
|
|
|
9
10
|
target: z.number().int().refine((v) => courtTargetValues.includes(v), { message: 'INVALID_COURT_TARGET' }),
|
|
10
11
|
activeTraits: z.array(z.enum(Object.values(TraitEnum))).default([]),
|
|
11
12
|
failure: z.number().int().refine((v) => receptionFailureValues.includes(v), { message: 'INVALID_RECEPTION_FAILURE' }),
|
|
12
|
-
type: z.number().int().refine((v) => receptionTypeValues.includes(v), { message: 'INVALID_RECEPTION_TYPE' })
|
|
13
|
+
type: z.number().int().refine((v) => receptionTypeValues.includes(v), { message: 'INVALID_RECEPTION_TYPE' }),
|
|
14
|
+
incident: EventIncidentSchema.optional()
|
|
13
15
|
});
|
|
@@ -26,5 +26,12 @@ export declare const ServeInputSchema: z.ZodObject<{
|
|
|
26
26
|
}>>>;
|
|
27
27
|
failure: z.ZodNumber;
|
|
28
28
|
type: z.ZodNumber;
|
|
29
|
+
incident: z.ZodOptional<z.ZodObject<{
|
|
30
|
+
kind: z.ZodEnum<{
|
|
31
|
+
KNOCK: "KNOCK";
|
|
32
|
+
INJURY: "INJURY";
|
|
33
|
+
}>;
|
|
34
|
+
severity: z.ZodNumber;
|
|
35
|
+
}, z.core.$strip>>;
|
|
29
36
|
}, z.core.$strip>;
|
|
30
37
|
export type ServeInput = z.infer<typeof ServeInputSchema>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { TraitEnum } from '../../player';
|
|
3
|
+
import { EventIncidentSchema } from './incident.z';
|
|
3
4
|
const serveTypeValues = [0, 1, 2, 3];
|
|
4
5
|
const serveFailureValues = [0, 1, 2, 3, 4];
|
|
5
6
|
const courtTargetValues = Array.from({ length: 13 }, (_, i) => i);
|
|
@@ -9,5 +10,6 @@ export const ServeInputSchema = z.object({
|
|
|
9
10
|
target: z.number().int().refine((v) => courtTargetValues.includes(v), { message: 'INVALID_COURT_TARGET' }),
|
|
10
11
|
activeTraits: z.array(z.enum(Object.values(TraitEnum))).default([]),
|
|
11
12
|
failure: z.number().int().refine((v) => serveFailureValues.includes(v), { message: 'INVALID_SERVE_FAILURE' }),
|
|
12
|
-
type: z.number().int().refine((v) => serveTypeValues.includes(v), { message: 'INVALID_SERVE_TYPE' })
|
|
13
|
+
type: z.number().int().refine((v) => serveTypeValues.includes(v), { message: 'INVALID_SERVE_TYPE' }),
|
|
14
|
+
incident: EventIncidentSchema.optional()
|
|
13
15
|
});
|
|
@@ -26,5 +26,12 @@ export declare const SetInputSchema: z.ZodObject<{
|
|
|
26
26
|
}>>>;
|
|
27
27
|
failure: z.ZodNumber;
|
|
28
28
|
type: z.ZodNumber;
|
|
29
|
+
incident: z.ZodOptional<z.ZodObject<{
|
|
30
|
+
kind: z.ZodEnum<{
|
|
31
|
+
KNOCK: "KNOCK";
|
|
32
|
+
INJURY: "INJURY";
|
|
33
|
+
}>;
|
|
34
|
+
severity: z.ZodNumber;
|
|
35
|
+
}, z.core.$strip>>;
|
|
29
36
|
}, z.core.$strip>;
|
|
30
37
|
export type SetInput = z.infer<typeof SetInputSchema>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { TraitEnum } from '../../player';
|
|
3
|
+
import { EventIncidentSchema } from './incident.z';
|
|
3
4
|
const setTypeValues = [0, 1];
|
|
4
5
|
const setFailureValues = [0, 1, 2, 3, 4];
|
|
5
6
|
const courtTargetValues = Array.from({ length: 13 }, (_, i) => i);
|
|
@@ -9,5 +10,6 @@ export const SetInputSchema = z.object({
|
|
|
9
10
|
target: z.number().int().refine((v) => courtTargetValues.includes(v), { message: 'INVALID_COURT_TARGET' }),
|
|
10
11
|
activeTraits: z.array(z.enum(Object.values(TraitEnum))).default([]),
|
|
11
12
|
failure: z.number().int().refine((v) => setFailureValues.includes(v), { message: 'INVALID_SET_FAILURE' }),
|
|
12
|
-
type: z.number().int().refine((v) => setTypeValues.includes(v), { message: 'INVALID_SET_TYPE' })
|
|
13
|
+
type: z.number().int().refine((v) => setTypeValues.includes(v), { message: 'INVALID_SET_TYPE' }),
|
|
14
|
+
incident: EventIncidentSchema.optional()
|
|
13
15
|
});
|
|
@@ -26,5 +26,12 @@ export declare const SpikeInputSchema: z.ZodObject<{
|
|
|
26
26
|
}>>>;
|
|
27
27
|
failure: z.ZodNumber;
|
|
28
28
|
type: z.ZodNumber;
|
|
29
|
+
incident: z.ZodOptional<z.ZodObject<{
|
|
30
|
+
kind: z.ZodEnum<{
|
|
31
|
+
KNOCK: "KNOCK";
|
|
32
|
+
INJURY: "INJURY";
|
|
33
|
+
}>;
|
|
34
|
+
severity: z.ZodNumber;
|
|
35
|
+
}, z.core.$strip>>;
|
|
29
36
|
}, z.core.$strip>;
|
|
30
37
|
export type SpikeInput = z.infer<typeof SpikeInputSchema>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { TraitEnum } from '../../player';
|
|
3
|
+
import { EventIncidentSchema } from './incident.z';
|
|
3
4
|
const spikeTypeValues = [0, 1, 2, 3, 4, 5];
|
|
4
5
|
const spikeFailureValues = [0, 1, 2, 3, 4];
|
|
5
6
|
const courtTargetValues = Array.from({ length: 13 }, (_, i) => i);
|
|
@@ -9,5 +10,6 @@ export const SpikeInputSchema = z.object({
|
|
|
9
10
|
target: z.number().int().refine((v) => courtTargetValues.includes(v), { message: 'INVALID_COURT_TARGET' }),
|
|
10
11
|
activeTraits: z.array(z.enum(Object.values(TraitEnum))).default([]),
|
|
11
12
|
failure: z.number().int().refine((v) => spikeFailureValues.includes(v), { message: 'INVALID_SPIKE_FAILURE' }),
|
|
12
|
-
type: z.number().int().refine((v) => spikeTypeValues.includes(v), { message: 'INVALID_SPIKE_TYPE' })
|
|
13
|
+
type: z.number().int().refine((v) => spikeTypeValues.includes(v), { message: 'INVALID_SPIKE_TYPE' }),
|
|
14
|
+
incident: EventIncidentSchema.optional()
|
|
13
15
|
});
|
|
@@ -30,8 +30,8 @@ export class Serve extends InPlayEvent {
|
|
|
30
30
|
}
|
|
31
31
|
return new Serve(result.data);
|
|
32
32
|
}
|
|
33
|
-
constructor({ score, playerId, target, failure, type, activeTraits }) {
|
|
34
|
-
super({ score, playerId, target, activeTraits, eventType });
|
|
33
|
+
constructor({ score, playerId, target, failure, type, activeTraits, incident }) {
|
|
34
|
+
super({ score, playerId, target, activeTraits, incident, eventType });
|
|
35
35
|
this.type = type;
|
|
36
36
|
this.failure = failure;
|
|
37
37
|
}
|
|
@@ -28,8 +28,8 @@ export class Set extends InPlayEvent {
|
|
|
28
28
|
}
|
|
29
29
|
return new Set(result.data);
|
|
30
30
|
}
|
|
31
|
-
constructor({ score, playerId, target, failure, type, activeTraits }) {
|
|
32
|
-
super({ score, playerId, target, activeTraits, eventType });
|
|
31
|
+
constructor({ score, playerId, target, failure, type, activeTraits, incident }) {
|
|
32
|
+
super({ score, playerId, target, activeTraits, incident, eventType });
|
|
33
33
|
this.type = type;
|
|
34
34
|
this.failure = failure;
|
|
35
35
|
}
|
|
@@ -32,8 +32,8 @@ export class Spike extends InPlayEvent {
|
|
|
32
32
|
}
|
|
33
33
|
return new Spike(result.data);
|
|
34
34
|
}
|
|
35
|
-
constructor({ score, playerId, target, failure, type, activeTraits }) {
|
|
36
|
-
super({ score, playerId, target, activeTraits, eventType });
|
|
35
|
+
constructor({ score, playerId, target, failure, type, activeTraits, incident }) {
|
|
36
|
+
super({ score, playerId, target, activeTraits, incident, eventType });
|
|
37
37
|
this.type = type;
|
|
38
38
|
this.failure = failure;
|
|
39
39
|
}
|