volleyballsimtypes 0.0.476 → 0.0.478

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/cjs/src/api/index.d.ts +9 -1
  2. package/dist/cjs/src/data/models/auth-session.d.ts +5 -1
  3. package/dist/cjs/src/data/models/auth-session.js +8 -0
  4. package/dist/cjs/src/data/models/tactics.d.ts +9 -1
  5. package/dist/cjs/src/data/transformers/tactics.js +33 -3
  6. package/dist/cjs/src/data/transformers/tactics.test.js +31 -0
  7. package/dist/cjs/src/service/team/designated-sub.d.ts +5 -0
  8. package/dist/cjs/src/service/team/pinch-condition.d.ts +7 -0
  9. package/dist/cjs/src/service/team/pinch-condition.js +10 -1
  10. package/dist/cjs/src/service/team/schemas/designated-sub.z.d.ts +131 -1
  11. package/dist/cjs/src/service/team/schemas/designated-sub.z.js +20 -6
  12. package/dist/cjs/src/service/team/schemas/designated-sub.z.test.js +83 -0
  13. package/dist/cjs/src/service/team/schemas/libero-sub.z.d.ts +13 -4
  14. package/dist/cjs/src/service/team/schemas/tactics.z.d.ts +90 -2
  15. package/dist/cjs/src/service/team/schemas/team.z.d.ts +90 -2
  16. package/dist/esm/src/api/index.d.ts +9 -1
  17. package/dist/esm/src/data/models/auth-session.d.ts +5 -1
  18. package/dist/esm/src/data/models/auth-session.js +8 -0
  19. package/dist/esm/src/data/models/tactics.d.ts +9 -1
  20. package/dist/esm/src/data/transformers/tactics.js +33 -3
  21. package/dist/esm/src/data/transformers/tactics.test.js +31 -0
  22. package/dist/esm/src/service/team/designated-sub.d.ts +5 -0
  23. package/dist/esm/src/service/team/pinch-condition.d.ts +7 -0
  24. package/dist/esm/src/service/team/pinch-condition.js +9 -0
  25. package/dist/esm/src/service/team/schemas/designated-sub.z.d.ts +131 -1
  26. package/dist/esm/src/service/team/schemas/designated-sub.z.js +20 -6
  27. package/dist/esm/src/service/team/schemas/designated-sub.z.test.js +84 -1
  28. package/dist/esm/src/service/team/schemas/libero-sub.z.d.ts +13 -4
  29. package/dist/esm/src/service/team/schemas/tactics.z.d.ts +90 -2
  30. package/dist/esm/src/service/team/schemas/team.z.d.ts +90 -2
  31. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { BoxScore, DataProps, DeclineStatus, Division as _Division, League as _League, Match as _Match, MatchSet as _MatchSet, Player as _Player, PlayerPosition, Qualifier as _Qualifier, QualifierMatch as _QualifierMatch, Rally as _Rally, RallyEvent as _RallyEvent, PointBreakdown, RallyMetrics, Season as _Season, Standing as _Standing, Team as _Team, Tournament as _Tournament, TournamentMatch as _TournamentMatch, National as _National, NationalMatch as _NationalMatch, Country as _Country, CourtPosition, ConditionLogic, EnergyBand, LiberoSubMode, MatchForfeitType, PerformanceStats, PinchCondition, RotationSystemEnum, SubBand, SubMode } from '../service';
