tods-competition-factory 1.8.3 → 1.8.4

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.
@@ -72,7 +72,7 @@ function groupConsecutiveNumbers(arr) {
72
72
  return result;
73
73
  }, []);
74
74
  }
75
- function allNumeric(arr) {
75
+ function allNumeric$1(arr) {
76
76
  return arr.reduce((numeric, item) => !isNaN(parseInt(item)) && numeric, true);
77
77
  }
78
78
  function noNumeric(arr) {
@@ -365,10 +365,18 @@ const MISSING_CONTEXT = {
365
365
  message: "Missing context",
366
366
  code: "ERR_MISSING_CONTEXT"
367
367
  };
368
+ const INVALID_COLLECTION_DEFINITION = {
369
+ message: "Invalid collectionDefinition",
370
+ code: "ERR_INVALID_COLLECTION_DEFINITION"
371
+ };
368
372
  const INVALID_OBJECT = {
369
373
  message: "Invalid object",
370
374
  code: "ERR_INVALID_OBJECT"
371
375
  };
376
+ const INVALID_CATEGORY = {
377
+ message: "Invalid category",
378
+ code: "ERR_INVALID_CATEGORY"
379
+ };
372
380
  const INVALID_VALUES = {
373
381
  message: "Invalid values",
374
382
  code: "ERR_INVALID_VALUES"
@@ -574,7 +582,11 @@ function addNotice(notice) {
574
582
  function getTopics() {
575
583
  return _globalStateProvider.getTopics();
576
584
  }
585
+ function getProvider() {
586
+ return _globalStateProvider;
587
+ }
577
588
 
589
+ const validDateString = /^[\d]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][\d]|3[0-1])$/;
578
590
  const validTimeString = /^((0[\d]|1[\d]|2[0-3]):[0-5][\d](:[0-5][\d])?)([.,][0-9]{3})?$/;
579
591
  const dateValidation = /^([\d]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][\d]|3[0-1]))([ T](0[\d]|1[\d]|2[0-3]):[0-5][\d](:[0-5][\d])?)?([.,][\d]{3})?Z?$/;
580
592
  const timeValidation = /^([\d]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][\d]|3[0-1]))?([ T]?(0[\d]|1[\d]|2[0-3]):[0-5][\d](:[0-5][\d])?)?([.,][\d]{3})?Z?$/;
@@ -605,6 +617,9 @@ function validTimeValue(value) {
605
617
  return false;
606
618
  return !!(!value || timeValidation.test(convertTime(value, true, true)));
607
619
  }
