volleyballsimtypes 0.0.481 → 0.0.483
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 +10 -18
- package/dist/cjs/src/data/models/tactics.d.ts +17 -19
- package/dist/cjs/src/data/models/tactics.js +9 -0
- package/dist/cjs/src/data/transformers/match-preset-override.test.js +10 -1
- package/dist/cjs/src/data/transformers/rally-event.d.ts +2 -1
- package/dist/cjs/src/data/transformers/rally-event.js +12 -0
- package/dist/cjs/src/data/transformers/rally.js +2 -0
- package/dist/cjs/src/data/transformers/rally.test.d.ts +1 -0
- package/dist/cjs/src/data/transformers/rally.test.js +62 -0
- package/dist/cjs/src/data/transformers/tactics.js +38 -58
- package/dist/cjs/src/data/transformers/tactics.test.js +39 -20
- package/dist/cjs/src/service/team/blocking-preference.d.ts +5 -0
- package/dist/cjs/src/service/team/blocking-preference.js +2 -0
- package/dist/cjs/src/service/team/designated-sub.d.ts +2 -4
- package/dist/cjs/src/service/team/index.d.ts +2 -0
- package/dist/cjs/src/service/team/index.js +2 -0
- package/dist/cjs/src/service/team/libero-sub.d.ts +0 -4
- package/dist/cjs/src/service/team/offensive-preference.d.ts +1 -2
- package/dist/cjs/src/service/team/pinch-condition.d.ts +11 -3
- package/dist/cjs/src/service/team/pinch-condition.js +9 -4
- package/dist/cjs/src/service/team/schemas/designated-sub.z.d.ts +30 -32
- package/dist/cjs/src/service/team/schemas/designated-sub.z.js +27 -23
- package/dist/cjs/src/service/team/schemas/designated-sub.z.test.js +4 -2
- package/dist/cjs/src/service/team/schemas/libero-sub.z.d.ts +15 -34
- package/dist/cjs/src/service/team/schemas/libero-sub.z.js +10 -26
- package/dist/cjs/src/service/team/schemas/libero-sub.z.test.js +74 -35
- package/dist/cjs/src/service/team/schemas/tactics.z.d.ts +39 -39
- package/dist/cjs/src/service/team/schemas/tactics.z.js +47 -13
- package/dist/cjs/src/service/team/schemas/tactics.z.test.js +81 -8
- package/dist/cjs/src/service/team/schemas/team.z.d.ts +38 -38
- package/dist/cjs/src/service/team/sub-config-convert.d.ts +13 -0
- package/dist/cjs/src/service/team/sub-config-convert.js +91 -0
- package/dist/cjs/src/service/team/sub-config-convert.test.d.ts +1 -0
- package/dist/cjs/src/service/team/sub-config-convert.test.js +84 -0
- package/dist/cjs/src/service/team/tactics.d.ts +5 -0
- package/dist/cjs/src/service/team/tactics.js +3 -1
- package/dist/esm/src/api/index.d.ts +10 -18
- package/dist/esm/src/data/models/tactics.d.ts +17 -19
- package/dist/esm/src/data/models/tactics.js +9 -0
- package/dist/esm/src/data/transformers/match-preset-override.test.js +10 -1
- package/dist/esm/src/data/transformers/rally-event.d.ts +2 -1
- package/dist/esm/src/data/transformers/rally-event.js +12 -1
- package/dist/esm/src/data/transformers/rally.js +4 -2
- package/dist/esm/src/data/transformers/rally.test.d.ts +1 -0
- package/dist/esm/src/data/transformers/rally.test.js +60 -0
- package/dist/esm/src/data/transformers/tactics.js +39 -59
- package/dist/esm/src/data/transformers/tactics.test.js +40 -21
- package/dist/esm/src/service/team/blocking-preference.d.ts +5 -0
- package/dist/esm/src/service/team/blocking-preference.js +1 -0
- package/dist/esm/src/service/team/designated-sub.d.ts +2 -4
- package/dist/esm/src/service/team/index.d.ts +2 -0
- package/dist/esm/src/service/team/index.js +2 -0
- package/dist/esm/src/service/team/libero-sub.d.ts +0 -4
- package/dist/esm/src/service/team/offensive-preference.d.ts +1 -2
- package/dist/esm/src/service/team/pinch-condition.d.ts +11 -3
- package/dist/esm/src/service/team/pinch-condition.js +9 -4
- package/dist/esm/src/service/team/schemas/designated-sub.z.d.ts +30 -32
- package/dist/esm/src/service/team/schemas/designated-sub.z.js +26 -22
- package/dist/esm/src/service/team/schemas/designated-sub.z.test.js +4 -2
- package/dist/esm/src/service/team/schemas/libero-sub.z.d.ts +15 -34
- package/dist/esm/src/service/team/schemas/libero-sub.z.js +9 -25
- package/dist/esm/src/service/team/schemas/libero-sub.z.test.js +75 -36
- package/dist/esm/src/service/team/schemas/tactics.z.d.ts +39 -39
- package/dist/esm/src/service/team/schemas/tactics.z.js +48 -14
- package/dist/esm/src/service/team/schemas/tactics.z.test.js +81 -8
- package/dist/esm/src/service/team/schemas/team.z.d.ts +38 -38
- package/dist/esm/src/service/team/sub-config-convert.d.ts +13 -0
- package/dist/esm/src/service/team/sub-config-convert.js +85 -0
- package/dist/esm/src/service/team/sub-config-convert.test.d.ts +1 -0
- package/dist/esm/src/service/team/sub-config-convert.test.js +82 -0
- package/dist/esm/src/service/team/tactics.d.ts +5 -0
- package/dist/esm/src/service/team/tactics.js +3 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { Player } from '../../player';
|
|
2
|
+
import { Player, RoleEnum } from '../../player';
|
|
3
3
|
import { EnergyBand } from '../energy-band';
|
|
4
4
|
import { RotationSystemEnum } from '../rotation-system';
|
|
5
5
|
export declare const TacticsInputSchema: z.ZodObject<{
|
|
@@ -15,16 +15,9 @@ export declare const TacticsInputSchema: z.ZodObject<{
|
|
|
15
15
|
}, z.core.$strip>;
|
|
16
16
|
liberoReplacements: z.ZodArray<z.ZodCustom<Player, Player>>;
|
|
17
17
|
receiveRotationOffset: z.ZodDefault<z.ZodBoolean>;
|
|
18
|
-
designatedSubs: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
19
|
-
sets: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
20
|
-
mode: z.ZodEnum<{
|
|
21
|
-
NEVER: "NEVER";
|
|
22
|
-
FATIGUE: "FATIGUE";
|
|
23
|
-
PINCH: "PINCH";
|
|
24
|
-
}>;
|
|
18
|
+
designatedSubs: z.ZodDefault<z.ZodArray<z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodObject<{
|
|
19
|
+
sets: z.ZodOptional<z.ZodArray<z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodObject<{
|
|
25
20
|
bench: z.ZodOptional<z.ZodCustom<Player, Player>>;
|
|
26
|
-
fatigueBand: z.ZodOptional<z.ZodEnum<typeof EnergyBand>>;
|
|
27
|
-
benchFatigueBand: z.ZodOptional<z.ZodEnum<typeof EnergyBand>>;
|
|
28
21
|
conditions: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
29
22
|
type: z.ZodLiteral<import("..").PinchConditionType.ASAP>;
|
|
30
23
|
}, z.core.$strip>, z.ZodObject<{
|
|
@@ -56,9 +49,13 @@ export declare const TacticsInputSchema: z.ZodObject<{
|
|
|
56
49
|
}, z.core.$strip>, z.ZodObject<{
|
|
57
50
|
type: z.ZodLiteral<import("..").PinchConditionType.PHASE>;
|
|
58
51
|
phase: z.ZodEnum<typeof import("..").MatchPhase>;
|
|
52
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
53
|
+
type: z.ZodLiteral<import("..").PinchConditionType.FATIGUE>;
|
|
54
|
+
band: z.ZodOptional<z.ZodEnum<typeof EnergyBand>>;
|
|
59
55
|
}, z.core.$strip>], "type">>>;
|
|
60
56
|
conditionLogic: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"ALL">, z.ZodLiteral<"ANY">]>>;
|
|
61
57
|
pinchServer: z.ZodOptional<z.ZodBoolean>;
|
|
58
|
+
benchFatigueBand: z.ZodOptional<z.ZodEnum<typeof EnergyBand>>;
|
|
62
59
|
subBackMode: z.ZodOptional<z.ZodEnum<{
|
|
63
60
|
FATIGUE: "FATIGUE";
|
|
64
61
|
CONDITIONS: "CONDITIONS";
|
|
@@ -94,17 +91,13 @@ export declare const TacticsInputSchema: z.ZodObject<{
|
|
|
94
91
|
}, z.core.$strip>, z.ZodObject<{
|
|
95
92
|
type: z.ZodLiteral<import("..").PinchConditionType.PHASE>;
|
|
96
93
|
phase: z.ZodEnum<typeof import("..").MatchPhase>;
|
|
94
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
95
|
+
type: z.ZodLiteral<import("..").PinchConditionType.FATIGUE>;
|
|
96
|
+
band: z.ZodOptional<z.ZodEnum<typeof EnergyBand>>;
|
|
97
97
|
}, z.core.$strip>], "type">>>;
|
|
98
98
|
subBackConditionLogic: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"ALL">, z.ZodLiteral<"ANY">]>>;
|
|
99
|
-
}, z.core.$strip
|
|
100
|
-
mode: z.ZodEnum<{
|
|
101
|
-
NEVER: "NEVER";
|
|
102
|
-
FATIGUE: "FATIGUE";
|
|
103
|
-
PINCH: "PINCH";
|
|
104
|
-
}>;
|
|
99
|
+
}, z.core.$strip>>>>;
|
|
105
100
|
bench: z.ZodOptional<z.ZodCustom<Player, Player>>;
|
|
106
|
-
fatigueBand: z.ZodOptional<z.ZodEnum<typeof EnergyBand>>;
|
|
107
|
-
benchFatigueBand: z.ZodOptional<z.ZodEnum<typeof EnergyBand>>;
|
|
108
101
|
conditions: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
109
102
|
type: z.ZodLiteral<import("..").PinchConditionType.ASAP>;
|
|
110
103
|
}, z.core.$strip>, z.ZodObject<{
|
|
@@ -136,9 +129,13 @@ export declare const TacticsInputSchema: z.ZodObject<{
|
|
|
136
129
|
}, z.core.$strip>, z.ZodObject<{
|
|
137
130
|
type: z.ZodLiteral<import("..").PinchConditionType.PHASE>;
|
|
138
131
|
phase: z.ZodEnum<typeof import("..").MatchPhase>;
|
|
132
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
133
|
+
type: z.ZodLiteral<import("..").PinchConditionType.FATIGUE>;
|
|
134
|
+
band: z.ZodOptional<z.ZodEnum<typeof EnergyBand>>;
|
|
139
135
|
}, z.core.$strip>], "type">>>;
|
|
140
136
|
conditionLogic: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"ALL">, z.ZodLiteral<"ANY">]>>;
|
|
141
137
|
pinchServer: z.ZodOptional<z.ZodBoolean>;
|
|
138
|
+
benchFatigueBand: z.ZodOptional<z.ZodEnum<typeof EnergyBand>>;
|
|
142
139
|
subBackMode: z.ZodOptional<z.ZodEnum<{
|
|
143
140
|
FATIGUE: "FATIGUE";
|
|
144
141
|
CONDITIONS: "CONDITIONS";
|
|
@@ -174,21 +171,17 @@ export declare const TacticsInputSchema: z.ZodObject<{
|
|
|
174
171
|
}, z.core.$strip>, z.ZodObject<{
|
|
175
172
|
type: z.ZodLiteral<import("..").PinchConditionType.PHASE>;
|
|
176
173
|
phase: z.ZodEnum<typeof import("..").MatchPhase>;
|
|
174
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
175
|
+
type: z.ZodLiteral<import("..").PinchConditionType.FATIGUE>;
|
|
176
|
+
band: z.ZodOptional<z.ZodEnum<typeof EnergyBand>>;
|
|
177
177
|
}, z.core.$strip>], "type">>>;
|
|
178
178
|
subBackConditionLogic: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"ALL">, z.ZodLiteral<"ANY">]>>;
|
|
179
179
|
starter: z.ZodCustom<Player, Player>;
|
|
180
|
-
}, z.core.$strip
|
|
180
|
+
}, z.core.$strip>>>>;
|
|
181
181
|
substitutionBand: z.ZodDefault<z.ZodUnion<readonly [z.ZodEnum<typeof EnergyBand>, z.ZodLiteral<"NEVER">]>>;
|
|
182
182
|
secondLibero: z.ZodOptional<z.ZodCustom<Player, Player>>;
|
|
183
|
-
liberoSub: z.ZodOptional<z.ZodObject<{
|
|
184
|
-
sets: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
185
|
-
mode: z.ZodEnum<{
|
|
186
|
-
NEVER: "NEVER";
|
|
187
|
-
FATIGUE: "FATIGUE";
|
|
188
|
-
CONDITIONS: "CONDITIONS";
|
|
189
|
-
ALWAYS: "ALWAYS";
|
|
190
|
-
}>;
|
|
191
|
-
fatigueBand: z.ZodOptional<z.ZodEnum<typeof EnergyBand>>;
|
|
183
|
+
liberoSub: z.ZodOptional<z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodObject<{
|
|
184
|
+
sets: z.ZodOptional<z.ZodArray<z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodObject<{
|
|
192
185
|
conditions: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
193
186
|
type: z.ZodLiteral<import("..").PinchConditionType.ASAP>;
|
|
194
187
|
}, z.core.$strip>, z.ZodObject<{
|
|
@@ -220,16 +213,12 @@ export declare const TacticsInputSchema: z.ZodObject<{
|
|
|
220
213
|
}, z.core.$strip>, z.ZodObject<{
|
|
221
214
|
type: z.ZodLiteral<import("..").PinchConditionType.PHASE>;
|
|
222
215
|
phase: z.ZodEnum<typeof import("..").MatchPhase>;
|
|
216
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
217
|
+
type: z.ZodLiteral<import("..").PinchConditionType.FATIGUE>;
|
|
218
|
+
band: z.ZodOptional<z.ZodEnum<typeof EnergyBand>>;
|
|
223
219
|
}, z.core.$strip>], "type">>>;
|
|
224
220
|
conditionLogic: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"ALL">, z.ZodLiteral<"ANY">]>>;
|
|
225
|
-
}, z.core.$strip
|
|
226
|
-
mode: z.ZodEnum<{
|
|
227
|
-
NEVER: "NEVER";
|
|
228
|
-
FATIGUE: "FATIGUE";
|
|
229
|
-
CONDITIONS: "CONDITIONS";
|
|
230
|
-
ALWAYS: "ALWAYS";
|
|
231
|
-
}>;
|
|
232
|
-
fatigueBand: z.ZodOptional<z.ZodEnum<typeof EnergyBand>>;
|
|
221
|
+
}, z.core.$strip>>>>;
|
|
233
222
|
conditions: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
234
223
|
type: z.ZodLiteral<import("..").PinchConditionType.ASAP>;
|
|
235
224
|
}, z.core.$strip>, z.ZodObject<{
|
|
@@ -261,15 +250,18 @@ export declare const TacticsInputSchema: z.ZodObject<{
|
|
|
261
250
|
}, z.core.$strip>, z.ZodObject<{
|
|
262
251
|
type: z.ZodLiteral<import("..").PinchConditionType.PHASE>;
|
|
263
252
|
phase: z.ZodEnum<typeof import("..").MatchPhase>;
|
|
253
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
254
|
+
type: z.ZodLiteral<import("..").PinchConditionType.FATIGUE>;
|
|
255
|
+
band: z.ZodOptional<z.ZodEnum<typeof EnergyBand>>;
|
|
264
256
|
}, z.core.$strip>], "type">>>;
|
|
265
257
|
conditionLogic: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"ALL">, z.ZodLiteral<"ANY">]>>;
|
|
266
|
-
}, z.core.$strip
|
|
258
|
+
}, z.core.$strip>>>;
|
|
267
259
|
liberoReplacementSets: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodCustom<Player, Player>>>>;
|
|
268
260
|
rotationSystem: z.ZodDefault<z.ZodEnum<typeof RotationSystemEnum>>;
|
|
269
261
|
designatedSetters: z.ZodDefault<z.ZodArray<z.ZodCustom<Player, Player>>>;
|
|
270
262
|
offensivePreferences: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
271
263
|
rotation: z.ZodNumber;
|
|
272
|
-
|
|
264
|
+
weights: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
273
265
|
tempos: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
274
266
|
FAST: "FAST";
|
|
275
267
|
HIGH: "HIGH";
|
|
@@ -281,12 +273,20 @@ export declare const TacticsInputSchema: z.ZodObject<{
|
|
|
281
273
|
}, z.core.$strip>>>;
|
|
282
274
|
offensivePreferenceSets: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodObject<{
|
|
283
275
|
rotation: z.ZodNumber;
|
|
284
|
-
|
|
276
|
+
weights: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
285
277
|
tempos: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
286
278
|
FAST: "FAST";
|
|
287
279
|
HIGH: "HIGH";
|
|
288
280
|
}>>>;
|
|
289
281
|
}, z.core.$strip>>>>;
|
|
282
|
+
blockingPreferences: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
283
|
+
rotation: z.ZodNumber;
|
|
284
|
+
targets: z.ZodRecord<z.ZodString, z.ZodEnum<typeof RoleEnum> & z.ZodType<RoleEnum.SETTER | RoleEnum.OUTSIDE_HITTER | RoleEnum.OPPOSITE_HITTER | RoleEnum.MIDDLE_BLOCKER, RoleEnum, z.core.$ZodTypeInternals<RoleEnum.SETTER | RoleEnum.OUTSIDE_HITTER | RoleEnum.OPPOSITE_HITTER | RoleEnum.MIDDLE_BLOCKER, RoleEnum>>>;
|
|
285
|
+
}, z.core.$strip>>>;
|
|
286
|
+
blockingPreferenceSets: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodObject<{
|
|
287
|
+
rotation: z.ZodNumber;
|
|
288
|
+
targets: z.ZodRecord<z.ZodString, z.ZodEnum<typeof RoleEnum> & z.ZodType<RoleEnum.SETTER | RoleEnum.OUTSIDE_HITTER | RoleEnum.OPPOSITE_HITTER | RoleEnum.MIDDLE_BLOCKER, RoleEnum, z.core.$ZodTypeInternals<RoleEnum.SETTER | RoleEnum.OUTSIDE_HITTER | RoleEnum.OPPOSITE_HITTER | RoleEnum.MIDDLE_BLOCKER, RoleEnum>>>;
|
|
289
|
+
}, z.core.$strip>>>>;
|
|
290
290
|
replaceKnockedImmediately: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
|
|
291
291
|
injuryReplacements: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
292
292
|
starter: z.ZodCustom<Player, Player>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { Player } from '../../player';
|
|
2
|
+
import { Player, RoleEnum } from '../../player';
|
|
3
3
|
import { EnergyBand } from '../energy-band';
|
|
4
4
|
import { RotationSystemEnum, setterCountFor } from '../rotation-system';
|
|
5
5
|
import { DesignatedSubSchema, SubBandSchema } from './designated-sub.z';
|
|
@@ -47,14 +47,23 @@ const lineupSchema = z.object({
|
|
|
47
47
|
});
|
|
48
48
|
// Per-player tempo preference (set-tempo rework): absent key = Auto.
|
|
49
49
|
const tempoPreferenceSchema = z.enum(['FAST', 'HIGH']);
|
|
50
|
-
// One rotation's
|
|
51
|
-
//
|
|
52
|
-
//
|
|
50
|
+
// One rotation's attacker weighting. `rotation` is the main setter's rotational slot (1..6); `weights` maps each
|
|
51
|
+
// attacker's starter id to an integer percentage share (values sum to 100; 0 removes an attacker). `tempos`
|
|
52
|
+
// optionally forces a per-starter tempo (Auto when absent). Cross-field checks (keys are starters, weights sum to
|
|
53
|
+
// 100) live in the superRefine below.
|
|
53
54
|
const offensivePreferenceSchema = z.object({
|
|
54
55
|
rotation: z.number().int().min(1).max(6),
|
|
55
|
-
|
|
56
|
+
weights: z.record(z.string(), z.number().int().min(0)),
|
|
56
57
|
tempos: z.record(z.string(), tempoPreferenceSchema).optional()
|
|
57
58
|
});
|
|
59
|
+
// The opposing attacking functions a dedicated blocker can commit to: every RoleEnum except the libero.
|
|
60
|
+
const blockingFunctionSchema = z.nativeEnum(RoleEnum).refine((v) => v !== RoleEnum.LIBERO, { message: 'BLOCKING_TARGET_CANNOT_BE_LIBERO' });
|
|
61
|
+
// One rotation's dedicated-blocking assignments: `targets` maps my front-row starter ids to the opposing function
|
|
62
|
+
// each commits to block. Cross-field checks (keys are starters) live in the superRefine below.
|
|
63
|
+
const blockingPreferenceSchema = z.object({
|
|
64
|
+
rotation: z.number().int().min(1).max(6),
|
|
65
|
+
targets: z.record(z.string(), blockingFunctionSchema)
|
|
66
|
+
});
|
|
58
67
|
// One set's rotation-system override (per-set tactics): system + its designated setters travel together.
|
|
59
68
|
const systemSetSchema = z.object({
|
|
60
69
|
rotationSystem: z.nativeEnum(RotationSystemEnum),
|
|
@@ -82,6 +91,9 @@ export const TacticsInputSchema = z.object({
|
|
|
82
91
|
// validated with the same cross-field rules as the flat fields (see superRefine below).
|
|
83
92
|
systemSets: z.array(systemSetSchema).max(5).optional(),
|
|
84
93
|
offensivePreferenceSets: z.array(z.array(offensivePreferenceSchema)).max(5).optional(),
|
|
94
|
+
// Blocking preferences (dedicated blocking). Defaults keep every existing Tactics.create({...}) call valid.
|
|
95
|
+
blockingPreferences: z.array(blockingPreferenceSchema).default([]),
|
|
96
|
+
blockingPreferenceSets: z.array(z.array(blockingPreferenceSchema)).max(5).optional(),
|
|
85
97
|
// Injuries. Defaults keep every existing Tactics.create({...}) call valid. replaceKnockedImmediately is
|
|
86
98
|
// PER STARTER (owner order 2026-07-05): keyed by starter id, missing key = ON; keys validated against the
|
|
87
99
|
// lineup in the superRefine below. injuryReplacements is the per-starter explicit replacement mapping
|
|
@@ -150,16 +162,17 @@ export const TacticsInputSchema = z.object({
|
|
|
150
162
|
ctx.addIssue({ code: 'custom', message: 'OFFENSIVE_PREFERENCE_DUPLICATE_ROTATION', path });
|
|
151
163
|
}
|
|
152
164
|
seenRotations.add(pref.rotation);
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
ctx.addIssue({ code: 'custom', message: 'OFFENSIVE_PREFERENCE_DUPLICATE_ATTACKER', path });
|
|
156
|
-
}
|
|
157
|
-
for (const id of ids) {
|
|
165
|
+
// Weight keys are on-court starters, and the percentages must sum to exactly 100 (0 removes an attacker).
|
|
166
|
+
for (const id of Object.keys(pref.weights)) {
|
|
158
167
|
if (!starterIds.has(id)) {
|
|
159
168
|
ctx.addIssue({ code: 'custom', message: 'OFFENSIVE_PREFERENCE_ATTACKER_NOT_A_STARTER', path });
|
|
160
169
|
}
|
|
161
170
|
}
|
|
162
|
-
|
|
171
|
+
const total = Object.values(pref.weights).reduce((sum, w) => sum + w, 0);
|
|
172
|
+
if (total !== 100) {
|
|
173
|
+
ctx.addIssue({ code: 'custom', message: 'OFFENSIVE_PREFERENCE_WEIGHTS_MUST_SUM_TO_100', path });
|
|
174
|
+
}
|
|
175
|
+
// Tempo preference keys are starter ids too.
|
|
163
176
|
for (const id of Object.keys(pref.tempos ?? {})) {
|
|
164
177
|
if (!starterIds.has(id)) {
|
|
165
178
|
ctx.addIssue({ code: 'custom', message: 'OFFENSIVE_PREFERENCE_TEMPO_NOT_A_STARTER', path });
|
|
@@ -167,6 +180,22 @@ export const TacticsInputSchema = z.object({
|
|
|
167
180
|
}
|
|
168
181
|
}
|
|
169
182
|
};
|
|
183
|
+
// Blocking preferences: unique rotations; each assignment keys an on-court starter (the UI only offers front-row
|
|
184
|
+
// players, the schema checks starters). The target function is validated by blockingFunctionSchema.
|
|
185
|
+
const validateBlockingPreferences = (preferences, path) => {
|
|
186
|
+
const seenRotations = new Set();
|
|
187
|
+
for (const pref of preferences) {
|
|
188
|
+
if (seenRotations.has(pref.rotation)) {
|
|
189
|
+
ctx.addIssue({ code: 'custom', message: 'BLOCKING_PREFERENCE_DUPLICATE_ROTATION', path });
|
|
190
|
+
}
|
|
191
|
+
seenRotations.add(pref.rotation);
|
|
192
|
+
for (const id of Object.keys(pref.targets)) {
|
|
193
|
+
if (!starterIds.has(id)) {
|
|
194
|
+
ctx.addIssue({ code: 'custom', message: 'BLOCKING_PREFERENCE_BLOCKER_NOT_A_STARTER', path });
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
};
|
|
170
199
|
validateSystem(data.rotationSystem, data.designatedSetters, ['designatedSetters']);
|
|
171
200
|
for (const [i, systemSet] of (data.systemSets ?? []).entries()) {
|
|
172
201
|
validateSystem(systemSet.rotationSystem, systemSet.designatedSetters, ['systemSets', i]);
|
|
@@ -175,6 +204,10 @@ export const TacticsInputSchema = z.object({
|
|
|
175
204
|
for (const [i, preferences] of (data.offensivePreferenceSets ?? []).entries()) {
|
|
176
205
|
validateOffensivePreferences(preferences, ['offensivePreferenceSets', i]);
|
|
177
206
|
}
|
|
207
|
+
validateBlockingPreferences(data.blockingPreferences, ['blockingPreferences']);
|
|
208
|
+
for (const [i, preferences] of (data.blockingPreferenceSets ?? []).entries()) {
|
|
209
|
+
validateBlockingPreferences(preferences, ['blockingPreferenceSets', i]);
|
|
210
|
+
}
|
|
178
211
|
// Second libero (L2). The second libero is a reserve (not a starter, the libero, or a bench player). A swap
|
|
179
212
|
// rule (FATIGUE/ALWAYS in any set) needs someone to swap in, so it requires a second libero, and a second
|
|
180
213
|
// libero needs a starting libero to replace ("no L2 without an L"). Per-set libero replacements, like the
|
|
@@ -185,10 +218,11 @@ export const TacticsInputSchema = z.object({
|
|
|
185
218
|
...(libero != null ? [libero.id] : []),
|
|
186
219
|
...data.lineup.bench.map(p => p.id)
|
|
187
220
|
]);
|
|
188
|
-
|
|
189
|
-
|
|
221
|
+
// Unified condition engine: the rule wants a swap when ANY config (flat or per-set) has conditions.
|
|
222
|
+
const liberoConditionSets = data.liberoSub != null
|
|
223
|
+
? [data.liberoSub.conditions ?? [], ...(data.liberoSub.sets ?? []).map(s => s.conditions ?? [])]
|
|
190
224
|
: [];
|
|
191
|
-
const wantsLiberoSwap =
|
|
225
|
+
const wantsLiberoSwap = liberoConditionSets.some(conditions => conditions.length > 0);
|
|
192
226
|
if (wantsLiberoSwap && data.secondLibero == null) {
|
|
193
227
|
ctx.addIssue({ code: 'custom', message: 'LIBERO_SWAP_REQUIRES_SECOND_LIBERO', path: ['secondLibero'] });
|
|
194
228
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect } from '@jest/globals';
|
|
2
2
|
import { TacticsInputSchema } from './tactics.z';
|
|
3
|
+
import { RoleEnum } from '../../player';
|
|
3
4
|
import { makeCountry, makePlayer } from '../../test-helpers';
|
|
4
5
|
describe('TacticsInputSchema — second libero rules', () => {
|
|
5
6
|
const country = makeCountry();
|
|
@@ -93,7 +94,7 @@ describe('TacticsInputSchema — per-set tactics (systemSets / offensivePreferen
|
|
|
93
94
|
{ rotationSystem: '4-2', designatedSetters: [p1, p4] }
|
|
94
95
|
],
|
|
95
96
|
offensivePreferenceSets: [
|
|
96
|
-
[{ rotation: 1,
|
|
97
|
+
[{ rotation: 1, weights: { [p2.id]: 60, [p3.id]: 40 } }],
|
|
97
98
|
[]
|
|
98
99
|
]
|
|
99
100
|
}));
|
|
@@ -102,7 +103,7 @@ describe('TacticsInputSchema — per-set tactics (systemSets / offensivePreferen
|
|
|
102
103
|
it('carries the per-set fields through Tactics.create parsing', () => {
|
|
103
104
|
const res = TacticsInputSchema.safeParse(baseInput({
|
|
104
105
|
systemSets: [{ rotationSystem: '5-1', designatedSetters: [p1] }],
|
|
105
|
-
offensivePreferenceSets: [[{ rotation: 2,
|
|
106
|
+
offensivePreferenceSets: [[{ rotation: 2, weights: { [p3.id]: 100 } }]]
|
|
106
107
|
}));
|
|
107
108
|
expect(res.success).toBe(true);
|
|
108
109
|
if (res.success) {
|
|
@@ -151,7 +152,7 @@ describe('TacticsInputSchema — per-set tactics (systemSets / offensivePreferen
|
|
|
151
152
|
});
|
|
152
153
|
it('rejects a per-set preferences list with a duplicate rotation', () => {
|
|
153
154
|
const res = TacticsInputSchema.safeParse(baseInput({
|
|
154
|
-
offensivePreferenceSets: [[{ rotation: 1,
|
|
155
|
+
offensivePreferenceSets: [[{ rotation: 1, weights: { [p2.id]: 100 } }, { rotation: 1, weights: { [p3.id]: 100 } }]]
|
|
155
156
|
}));
|
|
156
157
|
expect(res.success).toBe(false);
|
|
157
158
|
if (!res.success) {
|
|
@@ -159,18 +160,27 @@ describe('TacticsInputSchema — per-set tactics (systemSets / offensivePreferen
|
|
|
159
160
|
expect(issue?.path).toEqual(['offensivePreferenceSets', 0]);
|
|
160
161
|
}
|
|
161
162
|
});
|
|
162
|
-
it('rejects a per-set preferences
|
|
163
|
+
it('rejects a per-set preferences map that keys a non-starter', () => {
|
|
163
164
|
const res = TacticsInputSchema.safeParse(baseInput({
|
|
164
|
-
offensivePreferenceSets: [[{ rotation: 1,
|
|
165
|
+
offensivePreferenceSets: [[{ rotation: 1, weights: { [reserve.id]: 100 } }]]
|
|
165
166
|
}));
|
|
166
167
|
expect(res.success).toBe(false);
|
|
167
168
|
if (!res.success) {
|
|
168
169
|
expect(res.error.issues.some(i => i.message === 'OFFENSIVE_PREFERENCE_ATTACKER_NOT_A_STARTER')).toBe(true);
|
|
169
170
|
}
|
|
170
171
|
});
|
|
172
|
+
it('rejects offensive preference weights that do not sum to 100', () => {
|
|
173
|
+
const res = TacticsInputSchema.safeParse(baseInput({
|
|
174
|
+
offensivePreferences: [{ rotation: 1, weights: { [p2.id]: 50, [p3.id]: 40 } }]
|
|
175
|
+
}));
|
|
176
|
+
expect(res.success).toBe(false);
|
|
177
|
+
if (!res.success) {
|
|
178
|
+
expect(res.error.issues.some(i => i.message === 'OFFENSIVE_PREFERENCE_WEIGHTS_MUST_SUM_TO_100')).toBe(true);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
171
181
|
it('accepts offensive preferences with a starter-keyed tempos map', () => {
|
|
172
182
|
const res = TacticsInputSchema.safeParse(baseInput({
|
|
173
|
-
offensivePreferences: [{ rotation: 1,
|
|
183
|
+
offensivePreferences: [{ rotation: 1, weights: { [p2.id]: 60, [p3.id]: 40 }, tempos: { [p2.id]: 'FAST', [p3.id]: 'HIGH' } }]
|
|
174
184
|
}));
|
|
175
185
|
expect(res.success).toBe(true);
|
|
176
186
|
if (res.success) {
|
|
@@ -179,7 +189,7 @@ describe('TacticsInputSchema — per-set tactics (systemSets / offensivePreferen
|
|
|
179
189
|
});
|
|
180
190
|
it('rejects a tempos map keyed by a non-starter', () => {
|
|
181
191
|
const res = TacticsInputSchema.safeParse(baseInput({
|
|
182
|
-
offensivePreferences: [{ rotation: 1,
|
|
192
|
+
offensivePreferences: [{ rotation: 1, weights: { [p2.id]: 100 }, tempos: { [reserve.id]: 'FAST' } }]
|
|
183
193
|
}));
|
|
184
194
|
expect(res.success).toBe(false);
|
|
185
195
|
if (!res.success) {
|
|
@@ -188,7 +198,7 @@ describe('TacticsInputSchema — per-set tactics (systemSets / offensivePreferen
|
|
|
188
198
|
});
|
|
189
199
|
it('rejects an invalid tempo value', () => {
|
|
190
200
|
const res = TacticsInputSchema.safeParse(baseInput({
|
|
191
|
-
offensivePreferences: [{ rotation: 1,
|
|
201
|
+
offensivePreferences: [{ rotation: 1, weights: { [p2.id]: 100 }, tempos: { [p2.id]: 'SLOW' } }]
|
|
192
202
|
}));
|
|
193
203
|
expect(res.success).toBe(false);
|
|
194
204
|
});
|
|
@@ -206,3 +216,66 @@ describe('TacticsInputSchema — per-set tactics (systemSets / offensivePreferen
|
|
|
206
216
|
}
|
|
207
217
|
});
|
|
208
218
|
});
|
|
219
|
+
describe('TacticsInputSchema — blocking preferences', () => {
|
|
220
|
+
const country = makeCountry();
|
|
221
|
+
const p1 = makePlayer(country);
|
|
222
|
+
const p2 = makePlayer(country);
|
|
223
|
+
const p3 = makePlayer(country);
|
|
224
|
+
const p4 = makePlayer(country);
|
|
225
|
+
const p5 = makePlayer(country);
|
|
226
|
+
const p6 = makePlayer(country);
|
|
227
|
+
const reserve = makePlayer(country);
|
|
228
|
+
// Front-row starters (zones 2/3/4) are p2, p3, p4; the validator only requires target keys to be starters.
|
|
229
|
+
function baseInput(overrides = {}) {
|
|
230
|
+
return {
|
|
231
|
+
lineup: { 4: p4, 3: p3, 2: p2, 5: p5, 6: p6, 1: p1, bench: [] },
|
|
232
|
+
liberoReplacements: [],
|
|
233
|
+
...overrides
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
it('accepts a blocking preference that keys starters to attacking functions', () => {
|
|
237
|
+
const res = TacticsInputSchema.safeParse(baseInput({
|
|
238
|
+
blockingPreferences: [{ rotation: 1, targets: { [p4.id]: RoleEnum.OUTSIDE_HITTER, [p3.id]: RoleEnum.MIDDLE_BLOCKER } }]
|
|
239
|
+
}));
|
|
240
|
+
expect(res.success).toBe(true);
|
|
241
|
+
if (res.success) {
|
|
242
|
+
expect(res.data.blockingPreferences[0].targets[p4.id]).toBe(RoleEnum.OUTSIDE_HITTER);
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
it('rejects a blocking target that is not a starter', () => {
|
|
246
|
+
const res = TacticsInputSchema.safeParse(baseInput({
|
|
247
|
+
blockingPreferences: [{ rotation: 1, targets: { [reserve.id]: RoleEnum.OUTSIDE_HITTER } }]
|
|
248
|
+
}));
|
|
249
|
+
expect(res.success).toBe(false);
|
|
250
|
+
if (!res.success) {
|
|
251
|
+
expect(res.error.issues.some(i => i.message === 'BLOCKING_PREFERENCE_BLOCKER_NOT_A_STARTER')).toBe(true);
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
it('rejects a blocking target function of libero', () => {
|
|
255
|
+
const res = TacticsInputSchema.safeParse(baseInput({
|
|
256
|
+
blockingPreferences: [{ rotation: 1, targets: { [p4.id]: RoleEnum.LIBERO } }]
|
|
257
|
+
}));
|
|
258
|
+
expect(res.success).toBe(false);
|
|
259
|
+
if (!res.success) {
|
|
260
|
+
expect(res.error.issues.some(i => i.message === 'BLOCKING_TARGET_CANNOT_BE_LIBERO')).toBe(true);
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
it('rejects a duplicate rotation in blocking preferences', () => {
|
|
264
|
+
const res = TacticsInputSchema.safeParse(baseInput({
|
|
265
|
+
blockingPreferences: [
|
|
266
|
+
{ rotation: 1, targets: { [p4.id]: RoleEnum.OUTSIDE_HITTER } },
|
|
267
|
+
{ rotation: 1, targets: { [p3.id]: RoleEnum.MIDDLE_BLOCKER } }
|
|
268
|
+
]
|
|
269
|
+
}));
|
|
270
|
+
expect(res.success).toBe(false);
|
|
271
|
+
if (!res.success) {
|
|
272
|
+
expect(res.error.issues.some(i => i.message === 'BLOCKING_PREFERENCE_DUPLICATE_ROTATION')).toBe(true);
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
it('accepts per-set blocking preference overrides', () => {
|
|
276
|
+
const res = TacticsInputSchema.safeParse(baseInput({
|
|
277
|
+
blockingPreferenceSets: [[{ rotation: 1, targets: { [p4.id]: RoleEnum.OPPOSITE_HITTER } }], []]
|
|
278
|
+
}));
|
|
279
|
+
expect(res.success).toBe(true);
|
|
280
|
+
});
|
|
281
|
+
});
|
|
@@ -23,16 +23,9 @@ export declare const TeamInputSchema: z.ZodObject<{
|
|
|
23
23
|
}, z.core.$strip>;
|
|
24
24
|
liberoReplacements: z.ZodArray<z.ZodCustom<Player, Player>>;
|
|
25
25
|
receiveRotationOffset: z.ZodDefault<z.ZodBoolean>;
|
|
26
|
-
designatedSubs: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
27
|
-
sets: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
28
|
-
mode: z.ZodEnum<{
|
|
29
|
-
NEVER: "NEVER";
|
|
30
|
-
FATIGUE: "FATIGUE";
|
|
31
|
-
PINCH: "PINCH";
|
|
32
|
-
}>;
|
|
26
|
+
designatedSubs: z.ZodDefault<z.ZodArray<z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodObject<{
|
|
27
|
+
sets: z.ZodOptional<z.ZodArray<z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodObject<{
|
|
33
28
|
bench: z.ZodOptional<z.ZodCustom<Player, Player>>;
|
|
34
|
-
fatigueBand: z.ZodOptional<z.ZodEnum<typeof import("..").EnergyBand>>;
|
|
35
|
-
benchFatigueBand: z.ZodOptional<z.ZodEnum<typeof import("..").EnergyBand>>;
|
|
36
29
|
conditions: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
37
30
|
type: z.ZodLiteral<import("..").PinchConditionType.ASAP>;
|
|
38
31
|
}, z.core.$strip>, z.ZodObject<{
|
|
@@ -64,9 +57,13 @@ export declare const TeamInputSchema: z.ZodObject<{
|
|
|
64
57
|
}, z.core.$strip>, z.ZodObject<{
|
|
65
58
|
type: z.ZodLiteral<import("..").PinchConditionType.PHASE>;
|
|
66
59
|
phase: z.ZodEnum<typeof import("..").MatchPhase>;
|
|
60
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
61
|
+
type: z.ZodLiteral<import("..").PinchConditionType.FATIGUE>;
|
|
62
|
+
band: z.ZodOptional<z.ZodEnum<typeof import("..").EnergyBand>>;
|
|
67
63
|
}, z.core.$strip>], "type">>>;
|
|
68
64
|
conditionLogic: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"ALL">, z.ZodLiteral<"ANY">]>>;
|
|
69
65
|
pinchServer: z.ZodOptional<z.ZodBoolean>;
|
|
66
|
+
benchFatigueBand: z.ZodOptional<z.ZodEnum<typeof import("..").EnergyBand>>;
|
|
70
67
|
subBackMode: z.ZodOptional<z.ZodEnum<{
|
|
71
68
|
FATIGUE: "FATIGUE";
|
|
72
69
|
CONDITIONS: "CONDITIONS";
|
|
@@ -102,17 +99,13 @@ export declare const TeamInputSchema: z.ZodObject<{
|
|
|
102
99
|
}, z.core.$strip>, z.ZodObject<{
|
|
103
100
|
type: z.ZodLiteral<import("..").PinchConditionType.PHASE>;
|
|
104
101
|
phase: z.ZodEnum<typeof import("..").MatchPhase>;
|
|
102
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
103
|
+
type: z.ZodLiteral<import("..").PinchConditionType.FATIGUE>;
|
|
104
|
+
band: z.ZodOptional<z.ZodEnum<typeof import("..").EnergyBand>>;
|
|
105
105
|
}, z.core.$strip>], "type">>>;
|
|
106
106
|
subBackConditionLogic: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"ALL">, z.ZodLiteral<"ANY">]>>;
|
|
107
|
-
}, z.core.$strip
|
|
108
|
-
mode: z.ZodEnum<{
|
|
109
|
-
NEVER: "NEVER";
|
|
110
|
-
FATIGUE: "FATIGUE";
|
|
111
|
-
PINCH: "PINCH";
|
|
112
|
-
}>;
|
|
107
|
+
}, z.core.$strip>>>>;
|
|
113
108
|
bench: z.ZodOptional<z.ZodCustom<Player, Player>>;
|
|
114
|
-
fatigueBand: z.ZodOptional<z.ZodEnum<typeof import("..").EnergyBand>>;
|
|
115
|
-
benchFatigueBand: z.ZodOptional<z.ZodEnum<typeof import("..").EnergyBand>>;
|
|
116
109
|
conditions: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
117
110
|
type: z.ZodLiteral<import("..").PinchConditionType.ASAP>;
|
|
118
111
|
}, z.core.$strip>, z.ZodObject<{
|
|
@@ -144,9 +137,13 @@ export declare const TeamInputSchema: z.ZodObject<{
|
|
|
144
137
|
}, z.core.$strip>, z.ZodObject<{
|
|
145
138
|
type: z.ZodLiteral<import("..").PinchConditionType.PHASE>;
|
|
146
139
|
phase: z.ZodEnum<typeof import("..").MatchPhase>;
|
|
140
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
141
|
+
type: z.ZodLiteral<import("..").PinchConditionType.FATIGUE>;
|
|
142
|
+
band: z.ZodOptional<z.ZodEnum<typeof import("..").EnergyBand>>;
|
|
147
143
|
}, z.core.$strip>], "type">>>;
|
|
148
144
|
conditionLogic: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"ALL">, z.ZodLiteral<"ANY">]>>;
|
|
149
145
|
pinchServer: z.ZodOptional<z.ZodBoolean>;
|
|
146
|
+
benchFatigueBand: z.ZodOptional<z.ZodEnum<typeof import("..").EnergyBand>>;
|
|
150
147
|
subBackMode: z.ZodOptional<z.ZodEnum<{
|
|
151
148
|
FATIGUE: "FATIGUE";
|
|
152
149
|
CONDITIONS: "CONDITIONS";
|
|
@@ -182,21 +179,17 @@ export declare const TeamInputSchema: z.ZodObject<{
|
|
|
182
179
|
}, z.core.$strip>, z.ZodObject<{
|
|
183
180
|
type: z.ZodLiteral<import("..").PinchConditionType.PHASE>;
|
|
184
181
|
phase: z.ZodEnum<typeof import("..").MatchPhase>;
|
|
182
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
183
|
+
type: z.ZodLiteral<import("..").PinchConditionType.FATIGUE>;
|
|
184
|
+
band: z.ZodOptional<z.ZodEnum<typeof import("..").EnergyBand>>;
|
|
185
185
|
}, z.core.$strip>], "type">>>;
|
|
186
186
|
subBackConditionLogic: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"ALL">, z.ZodLiteral<"ANY">]>>;
|
|
187
187
|
starter: z.ZodCustom<Player, Player>;
|
|
188
|
-
}, z.core.$strip
|
|
188
|
+
}, z.core.$strip>>>>;
|
|
189
189
|
substitutionBand: z.ZodDefault<z.ZodUnion<readonly [z.ZodEnum<typeof import("..").EnergyBand>, z.ZodLiteral<"NEVER">]>>;
|
|
190
190
|
secondLibero: z.ZodOptional<z.ZodCustom<Player, Player>>;
|
|
191
|
-
liberoSub: z.ZodOptional<z.ZodObject<{
|
|
192
|
-
sets: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
193
|
-
mode: z.ZodEnum<{
|
|
194
|
-
NEVER: "NEVER";
|
|
195
|
-
FATIGUE: "FATIGUE";
|
|
196
|
-
CONDITIONS: "CONDITIONS";
|
|
197
|
-
ALWAYS: "ALWAYS";
|
|
198
|
-
}>;
|
|
199
|
-
fatigueBand: z.ZodOptional<z.ZodEnum<typeof import("..").EnergyBand>>;
|
|
191
|
+
liberoSub: z.ZodOptional<z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodObject<{
|
|
192
|
+
sets: z.ZodOptional<z.ZodArray<z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodObject<{
|
|
200
193
|
conditions: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
201
194
|
type: z.ZodLiteral<import("..").PinchConditionType.ASAP>;
|
|
202
195
|
}, z.core.$strip>, z.ZodObject<{
|
|
@@ -228,16 +221,12 @@ export declare const TeamInputSchema: z.ZodObject<{
|
|
|
228
221
|
}, z.core.$strip>, z.ZodObject<{
|
|
229
222
|
type: z.ZodLiteral<import("..").PinchConditionType.PHASE>;
|
|
230
223
|
phase: z.ZodEnum<typeof import("..").MatchPhase>;
|
|
224
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
225
|
+
type: z.ZodLiteral<import("..").PinchConditionType.FATIGUE>;
|
|
226
|
+
band: z.ZodOptional<z.ZodEnum<typeof import("..").EnergyBand>>;
|
|
231
227
|
}, z.core.$strip>], "type">>>;
|
|
232
228
|
conditionLogic: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"ALL">, z.ZodLiteral<"ANY">]>>;
|
|
233
|
-
}, z.core.$strip
|
|
234
|
-
mode: z.ZodEnum<{
|
|
235
|
-
NEVER: "NEVER";
|
|
236
|
-
FATIGUE: "FATIGUE";
|
|
237
|
-
CONDITIONS: "CONDITIONS";
|
|
238
|
-
ALWAYS: "ALWAYS";
|
|
239
|
-
}>;
|
|
240
|
-
fatigueBand: z.ZodOptional<z.ZodEnum<typeof import("..").EnergyBand>>;
|
|
229
|
+
}, z.core.$strip>>>>;
|
|
241
230
|
conditions: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
242
231
|
type: z.ZodLiteral<import("..").PinchConditionType.ASAP>;
|
|
243
232
|
}, z.core.$strip>, z.ZodObject<{
|
|
@@ -269,15 +258,18 @@ export declare const TeamInputSchema: z.ZodObject<{
|
|
|
269
258
|
}, z.core.$strip>, z.ZodObject<{
|
|
270
259
|
type: z.ZodLiteral<import("..").PinchConditionType.PHASE>;
|
|
271
260
|
phase: z.ZodEnum<typeof import("..").MatchPhase>;
|
|
261
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
262
|
+
type: z.ZodLiteral<import("..").PinchConditionType.FATIGUE>;
|
|
263
|
+
band: z.ZodOptional<z.ZodEnum<typeof import("..").EnergyBand>>;
|
|
272
264
|
}, z.core.$strip>], "type">>>;
|
|
273
265
|
conditionLogic: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"ALL">, z.ZodLiteral<"ANY">]>>;
|
|
274
|
-
}, z.core.$strip
|
|
266
|
+
}, z.core.$strip>>>;
|
|
275
267
|
liberoReplacementSets: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodCustom<Player, Player>>>>;
|
|
276
268
|
rotationSystem: z.ZodDefault<z.ZodEnum<typeof import("..").RotationSystemEnum>>;
|
|
277
269
|
designatedSetters: z.ZodDefault<z.ZodArray<z.ZodCustom<Player, Player>>>;
|
|
278
270
|
offensivePreferences: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
279
271
|
rotation: z.ZodNumber;
|
|
280
|
-
|
|
272
|
+
weights: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
281
273
|
tempos: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
282
274
|
FAST: "FAST";
|
|
283
275
|
HIGH: "HIGH";
|
|
@@ -289,12 +281,20 @@ export declare const TeamInputSchema: z.ZodObject<{
|
|
|
289
281
|
}, z.core.$strip>>>;
|
|
290
282
|
offensivePreferenceSets: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodObject<{
|
|
291
283
|
rotation: z.ZodNumber;
|
|
292
|
-
|
|
284
|
+
weights: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
293
285
|
tempos: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
294
286
|
FAST: "FAST";
|
|
295
287
|
HIGH: "HIGH";
|
|
296
288
|
}>>>;
|
|
297
289
|
}, z.core.$strip>>>>;
|
|
290
|
+
blockingPreferences: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
291
|
+
rotation: z.ZodNumber;
|
|
292
|
+
targets: z.ZodRecord<z.ZodString, z.ZodEnum<typeof import("../../player").RoleEnum> & z.ZodType<import("../../player").RoleEnum.SETTER | import("../../player").RoleEnum.OUTSIDE_HITTER | import("../../player").RoleEnum.OPPOSITE_HITTER | import("../../player").RoleEnum.MIDDLE_BLOCKER, import("../../player").RoleEnum, z.core.$ZodTypeInternals<import("../../player").RoleEnum.SETTER | import("../../player").RoleEnum.OUTSIDE_HITTER | import("../../player").RoleEnum.OPPOSITE_HITTER | import("../../player").RoleEnum.MIDDLE_BLOCKER, import("../../player").RoleEnum>>>;
|
|
293
|
+
}, z.core.$strip>>>;
|
|
294
|
+
blockingPreferenceSets: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodObject<{
|
|
295
|
+
rotation: z.ZodNumber;
|
|
296
|
+
targets: z.ZodRecord<z.ZodString, z.ZodEnum<typeof import("../../player").RoleEnum> & z.ZodType<import("../../player").RoleEnum.SETTER | import("../../player").RoleEnum.OUTSIDE_HITTER | import("../../player").RoleEnum.OPPOSITE_HITTER | import("../../player").RoleEnum.MIDDLE_BLOCKER, import("../../player").RoleEnum, z.core.$ZodTypeInternals<import("../../player").RoleEnum.SETTER | import("../../player").RoleEnum.OUTSIDE_HITTER | import("../../player").RoleEnum.OPPOSITE_HITTER | import("../../player").RoleEnum.MIDDLE_BLOCKER, import("../../player").RoleEnum>>>;
|
|
297
|
+
}, z.core.$strip>>>>;
|
|
298
298
|
replaceKnockedImmediately: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
|
|
299
299
|
injuryReplacements: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
300
300
|
starter: z.ZodCustom<Player, Player>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert ONE legacy set-sub config (flat or per-set entry). Handles BOTH legacy generations:
|
|
3
|
+
* mode-era rows ({mode: NEVER|FATIGUE|PINCH}) and the oldest isPinchServer-era rows (no mode;
|
|
4
|
+
* isPinchServer flag + a 'NEVER' fatigueBand for the old never-sub state). Non-records and
|
|
5
|
+
* already-unified shapes (neither mode nor isPinchServer nor fatigueBand keys) pass through.
|
|
6
|
+
*/
|
|
7
|
+
export declare function convertLegacySetSubConfig(raw: unknown): unknown;
|
|
8
|
+
/** Convert a legacy DesignatedSub (flat fields + per-set entries); unified shapes pass through. */
|
|
9
|
+
export declare function convertLegacyDesignatedSub(raw: unknown): unknown;
|
|
10
|
+
/** Convert ONE legacy libero set-sub config; unified shapes pass through. */
|
|
11
|
+
export declare function convertLegacyLiberoSetSubConfig(raw: unknown): unknown;
|
|
12
|
+
/** Convert a legacy LiberoSubConfig (flat fields + per-set entries); unified shapes pass through. */
|
|
13
|
+
export declare function convertLegacyLiberoSubConfig(raw: unknown): unknown;
|