1
+ import { BoxScore, DataProps, DeclineStatus, Division as _Division, League as _League, Match as _Match, MatchSet as _MatchSet, Player as _Player, PlayerPosition, Qualifier as _Qualifier, QualifierMatch as _QualifierMatch, Rally as _Rally, RallyEvent as _RallyEvent, PointBreakdown, RallyMetrics, Season as _Season, Standing as _Standing, Team as _Team, Tournament as _Tournament, TournamentMatch as _TournamentMatch, National as _National, NationalMatch as _NationalMatch, Country as _Country, CourtPosition, ConditionLogic, EnergyBand, LiberoSubMode, MatchForfeitType, PerformanceStats, PinchCondition, RotationSystemEnum, SubBackMode, SubBand, SubMode } from '../service';
2
2
  export type Rally = DataProps<_Rally> & {
3
3
  homePlayerPosition: PlayerPosition[];
4
4
  awayPlayerPosition: PlayerPosition[];
@@ -87,6 +87,10 @@ export interface ApiSetSubConfig {
87
87
  benchFatigueBand?: EnergyBand;
88
88
  conditions?: PinchCondition[];
89
89
  conditionLogic?: ConditionLogic;
90
+ pinchServer?: boolean;
91
+ subBackMode?: SubBackMode;
92
+ subBackConditions?: PinchCondition[];
93
+ subBackConditionLogic?: ConditionLogic;
90
94
  }
91
95
  export interface ApiDesignatedSub {
92
96
  starterId: string;
@@ -96,6 +100,10 @@ export interface ApiDesignatedSub {
96
100
  benchFatigueBand?: EnergyBand;
97
101
  conditions?: PinchCondition[];
98
102
  conditionLogic?: ConditionLogic;
103
+ pinchServer?: boolean;
104
+ subBackMode?: SubBackMode;
105
+ subBackConditions?: PinchCondition[];
106
+ subBackConditionLogic?: ConditionLogic;
99
107
  sets?: ApiSetSubConfig[];
100
108
  }
101
109
  export interface ApiOffensivePreference {
@@ -11,10 +11,12 @@ export interface AuthSessionAttributes {
11
11
  user_agent?: string | null;
12
12
  created_at?: Date;
13
13
  updated_at?: Date;
14
+ previous_refresh_token_hash?: string | null;
15
+ previous_token_expires_at?: Date | null;
14
16
  }
15
17
  export type AuthSessionPk = 'session_id';
16
18
  export type AuthSessionId = AuthSessionModel[AuthSessionPk];
17
- export type AuthSessionOptionalAttributes = 'revoked_at' | 'ip_address' | 'user_agent' | 'created_at' | 'updated_at';
19
+ export type AuthSessionOptionalAttributes = 'revoked_at' | 'ip_address' | 'user_agent' | 'created_at' | 'updated_at' | 'previous_refresh_token_hash' | 'previous_token_expires_at';
18
20
  export type AuthSessionCreationAttributes = Optional<AuthSessionAttributes, AuthSessionOptionalAttributes>;
19
21
  export declare class AuthSessionModel extends Model<AuthSessionAttributes, AuthSessionCreationAttributes> implements AuthSessionAttributes {
20
22
  session_id: string;
@@ -26,6 +28,8 @@ export declare class AuthSessionModel extends Model<AuthSessionAttributes, AuthS
26
28
  user_agent?: string | null;
27
29
  created_at?: Date;
28
30
  updated_at?: Date;
31
+ previous_refresh_token_hash?: string | null;
32
+ previous_token_expires_at?: Date | null;
29
33
  user: AuthUserModel;
30
34
  getUser: Sequelize.BelongsToGetAssociationMixin<AuthUserModel>;
31
35
  setUser: Sequelize.BelongsToSetAssociationMixin<AuthUserModel, AuthUserId>;
@@ -47,6 +47,14 @@ class AuthSessionModel extends sequelize_1.Model {
47
47
  type: sequelize_1.DataTypes.DATE,
48
48
  allowNull: false,
49
49
  defaultValue: sequelize_1.DataTypes.NOW
50
+ },
51
+ previous_refresh_token_hash: {
52
+ type: sequelize_1.DataTypes.STRING,
53
+ allowNull: true
54
+ },
55
+ previous_token_expires_at: {
56
+ type: sequelize_1.DataTypes.DATE,
57
+ allowNull: true
50
58
  }
51
59
  }, {
52
60
  sequelize,
@@ -1,7 +1,7 @@
1
1
  import * as Sequelize from 'sequelize';
2
2
  import { Model, Optional } from 'sequelize';
3
3
  import { PlayerId, TeamId, TeamModel } from '.';
4
- import { ConditionLogic, CourtPosition, EnergyBand, LiberoSubMode, PinchCondition, RotationSystemEnum, SubBand, SubMode } from '../../service';
4
+ import { ConditionLogic, CourtPosition, EnergyBand, LiberoSubMode, PinchCondition, RotationSystemEnum, SubBackMode, SubBand, SubMode } from '../../service';
5
5
  export interface TacticsLineupAttributes {
6
6
  [CourtPosition.LIBERO_ZONE]?: PlayerId;
7
7
  [CourtPosition.LEFT_BACK]: PlayerId;
@@ -19,6 +19,10 @@ export interface SetSubConfigAttributes {
19
19
  benchFatigueBand?: EnergyBand;
20
20
  conditions?: PinchCondition[];
21
21
  conditionLogic?: ConditionLogic;
22
+ pinchServer?: boolean;
23
+ subBackMode?: SubBackMode;
24
+ subBackConditions?: PinchCondition[];
25
+ subBackConditionLogic?: ConditionLogic;
22
26
  }
23
27
  export interface DesignatedSubAttributes {
24
28
  starterId: PlayerId;
@@ -29,6 +33,10 @@ export interface DesignatedSubAttributes {
29
33
  benchFatigueBand?: EnergyBand;
30
34
  conditions?: PinchCondition[];
31
35
  conditionLogic?: ConditionLogic;
36
+ pinchServer?: boolean;
37
+ subBackMode?: SubBackMode;
38
+ subBackConditions?: PinchCondition[];
39
+ subBackConditionLogic?: ConditionLogic;
32
40
  sets?: SetSubConfigAttributes[];
33
41
  }
34
42
  export interface OffensivePreferenceAttributes {
@@ -17,6 +17,12 @@ function subModeFromAttributes(d) {
17
17
  return 'NEVER';
18
18
  return 'FATIGUE';
19
19
  }
20
+ // pinchServer only applies to PINCH ("Conditions") mode. A LEGACY PINCH row (no flag) defaults to true so
21
+ // existing pinch servers keep serve-and-return behavior; a new conditional sub persists an explicit false. This
22
+ // default must resolve identically on every READ path (both transformToObject and tacticsColumnsToApiDto).
23
+ function effectivePinchServer(mode, pinchServer) {
24
+ return mode === 'PINCH' ? (pinchServer ?? true) : undefined;
25
+ }
20
26
  function findPlayer(id, roster) {
21
27
  const player = roster.find((p) => p.id === id);
22
28
  if (player == null)
@@ -65,13 +71,21 @@ function transformToAttributes(tactics, teamId) {
65
71
  benchFatigueBand: ds.benchFatigueBand,
66
72
  conditions: ds.conditions,
67
73
  conditionLogic: ds.conditionLogic,
74
+ pinchServer: ds.pinchServer,
75
+ subBackMode: ds.subBackMode,
76
+ subBackConditions: ds.subBackConditions,
77
+ subBackConditionLogic: ds.subBackConditionLogic,
68
78
  sets: ds.sets?.map(s => ({
69
79
  mode: s.mode,
70
80
  benchId: s.bench?.id,
71
81
  fatigueBand: s.fatigueBand,
72
82
  benchFatigueBand: s.benchFatigueBand,
73
83
  conditions: s.conditions,
74
- conditionLogic: s.conditionLogic
84
+ conditionLogic: s.conditionLogic,
85
+ pinchServer: s.pinchServer,
86
+ subBackMode: s.subBackMode,
87
+ subBackConditions: s.subBackConditions,
88
+ subBackConditionLogic: s.subBackConditionLogic
75
89
  }))
76
90
  })),
77
91
  rotation_system: tactics.rotationSystem,
@@ -155,13 +169,21 @@ function transformToObject(model, roster) {
155
169
  benchFatigueBand: d.benchFatigueBand,
156
170
  conditions: d.conditions,
157
171
  conditionLogic: d.conditionLogic,
172
+ pinchServer: effectivePinchServer(subModeFromAttributes(d), d.pinchServer),
173
+ subBackMode: d.subBackMode,
174
+ subBackConditions: d.subBackConditions,
175
+ subBackConditionLogic: d.subBackConditionLogic,
158
176
  sets: d.sets?.map(s => ({
159
177
  mode: s.mode,
160
178
  bench: s.benchId != null ? findPlayer(s.benchId, roster) : undefined,
161
179
  fatigueBand: s.fatigueBand,
162
180
  benchFatigueBand: s.benchFatigueBand,
163
181
  conditions: s.conditions,
164
- conditionLogic: s.conditionLogic
182
+ conditionLogic: s.conditionLogic,
183
+ pinchServer: effectivePinchServer(s.mode, s.pinchServer),
184
+ subBackMode: s.subBackMode,
185
+ subBackConditions: s.subBackConditions,
186
+ subBackConditionLogic: s.subBackConditionLogic
165
187
  }))
166
188
  })),
167
189
  rotationSystem: model.rotation_system,
@@ -312,13 +334,21 @@ function tacticsColumnsToApiDto(model) {
312
334
  benchFatigueBand: d.benchFatigueBand,
313
335
  conditions: d.conditions,
314
336
  conditionLogic: d.conditionLogic,
337
+ pinchServer: effectivePinchServer(subModeFromAttributes(d), d.pinchServer),
338
+ subBackMode: d.subBackMode,
339
+ subBackConditions: d.subBackConditions,
340
+ subBackConditionLogic: d.subBackConditionLogic,
315
341
  sets: d.sets?.map(s => ({
316
342
  mode: s.mode,
317
343
  benchId: s.benchId,
318
344
  fatigueBand: s.fatigueBand,
319
345
  benchFatigueBand: s.benchFatigueBand,
320
346
  conditions: s.conditions,
321
- conditionLogic: s.conditionLogic
347
+ conditionLogic: s.conditionLogic,
348
+ pinchServer: effectivePinchServer(s.mode, s.pinchServer),
349
+ subBackMode: s.subBackMode,
350
+ subBackConditions: s.subBackConditions,
351
+ subBackConditionLogic: s.subBackConditionLogic
322
352
  }))
323
353
  })),
324
354
  rotationSystem: model.rotation_system,
@@ -60,6 +60,37 @@ function makeTactics(designatedSubs) {
60
60
  (0, globals_1.expect)(dto.designatedSubs[0].fatigueBand).toBe(service_1.EnergyBand.WORN);
61
61
  (0, globals_1.expect)(dto.designatedSubs[0].benchFatigueBand).toBe(service_1.EnergyBand.TIRED);
62
62
  });
63
+ (0, globals_1.it)('defaults a legacy PINCH row (no pinchServer flag) to pinchServer true', () => {
64
+ const dto = (0, tactics_1.tacticsColumnsToApiDto)(makeTactics([
65
+ { starterId: 's1', benchId: 'b1', mode: 'PINCH', conditions: [{ type: 'ASAP' }] }
66
+ ]));
67
+ (0, globals_1.expect)(dto.designatedSubs[0].pinchServer).toBe(true);
68
+ });
69
+ (0, globals_1.it)('leaves pinchServer undefined for a non-PINCH row', () => {
70
+ const dto = (0, tactics_1.tacticsColumnsToApiDto)(makeTactics([
71
+ { starterId: 's1', benchId: 'b1', mode: 'FATIGUE', fatigueBand: service_1.EnergyBand.TIRED }
72
+ ]));
73
+ (0, globals_1.expect)(dto.designatedSubs[0].pinchServer).toBeUndefined();
74
+ });
75
+ (0, globals_1.it)('passes a conditional regular sub (pinchServer false + condition sub-back) through unchanged', () => {
76
+ const dto = (0, tactics_1.tacticsColumnsToApiDto)(makeTactics([
77
+ {
78
+ starterId: 's1',
79
+ benchId: 'b1',
80
+ mode: 'PINCH',
81
+ conditions: [{ type: 'SCORE_DIFF', direction: 'TRAILING', points: 3 }],
82
+ pinchServer: false,
83
+ subBackMode: 'CONDITIONS',
84
+ subBackConditions: [{ type: 'TEAM_SET_POINT', margin: 2, opponent: 'EITHER' }],
85
+ subBackConditionLogic: 'ANY'
86
+ }
87
+ ]));
88
+ const ds = dto.designatedSubs[0];
89
+ (0, globals_1.expect)(ds.pinchServer).toBe(false);
90
+ (0, globals_1.expect)(ds.subBackMode).toBe('CONDITIONS');
91
+ (0, globals_1.expect)(ds.subBackConditions).toEqual([{ type: 'TEAM_SET_POINT', margin: 2, opponent: 'EITHER' }]);
92
+ (0, globals_1.expect)(ds.subBackConditionLogic).toBe('ANY');
93
+ });
63
94
  (0, globals_1.it)('drops a second libero that collides with the starting libero (not a reserve)', () => {
64
95
  const model = makeTactics([]);
65
96
  model.lineup[service_1.CourtPosition.LIBERO_ZONE] = 'libero1';
@@ -1,6 +1,7 @@
1
1
  import { Player } from '../player';
2
2
  import { EnergyBand, SubMode } from './energy-band';
3
3
  import { ConditionLogic, PinchCondition } from './pinch-condition';
4
+ export type SubBackMode = 'FATIGUE' | 'CONDITIONS';
4
5
  export interface SetSubConfig {
5
6
  readonly mode: SubMode;
6
7
  readonly bench?: Player;
@@ -8,6 +9,10 @@ export interface SetSubConfig {
8
9
  readonly benchFatigueBand?: EnergyBand;
9
10
  readonly conditions?: PinchCondition[];
10
11
  readonly conditionLogic?: ConditionLogic;
12
+ readonly pinchServer?: boolean;
13
+ readonly subBackMode?: SubBackMode;
14
+ readonly subBackConditions?: PinchCondition[];
15
+ readonly subBackConditionLogic?: ConditionLogic;
11
16
  }
12
17
  export interface DesignatedSub extends SetSubConfig {
13
18
  readonly starter: Player;
@@ -22,6 +22,10 @@ export declare enum ScoreDirection {
22
22
  TRAILING = "TRAILING",
23
23
  LEADING = "LEADING"
24
24
  }
25
+ export declare enum Comparison {
26
+ AT_LEAST = "AT_LEAST",
27
+ AT_MOST = "AT_MOST"
28
+ }
25
29
  export interface AsapCondition {
26
30
  readonly type: PinchConditionType.ASAP;
27
31
  }
@@ -38,6 +42,7 @@ export interface ScoreDiffCondition {
38
42
  readonly type: PinchConditionType.SCORE_DIFF;
39
43
  readonly direction: ScoreDirection;
40
44
  readonly points: number;
45
+ readonly comparison?: Comparison;
41
46
  }
42
47
  export interface AfterRotationsCondition {
43
48
  readonly type: PinchConditionType.AFTER_ROTATIONS;
@@ -50,10 +55,12 @@ export interface FromSetCondition {
50
55
  export interface MinOwnScoreCondition {
51
56
  readonly type: PinchConditionType.MIN_OWN_SCORE;
52
57
  readonly score: number;
58
+ readonly comparison?: Comparison;
53
59
  }
54
60
  export interface MinOpponentScoreCondition {
55
61
  readonly type: PinchConditionType.MIN_OPPONENT_SCORE;
56
62
  readonly score: number;
63
+ readonly comparison?: Comparison;
57
64
  }
58
65
  export interface PhaseCondition {
59
66
  readonly type: PinchConditionType.PHASE;
@@ -3,7 +3,7 @@
3
3
  // wins back the serve, out the moment the serve is lost). Each condition is evaluated against the live set
4
4
  // state; a pinch entry combines them with ALL (every condition must hold) or ANY (one is enough).
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ScoreDirection = exports.OpponentRelation = exports.MatchPhase = exports.PinchConditionType = void 0;
6
+ exports.Comparison = exports.ScoreDirection = exports.OpponentRelation = exports.MatchPhase = exports.PinchConditionType = void 0;
7
7
  var PinchConditionType;
8
8
  (function (PinchConditionType) {
9
9
  PinchConditionType["ASAP"] = "ASAP";
@@ -34,3 +34,12 @@ var ScoreDirection;
34
34
  ScoreDirection["TRAILING"] = "TRAILING";
35
35
  ScoreDirection["LEADING"] = "LEADING";
36
36
  })(ScoreDirection || (exports.ScoreDirection = ScoreDirection = {}));
37
+ // Comparison direction for a numeric-threshold condition (SCORE_DIFF / MIN_OWN_SCORE / MIN_OPPONENT_SCORE).
38
+ // AT_LEAST ("Or more", value >= threshold) is the default when absent, so every existing stored condition keeps
39
+ // its `>=` behavior. AT_MOST ("Or less", value <= threshold) lets a rule fire as a value SHRINKS (e.g. a sub-back
40
+ // once "Leading by 2 or less" holds, instead of the always-implied "Leading by 2 or more").
41
+ var Comparison;
42
+ (function (Comparison) {
43
+ Comparison["AT_LEAST"] = "AT_LEAST";
44
+ Comparison["AT_MOST"] = "AT_MOST";
45
+ })(Comparison || (exports.Comparison = Comparison = {}));
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { Player } from '../../player';
3
3
  import { EnergyBand } from '../energy-band';
4
- import { MatchPhase, OpponentRelation, PinchConditionType, ScoreDirection } from '../pinch-condition';
4
+ import { Comparison, MatchPhase, OpponentRelation, PinchConditionType, ScoreDirection } from '../pinch-condition';
5
5
  export declare const SubBandSchema: z.ZodUnion<readonly [z.ZodEnum<typeof EnergyBand>, z.ZodLiteral<"NEVER">]>;
6
6
  export declare const PinchConditionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
7
7
  type: z.ZodLiteral<PinchConditionType.ASAP>;
@@ -16,6 +16,7 @@ export declare const PinchConditionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
16
16
  type: z.ZodLiteral<PinchConditionType.SCORE_DIFF>;
17
17
  direction: z.ZodEnum<typeof ScoreDirection>;
18
18
  points: z.ZodNumber;
19
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
19
20
  }, z.core.$strip>, z.ZodObject<{
20
21
  type: z.ZodLiteral<PinchConditionType.AFTER_ROTATIONS>;
21
22
  rotations: z.ZodNumber;
@@ -25,9 +26,11 @@ export declare const PinchConditionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
25
26
  }, z.core.$strip>, z.ZodObject<{
26
27
  type: z.ZodLiteral<PinchConditionType.MIN_OWN_SCORE>;
27
28
  score: z.ZodNumber;
29
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
28
30
  }, z.core.$strip>, z.ZodObject<{
29
31
  type: z.ZodLiteral<PinchConditionType.MIN_OPPONENT_SCORE>;
30
32
  score: z.ZodNumber;
33
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
31
34
  }, z.core.$strip>, z.ZodObject<{
32
35
  type: z.ZodLiteral<PinchConditionType.PHASE>;
33
36
  phase: z.ZodEnum<typeof MatchPhase>;
@@ -38,6 +41,10 @@ export declare const SubModeSchema: z.ZodEnum<{
38
41
  FATIGUE: "FATIGUE";
39
42
  PINCH: "PINCH";
40
43
  }>;
44
+ export declare const SubBackModeSchema: z.ZodEnum<{
45
+ FATIGUE: "FATIGUE";
46
+ CONDITIONS: "CONDITIONS";
47
+ }>;
41
48
  export declare const SetSubConfigSchema: z.ZodObject<{
42
49
  mode: z.ZodEnum<{
43
50
  NEVER: "NEVER";
@@ -60,6 +67,7 @@ export declare const SetSubConfigSchema: z.ZodObject<{
60
67
  type: z.ZodLiteral<PinchConditionType.SCORE_DIFF>;
61
68
  direction: z.ZodEnum<typeof ScoreDirection>;
62
69
  points: z.ZodNumber;
70
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
63
71
  }, z.core.$strip>, z.ZodObject<{
64
72
  type: z.ZodLiteral<PinchConditionType.AFTER_ROTATIONS>;
65
73
  rotations: z.ZodNumber;
@@ -69,14 +77,54 @@ export declare const SetSubConfigSchema: z.ZodObject<{
69
77
  }, z.core.$strip>, z.ZodObject<{
70
78
  type: z.ZodLiteral<PinchConditionType.MIN_OWN_SCORE>;
71
79
  score: z.ZodNumber;
80
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
72
81
  }, z.core.$strip>, z.ZodObject<{
73
82
  type: z.ZodLiteral<PinchConditionType.MIN_OPPONENT_SCORE>;
74
83
  score: z.ZodNumber;
84
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
75
85
  }, z.core.$strip>, z.ZodObject<{
76
86
  type: z.ZodLiteral<PinchConditionType.PHASE>;
77
87
  phase: z.ZodEnum<typeof MatchPhase>;
78
88
  }, z.core.$strip>], "type">>>;
79
89
  conditionLogic: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"ALL">, z.ZodLiteral<"ANY">]>>;
90
+ pinchServer: z.ZodOptional<z.ZodBoolean>;
91
+ subBackMode: z.ZodOptional<z.ZodEnum<{
92
+ FATIGUE: "FATIGUE";
93
+ CONDITIONS: "CONDITIONS";
94
+ }>>;
95
+ subBackConditions: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
96
+ type: z.ZodLiteral<PinchConditionType.ASAP>;
97
+ }, z.core.$strip>, z.ZodObject<{
98
+ type: z.ZodLiteral<PinchConditionType.TEAM_SET_POINT>;
99
+ margin: z.ZodNumber;
100
+ opponent: z.ZodEnum<typeof OpponentRelation>;
101
+ }, z.core.$strip>, z.ZodObject<{
102
+ type: z.ZodLiteral<PinchConditionType.OPPONENT_SET_POINT>;
103
+ margin: z.ZodNumber;
104
+ }, z.core.$strip>, z.ZodObject<{
105
+ type: z.ZodLiteral<PinchConditionType.SCORE_DIFF>;
106
+ direction: z.ZodEnum<typeof ScoreDirection>;
107
+ points: z.ZodNumber;
108
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
109
+ }, z.core.$strip>, z.ZodObject<{
110
+ type: z.ZodLiteral<PinchConditionType.AFTER_ROTATIONS>;
111
+ rotations: z.ZodNumber;
112
+ }, z.core.$strip>, z.ZodObject<{
113
+ type: z.ZodLiteral<PinchConditionType.FROM_SET>;
114
+ set: z.ZodNumber;
115
+ }, z.core.$strip>, z.ZodObject<{
116
+ type: z.ZodLiteral<PinchConditionType.MIN_OWN_SCORE>;
117
+ score: z.ZodNumber;
118
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
119
+ }, z.core.$strip>, z.ZodObject<{
120
+ type: z.ZodLiteral<PinchConditionType.MIN_OPPONENT_SCORE>;
121
+ score: z.ZodNumber;
122
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
123
+ }, z.core.$strip>, z.ZodObject<{
124
+ type: z.ZodLiteral<PinchConditionType.PHASE>;
125
+ phase: z.ZodEnum<typeof MatchPhase>;
126
+ }, z.core.$strip>], "type">>>;
127
+ subBackConditionLogic: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"ALL">, z.ZodLiteral<"ANY">]>>;
80
128
  }, z.core.$strip>;
81
129
  export declare const DesignatedSubSchema: z.ZodObject<{
82
130
  sets: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -101,6 +149,7 @@ export declare const DesignatedSubSchema: z.ZodObject<{
101
149
  type: z.ZodLiteral<PinchConditionType.SCORE_DIFF>;
102
150
  direction: z.ZodEnum<typeof ScoreDirection>;
103
151
  points: z.ZodNumber;
152
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
104
153
  }, z.core.$strip>, z.ZodObject<{
105
154
  type: z.ZodLiteral<PinchConditionType.AFTER_ROTATIONS>;
106
155
  rotations: z.ZodNumber;
@@ -110,14 +159,54 @@ export declare const DesignatedSubSchema: z.ZodObject<{
110
159
  }, z.core.$strip>, z.ZodObject<{
111
160
  type: z.ZodLiteral<PinchConditionType.MIN_OWN_SCORE>;
112
161
  score: z.ZodNumber;
162
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
113
163
  }, z.core.$strip>, z.ZodObject<{
114
164
  type: z.ZodLiteral<PinchConditionType.MIN_OPPONENT_SCORE>;
115
165
  score: z.ZodNumber;
166
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
116
167
  }, z.core.$strip>, z.ZodObject<{
117
168
  type: z.ZodLiteral<PinchConditionType.PHASE>;
118
169
  phase: z.ZodEnum<typeof MatchPhase>;
119
170
  }, z.core.$strip>], "type">>>;
120
171
  conditionLogic: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"ALL">, z.ZodLiteral<"ANY">]>>;
172
+ pinchServer: z.ZodOptional<z.ZodBoolean>;
173
+ subBackMode: z.ZodOptional<z.ZodEnum<{
174
+ FATIGUE: "FATIGUE";
175
+ CONDITIONS: "CONDITIONS";
176
+ }>>;
177
+ subBackConditions: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
178
+ type: z.ZodLiteral<PinchConditionType.ASAP>;
179
+ }, z.core.$strip>, z.ZodObject<{
180
+ type: z.ZodLiteral<PinchConditionType.TEAM_SET_POINT>;
181
+ margin: z.ZodNumber;
182
+ opponent: z.ZodEnum<typeof OpponentRelation>;
183
+ }, z.core.$strip>, z.ZodObject<{
184
+ type: z.ZodLiteral<PinchConditionType.OPPONENT_SET_POINT>;
185
+ margin: z.ZodNumber;
186
+ }, z.core.$strip>, z.ZodObject<{
187
+ type: z.ZodLiteral<PinchConditionType.SCORE_DIFF>;
188
+ direction: z.ZodEnum<typeof ScoreDirection>;
189
+ points: z.ZodNumber;
190
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
191
+ }, z.core.$strip>, z.ZodObject<{
192
+ type: z.ZodLiteral<PinchConditionType.AFTER_ROTATIONS>;
193
+ rotations: z.ZodNumber;
194
+ }, z.core.$strip>, z.ZodObject<{
195
+ type: z.ZodLiteral<PinchConditionType.FROM_SET>;
196
+ set: z.ZodNumber;
197
+ }, z.core.$strip>, z.ZodObject<{
198
+ type: z.ZodLiteral<PinchConditionType.MIN_OWN_SCORE>;
199
+ score: z.ZodNumber;
200
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
201
+ }, z.core.$strip>, z.ZodObject<{
202
+ type: z.ZodLiteral<PinchConditionType.MIN_OPPONENT_SCORE>;
203
+ score: z.ZodNumber;
204
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
205
+ }, z.core.$strip>, z.ZodObject<{
206
+ type: z.ZodLiteral<PinchConditionType.PHASE>;
207
+ phase: z.ZodEnum<typeof MatchPhase>;
208
+ }, z.core.$strip>], "type">>>;
209
+ subBackConditionLogic: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"ALL">, z.ZodLiteral<"ANY">]>>;
121
210
  }, z.core.$strip>>>;
122
211
  mode: z.ZodEnum<{
123
212
  NEVER: "NEVER";
@@ -140,6 +229,7 @@ export declare const DesignatedSubSchema: z.ZodObject<{
140
229
  type: z.ZodLiteral<PinchConditionType.SCORE_DIFF>;
141
230
  direction: z.ZodEnum<typeof ScoreDirection>;
142
231
  points: z.ZodNumber;
232
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
143
233
  }, z.core.$strip>, z.ZodObject<{
144
234
  type: z.ZodLiteral<PinchConditionType.AFTER_ROTATIONS>;
145
235
  rotations: z.ZodNumber;
@@ -149,13 +239,53 @@ export declare const DesignatedSubSchema: z.ZodObject<{
149
239
  }, z.core.$strip>, z.ZodObject<{
150
240
  type: z.ZodLiteral<PinchConditionType.MIN_OWN_SCORE>;
151
241
  score: z.ZodNumber;
242
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
152
243
  }, z.core.$strip>, z.ZodObject<{
153
244
  type: z.ZodLiteral<PinchConditionType.MIN_OPPONENT_SCORE>;
154
245
  score: z.ZodNumber;
246
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
155
247
  }, z.core.$strip>, z.ZodObject<{
156
248
  type: z.ZodLiteral<PinchConditionType.PHASE>;
157
249
  phase: z.ZodEnum<typeof MatchPhase>;
158
250
  }, z.core.$strip>], "type">>>;
159
251
  conditionLogic: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"ALL">, z.ZodLiteral<"ANY">]>>;
252
+ pinchServer: z.ZodOptional<z.ZodBoolean>;
253
+ subBackMode: z.ZodOptional<z.ZodEnum<{
254
+ FATIGUE: "FATIGUE";
255
+ CONDITIONS: "CONDITIONS";
256
+ }>>;
257
+ subBackConditions: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
258
+ type: z.ZodLiteral<PinchConditionType.ASAP>;
259
+ }, z.core.$strip>, z.ZodObject<{
260
+ type: z.ZodLiteral<PinchConditionType.TEAM_SET_POINT>;
261
+ margin: z.ZodNumber;
262
+ opponent: z.ZodEnum<typeof OpponentRelation>;
263
+ }, z.core.$strip>, z.ZodObject<{
264
+ type: z.ZodLiteral<PinchConditionType.OPPONENT_SET_POINT>;
265
+ margin: z.ZodNumber;
266
+ }, z.core.$strip>, z.ZodObject<{
267
+ type: z.ZodLiteral<PinchConditionType.SCORE_DIFF>;
268
+ direction: z.ZodEnum<typeof ScoreDirection>;
269
+ points: z.ZodNumber;
270
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
271
+ }, z.core.$strip>, z.ZodObject<{
272
+ type: z.ZodLiteral<PinchConditionType.AFTER_ROTATIONS>;
273
+ rotations: z.ZodNumber;
274
+ }, z.core.$strip>, z.ZodObject<{
275
+ type: z.ZodLiteral<PinchConditionType.FROM_SET>;
276
+ set: z.ZodNumber;
277
+ }, z.core.$strip>, z.ZodObject<{
278
+ type: z.ZodLiteral<PinchConditionType.MIN_OWN_SCORE>;
279
+ score: z.ZodNumber;
280
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
281
+ }, z.core.$strip>, z.ZodObject<{
282
+ type: z.ZodLiteral<PinchConditionType.MIN_OPPONENT_SCORE>;
283
+ score: z.ZodNumber;
284
+ comparison: z.ZodOptional<z.ZodEnum<typeof Comparison>>;
285
+ }, z.core.$strip>, z.ZodObject<{
286
+ type: z.ZodLiteral<PinchConditionType.PHASE>;
287
+ phase: z.ZodEnum<typeof MatchPhase>;
288
+ }, z.core.$strip>], "type">>>;
289
+ subBackConditionLogic: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"ALL">, z.ZodLiteral<"ANY">]>>;
160
290
  starter: z.ZodCustom<Player, Player>;