620
+ function isValidDateString(scheduleDate) {
621
+ return isISODateString(scheduleDate) || validDateString.test(scheduleDate);
622
+ }
608
623
  const getUTCdateString = (date) => {
609
624
  const dateDate = isDate(date) || isISODateString(date) ? new Date(date) : /* @__PURE__ */ new Date();
610
625
  const monthNumber = dateDate.getUTCMonth() + 1;
@@ -762,6 +777,13 @@ function sameDay(date1, date2) {
762
777
  }
763
778
 
764
779
  function makeDeepCopy(sourceObject, convertExtensions, internalUse, removeExtensions, iteration = 0) {
780
+ if (getProvider().makeDeepCopy)
781
+ return getProvider().makeDeepCopy(
782
+ sourceObject,
783
+ convertExtensions,
784
+ internalUse,
785
+ removeExtensions
786
+ );
765
787
  const deepCopy = deepCopyEnabled();
766
788
  const { stringify, toJSON, ignore, modulate } = deepCopy || {};
767
789
  if (!deepCopy?.enabled && !internalUse || typeof sourceObject !== "object" || typeof sourceObject === "function" || sourceObject === null || typeof deepCopy?.threshold === "number" && iteration >= deepCopy.threshold) {
@@ -1411,6 +1433,208 @@ function removeTournamentExtension(params) {
1411
1433
  });
1412
1434
  }
1413
1435
 
1436
+ const typeMatch = (arr, type) => arr.filter(Boolean).every((i) => typeof i === type);
1437
+ const allNumeric = (arr) => arr.filter(Boolean).every(isNumeric);
1438
+ function getCategoryAgeDetails(params) {
1439
+ const category = params.category;
1440
+ if (typeof category !== "object")
1441
+ return { error: INVALID_CATEGORY };
1442
+ let { ageCategoryCode, ageMaxDate, ageMinDate, ageMax, ageMin } = category;
1443
+ const categoryName = category.categoryName;
1444
+ let combinedAge;
1445
+ if (!typeMatch(
1446
+ [ageCategoryCode, ageMaxDate, ageMinDate, categoryName],
1447
+ "string"
1448
+ ) || !allNumeric(
1449
+ [ageMax, ageMin]
1450
+ ))
1451
+ return { error: INVALID_CATEGORY };
1452
+ const consideredDate = params.consideredDate ?? extractDate((/* @__PURE__ */ new Date()).toLocaleDateString("sv"));
1453
+ if (!isValidDateString(consideredDate))
1454
+ return { error: INVALID_DATE };
1455
+ const [consideredYear] = consideredDate.split("-").slice(0, 3).map((n) => parseInt(n));
1456
+ const previousDayDate = dateStringDaysChange(consideredDate, -1);
1457
+ const [previousDayMonth, previousDay] = previousDayDate.split("-").slice(1, 3).map((n) => parseInt(n));
1458
+ const previousMonthDay = `${zeroPad(previousDayMonth)}-${zeroPad(
1459
+ previousDay
1460
+ )}`;
1461
+ const nextDayDate = dateStringDaysChange(consideredDate, 1);
1462
+ const [nextDayMonth, nextDay] = nextDayDate.split("-").slice(1, 3).map((n) => parseInt(n));
1463
+ const nextMonthDay = `${zeroPad(nextDayMonth)}-${zeroPad(nextDay)}`;
1464
+ let calculatedAgeMaxDate = ageMin && dateStringDaysChange(consideredDate, -1 * 365 * ageMin);
1465
+ let calculatedAgeMinDate = ageMax && dateStringDaysChange(consideredDate, -1 * 365 * ageMax);
1466
+ const errors = [];
1467
+ const addError = (errorString) => !errors.includes(errorString) && errors.push(errorString);
1468
+ ageCategoryCode = ageCategoryCode ?? categoryName;
1469
+ const prePost = /^([UO]?)(\d{1,2})([UO]?)$/;
1470
+ const extractCombined = /^C(\d{1,2})-(\d{1,2})$/;
1471
+ const isBetween = ageCategoryCode?.includes("-");
1472
+ const isCombined = isBetween && ageCategoryCode?.match(extractCombined);
1473
+ const isCoded = ageCategoryCode?.match(prePost);
1474
+ const constructedDate = (y, df) => `${y}-${df}`;
1475
+ const uPre = (ageInt) => {
1476
+ const ageMinYear = consideredYear - ageInt;
1477
+ const newMinDate = constructedDate(ageMinYear, nextMonthDay);
1478
+ if (category.ageMinDate && category.ageMinDate !== newMinDate)
1479
+ addError(`Invalid submitted ageMinDate: ${ageMinDate}`);
1480
+ ageMinDate = newMinDate;
1481
+ if (ageCategoryCode) {
1482
+ if (category.ageMax && category.ageMax !== ageInt - 1) {
1483
+ addError(`Invalid submitted ageMax: ${ageMax}`);
1484
+ calculatedAgeMinDate = void 0;
1485
+ }
1486
+ ageMax = ageInt - 1;
1487
+ }
1488
+ };
1489
+ const uPost = (ageInt) => {
1490
+ const ageMinYear = consideredYear - ageInt - 1;
1491
+ const newMinDate = constructedDate(ageMinYear, nextMonthDay);
1492
+ if (category.ageMin && category.ageMin > ageInt) {
1493
+ addError(`Invalid submitted ageMin: ${ageMin}`);
1494
+ }
1495
+ if (category.ageMax && category.ageMax > ageInt) {
1496
+ addError(`Invalid submitted ageMax: ${ageMax}`);
1497
+ }
1498
+ if (category.ageMinDate && category.ageMinDate !== newMinDate)
1499
+ addError(`Invalid submitted ageMinDate: ${ageMinDate}`);
1500
+ ageMinDate = newMinDate;
1501
+ if (ageCategoryCode) {
1502
+ if (category.ageMax && category.ageMax !== ageInt) {
1503
+ addError(`Invalid submitted ageMax: ${ageMax}`);
1504
+ calculatedAgeMaxDate = void 0;
1505
+ }
1506
+ ageMax = ageInt;
1507
+ }
1508
+ };
1509
+ const oPre = (ageInt) => {
1510
+ const ageMaxYear = consideredYear - ageInt;
1511
+ const newMaxDate = constructedDate(ageMaxYear, previousMonthDay);
1512
+ if (category.ageMaxDate && category.ageMaxDate !== newMaxDate)
1513
+ addError(`Invalid submitted ageMaxDate: ${ageMaxDate}`);
1514
+ ageMaxDate = newMaxDate;
1515
+ if (ageCategoryCode) {
1516
+ if (category.ageMin && category.ageMin !== ageInt + 1) {
1517
+ addError(`Invalid submitted ageMin: ${ageMin}`);
1518
+ calculatedAgeMaxDate = void 0;
1519
+ }
1520
+ ageMin = ageInt + 1;
1521
+ }
1522
+ };
1523
+ const oPost = (ageInt) => {
1524
+ const ageMaxYear = consideredYear - ageInt - 1;
1525
+ const newMaxDate = constructedDate(ageMaxYear, previousMonthDay);
1526
+ if (category.ageMaxDate && category.ageMaxDate !== newMaxDate)
1527
+ addError(`Invalid submitted ageMaxDate: ${ageMaxDate}`);
1528
+ ageMaxDate = newMaxDate;
1529
+ if (ageCategoryCode) {
1530
+ if (category.ageMin && category.ageMin !== ageInt) {
1531
+ addError(`Invalid submitted ageMin: ${ageMin}`);
1532
+ calculatedAgeMaxDate = void 0;
1533
+ }
1534
+ ageMin = ageInt;
1535
+ }
1536
+ };
1537
+ const processCode = (code) => {
1538
+ const [pre, age, post] = (code.match(prePost) || []).slice(1);
1539
+ const ageInt = parseInt(age);
1540
+ if (pre === "U") {
1541
+ if (category.ageMaxDate && category.ageMaxDate !== ageMaxDate) {
1542
+ addError(`Invalid submitted ageMaxDate: ${category.ageMaxDate}`);
1543
+ }
1544
+ uPre(ageInt);
1545
+ } else if (pre === "O") {
1546
+ oPre(ageInt);
1547
+ }
1548
+ if (post === "U") {
1549
+ if (category.ageMaxDate && category.ageMaxDate !== ageMaxDate) {
1550
+ addError(`Invalid submitted ageMaxDate: ${category.ageMaxDate}`);
1551
+ }
1552
+ uPost(ageInt);
1553
+ } else if (post === "O") {
1554
+ oPost(ageInt);
1555
+ }
1556
+ ageMaxDate = ageMaxDate ?? calculatedAgeMaxDate;
1557
+ ageMinDate = ageMinDate ?? calculatedAgeMinDate;
1558
+ };
1559
+ if (isCombined) {
1560
+ ageMaxDate = void 0;
1561
+ ageMinDate = void 0;
1562
+ ageMax = void 0;
1563
+ ageMin = void 0;
1564
+ if (category.ageMin) {
1565
+ const ageMaxYear = consideredYear - category.ageMin;
1566
+ ageMaxDate = constructedDate(ageMaxYear, previousMonthDay);
1567
+ }
1568
+ if (category.ageMax) {
1569
+ const ageMinYear = consideredYear - category.ageMax - 1;
1570
+ ageMinDate = constructedDate(ageMinYear, nextMonthDay);
1571
+ }
1572
+ const [lowAge, highAge] = (ageCategoryCode?.match(extractCombined) ?? []).slice(1).map((n) => parseInt(n));
1573
+ if (lowAge <= highAge) {
1574
+ ageMin = lowAge;
1575
+ ageMax = highAge;
1576
+ combinedAge = true;
1577
+ } else {
1578
+ addError(`Invalid combined age range ${ageCategoryCode}`);
1579
+ }
1580
+ } else if (isBetween) {
1581
+ ageCategoryCode?.split("-").forEach(processCode);
1582
+ } else if (isCoded) {
1583
+ processCode(ageCategoryCode);
1584
+ } else {
1585
+ if (ageMin)
1586
+ oPre(ageMin);
1587
+ if (ageMax)
1588
+ uPost(ageMax);
1589
+ }
1590
+ if (ageMax && category.ageMin && category.ageMin > ageMax) {
1591
+ addError(`Invalid submitted ageMin: ${category.ageMin}`);
1592
+ ageMin = void 0;
1593
+ }
1594
+ const result = definedAttributes({
1595
+ consideredDate,
1596
+ combinedAge,
1597
+ ageMaxDate,
1598
+ ageMinDate,
1599
+ ageMax,
1600
+ ageMin
1601
+ });
1602
+ if (errors.length)
1603
+ result.errors = errors;
1604
+ return result;
1605
+ }
1606
+
1607
+ function categoryCanContain({
1608
+ childCategory,
1609
+ withDetails,
1610
+ category
1611
+ }) {
1612
+ const categoryDetails = getCategoryAgeDetails({ category });
1613
+ const childCategoryDetails = getCategoryAgeDetails({
1614
+ category: childCategory
1615
+ });
1616
+ const invalidAgeMin = childCategoryDetails.ageMin && (categoryDetails.ageMin && childCategoryDetails.ageMin < categoryDetails.ageMin || categoryDetails.ageMax && childCategoryDetails.ageMin > categoryDetails.ageMax);
1617
+ const invalidAgeMax = childCategoryDetails.ageMax && (categoryDetails.ageMax && childCategoryDetails.ageMax > categoryDetails.ageMax || categoryDetails.ageMin && childCategoryDetails.ageMax < categoryDetails.ageMin);
1618
+ const invalidAgeMinDate = childCategoryDetails.ageMinDate && categoryDetails.ageMaxDate && new Date(childCategoryDetails.ageMinDate) > new Date(categoryDetails.ageMaxDate);
1619
+ const invalidAgeMaxDate = childCategoryDetails.ageMaxDate && categoryDetails.ageMinDate && new Date(childCategoryDetails.ageMaxDate) < new Date(categoryDetails.ageMinDate);
1620
+ const valid = !invalidAgeMax && !invalidAgeMin && !invalidAgeMinDate && !invalidAgeMaxDate;
1621
+ const ignoreFalse = true;
1622
+ const result = definedAttributes(
1623
+ {
1624
+ valid,
1625
+ invalidAgeMax,
1626
+ invalidAgeMin,
1627
+ invalidAgeMinDate,
1628
+ invalidAgeMaxDate
1629
+ },
1630
+ ignoreFalse
1631
+ );
1632
+ if (withDetails) {
1633
+ Object.assign(result, { categoryDetails, childCategoryDetails });
1634
+ }
1635
+ return result;
1636
+ }
1637
+
1414
1638
  const NORMAL = "normal";
1415
1639
  const TIMED = "timed";
1416
1640
  const FINAL = "final";
@@ -1719,6 +1943,7 @@ var ParticipantTypeEnum = /* @__PURE__ */ ((ParticipantTypeEnum2) => {
1719
1943
  })(ParticipantTypeEnum || {});
1720
1944
 
1721
1945
  function validateTieFormat(params) {
1946
+ const checkCategory = !!(params?.enforceCategory !== false && params?.category);
1722
1947
  const checkGender = !!(params?.enforceGender !== false && params?.gender);
1723
1948
  const checkCollectionIds = params?.checkCollectionIds;
1724
1949
  const tieFormat = params?.tieFormat;
@@ -1755,9 +1980,11 @@ function validateTieFormat(params) {
1755
1980
  if ((setValue || scoreValue) && !collectionValue)
1756
1981
  aggregateValueImperative = true;
1757
1982
  const { valid: valid2, errors: collectionDefinitionErrors } = validateCollectionDefinition({
1983
+ referenceCategory: params.category,
1758
1984
  referenceGender: params.gender,
1759
1985
  collectionDefinition,
1760
1986
  checkCollectionIds,
1987
+ checkCategory,
1761
1988
  checkGender
1762
1989
  });
1763
1990
  if (valid2) {
@@ -1799,19 +2026,22 @@ function validateTieFormat(params) {
1799
2026
  return result;
1800
2027
  }
1801
2028
  function validateCollectionDefinition({
2029
+ checkCategory = true,
1802
2030
  collectionDefinition,
1803
2031
  checkCollectionIds,
1804
2032
  checkGender = true,
2033
+ referenceCategory,
1805
2034
  referenceGender,
1806
2035
  event
1807
2036
  }) {
1808
2037
  referenceGender = referenceGender ?? event?.gender;
2038
+ const stack = "validateCollectionDefinition";
1809
2039
  const errors = [];
1810
2040
  if (typeof collectionDefinition !== "object") {
1811
2041
  errors.push(
1812
2042
  `collectionDefinition must be an object: ${collectionDefinition}`
1813
2043
  );
1814
- return { errors, error: INVALID_OBJECT };
2044
+ return decorateResult({ result: { errors, error: INVALID_OBJECT }, stack });
1815
2045
  }
1816
2046
  const {
1817
2047
  collectionValueProfiles,
@@ -1824,6 +2054,7 @@ function validateCollectionDefinition({
1824
2054
  matchUpType,
1825
2055
  scoreValue,
1826
2056
  setValue,
2057
+ category,
1827
2058
  gender
1828
2059
  } = collectionDefinition;
1829
2060
  if (checkCollectionIds && typeof collectionId !== "string") {
@@ -1869,8 +2100,23 @@ function validateCollectionDefinition({
1869
2100
  if (checkGender && referenceGender && gender && [GenderEnum.Male, GenderEnum.Female].includes(referenceGender) && referenceGender !== gender) {
1870
2101
  errors.push(`Invalid gender: ${gender}`);
1871
2102
  }
2103
+ if (checkCategory && referenceCategory && category) {
2104
+ const result = categoryCanContain({
2105
+ category: referenceCategory,
2106
+ childCategory: category
2107
+ });
2108
+ if (!result.valid)
2109
+ return decorateResult({
2110
+ result: { error: INVALID_CATEGORY },
2111
+ context: result,
2112
+ stack
2113
+ });
2114
+ }
1872
2115
  if (errors.length)
1873
- return { errors, error: INVALID_OBJECT };
2116
+ return decorateResult({
2117
+ result: { errors, error: INVALID_COLLECTION_DEFINITION },
2118
+ stack
2119
+ });
1874
2120
  return { valid: true };
1875
2121
  }
1876
2122
  function validateCollectionValueProfiles({
@@ -5238,7 +5484,7 @@ function getOrderedDrawPositions({
5238
5484
  (pair) => overlap(pair || [], drawPositions.filter(Boolean))
5239
5485
  ) || unassignedDrawPositions;
5240
5486
  const isFeedRound = targetRoundProfile?.feedRound;
5241
- if (allNumeric(drawPositions)) {
5487
+ if (allNumeric$1(drawPositions)) {
5242
5488
  const orderedDrawPositions = drawPositions.sort(numericSort);
5243
5489
  return {
5244
5490
  orderedDrawPositions: orderedDrawPositions.length === 2 ? orderedDrawPositions : displayOrder,