tods-competition-factory 1.7.8 → 1.7.9

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.
@@ -1276,6 +1276,28 @@ interface UnifiedVenueID {
1276
1276
  venueId: string;
1277
1277
  }
1278
1278
 
1279
+ /**
1280
+ *
1281
+ * @param {object} playoffAttributes - mapping of exitProfile to structure names, e.g. 0-1-1 for SOUTH
1282
+ * @param {string} playoffStructureNameBase - Root word for default playoff naming, e.g. 'Playoff' for 'Playoff 3-4'
1283
+ * @param {string} exitProfile - rounds at which a participant exited each structure, e.g. 0-1-1-1 for losing EAST, WEST, SOUTH
1284
+ * @param {boolean} exitProfileLimit - limit playoff rounds generated by the attributes present in playoffAttributes
1285
+ * @param {number} finishingPositionOffset - amount by which to offset finishingPositions, e.g. 2 for playing off 3-4
1286
+ * @param {number} finishingPositionLimit - highest value of possible finishing Positions to play off
1287
+ * @param {object} finishingPositionNaming - map of { [finishingPositionRange]: customName }
1288
+ * @param {number} roundOffsetLimit - how many rounds to play off (# of additional matchUps per participant)
1289
+ * @param {number} roundOffset - used internally to track generated structures; saved in structure attributes;
1290
+ * @param {number} stageSequence - what sequence within stage structures, e.g. WEST is stageSequence 2 in COMPASS
1291
+ * @param {string} stage - [QUALIFYING, MAIN, CONSOLATION, PLAY-OFF]
1292
+ *
1293
+ */
1294
+ type NamingEntry = {
1295
+ [key: string]: {
1296
+ name: string;
1297
+ abbreviation: string;
1298
+ };
1299
+ };
1300
+
1279
1301
  type HydratedParticipant = {
1280
1302
  [key: string | number]: any;
1281
1303
  } & Participant;