161
291
  }, z.core.$strip>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DesignatedSubSchema = exports.SetSubConfigSchema = exports.SubModeSchema = exports.ConditionLogicSchema = exports.PinchConditionSchema = exports.SubBandSchema = void 0;
3
+ exports.DesignatedSubSchema = exports.SetSubConfigSchema = exports.SubBackModeSchema = exports.SubModeSchema = exports.ConditionLogicSchema = exports.PinchConditionSchema = exports.SubBandSchema = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const player_1 = require("../../player");
6
6
  const energy_band_1 = require("../energy-band");
@@ -13,16 +13,19 @@ exports.PinchConditionSchema = zod_1.z.discriminatedUnion('type', [
13
13
  zod_1.z.object({ type: zod_1.z.literal(pinch_condition_1.PinchConditionType.ASAP) }),
14
14
  zod_1.z.object({ type: zod_1.z.literal(pinch_condition_1.PinchConditionType.TEAM_SET_POINT), margin: zod_1.z.number().int().min(1).max(25), opponent: zod_1.z.nativeEnum(pinch_condition_1.OpponentRelation) }),
15
15
  zod_1.z.object({ type: zod_1.z.literal(pinch_condition_1.PinchConditionType.OPPONENT_SET_POINT), margin: zod_1.z.number().int().min(1).max(25) }),
16
- zod_1.z.object({ type: zod_1.z.literal(pinch_condition_1.PinchConditionType.SCORE_DIFF), direction: zod_1.z.nativeEnum(pinch_condition_1.ScoreDirection), points: zod_1.z.number().int().min(1).max(25) }),
16
+ // SCORE_DIFF / MIN_OWN_SCORE / MIN_OPPONENT_SCORE carry an optional comparison direction ("Or more" AT_LEAST,
17
+ // the default; "Or less" AT_MOST). Absent = AT_LEAST so existing conditions keep their `>=` behavior.
18
+ zod_1.z.object({ type: zod_1.z.literal(pinch_condition_1.PinchConditionType.SCORE_DIFF), direction: zod_1.z.nativeEnum(pinch_condition_1.ScoreDirection), points: zod_1.z.number().int().min(1).max(25), comparison: zod_1.z.nativeEnum(pinch_condition_1.Comparison).optional() }),
17
19
  zod_1.z.object({ type: zod_1.z.literal(pinch_condition_1.PinchConditionType.AFTER_ROTATIONS), rotations: zod_1.z.number().int().min(1).max(6) }),
18
20
  zod_1.z.object({ type: zod_1.z.literal(pinch_condition_1.PinchConditionType.FROM_SET), set: zod_1.z.number().int().min(1).max(5) }),
19
- zod_1.z.object({ type: zod_1.z.literal(pinch_condition_1.PinchConditionType.MIN_OWN_SCORE), score: zod_1.z.number().int().min(0).max(40) }),
20
- zod_1.z.object({ type: zod_1.z.literal(pinch_condition_1.PinchConditionType.MIN_OPPONENT_SCORE), score: zod_1.z.number().int().min(0).max(40) }),
21
+ zod_1.z.object({ type: zod_1.z.literal(pinch_condition_1.PinchConditionType.MIN_OWN_SCORE), score: zod_1.z.number().int().min(0).max(40), comparison: zod_1.z.nativeEnum(pinch_condition_1.Comparison).optional() }),
22
+ zod_1.z.object({ type: zod_1.z.literal(pinch_condition_1.PinchConditionType.MIN_OPPONENT_SCORE), score: zod_1.z.number().int().min(0).max(40), comparison: zod_1.z.nativeEnum(pinch_condition_1.Comparison).optional() }),
21
23
  // PHASE is used by the libero deployment rule (which reuses this schema); pinch servers never offer it.
22
24
  zod_1.z.object({ type: zod_1.z.literal(pinch_condition_1.PinchConditionType.PHASE), phase: zod_1.z.nativeEnum(pinch_condition_1.MatchPhase) })
23
25
  ]);
