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.
package/dist/index.mjs CHANGED
@@ -333,7 +333,7 @@ const matchUpFormatCode = {
333
333
  };
334
334
 
335
335
  function factoryVersion() {
336
- return "1.8.3";
336
+ return "1.8.4";
337
337
  }
338
338
 
339
339
  function getObjectTieFormat(obj) {
@@ -396,10 +396,6 @@ function resolveTieFormat({
396
396
  };
397
397
  }
398
398
 
399
- function mustBeAnArray(value) {
400
- return `${value} must be an array`;
401
- }
402
-
403
399
  function unique(arr) {
404
400
  return arr.filter((item, i, s) => s.lastIndexOf(item) === i);
405
401
  }
@@ -1166,10 +1162,18 @@ const INVALID_CONFIGURATION = {
1166
1162
  message: "Invalid configuration",
1167
1163
  code: "ERR_INVALID_CONFIG"
1168
1164
  };
1165
+ const INVALID_COLLECTION_DEFINITION = {
1166
+ message: "Invalid collectionDefinition",
1167
+ code: "ERR_INVALID_COLLECTION_DEFINITION"
1168
+ };
1169
1169
  const INVALID_OBJECT = {
1170
1170
  message: "Invalid object",
1171
1171
  code: "ERR_INVALID_OBJECT"
1172
1172
  };
1173
+ const INVALID_CATEGORY = {
1174
+ message: "Invalid category",
1175
+ code: "ERR_INVALID_CATEGORY"
1176
+ };
1173
1177
  const INVALID_VALUES = {
1174
1178
  message: "Invalid values",
1175
1179
  code: "ERR_INVALID_VALUES"
@@ -1270,6 +1274,8 @@ const errorConditionConstants = {
1270
1274
  INVALID_ACTION,
1271
1275
  INVALID_ASSIGNMENT,
1272
1276
  INVALID_BOOKINGS,
1277
+ INVALID_CATEGORY,
1278
+ INVALID_COLLECTION_DEFINITION,
1273
1279
  INVALID_CONFIGURATION,
1274
1280
  INVALID_DATE_AVAILABILITY,
1275
1281
  INVALID_DATE,
@@ -1712,6 +1718,9 @@ function setTournamentId(tournamentId) {
1712
1718
  function removeTournamentRecord(tournamentId) {
1713
1719
  return _globalStateProvider.removeTournamentRecord(tournamentId);
1714
1720
  }
1721
+ function getProvider() {
1722
+ return _globalStateProvider;
1723
+ }
1715
1724
  function handleCaughtError({
1716
1725
  engineName,
1717
1726
  methodName,
@@ -2040,6 +2049,13 @@ const dateTime = {
2040
2049
  };
2041
2050
 
2042
2051
  function makeDeepCopy(sourceObject, convertExtensions, internalUse, removeExtensions, iteration = 0) {
2052
+ if (getProvider().makeDeepCopy)
2053
+ return getProvider().makeDeepCopy(
2054
+ sourceObject,
2055
+ convertExtensions,
2056
+ internalUse,
2057
+ removeExtensions
2058
+ );
2043
2059
  const deepCopy = deepCopyEnabled();
2044
2060
  const { stringify, toJSON, ignore, modulate } = deepCopy || {};
2045
2061
  if (!deepCopy?.enabled && !internalUse || typeof sourceObject !== "object" || typeof sourceObject === "function" || sourceObject === null || typeof deepCopy?.threshold === "number" && iteration >= deepCopy.threshold) {
@@ -2214,6 +2230,177 @@ function generateHashCode(o) {
2214
2230
  return [str.length, keyCount, charSum].map((e) => e.toString(36)).join("");
2215
2231
  }
2216
2232
 
2233
+ const typeMatch = (arr, type) => arr.filter(Boolean).every((i) => typeof i === type);
2234
+ const allNumeric = (arr) => arr.filter(Boolean).every(isNumeric);
2235
+ function getCategoryAgeDetails(params) {
2236
+ const category = params.category;
2237
+ if (typeof category !== "object")
2238
+ return { error: INVALID_CATEGORY };
2239
+ let { ageCategoryCode, ageMaxDate, ageMinDate, ageMax, ageMin } = category;
2240
+ const categoryName = category.categoryName;
2241
+ let combinedAge;
2242
+ if (!typeMatch(
2243
+ [ageCategoryCode, ageMaxDate, ageMinDate, categoryName],
2244
+ "string"
2245
+ ) || !allNumeric(
2246
+ [ageMax, ageMin]
2247
+ ))
2248
+ return { error: INVALID_CATEGORY };
2249
+ const consideredDate = params.consideredDate ?? extractDate((/* @__PURE__ */ new Date()).toLocaleDateString("sv"));
2250
+ if (!isValidDateString(consideredDate))
2251
+ return { error: INVALID_DATE };
2252
+ const [consideredYear] = consideredDate.split("-").slice(0, 3).map((n) => parseInt(n));
2253
+ const previousDayDate = dateStringDaysChange(consideredDate, -1);
2254
+ const [previousDayMonth, previousDay] = previousDayDate.split("-").slice(1, 3).map((n) => parseInt(n));
2255
+ const previousMonthDay = `${zeroPad(previousDayMonth)}-${zeroPad(
2256
+ previousDay
2257
+ )}`;
2258
+ const nextDayDate = dateStringDaysChange(consideredDate, 1);
2259
+ const [nextDayMonth, nextDay] = nextDayDate.split("-").slice(1, 3).map((n) => parseInt(n));
2260
+ const nextMonthDay = `${zeroPad(nextDayMonth)}-${zeroPad(nextDay)}`;
2261
+ let calculatedAgeMaxDate = ageMin && dateStringDaysChange(consideredDate, -1 * 365 * ageMin);
2262
+ let calculatedAgeMinDate = ageMax && dateStringDaysChange(consideredDate, -1 * 365 * ageMax);
2263
+ const errors = [];
2264
+ const addError = (errorString) => !errors.includes(errorString) && errors.push(errorString);
2265
+ ageCategoryCode = ageCategoryCode ?? categoryName;
2266
+ const prePost = /^([UO]?)(\d{1,2})([UO]?)$/;
2267
+ const extractCombined = /^C(\d{1,2})-(\d{1,2})$/;
2268
+ const isBetween = ageCategoryCode?.includes("-");
2269
+ const isCombined = isBetween && ageCategoryCode?.match(extractCombined);
2270
+ const isCoded = ageCategoryCode?.match(prePost);
2271
+ const constructedDate = (y, df) => `${y}-${df}`;
2272
+ const uPre = (ageInt) => {
2273
+ const ageMinYear = consideredYear - ageInt;
2274
+ const newMinDate = constructedDate(ageMinYear, nextMonthDay);
2275
+ if (category.ageMinDate && category.ageMinDate !== newMinDate)
2276
+ addError(`Invalid submitted ageMinDate: ${ageMinDate}`);
2277
+ ageMinDate = newMinDate;
2278
+ if (ageCategoryCode) {
2279
+ if (category.ageMax && category.ageMax !== ageInt - 1) {
2280
+ addError(`Invalid submitted ageMax: ${ageMax}`);
2281
+ calculatedAgeMinDate = void 0;
2282
+ }
2283
+ ageMax = ageInt - 1;
2284
+ }
2285
+ };
2286
+ const uPost = (ageInt) => {
2287
+ const ageMinYear = consideredYear - ageInt - 1;
2288
+ const newMinDate = constructedDate(ageMinYear, nextMonthDay);
2289
+ if (category.ageMin && category.ageMin > ageInt) {
2290
+ addError(`Invalid submitted ageMin: ${ageMin}`);
2291
+ }
2292
+ if (category.ageMax && category.ageMax > ageInt) {
2293
+ addError(`Invalid submitted ageMax: ${ageMax}`);
2294
+ }
2295
+ if (category.ageMinDate && category.ageMinDate !== newMinDate)
2296
+ addError(`Invalid submitted ageMinDate: ${ageMinDate}`);
2297
+ ageMinDate = newMinDate;
2298
+ if (ageCategoryCode) {
2299
+ if (category.ageMax && category.ageMax !== ageInt) {
2300
+ addError(`Invalid submitted ageMax: ${ageMax}`);
2301
+ calculatedAgeMaxDate = void 0;
2302
+ }
2303
+ ageMax = ageInt;
2304
+ }
2305
+ };
2306
+ const oPre = (ageInt) => {
2307
+ const ageMaxYear = consideredYear - ageInt;
2308
+ const newMaxDate = constructedDate(ageMaxYear, previousMonthDay);
2309
+ if (category.ageMaxDate && category.ageMaxDate !== newMaxDate)
2310
+ addError(`Invalid submitted ageMaxDate: ${ageMaxDate}`);
2311
+ ageMaxDate = newMaxDate;
2312
+ if (ageCategoryCode) {
2313
+ if (category.ageMin && category.ageMin !== ageInt + 1) {
2314
+ addError(`Invalid submitted ageMin: ${ageMin}`);
2315
+ calculatedAgeMaxDate = void 0;
2316
+ }
2317
+ ageMin = ageInt + 1;
2318
+ }
2319
+ };
2320
+ const oPost = (ageInt) => {
2321
+ const ageMaxYear = consideredYear - ageInt - 1;
2322
+ const newMaxDate = constructedDate(ageMaxYear, previousMonthDay);
2323
+ if (category.ageMaxDate && category.ageMaxDate !== newMaxDate)
2324
+ addError(`Invalid submitted ageMaxDate: ${ageMaxDate}`);
2325
+ ageMaxDate = newMaxDate;
2326
+ if (ageCategoryCode) {
2327
+ if (category.ageMin && category.ageMin !== ageInt) {
2328
+ addError(`Invalid submitted ageMin: ${ageMin}`);
2329
+ calculatedAgeMaxDate = void 0;
2330
+ }
2331
+ ageMin = ageInt;
2332
+ }
2333
+ };
2334
+ const processCode = (code) => {
2335
+ const [pre, age, post] = (code.match(prePost) || []).slice(1);
2336
+ const ageInt = parseInt(age);
2337
+ if (pre === "U") {
2338
+ if (category.ageMaxDate && category.ageMaxDate !== ageMaxDate) {
2339
+ addError(`Invalid submitted ageMaxDate: ${category.ageMaxDate}`);
2340
+ }
2341
+ uPre(ageInt);
2342
+ } else if (pre === "O") {
2343
+ oPre(ageInt);
2344
+ }
2345
+ if (post === "U") {
2346
+ if (category.ageMaxDate && category.ageMaxDate !== ageMaxDate) {
2347
+ addError(`Invalid submitted ageMaxDate: ${category.ageMaxDate}`);
2348
+ }
2349
+ uPost(ageInt);
2350
+ } else if (post === "O") {
2351
+ oPost(ageInt);
2352
+ }
2353
+ ageMaxDate = ageMaxDate ?? calculatedAgeMaxDate;
2354
+ ageMinDate = ageMinDate ?? calculatedAgeMinDate;
2355
+ };
2356
+ if (isCombined) {
2357
+ ageMaxDate = void 0;
2358
+ ageMinDate = void 0;
2359
+ ageMax = void 0;
2360
+ ageMin = void 0;
2361
+ if (category.ageMin) {
2362
+ const ageMaxYear = consideredYear - category.ageMin;
2363
+ ageMaxDate = constructedDate(ageMaxYear, previousMonthDay);
2364
+ }
2365
+ if (category.ageMax) {
2366
+ const ageMinYear = consideredYear - category.ageMax - 1;
2367
+ ageMinDate = constructedDate(ageMinYear, nextMonthDay);
2368
+ }
2369
+ const [lowAge, highAge] = (ageCategoryCode?.match(extractCombined) ?? []).slice(1).map((n) => parseInt(n));
2370
+ if (lowAge <= highAge) {
2371
+ ageMin = lowAge;
2372
+ ageMax = highAge;
2373
+ combinedAge = true;
2374
+ } else {
2375
+ addError(`Invalid combined age range ${ageCategoryCode}`);
2376
+ }
2377
+ } else if (isBetween) {
2378
+ ageCategoryCode?.split("-").forEach(processCode);
2379
+ } else if (isCoded) {
2380
+ processCode(ageCategoryCode);
2381
+ } else {
2382
+ if (ageMin)
2383
+ oPre(ageMin);
2384
+ if (ageMax)
2385
+ uPost(ageMax);
2386
+ }
2387
+ if (ageMax && category.ageMin && category.ageMin > ageMax) {
2388
+ addError(`Invalid submitted ageMin: ${category.ageMin}`);
2389
+ ageMin = void 0;
2390
+ }
2391
+ const result = definedAttributes({
2392
+ consideredDate,
2393
+ combinedAge,
2394
+ ageMaxDate,
2395
+ ageMinDate,
2396
+ ageMax,
2397
+ ageMin
2398
+ });
2399
+ if (errors.length)
2400
+ result.errors = errors;
2401
+ return result;
2402
+ }
2403
+
2217
2404
  function attributeFilter(params) {
2218
2405
  if (params === null)
2219
2406
  return {};
@@ -2415,6 +2602,41 @@ function UUID() {
2415
2602
  lut[d3 & 255] + lut[d3 >> 8 & 255] + lut[d3 >> 16 & 255] + lut[d3 >> 24 & 255];
2416
2603
  }
2417
2604
 
2605
+ function categoryCanContain({
2606
+ childCategory,
2607
+ withDetails,
2608
+ category
2609
+ }) {
2610
+ const categoryDetails = getCategoryAgeDetails({ category });
2611
+ const childCategoryDetails = getCategoryAgeDetails({
2612
+ category: childCategory
2613
+ });
2614
+ const invalidAgeMin = childCategoryDetails.ageMin && (categoryDetails.ageMin && childCategoryDetails.ageMin < categoryDetails.ageMin || categoryDetails.ageMax && childCategoryDetails.ageMin > categoryDetails.ageMax);
2615
+ const invalidAgeMax = childCategoryDetails.ageMax && (categoryDetails.ageMax && childCategoryDetails.ageMax > categoryDetails.ageMax || categoryDetails.ageMin && childCategoryDetails.ageMax < categoryDetails.ageMin);
2616
+ const invalidAgeMinDate = childCategoryDetails.ageMinDate && categoryDetails.ageMaxDate && new Date(childCategoryDetails.ageMinDate) > new Date(categoryDetails.ageMaxDate);
2617
+ const invalidAgeMaxDate = childCategoryDetails.ageMaxDate && categoryDetails.ageMinDate && new Date(childCategoryDetails.ageMaxDate) < new Date(categoryDetails.ageMinDate);
2618
+ const valid = !invalidAgeMax && !invalidAgeMin && !invalidAgeMinDate && !invalidAgeMaxDate;
2619
+ const ignoreFalse = true;
2620
+ const result = definedAttributes(
2621
+ {
2622
+ valid,
2623
+ invalidAgeMax,
2624
+ invalidAgeMin,
2625
+ invalidAgeMinDate,
2626
+ invalidAgeMaxDate
2627
+ },
2628
+ ignoreFalse
2629
+ );
2630
+ if (withDetails) {
2631
+ Object.assign(result, { categoryDetails, childCategoryDetails });
2632
+ }
2633
+ return result;
2634
+ }
2635
+
2636
+ function mustBeAnArray(value) {
2637
+ return `${value} must be an array`;
2638
+ }
2639
+
2418
2640
  function decorateResult({
2419
2641
  context,
2420
2642
  result,
@@ -2553,6 +2775,7 @@ var ParticipantTypeEnum = /* @__PURE__ */ ((ParticipantTypeEnum2) => {
2553
2775
  })(ParticipantTypeEnum || {});
2554
2776
 
2555
2777
  function validateTieFormat(params) {
2778
+ const checkCategory = !!(params?.enforceCategory !== false && params?.category);
2556
2779
  const checkGender = !!(params?.enforceGender !== false && params?.gender);
2557
2780
  const checkCollectionIds = params?.checkCollectionIds;
2558
2781
  const tieFormat = params?.tieFormat;
@@ -2589,9 +2812,11 @@ function validateTieFormat(params) {
2589
2812
  if ((setValue || scoreValue) && !collectionValue)
2590
2813
  aggregateValueImperative = true;
2591
2814
  const { valid: valid2, errors: collectionDefinitionErrors } = validateCollectionDefinition({
2815
+ referenceCategory: params.category,
2592
2816
  referenceGender: params.gender,
2593
2817
  collectionDefinition,
2594
2818
  checkCollectionIds,
2819
+ checkCategory,
2595
2820
  checkGender
2596
2821
  });
2597
2822
  if (valid2) {
@@ -2633,19 +2858,22 @@ function validateTieFormat(params) {
2633
2858
  return result;
2634
2859
  }
2635
2860
  function validateCollectionDefinition({
2861
+ checkCategory = true,
2636
2862
  collectionDefinition,
2637
2863
  checkCollectionIds,
2638
2864
  checkGender = true,
2865
+ referenceCategory,
2639
2866
  referenceGender,
2640
2867
  event
2641
2868
  }) {
2642
2869
  referenceGender = referenceGender ?? event?.gender;
2870
+ const stack = "validateCollectionDefinition";
2643
2871
  const errors = [];
2644
2872
  if (typeof collectionDefinition !== "object") {
2645
2873
  errors.push(
2646
2874
  `collectionDefinition must be an object: ${collectionDefinition}`
2647
2875
  );
2648
- return { errors, error: INVALID_OBJECT };
2876
+ return decorateResult({ result: { errors, error: INVALID_OBJECT }, stack });
2649
2877
  }
2650
2878
  const {
2651
2879
  collectionValueProfiles,
@@ -2658,6 +2886,7 @@ function validateCollectionDefinition({
2658
2886
  matchUpType,
2659
2887
  scoreValue,
2660
2888
  setValue,
2889
+ category,
2661
2890
  gender
2662
2891
  } = collectionDefinition;
2663
2892
  if (checkCollectionIds && typeof collectionId !== "string") {
@@ -2703,8 +2932,23 @@ function validateCollectionDefinition({
2703
2932
  if (checkGender && referenceGender && gender && [GenderEnum.Male, GenderEnum.Female].includes(referenceGender) && referenceGender !== gender) {
2704
2933
  errors.push(`Invalid gender: ${gender}`);
2705
2934
  }
2935
+ if (checkCategory && referenceCategory && category) {
2936
+ const result = categoryCanContain({
2937
+ category: referenceCategory,
2938
+ childCategory: category
2939
+ });
2940
+ if (!result.valid)
2941
+ return decorateResult({
2942
+ result: { error: INVALID_CATEGORY },
2943
+ context: result,
2944
+ stack
2945
+ });
2946
+ }
2706
2947
  if (errors.length)
2707
- return { errors, error: INVALID_OBJECT };
2948
+ return decorateResult({
2949
+ result: { errors, error: INVALID_COLLECTION_DEFINITION },
2950
+ stack
2951
+ });
2708
2952
  return { valid: true };
2709
2953
  }
2710
2954
  function checkTieFormat(tieFormat) {
@@ -17427,103 +17671,6 @@ const garman = {
17427
17671
  courtGenerator
17428
17672
  };
17429
17673
 
17430
- const typeMatch = (arr, type) => arr.filter(Boolean).every((i) => typeof i === type);
17431
- const allNumeric = (arr) => arr.filter(Boolean).every(isNumeric);
17432
- function parseAgeCategoryCode({ consideredDate, category } = { consideredDate: "" }) {
17433
- const invalid = { error: INVALID_VALUES, ageMin: 8, ageMax: 99 };
17434
- if (typeof category !== "object" || !isValidDateString(consideredDate))
17435
- return invalid;
17436
- const consideredYear = parseInt(consideredDate.split("-")[0]);
17437
- const errors = [];
17438
- let { ageCategoryCode, ageMaxDate, ageMinDate, ageMax, ageMin } = category;
17439
- const categoryName = category.categoryName;
17440
- let combinedAge;
17441
- if (!typeMatch(
17442
- [ageCategoryCode, ageMaxDate, ageMinDate, categoryName],
17443
- "string"
17444
- ) || !allNumeric([ageMax, ageMin]))
17445
- return invalid;
17446
- ageCategoryCode = ageCategoryCode ?? categoryName;
17447
- const prePost = /^([UO]?)(\d{1,2})([UO]?)$/;
17448
- const extractCombined = /^C(\d{1,2})-(\d{1,2})$/;
17449
- const isBetween = ageCategoryCode?.includes("-");
17450
- const isCombined = isBetween && ageCategoryCode?.match(extractCombined);
17451
- const isCoded = ageCategoryCode?.match(prePost);
17452
- const isYYMM = (datePart) => datePart.match(/^\d{2}-\d{2}$/);
17453
- const constructedDate = (y, d, df) => isValidDateString(d) && d || d && isYYMM(d) && `${y}-${d}` || `${y}-${df}`;
17454
- const uPre = (ageInt) => {
17455
- const ageMinYear = consideredYear - ageInt;
17456
- ageMinDate = constructedDate(ageMinYear, ageMinDate, "01-01");
17457
- if (ageMax && ageMax !== ageInt - 1)
17458
- errors.push(`Invalid ageMax: ${ageMax}`);
17459
- if (!ageMax)
17460
- ageMax = ageInt - 1;
17461
- return { ageMinDate, ageMax };
17462
- };
17463
- const uPost = (ageInt) => {
17464
- const ageMinYear = consideredYear - ageInt - 1;
17465
- ageMinDate = constructedDate(ageMinYear, ageMinDate, "01-01");
17466
- if (ageMax && ageMax !== ageInt)
17467
- errors.push(`Invalid ageMax: ${ageMax}`);
17468
- if (!ageMax)
17469
- ageMax = ageInt;
17470
- return { ageMinDate, ageMax };
17471
- };
17472
- const oPre = (ageInt) => {
17473
- const ageMaxYear = consideredYear - ageInt - 2;
17474
- ageMaxDate = constructedDate(ageMaxYear, ageMaxDate, "12-31");
17475
- if (ageMin && ageMin !== ageInt + 1)
17476
- errors.push(`Invalid ageMin: ${ageMin}`);
17477
- if (!ageMin)
17478
- ageMin = ageInt + 1;
17479
- return { ageMaxDate, ageMin };
17480
- };
17481
- const oPost = (ageInt) => {
17482
- const ageMaxYear = consideredYear - ageInt - 1;
17483
- ageMaxDate = constructedDate(ageMaxYear, ageMaxDate, "12-31");
17484
- if (ageMin && ageMin !== ageInt)
17485
- errors.push(`Invalid ageMin: ${ageMin}`);
17486
- if (!ageMin)
17487
- ageMin = ageInt;
17488
- return { ageMaxDate, ageMin };
17489
- };
17490
- const processCode = (code) => {
17491
- const [pre, age, post] = (code.match(prePost) || []).slice(1);
17492
- const ageInt = parseInt(age);
17493
- if (pre === "U")
17494
- ({ ageMinDate, ageMax } = uPre(ageInt));
17495
- if (post === "U")
17496
- ({ ageMinDate, ageMax } = uPost(ageInt));
17497
- if (pre === "O")
17498
- ({ ageMaxDate, ageMin } = oPre(ageInt));
17499
- if (post === "O")
17500
- ({ ageMaxDate, ageMin } = oPost(ageInt));
17501
- };
17502
- if (isCombined) {
17503
- const [lowAge, highAge] = (ageCategoryCode?.match(extractCombined) ?? []).slice(1).map((n) => parseInt(n));
17504
- if (lowAge <= highAge) {
17505
- ageMin = ageMin ?? lowAge;
17506
- ageMax = ageMax ?? highAge;
17507
- combinedAge = true;
17508
- } else {
17509
- errors.push(`Invalid combined age range ${ageCategoryCode}`);
17510
- }
17511
- } else if (isBetween) {
17512
- ageCategoryCode?.split("-").forEach(processCode);
17513
- } else if (isCoded) {
17514
- processCode(ageCategoryCode);
17515
- }
17516
- if (errors.length)
17517
- return { error: errors, ageMin: 8, ageMax: 99 };
17518
- return definedAttributes({
17519
- combinedAge,
17520
- ageMaxDate,
17521
- ageMinDate,
17522
- ageMax,
17523
- ageMin
17524
- });
17525
- }
17526
-
17527
17674
  function parseScoreString({
17528
17675
  tiebreakTo = 7,
17529
17676
  scoreString
@@ -23108,22 +23255,25 @@ const structureTemplate = ({
23108
23255
  return structure;
23109
23256
  };
23110
23257
 
23111
- function generateRoundRobin({
23112
- structureName = constantToString(MAIN),
23113
- groupNameBase = "Group",
23114
- stageSequence = 1,
23115
- structureOptions,
23116
- appliedPolicies,
23117
- seedingProfile,
23118
- stage = MAIN,
23119
- matchUpType,
23120
- roundTarget,
23121
- structureId,
23122
- drawSize,
23123
- idPrefix,
23124
- isMock,
23125
- uuids
23126
- }) {
23258
+ function generateRoundRobin(params) {
23259
+ const {
23260
+ groupNameBase = "Group",
23261
+ playoffAttributes,
23262
+ stageSequence = 1,
23263
+ structureOptions,
23264
+ appliedPolicies,
23265
+ seedingProfile,
23266
+ stage = MAIN,
23267
+ matchUpType,
23268
+ roundTarget,
23269
+ structureId,
23270
+ groupNames,
23271
+ drawSize,
23272
+ idPrefix,
23273
+ isMock,
23274
+ uuids
23275
+ } = params;
23276
+ const structureName = params.structureName ?? playoffAttributes?.["0"]?.name ?? constantToString(MAIN);
23127
23277
  const { groupCount, groupSize } = deriveGroups({
23128
23278
  structureOptions,
23129
23279
  appliedPolicies,
@@ -23143,12 +23293,13 @@ function generateRoundRobin({
23143
23293
  maxRoundNumber = Math.max(
23144
23294
  ...matchUps.map(({ roundNumber }) => roundNumber)
23145
23295
  );
23296
+ const structureName2 = groupNames?.[structureOrder - 1] ?? `${groupNameBase} ${structureOrder}`;
23146
23297
  return structureTemplate({
23147
- structureName: `${groupNameBase} ${structureOrder}`,
23148
23298
  structureId: uuids?.pop(),
23149
23299
  structureType: ITEM,
23150
23300
  finishingPosition,
23151
23301
  structureOrder,
23302
+ structureName: structureName2,
23152
23303
  matchUps
23153
23304
  });
23154
23305
  });
@@ -30305,7 +30456,9 @@ function removeCollectionDefinition(params) {
30305
30456
  function addCollectionDefinition$1({
30306
30457
  updateInProgressMatchUps = true,
30307
30458
  collectionDefinition,
30459
+ referenceCategory,
30308
30460
  tournamentRecord,
30461
+ enforceCategory,
30309
30462
  referenceGender,
30310
30463
  drawDefinition,
30311
30464
  tieFormatName,
@@ -30323,16 +30476,21 @@ function addCollectionDefinition$1({
30323
30476
  drawDefinition,
30324
30477
  event
30325
30478
  }).appliedPolicies ?? {};
30326
- enforceGender = enforceGender ?? appliedPolicies?.[POLICY_TYPE_MATCHUP_ACTIONS]?.participants?.enforceGender;
30327
- const checkGender = !!(enforceGender !== false && event?.gender);
30328
- const { valid, errors } = validateCollectionDefinition({
30479
+ const matchUpActionsPolicy = appliedPolicies?.[POLICY_TYPE_MATCHUP_ACTIONS];
30480
+ enforceCategory = enforceCategory ?? matchUpActionsPolicy?.participants?.enforceCategory;
30481
+ enforceGender = enforceGender ?? matchUpActionsPolicy?.participants?.enforceGender;
30482
+ const checkCategory = !!((referenceCategory ?? event?.category) && enforceCategory !== false);
30483
+ const checkGender = !!((referenceGender ?? event?.gender) && enforceGender !== false);
30484
+ const validationResult = validateCollectionDefinition({
30485
+ referenceCategory: referenceCategory ?? event?.category,
30329
30486
  collectionDefinition,
30330
30487
  referenceGender,
30488
+ checkCategory,
30331
30489
  checkGender,
30332
30490
  event
30333
30491
  });
30334
- if (!valid) {
30335
- return decorateResult({ result: { error: INVALID_VALUES, errors }, stack });
30492
+ if (validationResult.error) {
30493
+ return decorateResult({ result: validationResult, stack });
30336
30494
  }
30337
30495
  let result = !matchUp?.tieFormat ? getTieFormat$1({
30338
30496
  drawDefinition,
@@ -36991,6 +37149,8 @@ const POLICY_MATCHUP_ACTIONS_DEFAULT = {
36991
37149
  }
36992
37150
  ],
36993
37151
  participants: {
37152
+ enforceCategory: true,
37153
+ // validate collectionDefinition.category against event.category
36994
37154
  enforceGender: true
36995
37155
  // disallow placing FEMALEs in MALE events and vice versa
36996
37156
  },
@@ -40403,7 +40563,7 @@ function generatePlayoffStructures(params) {
40403
40563
  const attributeProfile = playoffAttributes?.[exitProfile];
40404
40564
  const base = playoffStructureNameBase && `${playoffStructureNameBase} ` || "";
40405
40565
  const customNaming = playoffAttributes?.[finishingPositionRange] ?? finishingPositionNaming?.[finishingPositionRange];
40406
- const structureName = customNaming?.name || attributeProfile?.name && (addNameBaseToAttributeName ? `${base}${attributeProfile?.name}` : attributeProfile.name) || `${base}${finishingPositionRange}`;
40566
+ const structureName = params.structureName || customNaming?.name || attributeProfile?.name && (addNameBaseToAttributeName ? `${base}${attributeProfile?.name}` : attributeProfile.name) || `${base}${finishingPositionRange}`;
40407
40567
  const structureAbbreviation = customNaming?.abbreviation || attributeProfile?.abbreviation;
40408
40568
  const mainParams = {
40409
40569
  idPrefix: idPrefix && `${idPrefix}-${structureName}-RP`,
@@ -40559,12 +40719,14 @@ function feedInChampionship(params) {
40559
40719
  fmlc
40560
40720
  });
40561
40721
  if (drawSize > 2) {
40722
+ const name = playoffAttributes?.["0-1"]?.name ?? constantToString(CONSOLATION);
40723
+ const structureName2 = params.playoffStructureNameBase ? `${params.playoffStructureNameBase} ${name}` : name;
40562
40724
  const consolationStructure = structureTemplate({
40563
- structureName: playoffAttributes?.["0-1"]?.name ?? constantToString(CONSOLATION),
40564
40725
  matchUps: consolationMatchUps,
40565
40726
  structureId: uuids?.pop(),
40566
40727
  stage: CONSOLATION,
40567
40728
  stageSequence: 1,
40729
+ structureName: structureName2,
40568
40730
  matchUpType
40569
40731
  });
40570
40732
  structures.push(consolationStructure);
@@ -40710,8 +40872,9 @@ function processPlayoffGroups({
40710
40872
  } else if ([COMPASS, OLYMPIC, PLAY_OFF].includes(playoffDrawType)) {
40711
40873
  const params2 = {
40712
40874
  playoffAttributes: playoffGroup.playoffAttributes ?? playoffAttributes,
40875
+ playoffStructureNameBase: playoffGroup.playoffStructureNameBase,
40713
40876
  structureId: playoffGroup.structureId ?? uuids?.pop(),
40714
- playoffStructureNameBase: structureName,
40877
+ structureName: playoffGroup.structureName,
40715
40878
  idPrefix: idPrefix && `${idPrefix}-po`,
40716
40879
  addNameBaseToAttributeName: true,
40717
40880
  finishingPositionOffset,
@@ -40764,7 +40927,9 @@ function processPlayoffGroups({
40764
40927
  ].includes(playoffDrawType)) {
40765
40928
  const uuidsFMLC = [uuids?.pop(), uuids?.pop()];
40766
40929
  const params2 = {
40930
+ playoffStructureNameBase: playoffGroup.playoffStructureNameBase,
40767
40931
  structureId: playoffGroup.structureId ?? uuids?.pop(),
40932
+ playoffAttributes: playoffGroup.playoffAttributes,
40768
40933
  idPrefix: idPrefix && `${idPrefix}-po`,
40769
40934
  finishingPositionOffset,
40770
40935
  uuids: uuidsFMLC,
@@ -40855,7 +41020,7 @@ function generateRoundRobinWithPlayOff(params) {
40855
41020
  };
40856
41021
  const { structures, groupCount, groupSize } = generateRoundRobin(mainDrawProperties);
40857
41022
  if (groupCount < 1) {
40858
- console.log(INVALID_CONFIGURATION);
41023
+ return { error: INVALID_CONFIGURATION };
40859
41024
  }
40860
41025
  const playoffGroups = structureOptions?.playoffGroups || [
40861
41026
  { finishingPositions: [1], structureName: constantToString(PLAY_OFF) }
@@ -58240,8 +58405,8 @@ function prepareStage(params) {
58240
58405
  });
58241
58406
  if (!scaledEntries?.length && seedByRanking) {
58242
58407
  const rankingScaleAttributes = {
58243
- scaleType: RANKING$1,
58244
58408
  scaleName: categoryName || ageCategoryCode,
58409
+ scaleType: RANKING$1,
58245
58410
  eventType
58246
58411
  };
58247
58412
  ({ scaledEntries } = getScaledEntries({
@@ -61264,7 +61429,7 @@ function generatePersons(params) {
61264
61429
  shuffledPersons.push(person);
61265
61430
  });
61266
61431
  }
61267
- const { ageMinDate, ageMaxDate } = parseAgeCategoryCode({
61432
+ const { ageMinDate, ageMaxDate } = getCategoryAgeDetails({
61268
61433
  consideredDate,
61269
61434
  category
61270
61435
  });
@@ -64125,7 +64290,8 @@ const utilities = {
64125
64290
  nextPowerOf2,
64126
64291
  numericSort,
64127
64292
  overlap,
64128
- parseAgeCategoryCode,
64293
+ getCategoryAgeDetails,
64294
+ categoryCanContain,
64129
64295
  randomMember,
64130
64296
  randomPop,
64131
64297
  shuffleArray,