volleyballsimtypes 0.0.505 → 0.0.507

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 (63) hide show
  1. package/dist/cjs/src/api/index.d.ts +2 -2
  2. package/dist/cjs/src/api/tactics-player-refs.js +2 -2
  3. package/dist/cjs/src/data/init-models.js +4 -0
  4. package/dist/cjs/src/data/models/base-position-preset.d.ts +22 -0
  5. package/dist/cjs/src/data/models/base-position-preset.js +54 -0
  6. package/dist/cjs/src/data/models/index.d.ts +1 -0
  7. package/dist/cjs/src/data/models/index.js +1 -0
  8. package/dist/cjs/src/data/models/tactics.d.ts +2 -2
  9. package/dist/cjs/src/data/transformers/tactics.test.js +10 -10
  10. package/dist/cjs/src/service/competition/competition-rewards.d.ts +20 -0
  11. package/dist/cjs/src/service/competition/competition-rewards.js +47 -0
  12. package/dist/cjs/src/service/competition/competition-rewards.test.d.ts +1 -0
  13. package/dist/cjs/src/service/competition/competition-rewards.test.js +32 -0
  14. package/dist/cjs/src/service/competition/index.d.ts +2 -0
  15. package/dist/cjs/src/service/competition/index.js +2 -0
  16. package/dist/cjs/src/service/competition/league-rewards.d.ts +21 -0
  17. package/dist/cjs/src/service/competition/league-rewards.js +58 -0
  18. package/dist/cjs/src/service/competition/league-rewards.test.d.ts +1 -0
  19. package/dist/cjs/src/service/competition/league-rewards.test.js +50 -0
  20. package/dist/cjs/src/service/team/base-config.d.ts +1 -0
  21. package/dist/cjs/src/service/team/blocking-preference.d.ts +3 -1
  22. package/dist/cjs/src/service/team/blocking-preference.js +2 -1
  23. package/dist/cjs/src/service/team/default-base-config.d.ts +4 -0
  24. package/dist/cjs/src/service/team/default-base-config.js +158 -0
  25. package/dist/cjs/src/service/team/index.d.ts +1 -0
  26. package/dist/cjs/src/service/team/index.js +1 -0
  27. package/dist/cjs/src/service/team/schemas/tactics.z.d.ts +11 -2
  28. package/dist/cjs/src/service/team/schemas/tactics.z.js +17 -5
  29. package/dist/cjs/src/service/team/schemas/tactics.z.test.js +29 -16
  30. package/dist/cjs/src/service/team/schemas/team.z.d.ts +11 -2
  31. package/dist/cjs/src/service/team/team-generator.js +6 -1
  32. package/dist/esm/src/api/index.d.ts +2 -2
  33. package/dist/esm/src/api/tactics-player-refs.js +2 -2
  34. package/dist/esm/src/data/init-models.js +5 -1
  35. package/dist/esm/src/data/models/base-position-preset.d.ts +22 -0
  36. package/dist/esm/src/data/models/base-position-preset.js +50 -0
  37. package/dist/esm/src/data/models/index.d.ts +1 -0
  38. package/dist/esm/src/data/models/index.js +1 -0
  39. package/dist/esm/src/data/models/tactics.d.ts +2 -2
  40. package/dist/esm/src/data/transformers/tactics.test.js +10 -10
  41. package/dist/esm/src/service/competition/competition-rewards.d.ts +20 -0
  42. package/dist/esm/src/service/competition/competition-rewards.js +43 -0
  43. package/dist/esm/src/service/competition/competition-rewards.test.d.ts +1 -0
  44. package/dist/esm/src/service/competition/competition-rewards.test.js +30 -0
  45. package/dist/esm/src/service/competition/index.d.ts +2 -0
  46. package/dist/esm/src/service/competition/index.js +2 -0
  47. package/dist/esm/src/service/competition/league-rewards.d.ts +21 -0
  48. package/dist/esm/src/service/competition/league-rewards.js +53 -0
  49. package/dist/esm/src/service/competition/league-rewards.test.d.ts +1 -0
  50. package/dist/esm/src/service/competition/league-rewards.test.js +48 -0
  51. package/dist/esm/src/service/team/base-config.d.ts +1 -0
  52. package/dist/esm/src/service/team/blocking-preference.d.ts +3 -1
  53. package/dist/esm/src/service/team/blocking-preference.js +1 -0
  54. package/dist/esm/src/service/team/default-base-config.d.ts +4 -0
  55. package/dist/esm/src/service/team/default-base-config.js +154 -0
  56. package/dist/esm/src/service/team/index.d.ts +1 -0
  57. package/dist/esm/src/service/team/index.js +1 -0
  58. package/dist/esm/src/service/team/schemas/tactics.z.d.ts +11 -2
  59. package/dist/esm/src/service/team/schemas/tactics.z.js +17 -5
  60. package/dist/esm/src/service/team/schemas/tactics.z.test.js +29 -16
  61. package/dist/esm/src/service/team/schemas/team.z.d.ts +11 -2
  62. package/dist/esm/src/service/team/team-generator.js +6 -1
  63. package/package.json +1 -1