24
26
  exports.ConditionLogicSchema = zod_1.z.union([zod_1.z.literal('ALL'), zod_1.z.literal('ANY')]);
25
27
  exports.SubModeSchema = zod_1.z.enum(['FATIGUE', 'PINCH', 'NEVER']);
28
+ exports.SubBackModeSchema = zod_1.z.enum(['FATIGUE', 'CONDITIONS']);
26
29
  // Fields shared by the all-sets config and each per-set config.
27
30
  const setSubConfigShape = {
28
31
  mode: exports.SubModeSchema,
@@ -30,9 +33,16 @@ const setSubConfigShape = {
30
33
  fatigueBand: zod_1.z.nativeEnum(energy_band_1.EnergyBand).optional(),
31
34
  benchFatigueBand: zod_1.z.nativeEnum(energy_band_1.EnergyBand).optional(),
32
35
  conditions: zod_1.z.array(exports.PinchConditionSchema).optional(),
33
- conditionLogic: exports.ConditionLogicSchema.optional()
36
+ conditionLogic: exports.ConditionLogicSchema.optional(),
37
+ // pinch ("Conditions") mode. true = serve-and-return pinch server; false/absent = regular conditional sub.
38
+ pinchServer: zod_1.z.boolean().optional(),
39
+ // a regular conditional sub's sub-back trigger + its condition set (subBackMode === 'CONDITIONS').
40
+ subBackMode: exports.SubBackModeSchema.optional(),
41
+ subBackConditions: zod_1.z.array(exports.PinchConditionSchema).optional(),
42
+ subBackConditionLogic: exports.ConditionLogicSchema.optional()
34
43
  };
35
- // Pinch mode needs a designated bench player (the server) and at least one condition.
44
+ // Pinch ("Conditions") mode needs a designated bench player and at least one sub-in condition. A regular
45
+ // conditional sub (pinchServer !== true) with a CONDITIONS sub-back also needs at least one sub-back condition.
36
46
  function refinePinch(data, ctx) {
37
47
  if (data.mode !== 'PINCH')
38
48
  return;
@@ -42,6 +52,10 @@ function refinePinch(data, ctx) {
42
52
  if (data.conditions == null || data.conditions.length === 0) {
43
53
  ctx.addIssue({ code: 'custom', message: 'PINCH_SERVER_REQUIRES_CONDITIONS', path: ['conditions'] });
44
54
  }
55
+ if (data.pinchServer !== true && data.subBackMode === 'CONDITIONS' &&
56
+ (data.subBackConditions == null || data.subBackConditions.length === 0)) {
57
+ ctx.addIssue({ code: 'custom', message: 'CONDITIONAL_SUB_BACK_REQUIRES_CONDITIONS', path: ['subBackConditions'] });
58
+ }
45
59
  }
46
60
  exports.SetSubConfigSchema = zod_1.z.object(setSubConfigShape).superRefine(refinePinch);
47
61
  exports.DesignatedSubSchema = zod_1.z.object({