@@ -1349,13 +1371,16 @@ type RoundProfile = {
1349
1371
 
1350
1372
  type GenerateAndPopulateArgs = {
1351
1373
  addNameBaseToAttributeName?: boolean;
1374
+ finishingPositionNaming?: NamingEntry;
1352
1375
  playoffStructureNameBase?: string;
1376
+ playoffAttributes?: NamingEntry;
1377
+ finishingPositionLimit?: number;
1353
1378
  tournamentRecord?: Tournament;
1354
1379
  drawDefinition: DrawDefinition;
1355
1380
  roundProfiles?: RoundProfile[];
1356
1381
  playoffPositions?: number[];
1382
+ roundOffsetLimit?: number;
1357
1383
  exitProfileLimit?: boolean;
1358
- playoffAttributes?: any;
1359
1384
  roundNumbers?: number[];
1360
1385
  structureId: string;
1361
1386
  idPrefix?: string;
@@ -503,6 +503,10 @@ const INVALID_STAGE = {
503
503
  message: "Invalid stage",
504
504
  code: "ERR_INVALID_STAGE"
505
505
  };
506
+ const STAGE_SEQUENCE_LIMIT = {
507
+ message: "stageSequence limit",
508
+ code: "ERR_LIMIT_STAGE_SEQUENCE"
509
+ };
506
510
  const MISSING_POSITION_ASSIGNMENTS = {
507
511
  message: "Missing positionAssignments",
508
512
  code: "ERR_MISSING_POSITION_ASSIGNMENTS"
@@ -724,6 +728,10 @@ const EXISTING_STAGE = {
724
728
  message: "Existing stage",
725
729
  code: "ERR_EXISTING_STAGE"
726
730
  };
731
+ const EXISTING_STRUCTURE = {
732
+ message: "Existing structure",
733
+ code: "ERR_EXISTING_STRUCTURE"
734
+ };
727
735
 
728
736
  const syncGlobalState = {
729
737
  disableNotifications: false,
@@ -1164,6 +1172,9 @@ function getAccessorValue({ element, accessor }) {
1164
1172
  }
1165
1173
  }
1166
1174
 
1175
+ function isString(obj) {
1176
+ return typeof obj === "string";
1177
+ }
1167
1178
  function isObject(obj) {
1168
1179
  return typeof obj === "object";
1169
1180
  }
@@ -4961,6 +4972,15 @@ function getNumericSeedValue(seedValue) {
4961
4972
  return Infinity;
4962
4973
  }
4963
4974
 
4975
+ function capitalizeFirst(str) {
4976
+ return !isString(str) ? str : str.split(" ").map(
4977
+ (name) => name.split("").map((c, i) => i ? c.toLowerCase() : c.toUpperCase()).join("")
4978
+ ).join(" ");
4979
+ }
4980
+ function constantToString(str) {
4981
+ return !isString(str) ? str : capitalizeFirst(str.replace(/_/g, " "));
4982
+ }
4983
+
4964
4984
  const structureTemplate = ({
4965
4985
  finishingPosition = ROUND_OUTCOME,
4966
4986
  qualifyingRoundNumber,
@@ -5073,7 +5093,7 @@ function groupRounds({ groupSize, drawPositionOffset }) {
5073
5093
  }
5074
5094
 
5075
5095
  function generateRoundRobin({
5076
- structureName = MAIN,
5096
+ structureName = constantToString(MAIN),
5077
5097
  stageSequence = 1,
5078
5098
  structureOptions,
5079
5099
  appliedPolicies,
@@ -14055,8 +14075,8 @@ function firstRoundLoserConsolation(params) {
14055
14075
  };
14056
14076
  const { matchUps } = staggeredEntry ? feedInMatchUps(mainParams) : treeMatchUps(mainParams);
14057
14077
  const mainStructure = structureTemplate({
14078
+ structureName: structureName || constantToString(MAIN),
14058
14079
  structureId: structureId || uuids?.pop(),
14059
- structureName: structureName || MAIN,
14060
14080
  stageSequence,
14061
14081
  matchUpType,
14062
14082
  matchUps,
@@ -14073,7 +14093,8 @@ function firstRoundLoserConsolation(params) {
14073
14093
  matchUpType,
14074
14094
  isMock
14075
14095
  });
14076
- const consolationStructureName = params.consolationStructureName || (structureName ? `${structureName} ${CONSOLATION}` : CONSOLATION);
14096
+ const consolation = constantToString(CONSOLATION);
14097
+ const consolationStructureName = params.consolationStructureName || (structureName ? `${structureName} ${consolation}` : consolation);
14077
14098
  const consolationStructure = structureTemplate({
14078
14099
  structureName: consolationStructureName,
14079
14100
  matchUps: consolationMatchUps,
@@ -14151,8 +14172,9 @@ function feedInLinks({
14151
14172
 
14152
14173
  function generateCurtisConsolation(params) {
14153
14174
  const {
14175
+ structureName = constantToString(MAIN),
14176
+ playoffStructureNameBase,
14154
14177
  finishingPositionOffset,
14155
- structureName = MAIN,
14156
14178
  stageSequence = 1,
14157
14179
  structureNameMap,
14158
14180
  staggeredEntry,
@@ -14190,6 +14212,7 @@ function generateCurtisConsolation(params) {
14190
14212
  const { consolationStructure } = consolationFeedStructure({
14191
14213
  idPrefix: idPrefix && `${idPrefix}-c${index}`,
14192
14214
  structureId: uuids?.pop(),
14215
+ playoffStructureNameBase,
14193
14216
  structureNameMap,
14194
14217
  stageSequence: stageSequence2,
14195
14218
  roundOffset,
@@ -14218,12 +14241,15 @@ function generateCurtisConsolation(params) {
14218
14241
  matchUpType,
14219
14242
  isMock
14220
14243
  });
14244
+ const defaultName = constantToString(PLAY_OFF);
14245
+ const mappedStructureName = structureNameMap?.[defaultName] || defaultName;
14246
+ const structureName2 = playoffStructureNameBase ? `${playoffStructureNameBase} ${mappedStructureName}` : mappedStructureName;
14221
14247
  const playoffStructure = structureTemplate({
14222
- structureName: structureNameMap?.[PLAY_OFF] || PLAY_OFF,
14223
14248
  structureId: uuids?.pop(),
14224
14249
  matchUps: playoffMatchUps,
14225
14250
  stageSequence: 2,
14226
14251
  stage: PLAY_OFF,
14252
+ structureName: structureName2,
14227
14253
  matchUpType
14228
14254
  });
14229
14255
  const playoffLink = {
@@ -14245,6 +14271,7 @@ function generateCurtisConsolation(params) {
14245
14271
  return { structures, links, ...SUCCESS };
14246
14272
  }
14247
14273
  function consolationFeedStructure({
14274
+ playoffStructureNameBase,
14248
14275
  stageSequence = 1,
14249
14276
  structureNameMap,
14250
14277
  roundOffset = 0,
@@ -14267,8 +14294,9 @@ function consolationFeedStructure({
14267
14294
  isMock,
14268
14295
  uuids
14269
14296
  });
14270
- const defaultName = `${CONSOLATION} ${index + 1}`;
14271
- const structureName = structureNameMap?.[defaultName] || defaultName;
14297
+ const defaultName = `${constantToString(CONSOLATION)} ${index + 1}`;
14298
+ const mappedStructureName = structureNameMap?.[defaultName] || defaultName;
14299
+ const structureName = playoffStructureNameBase ? `${playoffStructureNameBase} ${mappedStructureName}` : mappedStructureName;
14272
14300
  const consolationStructure = structureTemplate({
14273
14301
  matchUps: consolationMatchUps,
14274
14302
  stage: CONSOLATION,
@@ -14281,7 +14309,6 @@ function consolationFeedStructure({
14281
14309
  }
14282
14310
 
14283
14311
  function generatePlayoffStructures(params) {
14284
- let { matchUpType } = params;
14285
14312
  const {
14286
14313
  finishingPositionOffset = 0,
14287
14314
  addNameBaseToAttributeName,
@@ -14311,7 +14338,7 @@ function generatePlayoffStructures(params) {
14311
14338
  const allMatchUps = [];
14312
14339
  const structures = [];
14313
14340
  const links = [];
14314
- matchUpType = matchUpType || drawDefinition?.matchUpType;
14341
+ const matchUpType = params.matchUpType || drawDefinition?.matchUpType;
14315
14342
  const finishingPositionsFrom = finishingPositionOffset + 1;
14316
14343
  const finishingPositionsTo = finishingPositionOffset + drawSize;
14317
14344
  const finishingPositionRange = `${finishingPositionsFrom}-${finishingPositionsTo}`;
@@ -14361,7 +14388,7 @@ function generatePlayoffStructures(params) {
14361
14388
  if (playoffDrawPositions < 2)
14362
14389
  return;
14363
14390
  const childFinishingPositionOffset = drawSize / Math.pow(2, roundNumber) + finishingPositionOffset;
14364
- if (childFinishingPositionOffset + 1 > finishingPositionLimit)
14391
+ if (finishingPositionLimit && childFinishingPositionOffset + 1 > finishingPositionLimit)
14365
14392
  return;
14366
14393
  const {
14367
14394
  structures: childStructures,
@@ -14449,8 +14476,8 @@ function feedInChampionship(params) {
14449
14476
  };
14450
14477
  const { matchUps } = staggeredEntry ? feedInMatchUps(mainParams) : treeMatchUps(mainParams);
14451
14478
  const mainStructure = structureTemplate({
14479
+ structureName: structureName || constantToString(MAIN),
14452
14480
  structureId: structureId || uuids?.pop(),
14453
- structureName: structureName || MAIN,
14454
14481
  stageSequence,
14455
14482
  matchUpType,
14456
14483
  matchUps,
@@ -14474,9 +14501,9 @@ function feedInChampionship(params) {
14474
14501
  });
14475
14502
  if (drawSize > 2) {
14476
14503
  const consolationStructure = structureTemplate({
14504
+ structureName: constantToString(CONSOLATION),
14477
14505
  matchUps: consolationMatchUps,
14478
14506
  structureId: uuids?.pop(),
14479
- structureName: CONSOLATION,
14480
14507
  stage: CONSOLATION,
14481
14508
  stageSequence: 1,
14482
14509
  matchUpType
@@ -14551,10 +14578,19 @@ function processPlayoffGroups({
14551
14578
  if (positionsPlayedOff) {
14552
14579
  finishingPositionOffset = Math.min(...positionsPlayedOff) - 1;
14553
14580
  }
14554
- const params = {
14581
+ const playoffGroupParams = {
14582
+ addNameBaseToAttributeName: playoffGroup.addNameBaseToAttributeName,
14583
+ playoffStructureNameBase: playoffGroup.playoffStructureNameBase,
14584
+ finishingPositionNaming: playoffGroup.finishingPositionNaming,
14585
+ finishingPositionLimit: playoffGroup.finishingPositionLimit,
14555
14586
  structureId: playoffGroup.structureId ?? uuids?.pop(),
14587
+ playoffAttributes: playoffGroup.playoffAttributes,
14556
14588
  structureNameMap: playoffGroup.structureNameMap,
14557
14589
  structureName: playoffGroup.structureName,
14590
+ sequenceLimit: playoffGroup.sequenceLimit
14591
+ };
14592
+ const params = {
14593
+ ...playoffGroupParams,
14558
14594
  idPrefix: idPrefix && `${idPrefix}-po`,
14559
14595
  appliedPolicies: policyDefinitions,
14560
14596
  finishingPositionOffset,
@@ -17402,8 +17438,11 @@ function generateAndPopulatePlayoffStructures(params) {
17402
17438
  structureId: sourceStructureId,
17403
17439
  addNameBaseToAttributeName,
17404
17440
  playoffStructureNameBase,
17441
+ finishingPositionNaming,
17442
+ finishingPositionLimit,
17405
17443
  playoffAttributes,
17406
17444
  playoffPositions,
17445
+ roundOffsetLimit,
17407
17446
  tournamentRecord,
17408
17447
  exitProfileLimit,
17409
17448
  roundProfiles,
@@ -17508,7 +17547,10 @@ function generateAndPopulatePlayoffStructures(params) {
17508
17547
  drawSize,
17509
17548
  idPrefix,
17510
17549
  isMock,
17511
- uuids
17550
+ uuids,
17551
+ finishingPositionNaming,
17552
+ finishingPositionLimit,
17553
+ roundOffsetLimit
17512
17554
  });
17513
17555
  if (result.error)
17514
17556
  return decorateResult({ result, stack });
@@ -19129,13 +19171,17 @@ function createGroupParticipant({
19129
19171
 
19130
19172
  function generateRoundRobinWithPlayOff(params) {
19131
19173
  const { drawDefinition, structureOptions, requireSequential } = params;
19132
- const mainDrawProperties = { structureName: MAIN, ...params, stage: MAIN };
19174
+ const mainDrawProperties = {
19175
+ structureName: constantToString(MAIN),
19176
+ ...params,
19177
+ stage: MAIN
19178
+ };
19133
19179
  const { structures, groupCount, groupSize } = generateRoundRobin(mainDrawProperties);
19134
19180
  if (groupCount < 1) {
19135
19181
  console.log(INVALID_CONFIGURATION);
19136
19182
  }
19137
19183
  const playoffGroups = structureOptions?.playoffGroups || [
19138
- { finishingPositions: [1], structureName: PLAY_OFF }
19184
+ { finishingPositions: [1], structureName: constantToString(PLAY_OFF) }
19139
19185
  ];
19140
19186
  const [mainStructure] = structures;
19141
19187
  const { structures: playoffStructures, links } = processPlayoffGroups({
@@ -19253,7 +19299,7 @@ function generateDoubleElimination({
19253
19299
  isMock
19254
19300
  });
19255
19301
  const mainStructure = structureTemplate({
19256
- structureName: structureName || MAIN,
19302
+ structureName: structureName || constantToString(MAIN),
19257
19303
  structureId: uuids?.pop(),
19258
19304
  stageSequence: 1,
19259
19305
  stage: MAIN,
@@ -19272,9 +19318,9 @@ function generateDoubleElimination({
19272
19318
  uuids
19273
19319
  });
19274
19320
  const consolationStructure = structureTemplate({
19321
+ structureName: constantToString(BACKDRAW),
19275
19322
  matchUps: consolationMatchUps,
19276
19323
  structureId: uuids?.pop(),
19277
- structureName: BACKDRAW,
19278
19324
  stage: CONSOLATION,
19279
19325
  stageSequence: 2,
19280
19326
  matchUpType
@@ -19287,9 +19333,9 @@ function generateDoubleElimination({
19287
19333
  isMock
19288
19334
  });
19289
19335
  const deciderStructure = structureTemplate({
19336
+ structureName: constantToString(DECIDER),
19290
19337
  matchUps: deciderMatchUps,
19291
19338
  structureId: uuids?.pop(),
19292
- structureName: DECIDER,
19293
19339
  stageSequence: 3,
19294
19340
  stage: PLAY_OFF,
19295
19341
  matchUpType
@@ -19411,11 +19457,12 @@ function getGenerators(params) {
19411
19457
  const { appliedPolicies } = getAppliedPolicies(params);
19412
19458
  const feedPolicy = params.policyDefinitions?.[POLICY_TYPE_FEED_IN] || appliedPolicies?.[POLICY_TYPE_FEED_IN];
19413
19459
  params.skipRounds = params.skipRounds || drawSize <= 4 && (feedPolicy?.feedMainFinal ? 0 : 1) || 0;
19460
+ const main = constantToString(MAIN);
19414
19461
  const singleElimination = () => {
19415
19462
  const { matchUps } = treeMatchUps(params);
19416
19463
  const structure = structureTemplate({
19417
- structureName: structureName || MAIN,
19418
19464
  structureId: structureId || uuids?.pop(),
19465
+ structureName: structureName || main,
19419
19466
  stageSequence,
19420
19467
  matchUpType,
19421
19468
  matchUps,
@@ -19426,8 +19473,8 @@ function getGenerators(params) {
19426
19473
  const generators = {
19427
19474
  [AD_HOC]: () => {
19428
19475
  const structure = structureTemplate({
19429
- structureName: structureName || MAIN,
19430
19476
  structureId: structureId || uuids?.pop(),
19477
+ structureName: structureName || main,
19431
19478
  finishingPosition: WIN_RATIO,
19432
19479
  stageSequence,
19433
19480
  matchUps: [],
@@ -19439,8 +19486,8 @@ function getGenerators(params) {
19439
19486
  [LUCKY_DRAW]: () => {
19440
19487
  const { matchUps } = luckyDraw(params);
19441
19488
  const structure = structureTemplate({
19442
- structureName: structureName || MAIN,
19443
19489
  structureId: structureId || uuids?.pop(),
19490
+ structureName: structureName || main,
19444
19491
  stageSequence,
19445
19492
  matchUpType,
19446
19493
  matchUps,
@@ -19466,8 +19513,8 @@ function getGenerators(params) {
19466
19513
  [FEED_IN$1]: () => {
19467
19514
  const { matchUps } = feedInMatchUps({ drawSize, uuids, matchUpType });
19468
19515
  const structure = structureTemplate({
19469
- structureName: structureName || MAIN,
19470
19516
  structureId: structureId || uuids?.pop(),
19517
+ structureName: structureName || main,
19471
19518
  stageSequence,
19472
19519
  matchUpType,
19473
19520
  stage: MAIN,
@@ -19529,9 +19576,9 @@ function generateVoluntaryConsolation$1(params) {
19529
19576
  return result2;
19530
19577
  }
19531
19578
  tieFormat = copyTieFormat(
19532
- tieFormat || resolveTieFormat({ drawDefinition })?.tieFormat
19579
+ tieFormat ?? resolveTieFormat({ drawDefinition })?.tieFormat
19533
19580
  );
19534
- matchUpType = matchUpType || drawDefinition.matchUpType || TypeEnum.Singles;
19581
+ matchUpType = matchUpType ?? drawDefinition.matchUpType ?? TypeEnum.Singles;
19535
19582
  const { structures: stageStructures } = getDrawStructures({
19536
19583
  stageSequence: 1,
19537
19584
  drawDefinition,
@@ -19539,14 +19586,14 @@ function generateVoluntaryConsolation$1(params) {
19539
19586
  });
19540
19587
  const structureCount = stageStructures.length;
19541
19588
  if (structureCount > 1)
19542
- return { error: INVALID_STRUCTURE };
19589
+ return { error: STAGE_SEQUENCE_LIMIT };
19543
19590
  if (stageStructures?.[0]?.matchUps?.length)
19544
- return { error: INVALID_STRUCTURE };
19591
+ return { error: EXISTING_STRUCTURE };
19545
19592
  const structureId = stageStructures?.[0]?.structureId;
19546
19593
  Object.assign(
19547
19594
  params,
19548
19595
  definedAttributes({
19549
- structureName: params.structureName || VOLUNTARY_CONSOLATION,
19596
+ structureName: params.structureName ?? constantToString(VOLUNTARY_CONSOLATION),
19550
19597
  structureId,
19551
19598
  matchUpType,
19552
19599
  tieFormat,
@@ -23268,7 +23315,7 @@ function generateDrawDefinition(params) {
23268
23315
  }
23269
23316
  } else if (structureId && generateQualifyingPlaceholder) {
23270
23317
  const qualifyingStructure = structureTemplate({
23271
- structureName: QUALIFYING,
23318
+ structureName: constantToString(QUALIFYING),
23272
23319
  stage: QUALIFYING
23273
23320
  });
23274
23321
  const { link } = generateQualifyingLink({