@@ -234,18 +234,31 @@ describe('TacticsInputSchema — blocking preferences', () => {
234
234
  ...overrides
235
235
  };
236
236
  }
237
- it('accepts a blocking preference that keys starters to attacking functions', () => {
237
+ it('accepts a blocking preference that keys starters to attacking functions, per defence side', () => {
238
238
  const res = TacticsInputSchema.safeParse(baseInput({
239
- blockingPreferences: [{ rotation: 1, targets: { [p4.id]: RoleEnum.OUTSIDE_HITTER, [p3.id]: RoleEnum.MIDDLE_BLOCKER } }]
239
+ blockingPreferences: [{ rotation: 1, targets: { DEF_L: { [p4.id]: RoleEnum.OUTSIDE_HITTER }, DEF_M: {}, DEF_R: { [p3.id]: RoleEnum.MIDDLE_BLOCKER } } }]
240
240
  }));
241
241
  expect(res.success).toBe(true);
242
242
  if (res.success) {
243
- expect(res.data.blockingPreferences[0].targets[p4.id]).toBe(RoleEnum.OUTSIDE_HITTER);
243
+ expect(res.data.blockingPreferences[0].targets.DEF_L[p4.id]).toBe(RoleEnum.OUTSIDE_HITTER);
244
+ expect(res.data.blockingPreferences[0].targets.DEF_R[p3.id]).toBe(RoleEnum.MIDDLE_BLOCKER);
245
+ expect(res.data.blockingPreferences[0].targets.DEF_M).toEqual({}); // the middle side is independent (empty here)
244
246
  }
245
247
  });
246
- it('rejects a blocking target that is not a starter', () => {
248
+ it('defaults the omitted defence sides to empty maps', () => {
247
249
  const res = TacticsInputSchema.safeParse(baseInput({
248
- blockingPreferences: [{ rotation: 1, targets: { [reserve.id]: RoleEnum.OUTSIDE_HITTER } }]
250
+ blockingPreferences: [{ rotation: 1, targets: { DEF_L: { [p4.id]: NO_BLOCK } } }]
251
+ }));
252
+ expect(res.success).toBe(true);
253
+ if (res.success) {
254
+ expect(res.data.blockingPreferences[0].targets.DEF_L[p4.id]).toBe(NO_BLOCK);
255
+ expect(res.data.blockingPreferences[0].targets.DEF_M).toEqual({});
256
+ expect(res.data.blockingPreferences[0].targets.DEF_R).toEqual({});
257
+ }
258
+ });
259
+ it('rejects a blocking target (on any side) that is not a starter', () => {
260
+ const res = TacticsInputSchema.safeParse(baseInput({
261
+ blockingPreferences: [{ rotation: 1, targets: { DEF_M: { [reserve.id]: RoleEnum.OUTSIDE_HITTER } } }]
249
262
  }));
250
263
  expect(res.success).toBe(false);
251
264
  if (!res.success) {
@@ -254,7 +267,7 @@ describe('TacticsInputSchema — blocking preferences', () => {
254
267
  });
255
268
  it('rejects a blocking target function of libero', () => {
256
269
  const res = TacticsInputSchema.safeParse(baseInput({
257
- blockingPreferences: [{ rotation: 1, targets: { [p4.id]: RoleEnum.LIBERO } }]
270
+ blockingPreferences: [{ rotation: 1, targets: { DEF_L: { [p4.id]: RoleEnum.LIBERO } } }]
258
271
  }));
259
272
  expect(res.success).toBe(false);
260
273
  if (!res.success) {
@@ -264,8 +277,8 @@ describe('TacticsInputSchema — blocking preferences', () => {
264
277
  it('rejects a duplicate rotation in blocking preferences', () => {
265
278
  const res = TacticsInputSchema.safeParse(baseInput({
266
279
  blockingPreferences: [
267
- { rotation: 1, targets: { [p4.id]: RoleEnum.OUTSIDE_HITTER } },
268
- { rotation: 1, targets: { [p3.id]: RoleEnum.MIDDLE_BLOCKER } }
280
+ { rotation: 1, targets: { DEF_L: { [p4.id]: RoleEnum.OUTSIDE_HITTER } } },
281
+ { rotation: 1, targets: { DEF_M: { [p3.id]: RoleEnum.MIDDLE_BLOCKER } } }
269
282
  ]
270
283
  }));
271
284
  expect(res.success).toBe(false);
@@ -275,29 +288,29 @@ describe('TacticsInputSchema — blocking preferences', () => {
275
288
  });
276
289
  it('accepts per-set blocking preference overrides', () => {
277
290
  const res = TacticsInputSchema.safeParse(baseInput({
278
- blockingPreferenceSets: [[{ rotation: 1, targets: { [p4.id]: RoleEnum.OPPOSITE_HITTER } }], []]
291
+ blockingPreferenceSets: [[{ rotation: 1, targets: { DEF_R: { [p4.id]: RoleEnum.OPPOSITE_HITTER } } }], []]
279
292
  }));
280
293
  expect(res.success).toBe(true);
281
294
  });
282
- it('accepts NO_BLOCK as an assignment, alongside a commit on another starter', () => {
295
+ it('accepts NO_BLOCK as an assignment, alongside a commit on another starter, on the same side', () => {
283
296
  const res = TacticsInputSchema.safeParse(baseInput({
284
- blockingPreferences: [{ rotation: 1, targets: { [p4.id]: NO_BLOCK, [p3.id]: RoleEnum.MIDDLE_BLOCKER } }]
297
+ blockingPreferences: [{ rotation: 1, targets: { DEF_L: { [p4.id]: NO_BLOCK, [p3.id]: RoleEnum.MIDDLE_BLOCKER } } }]
285
298
  }));
286
299
  expect(res.success).toBe(true);
287
300
  if (res.success) {
288
- expect(res.data.blockingPreferences[0].targets[p4.id]).toBe(NO_BLOCK);
289
- expect(res.data.blockingPreferences[0].targets[p3.id]).toBe(RoleEnum.MIDDLE_BLOCKER);
301
+ expect(res.data.blockingPreferences[0].targets.DEF_L[p4.id]).toBe(NO_BLOCK);
302
+ expect(res.data.blockingPreferences[0].targets.DEF_L[p3.id]).toBe(RoleEnum.MIDDLE_BLOCKER);
290
303
  }
291
304
  });
292
305
  it('accepts NO_BLOCK in a per-set override', () => {
293
306
  const res = TacticsInputSchema.safeParse(baseInput({
294
- blockingPreferenceSets: [[{ rotation: 1, targets: { [p4.id]: NO_BLOCK } }], []]
307
+ blockingPreferenceSets: [[{ rotation: 1, targets: { DEF_M: { [p4.id]: NO_BLOCK } } }], []]
295
308
  }));
296
309
  expect(res.success).toBe(true);
297
310
  });
298
311
  it('still rejects a NO_BLOCK assignment on a player who is not a starter', () => {
299
312
  const res = TacticsInputSchema.safeParse(baseInput({
300
- blockingPreferences: [{ rotation: 1, targets: { [reserve.id]: NO_BLOCK } }]
313
+ blockingPreferences: [{ rotation: 1, targets: { DEF_R: { [reserve.id]: NO_BLOCK } } }]
301
314
  }));
302
315
  expect(res.success).toBe(false);
303
316
  if (!res.success) {
@@ -306,7 +319,7 @@ describe('TacticsInputSchema — blocking preferences', () => {
306
319
  });
307
320
  it('rejects an unknown assignment string', () => {
308
321
  const res = TacticsInputSchema.safeParse(baseInput({
309
- blockingPreferences: [{ rotation: 1, targets: { [p4.id]: 'NO_BLOCKING' } }]
322
+ blockingPreferences: [{ rotation: 1, targets: { DEF_L: { [p4.id]: 'NO_BLOCKING' } } }]
310
323
  }));
311
324
  expect(res.success).toBe(false);
312
325
  });
@@ -290,11 +290,19 @@ export declare const TeamInputSchema: z.ZodObject<{
290
290
  }, z.core.$strip>>>>;
291
291
  blockingPreferences: z.ZodDefault<z.ZodArray<z.ZodObject<{
292
292
  rotation: z.ZodNumber;
293
- targets: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [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>>, z.ZodLiteral<"NO_BLOCK">]>>;
293
+ targets: z.ZodObject<{
294
+ DEF_L: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [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>>, z.ZodLiteral<"NO_BLOCK">]>>>;
295
+ DEF_M: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [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>>, z.ZodLiteral<"NO_BLOCK">]>>>;
296
+ DEF_R: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [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>>, z.ZodLiteral<"NO_BLOCK">]>>>;
297
+ }, z.core.$strip>;
294
298
  }, z.core.$strip>>>;
295
299
  blockingPreferenceSets: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodObject<{
296
300
  rotation: z.ZodNumber;
297
- targets: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [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>>, z.ZodLiteral<"NO_BLOCK">]>>;
301
+ targets: z.ZodObject<{
302
+ DEF_L: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [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>>, z.ZodLiteral<"NO_BLOCK">]>>>;
303
+ DEF_M: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [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>>, z.ZodLiteral<"NO_BLOCK">]>>>;
304
+ DEF_R: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [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>>, z.ZodLiteral<"NO_BLOCK">]>>>;
305
+ }, z.core.$strip>;
298
306
  }, z.core.$strip>>>>;
299
307
  basePositions: z.ZodOptional<z.ZodObject<{
300
308
  coords: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodObject<{
@@ -302,6 +310,7 @@ export declare const TeamInputSchema: z.ZodObject<{
302
310
  r: z.ZodNumber;
303
311
  }, z.core.$strip>>>>;
304
312
  receive: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodBoolean>>;
313
+ blocking: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodBoolean>>>>;
305
314
  }, z.core.$strip>>;
306
315
  replaceKnockedImmediately: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
307
316
  injuryReplacements: z.ZodDefault<z.ZodArray<z.ZodObject<{
@@ -5,6 +5,8 @@ import { Team } from './team';
5
5
  import { Tactics } from './tactics';
6
6
  import { EnergyBand } from './energy-band';
7
7
  import { Formation } from './formation';
8
+ import { RotationSystemEnum } from './rotation-system';
9
+ import { defaultBaseConfig } from './default-base-config';
8
10
  import { CourtPosition } from '../match';
9
11
  import logger from '../../logger';
10
12
  const buildBlock = (rarity, count) => Array.from({ length: count }, () => rarity);
@@ -62,7 +64,10 @@ export class TeamGenerator {
62
64
  return Tactics.create({
63
65
  lineup,
64
66
  liberoReplacements: [lineup[3], lineup[6]],
65
- substitutionBand: TeamGenerator.BOT_SUB_BANDS[Math.floor(Math.random() * TeamGenerator.BOT_SUB_BANDS.length)]
67
+ substitutionBand: TeamGenerator.BOT_SUB_BANDS[Math.floor(Math.random() * TeamGenerator.BOT_SUB_BANDS.length)],
68
+ // basePositions is never null: a team always carries the default base config for its system. createTactics
69
+ // makes 6-0 teams (Tactics.create default); when a user picks another system the API re-materializes.
70
+ basePositions: defaultBaseConfig(RotationSystemEnum.SIX_ZERO)
66
71
  });
67
72
  }
68
73
  static createLineup(players, formation) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "volleyballsimtypes",
3
- "version": "0.0.505",
3
+ "version": "0.0.507",
4
4
  "description": "vbsim types",
5
5
  "main": "./dist/cjs/src/index.js",
6
6
  "module": "./dist/esm/src/index.js",