1. 调整计划列表展示项
2. 调整设备列表展示项
This commit is contained in:
382
node_modules/cron-parser/dist/CronExpressionParser.js
generated
vendored
Normal file
382
node_modules/cron-parser/dist/CronExpressionParser.js
generated
vendored
Normal file
@@ -0,0 +1,382 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CronExpressionParser = exports.DayOfWeek = exports.Months = exports.CronUnit = exports.PredefinedExpressions = void 0;
|
||||
const CronFieldCollection_1 = require("./CronFieldCollection");
|
||||
const CronExpression_1 = require("./CronExpression");
|
||||
const random_1 = require("./utils/random");
|
||||
const fields_1 = require("./fields");
|
||||
var PredefinedExpressions;
|
||||
(function (PredefinedExpressions) {
|
||||
PredefinedExpressions["@yearly"] = "0 0 0 1 1 *";
|
||||
PredefinedExpressions["@annually"] = "0 0 0 1 1 *";
|
||||
PredefinedExpressions["@monthly"] = "0 0 0 1 * *";
|
||||
PredefinedExpressions["@weekly"] = "0 0 0 * * 0";
|
||||
PredefinedExpressions["@daily"] = "0 0 0 * * *";
|
||||
PredefinedExpressions["@hourly"] = "0 0 * * * *";
|
||||
PredefinedExpressions["@minutely"] = "0 * * * * *";
|
||||
PredefinedExpressions["@secondly"] = "* * * * * *";
|
||||
PredefinedExpressions["@weekdays"] = "0 0 0 * * 1-5";
|
||||
PredefinedExpressions["@weekends"] = "0 0 0 * * 0,6";
|
||||
})(PredefinedExpressions || (exports.PredefinedExpressions = PredefinedExpressions = {}));
|
||||
var CronUnit;
|
||||
(function (CronUnit) {
|
||||
CronUnit["Second"] = "Second";
|
||||
CronUnit["Minute"] = "Minute";
|
||||
CronUnit["Hour"] = "Hour";
|
||||
CronUnit["DayOfMonth"] = "DayOfMonth";
|
||||
CronUnit["Month"] = "Month";
|
||||
CronUnit["DayOfWeek"] = "DayOfWeek";
|
||||
})(CronUnit || (exports.CronUnit = CronUnit = {}));
|
||||
// these need to be lowercase for the parser to work
|
||||
var Months;
|
||||
(function (Months) {
|
||||
Months[Months["jan"] = 1] = "jan";
|
||||
Months[Months["feb"] = 2] = "feb";
|
||||
Months[Months["mar"] = 3] = "mar";
|
||||
Months[Months["apr"] = 4] = "apr";
|
||||
Months[Months["may"] = 5] = "may";
|
||||
Months[Months["jun"] = 6] = "jun";
|
||||
Months[Months["jul"] = 7] = "jul";
|
||||
Months[Months["aug"] = 8] = "aug";
|
||||
Months[Months["sep"] = 9] = "sep";
|
||||
Months[Months["oct"] = 10] = "oct";
|
||||
Months[Months["nov"] = 11] = "nov";
|
||||
Months[Months["dec"] = 12] = "dec";
|
||||
})(Months || (exports.Months = Months = {}));
|
||||
// these need to be lowercase for the parser to work
|
||||
var DayOfWeek;
|
||||
(function (DayOfWeek) {
|
||||
DayOfWeek[DayOfWeek["sun"] = 0] = "sun";
|
||||
DayOfWeek[DayOfWeek["mon"] = 1] = "mon";
|
||||
DayOfWeek[DayOfWeek["tue"] = 2] = "tue";
|
||||
DayOfWeek[DayOfWeek["wed"] = 3] = "wed";
|
||||
DayOfWeek[DayOfWeek["thu"] = 4] = "thu";
|
||||
DayOfWeek[DayOfWeek["fri"] = 5] = "fri";
|
||||
DayOfWeek[DayOfWeek["sat"] = 6] = "sat";
|
||||
})(DayOfWeek || (exports.DayOfWeek = DayOfWeek = {}));
|
||||
/**
|
||||
* Static class that parses a cron expression and returns a CronExpression object.
|
||||
* @static
|
||||
* @class CronExpressionParser
|
||||
*/
|
||||
class CronExpressionParser {
|
||||
/**
|
||||
* Parses a cron expression and returns a CronExpression object.
|
||||
* @param {string} expression - The cron expression to parse.
|
||||
* @param {CronExpressionOptions} [options={}] - The options to use when parsing the expression.
|
||||
* @param {boolean} [options.strict=false] - If true, will throw an error if the expression contains both dayOfMonth and dayOfWeek.
|
||||
* @param {CronDate} [options.currentDate=new CronDate(undefined, 'UTC')] - The date to use when calculating the next/previous occurrence.
|
||||
*
|
||||
* @returns {CronExpression} A CronExpression object.
|
||||
*/
|
||||
static parse(expression, options = {}) {
|
||||
const { strict = false, hashSeed } = options;
|
||||
const rand = (0, random_1.seededRandom)(hashSeed);
|
||||
expression = PredefinedExpressions[expression] || expression;
|
||||
const rawFields = CronExpressionParser.#getRawFields(expression, strict);
|
||||
if (!(rawFields.dayOfMonth === '*' || rawFields.dayOfWeek === '*' || !strict)) {
|
||||
throw new Error('Cannot use both dayOfMonth and dayOfWeek together in strict mode!');
|
||||
}
|
||||
const second = CronExpressionParser.#parseField(CronUnit.Second, rawFields.second, fields_1.CronSecond.constraints, rand);
|
||||
const minute = CronExpressionParser.#parseField(CronUnit.Minute, rawFields.minute, fields_1.CronMinute.constraints, rand);
|
||||
const hour = CronExpressionParser.#parseField(CronUnit.Hour, rawFields.hour, fields_1.CronHour.constraints, rand);
|
||||
const month = CronExpressionParser.#parseField(CronUnit.Month, rawFields.month, fields_1.CronMonth.constraints, rand);
|
||||
const dayOfMonth = CronExpressionParser.#parseField(CronUnit.DayOfMonth, rawFields.dayOfMonth, fields_1.CronDayOfMonth.constraints, rand);
|
||||
const { dayOfWeek: _dayOfWeek, nthDayOfWeek } = CronExpressionParser.#parseNthDay(rawFields.dayOfWeek);
|
||||
const dayOfWeek = CronExpressionParser.#parseField(CronUnit.DayOfWeek, _dayOfWeek, fields_1.CronDayOfWeek.constraints, rand);
|
||||
const fields = new CronFieldCollection_1.CronFieldCollection({
|
||||
second: new fields_1.CronSecond(second, { rawValue: rawFields.second }),
|
||||
minute: new fields_1.CronMinute(minute, { rawValue: rawFields.minute }),
|
||||
hour: new fields_1.CronHour(hour, { rawValue: rawFields.hour }),
|
||||
dayOfMonth: new fields_1.CronDayOfMonth(dayOfMonth, { rawValue: rawFields.dayOfMonth }),
|
||||
month: new fields_1.CronMonth(month, { rawValue: rawFields.month }),
|
||||
dayOfWeek: new fields_1.CronDayOfWeek(dayOfWeek, { rawValue: rawFields.dayOfWeek, nthDayOfWeek }),
|
||||
});
|
||||
return new CronExpression_1.CronExpression(fields, { ...options, expression });
|
||||
}
|
||||
/**
|
||||
* Get the raw fields from a cron expression.
|
||||
* @param {string} expression - The cron expression to parse.
|
||||
* @param {boolean} strict - If true, will throw an error if the expression contains both dayOfMonth and dayOfWeek.
|
||||
* @private
|
||||
* @returns {RawCronFields} The raw fields.
|
||||
*/
|
||||
static #getRawFields(expression, strict) {
|
||||
if (strict && !expression.length) {
|
||||
throw new Error('Invalid cron expression');
|
||||
}
|
||||
expression = expression || '0 * * * * *';
|
||||
const atoms = expression.trim().split(/\s+/);
|
||||
if (strict && atoms.length < 6) {
|
||||
throw new Error('Invalid cron expression, expected 6 fields');
|
||||
}
|
||||
if (atoms.length > 6) {
|
||||
throw new Error('Invalid cron expression, too many fields');
|
||||
}
|
||||
const defaults = ['*', '*', '*', '*', '*', '0'];
|
||||
if (atoms.length < defaults.length) {
|
||||
atoms.unshift(...defaults.slice(atoms.length));
|
||||
}
|
||||
const [second, minute, hour, dayOfMonth, month, dayOfWeek] = atoms;
|
||||
return { second, minute, hour, dayOfMonth, month, dayOfWeek };
|
||||
}
|
||||
/**
|
||||
* Parse a field from a cron expression.
|
||||
* @param {CronUnit} field - The field to parse.
|
||||
* @param {string} value - The value of the field.
|
||||
* @param {CronConstraints} constraints - The constraints for the field.
|
||||
* @private
|
||||
* @returns {(number | string)[]} The parsed field.
|
||||
*/
|
||||
static #parseField(field, value, constraints, rand) {
|
||||
// Replace aliases for month and dayOfWeek
|
||||
if (field === CronUnit.Month || field === CronUnit.DayOfWeek) {
|
||||
value = value.replace(/[a-z]{3}/gi, (match) => {
|
||||
match = match.toLowerCase();
|
||||
const replacer = Months[match] || DayOfWeek[match];
|
||||
if (replacer === undefined) {
|
||||
throw new Error(`Validation error, cannot resolve alias "${match}"`);
|
||||
}
|
||||
return replacer.toString();
|
||||
});
|
||||
}
|
||||
// Check for valid characters
|
||||
if (!constraints.validChars.test(value)) {
|
||||
throw new Error(`Invalid characters, got value: ${value}`);
|
||||
}
|
||||
value = this.#parseWildcard(value, constraints);
|
||||
value = this.#parseHashed(value, constraints, rand);
|
||||
return this.#parseSequence(field, value, constraints);
|
||||
}
|
||||
/**
|
||||
* Parse a wildcard from a cron expression.
|
||||
* @param {string} value - The value to parse.
|
||||
* @param {CronConstraints} constraints - The constraints for the field.
|
||||
* @private
|
||||
*/
|
||||
static #parseWildcard(value, constraints) {
|
||||
return value.replace(/[*?]/g, constraints.min + '-' + constraints.max);
|
||||
}
|
||||
/**
|
||||
* Parse a hashed value from a cron expression.
|
||||
* @param {string} value - The value to parse.
|
||||
* @param {CronConstraints} constraints - The constraints for the field.
|
||||
* @param {PRNG} rand - The random number generator to use.
|
||||
* @private
|
||||
*/
|
||||
static #parseHashed(value, constraints, rand) {
|
||||
const randomValue = rand();
|
||||
return value.replace(/H(?:\((\d+)-(\d+)\))?(?:\/(\d+))?/g, (_, min, max, step) => {
|
||||
// H(range)/step
|
||||
if (min && max && step) {
|
||||
const minNum = parseInt(min, 10);
|
||||
const maxNum = parseInt(max, 10);
|
||||
const stepNum = parseInt(step, 10);
|
||||
if (minNum > maxNum) {
|
||||
throw new Error(`Invalid range: ${minNum}-${maxNum}, min > max`);
|
||||
}
|
||||
if (stepNum <= 0) {
|
||||
throw new Error(`Invalid step: ${stepNum}, must be positive`);
|
||||
}
|
||||
const minStart = Math.max(minNum, constraints.min);
|
||||
const offset = Math.floor(randomValue * stepNum);
|
||||
const values = [];
|
||||
for (let i = Math.floor(minStart / stepNum) * stepNum + offset; i <= maxNum; i += stepNum) {
|
||||
if (i >= minStart) {
|
||||
values.push(i);
|
||||
}
|
||||
}
|
||||
return values.join(',');
|
||||
}
|
||||
// H(range)
|
||||
else if (min && max) {
|
||||
const minNum = parseInt(min, 10);
|
||||
const maxNum = parseInt(max, 10);
|
||||
if (minNum > maxNum) {
|
||||
throw new Error(`Invalid range: ${minNum}-${maxNum}, min > max`);
|
||||
}
|
||||
return String(Math.floor(randomValue * (maxNum - minNum + 1)) + minNum);
|
||||
}
|
||||
// H/step
|
||||
else if (step) {
|
||||
const stepNum = parseInt(step, 10);
|
||||
// Validate step
|
||||
if (stepNum <= 0) {
|
||||
throw new Error(`Invalid step: ${stepNum}, must be positive`);
|
||||
}
|
||||
const offset = Math.floor(randomValue * stepNum);
|
||||
const values = [];
|
||||
for (let i = Math.floor(constraints.min / stepNum) * stepNum + offset; i <= constraints.max; i += stepNum) {
|
||||
if (i >= constraints.min) {
|
||||
values.push(i);
|
||||
}
|
||||
}
|
||||
return values.join(',');
|
||||
}
|
||||
// H
|
||||
else {
|
||||
return String(Math.floor(randomValue * (constraints.max - constraints.min + 1) + constraints.min));
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Parse a sequence from a cron expression.
|
||||
* @param {CronUnit} field - The field to parse.
|
||||
* @param {string} val - The sequence to parse.
|
||||
* @param {CronConstraints} constraints - The constraints for the field.
|
||||
* @private
|
||||
*/
|
||||
static #parseSequence(field, val, constraints) {
|
||||
const stack = [];
|
||||
function handleResult(result, constraints) {
|
||||
if (Array.isArray(result)) {
|
||||
stack.push(...result);
|
||||
}
|
||||
else {
|
||||
if (CronExpressionParser.#isValidConstraintChar(constraints, result)) {
|
||||
stack.push(result);
|
||||
}
|
||||
else {
|
||||
const v = parseInt(result.toString(), 10);
|
||||
const isValid = v >= constraints.min && v <= constraints.max;
|
||||
if (!isValid) {
|
||||
throw new Error(`Constraint error, got value ${result} expected range ${constraints.min}-${constraints.max}`);
|
||||
}
|
||||
stack.push(field === CronUnit.DayOfWeek ? v % 7 : result);
|
||||
}
|
||||
}
|
||||
}
|
||||
const atoms = val.split(',');
|
||||
atoms.forEach((atom) => {
|
||||
if (!(atom.length > 0)) {
|
||||
throw new Error('Invalid list value format');
|
||||
}
|
||||
handleResult(CronExpressionParser.#parseRepeat(field, atom, constraints), constraints);
|
||||
});
|
||||
return stack;
|
||||
}
|
||||
/**
|
||||
* Parse repeat from a cron expression.
|
||||
* @param {CronUnit} field - The field to parse.
|
||||
* @param {string} val - The repeat to parse.
|
||||
* @param {CronConstraints} constraints - The constraints for the field.
|
||||
* @private
|
||||
* @returns {(number | string)[]} The parsed repeat.
|
||||
*/
|
||||
static #parseRepeat(field, val, constraints) {
|
||||
const atoms = val.split('/');
|
||||
if (atoms.length > 2) {
|
||||
throw new Error(`Invalid repeat: ${val}`);
|
||||
}
|
||||
if (atoms.length === 2) {
|
||||
if (!isNaN(parseInt(atoms[0], 10))) {
|
||||
atoms[0] = `${atoms[0]}-${constraints.max}`;
|
||||
}
|
||||
return CronExpressionParser.#parseRange(field, atoms[0], parseInt(atoms[1], 10), constraints);
|
||||
}
|
||||
return CronExpressionParser.#parseRange(field, val, 1, constraints);
|
||||
}
|
||||
/**
|
||||
* Validate a cron range.
|
||||
* @param {number} min - The minimum value of the range.
|
||||
* @param {number} max - The maximum value of the range.
|
||||
* @param {CronConstraints} constraints - The constraints for the field.
|
||||
* @private
|
||||
* @returns {void}
|
||||
* @throws {Error} Throws an error if the range is invalid.
|
||||
*/
|
||||
static #validateRange(min, max, constraints) {
|
||||
const isValid = !isNaN(min) && !isNaN(max) && min >= constraints.min && max <= constraints.max;
|
||||
if (!isValid) {
|
||||
throw new Error(`Constraint error, got range ${min}-${max} expected range ${constraints.min}-${constraints.max}`);
|
||||
}
|
||||
if (min > max) {
|
||||
throw new Error(`Invalid range: ${min}-${max}, min(${min}) > max(${max})`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Validate a cron repeat interval.
|
||||
* @param {number} repeatInterval - The repeat interval to validate.
|
||||
* @private
|
||||
* @returns {void}
|
||||
* @throws {Error} Throws an error if the repeat interval is invalid.
|
||||
*/
|
||||
static #validateRepeatInterval(repeatInterval) {
|
||||
if (!(!isNaN(repeatInterval) && repeatInterval > 0)) {
|
||||
throw new Error(`Constraint error, cannot repeat at every ${repeatInterval} time.`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Create a range from a cron expression.
|
||||
* @param {CronUnit} field - The field to parse.
|
||||
* @param {number} min - The minimum value of the range.
|
||||
* @param {number} max - The maximum value of the range.
|
||||
* @param {number} repeatInterval - The repeat interval of the range.
|
||||
* @private
|
||||
* @returns {number[]} The created range.
|
||||
*/
|
||||
static #createRange(field, min, max, repeatInterval) {
|
||||
const stack = [];
|
||||
if (field === CronUnit.DayOfWeek && max % 7 === 0) {
|
||||
stack.push(0);
|
||||
}
|
||||
for (let index = min; index <= max; index += repeatInterval) {
|
||||
if (stack.indexOf(index) === -1) {
|
||||
stack.push(index);
|
||||
}
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
/**
|
||||
* Parse a range from a cron expression.
|
||||
* @param {CronUnit} field - The field to parse.
|
||||
* @param {string} val - The range to parse.
|
||||
* @param {number} repeatInterval - The repeat interval of the range.
|
||||
* @param {CronConstraints} constraints - The constraints for the field.
|
||||
* @private
|
||||
* @returns {number[] | string[] | number | string} The parsed range.
|
||||
*/
|
||||
static #parseRange(field, val, repeatInterval, constraints) {
|
||||
const atoms = val.split('-');
|
||||
if (atoms.length <= 1) {
|
||||
return isNaN(+val) ? val : +val;
|
||||
}
|
||||
const [min, max] = atoms.map((num) => parseInt(num, 10));
|
||||
this.#validateRange(min, max, constraints);
|
||||
this.#validateRepeatInterval(repeatInterval);
|
||||
// Create range
|
||||
return this.#createRange(field, min, max, repeatInterval);
|
||||
}
|
||||
/**
|
||||
* Parse a cron expression.
|
||||
* @param {string} val - The cron expression to parse.
|
||||
* @private
|
||||
* @returns {string} The parsed cron expression.
|
||||
*/
|
||||
static #parseNthDay(val) {
|
||||
const atoms = val.split('#');
|
||||
if (atoms.length <= 1) {
|
||||
return { dayOfWeek: atoms[0] };
|
||||
}
|
||||
const nthValue = +atoms[atoms.length - 1];
|
||||
const matches = val.match(/([,-/])/);
|
||||
if (matches !== null) {
|
||||
throw new Error(`Constraint error, invalid dayOfWeek \`#\` and \`${matches?.[0]}\` special characters are incompatible`);
|
||||
}
|
||||
if (!(atoms.length <= 2 && !isNaN(nthValue) && nthValue >= 1 && nthValue <= 5)) {
|
||||
throw new Error('Constraint error, invalid dayOfWeek occurrence number (#)');
|
||||
}
|
||||
return { dayOfWeek: atoms[0], nthDayOfWeek: nthValue };
|
||||
}
|
||||
/**
|
||||
* Checks if a character is valid for a field.
|
||||
* @param {CronConstraints} constraints - The constraints for the field.
|
||||
* @param {string | number} value - The value to check.
|
||||
* @private
|
||||
* @returns {boolean} Whether the character is valid for the field.
|
||||
*/
|
||||
static #isValidConstraintChar(constraints, value) {
|
||||
return constraints.chars.some((char) => value.toString().includes(char));
|
||||
}
|
||||
}
|
||||
exports.CronExpressionParser = CronExpressionParser;
|
||||
Reference in New Issue
Block a user