Skip to content

Commit f708b65

Browse files
committed
[O2B-1503] JSDoc enhancements. Extracted duplicate functions to utils. Feedback processed.
1 parent ecfa3d9 commit f708b65

7 files changed

Lines changed: 92 additions & 78 deletions

File tree

lib/domain/dtos/filters/LhcFillsFilterDto.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* or submit itself to any jurisdiction.
1212
*/
1313
const Joi = require('joi');
14-
const { validateRange } = require('../../../utilities/validateRange');
14+
const { validateRange } = require('../../../utilities/rangeUtils');
1515

1616
exports.LhcFillsFilterDto = Joi.object({
1717
hasStableBeams: Joi.boolean(),

lib/domain/dtos/filters/RunFilterDto.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const { IntegerComparisonDto, FloatComparisonDto } = require('./NumericalCompari
1818
const { RUN_CALIBRATION_STATUS } = require('../../enums/RunCalibrationStatus.js');
1919
const { RUN_DEFINITIONS } = require('../../enums/RunDefinition.js');
2020
const { singleRunsCollectionCustomCheck } = require('../utils.js');
21-
const { validateRange } = require('../../../utilities/validateRange.js');
21+
const { validateRange } = require('../../../utilities/rangeUtils.js');
2222

2323
const DetectorsFilterDto = Joi.object({
2424
operator: Joi.string().valid('or', 'and', 'none').required(),

lib/usecases/lhcFill/GetAllLhcFillsUseCase.js

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ const {
2222
const { lhcFillAdapter } = require('../../database/adapters/index.js');
2323
const { ApiConfig } = require('../../config/index.js');
2424
const { RunDefinition } = require('../../domain/enums/RunDefinition.js');
25+
const { unpackNumberRange } = require('../../utilities/rangeUtils.js');
26+
const { splitStringToStringsTrimmed } = require('../../utilities/stringUtils.js');
2527

2628
/**
2729
* GetAllLhcFillsUseCase
@@ -50,33 +52,9 @@ class GetAllLhcFillsUseCase {
5052
}
5153

5254
if (fillNumbers) {
53-
/*
54-
* Split by SEARCH_ITEMS_SEPARATOR. Don't validate for only numbers
55-
* Boolean trick: https://michaeluloth.com/javascript-filter-boolean/
56-
*/
57-
const fillNumberCriteria = fillNumbers.split(SEARCH_ITEMS_SEPARATOR)
58-
.map((runNumbers) => runNumbers.trim())
59-
.filter(Boolean);
55+
const fillNumberCriteria = splitStringToStringsTrimmed(fillNumbers, SEARCH_ITEMS_SEPARATOR);
6056

61-
// Set to prevent duplicate values.
62-
const fillNumberSet = new Set();
63-
64-
fillNumberCriteria.forEach((fillNumber) => {
65-
if (fillNumber.includes('-')) {
66-
const [start, end] = fillNumber.split('-').map((n) => parseInt(n, 10));
67-
if (!Number.isNaN(start) && !Number.isNaN(end)) {
68-
for (let i = start; i <= end; i++) {
69-
fillNumberSet.add(i);
70-
}
71-
}
72-
} else {
73-
if (!Number.isNaN(fillNumber)) {
74-
fillNumberSet.add(Number(fillNumber));
75-
}
76-
}
77-
});
78-
79-
const finalFillnumberList = Array.from(fillNumberSet);
57+
const finalFillnumberList = Array.from(unpackNumberRange(fillNumberCriteria));
8058

8159
// Check that the final fill numbers list contains at least one valid fill number
8260
if (finalFillnumberList.length > 0) {

lib/usecases/run/GetAllRunsUseCase.js

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ const { BadParameterError } = require('../../server/errors/BadParameterError');
2323
const { gaqService } = require('../../server/services/qualityControlFlag/GaqService.js');
2424
const { qcFlagSummaryService } = require('../../server/services/qualityControlFlag/QcFlagSummaryService.js');
2525
const { DetectorType } = require('../../domain/enums/DetectorTypes.js');
26+
const { unpackNumberRange } = require('../../utilities/rangeUtils.js');
27+
const { splitStringToStringsTrimmed } = require('../../utilities/stringUtils.js');
2628

2729
/**
2830
* GetAllRunsUseCase
@@ -83,29 +85,9 @@ class GetAllRunsUseCase {
8385
} = filter;
8486

8587
if (runNumbers) {
86-
const runNumberCriteria = runNumbers.split(SEARCH_ITEMS_SEPARATOR)
87-
.map((runNumbers) => runNumbers.trim())
88-
.filter(Boolean);
89-
90-
const runNumberSet = new Set();
91-
92-
runNumberCriteria.forEach((runNumber) => {
93-
if (runNumber.includes('-')) {
94-
const [start, end] = runNumber.split('-').map((n) => parseInt(n, 10));
95-
if (!Number.isNaN(start) && !Number.isNaN(end)) {
96-
for (let i = start; i <= end; i++) {
97-
runNumberSet.add(i);
98-
}
99-
}
100-
} else {
101-
const parsedRunNumber = parseInt(runNumber, 10);
102-
if (!Number.isNaN(parsedRunNumber)) {
103-
runNumberSet.add(parsedRunNumber);
104-
}
105-
}
106-
});
88+
const runNumberCriteria = splitStringToStringsTrimmed(runNumbers, SEARCH_ITEMS_SEPARATOR);
10789

108-
const finalRunNumberList = Array.from(runNumberSet);
90+
const finalRunNumberList = Array.from(unpackNumberRange(runNumberCriteria));
10991

11092
// Check that the final run numbers list contains at least one valid run number
11193
if (finalRunNumberList.length > 0) {

lib/utilities/rangeUtils.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/**
2+
* @license
3+
* Copyright CERN and copyright holders of ALICE O2. This software is
4+
* distributed under the terms of the GNU General Public License v3 (GPL
5+
* Version 3), copied verbatim in the file "COPYING".
6+
*
7+
* See http://alice-o2.web.cern.ch/license for full licensing information.
8+
*
9+
* In applying this license CERN does not waive the privileges and immunities
10+
* granted to it by virtue of its status as an Intergovernmental Organization
11+
* or submit itself to any jurisdiction.
12+
*/
13+
14+
/**
15+
* Validates numbers ranges to not exceed 100 entities
16+
* Expects a string containing comma seperated number values.
17+
*
18+
* @param {string} value The value to validate
19+
* @param {*} helpers The helpers object
20+
* @returns {Object} The value if validation passes
21+
*/
22+
export const validateRange = (value, helpers) => {
23+
const MAX_RANGE_SIZE = 100;
24+
25+
const numbers = value.split(',').map((number) => number.trim());
26+
27+
for (const number of numbers) {
28+
if (number.includes('-')) {
29+
const [start, end] = number.split('-').map((n) => parseInt(n, 10));
30+
if (Number.isNaN(start) || Number.isNaN(end) || start > end) {
31+
return helpers.error('any.invalid', { message: `Invalid range: ${number}` });
32+
}
33+
const rangeSize = end - start + 1;
34+
35+
if (rangeSize > MAX_RANGE_SIZE) {
36+
return helpers.error('any.invalid', { message: `Given range exceeds max size of ${MAX_RANGE_SIZE} range: ${number}` });
37+
}
38+
}
39+
}
40+
41+
return value;
42+
};
43+
44+
/**
45+
* Unpacks a given string containing number ranges.
46+
* E.G. input: 5,7-9 => output: 5,7,8,9
47+
* @param {string} numbersRange numbers that may or may not contain ranges.
48+
* @param {string} rangeSplitter string used to indicate and unpack a range.
49+
* @returns {Set<Number>} set containing the unpacked range.
50+
*/
51+
export function unpackNumberRange(numbersRange, rangeSplitter = '-') {
52+
// Set to prevent duplicate values.
53+
const resultNumbers = new Set();
54+
55+
numbersRange.forEach((number) => {
56+
if (number.includes(rangeSplitter)) {
57+
const [start, end] = number.split(rangeSplitter).map((n) => parseInt(n, 10));
58+
if (!Number.isNaN(start) && !Number.isNaN(end)) {
59+
for (let i = start; i <= end; i++) {
60+
resultNumbers.add(Number(i));
61+
}
62+
}
63+
} else {
64+
if (!Number.isNaN(number)) {
65+
resultNumbers.add(Number(number));
66+
}
67+
}
68+
});
69+
return resultNumbers;
70+
}

lib/utilities/stringUtils.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ const snakeToCamel = (snake) => snake.toLowerCase()
6262
*/
6363
const snakeToPascal = (snake) => ucFirst(snakeToCamel(snake));
6464

65+
/**
66+
* Split the received string to an array of trimmed strings.
67+
* Boolean trick: https://michaeluloth.com/javascript-filter-boolean/
68+
* @param {string} stringCollection String containing other strings withing split by seperator.
69+
* @param {string} stringSeperator Used to seperate the stringCollection.
70+
*/
71+
const splitStringToStringsTrimmed = (stringCollection, stringSeperator = ',') => stringCollection.split(stringSeperator)
72+
.map((string) => string.trim())
73+
.filter(Boolean);
74+
6575
exports.ucFirst = ucFirst;
6676

6777
exports.lcFirst = lcFirst;
@@ -73,3 +83,5 @@ exports.pascalToSnake = pascalToSnake;
7383
exports.snakeToCamel = snakeToCamel;
7484

7585
exports.snakeToPascal = snakeToPascal;
86+
87+
exports.splitStringToStringsTrimmed = splitStringToStringsTrimmed;

lib/utilities/validateRange.js

Lines changed: 0 additions & 28 deletions
This file was deleted.

0 commit comments

Comments
 (0)