Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

cron-parser

Package Overview
Dependencies
Maintainers
1
Versions
96
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cron-parser - npm Package Compare versions

Comparing version 0.4.5 to 0.5.0

12

lib/date.js

@@ -32,7 +32,9 @@ 'use strict';

this.setDate(day + 1);
this.setHours(0);
this.setMinutes(0);
this.setSeconds(0);
if (this.getDate() === day) {
this.setDate(day + 1);
this.setDate(day + 2);
}

@@ -45,3 +47,9 @@ };

Date.prototype.addHour = function addHour () {
this.setHours(this.getHours() + 1);
var hours = this.getHours();
this.setHours(hours + 1);
if (this.getHours() === hours) {
this.setHours(hours + 2);
}
this.setMinutes(0);

@@ -48,0 +56,0 @@ this.setSeconds(0);

282

lib/expression.js

@@ -20,4 +20,4 @@ 'use strict';

this._options = options;
this._currentDate = new Date(options.currentDate.toUTCString());
this._endDate = options.endDate ? new Date(options.endDate.toUTCString()) : null;
this._currentDate = new Date(options.currentDate);
this._endDate = options.endDate ? new Date(options.endDate) : null;
this._fields = {};

@@ -64,2 +64,21 @@

/**
* Days in month
* @type {number[]}
*/
CronExpression.daysInMonth = [
31,
28,
31,
30,
31,
30,
31,
31,
30,
31,
30,
31
];
/**
* Field aliases

@@ -129,4 +148,4 @@ * @type {Object}

//Check for valid characters.
if (!CronExpression._validateCharacters(value)){
// Check for valid characters.
if (!(/^[\d|/|*|\-|,]+$/.test(value))) {
throw new Error('Invalid characters, got value: ' + value)

@@ -137,3 +156,3 @@ }

if (value.indexOf('*') !== -1) {
value = value.replace(/\*/g, constraints[0] + '-' + constraints[1]);
value = value.replace(/\*/g, constraints.join('-'));
}

@@ -163,8 +182,10 @@

if (result instanceof Array) { // Make sequence linear
result.forEach(function (value) {
for (var i = 0, c = result.length; i < c; i++) {
var value = result[i];
// Check constraints
if (!CronExpression._validateConstraint(value, constraints)) {
if (value < constraints[0] || value > constraints[1]) {
throw new Error(
'Constraint error, got value ' + value + ' expected range ' +
constraints[0] + '-' + constraints[1]
'Constraint error, got value ' + value + ' expected range ' +
constraints[0] + '-' + constraints[1]
);

@@ -178,8 +199,8 @@ }

max = Math.max.apply(Math, stack);
});
}
} else { // Scalar value
result = parseInt(result, 10);
result = +result;
// Check constraints
if (!CronExpression._validateConstraint(result, constraints)) {
if (result < constraints[0] || result > constraints[1]) {
throw new Error(

@@ -201,9 +222,7 @@ 'Constraint error, got value ' + result + ' expected range ' +

if (val.indexOf(',') !== -1) {
var atoms = val.split(',');
atoms.forEach(function(value, index) {
handleResult(parseRepeat(value.toString()));
});
var atoms = val.split(',');
if (atoms.length > 1) {
for (var i = 0, c = atoms.length; i < c; i++) {
handleResult(parseRepeat(atoms[i]));
}
} else {

@@ -224,11 +243,9 @@ handleResult(parseRepeat(val));

var repeatInterval = 1;
var atoms = val.split('/');
if (val.indexOf('/') !== -1) {
var atoms = val.split('/');
repeatInterval = atoms[atoms.length - 1];
if (atoms.length > 1) {
return parseRange(atoms[0], atoms[atoms.length - 1]);
}
return parseRange(atoms[0], repeatInterval);
} else {
return parseRange(val, repeatInterval);
}
return parseRange(val, repeatInterval);
}

@@ -246,14 +263,13 @@

var stack = [];
var atoms = val.split('-');
if (val.indexOf('-') !== -1) {
var atoms = val.split('-');
// Validate format
if (atoms.length != 2) {
throw new Error('Invalid range format: ' + val);
if (atoms.length > 1 ) {
// Invalid range, return value
if (atoms.length < 2 || !atoms[0].length) {
return +val;
}
// Validate range
var min = parseInt(atoms[0], 10);
var max = parseInt(atoms[1], 10);
var min = +atoms[0];
var max = +atoms[1];

@@ -285,5 +301,5 @@ if (Number.isNaN(min) || Number.isNaN(max) ||

return stack;
} else {
return val;
}
return +val;
}

@@ -295,117 +311,61 @@

/**
* Detect if input range fully matches constraint bounds
* @param {Array} range Input range
* @param {Array} constraints Input constraints
* @returns {Boolean}
* @private
*/
CronExpression._isWildcardRange = function _isWildcardRange (range, constraints) {
if (!(range instanceof Array)) {
return false;
}
if (constraints.length !== 2) {
return false;
}
return range.length === (constraints[1] - (constraints[0] < 1 ? - 1 : 0));
};
/**
* Match field value
* Find next matching schedule date
*
* @param {String} value
* @param {Array} sequence
* @return {Boolean}
* @return {Date}
* @private
*/
CronExpression._matchSchedule = function matchSchedule (value, sequence) {
for (var i = 0, c = sequence.length; i < c; i++) {
if (sequence[i] >= value) {
return sequence[i] === value;
CronExpression.prototype._findSchedule = function _findSchedule () {
/**
* Match field value
*
* @param {String} value
* @param {Array} sequence
* @return {Boolean}
* @private
*/
function matchSchedule (value, sequence) {
for (var i = 0, c = sequence.length; i < c; i++) {
if (sequence[i] >= value) {
return sequence[i] === value;
}
}
}
return sequence[0] === value;
};
/**
* Validate expression allowed characters
*
* @param {String} value Input expression
* @returns {Boolean}
* @private
*/
CronExpression._validateCharacters = function _validateCharacters (value) {
var regex = new RegExp('^[\\d|/|*|\\-|,]+$');
return regex.test(value);
};
/**
* Constraint validation
*
* @private
* @static
* @param {Object} value alue to check
* @return {Boolean} True if validation succeeds, false if not
*/
CronExpression._validateConstraint = function _validateConstraint (value, constraints) {
if (value < constraints[0] || value > constraints[1]) {
return false;
return sequence[0] === value;
}
return true;
};
/**
* Detect if input range fully matches constraint bounds
* @param {Array} range Input range
* @param {Array} constraints Input constraints
* @returns {Boolean}
* @private
*/
function isWildcardRange (range, constraints) {
if (range instanceof Array && !range.length) {
return false;
}
/**
* Timespan validation
*
* @private
* @static
* @param {Date} current Current date
* @param {Date} end End date
* @return {Boolean} Return true if timespan is still valid, otherwise return false
*/
CronExpression._validateTimespan = function _validateTimespan (current, end) {
if (end && (end.getTime() - current.getTime()) < 0) {
return false;
}
if (constraints.length !== 2) {
return false;
}
return true;
};
/**
* Find next matching schedule date
*
* @return {Date}
* @private
*/
CronExpression.prototype._findSchedule = function _findSchedule () {
// Validate timespan
if (!CronExpression._validateTimespan(this._currentDate, this._endDate)) {
throw new Error('Out of the timespan range');
return range.length === (constraints[1] - (constraints[0] < 1 ? - 1 : 0));
}
var current = new Date(this._currentDate.toUTCString());
var currentDate = new Date(this._currentDate);
var endDate = this._endDate;
// Reset
if (this._fields.second.length === 1 && this._fields.second[0] === 0) {
current.addMinute();
} else {
current.addSecond();
// Append minute if second is 0
if (this._fields.second[0] === 0) {
currentDate.addMinute();
}
// Iterate and match schedule
// Find matching schedule
while (true) {
// Validate timespan
if (!CronExpression._validateTimespan(current, this._endDate)) {
if (endDate && (endDate.getTime() - currentDate.getTime()) < 0) {
throw new Error('Out of the timespan range');
}
// Match month
if (!CronExpression._matchSchedule(current.getMonth() + 1, this._fields.month)) {
current.addMonth();
continue;
}
console.log(currentDate);

@@ -423,10 +383,31 @@ // Day of month and week matching:

var dayOfMonthMatch = CronExpression._matchSchedule(current.getDate(), this._fields.dayOfMonth);
var dayOfWeekMatch = CronExpression._matchSchedule(current.getDay(), this._fields.dayOfWeek);
var isDayOfMonthWildcardMatch = CronExpression._isWildcardRange(this._fields.dayOfMonth, CronExpression.constraints[3]);
var isDayOfWeekWildcardMatch = CronExpression._isWildcardRange(this._fields.dayOfWeek, CronExpression.constraints[5]);
var dayOfMonthMatch = matchSchedule(currentDate.getDate(), this._fields.dayOfMonth);
var dayOfWeekMatch = matchSchedule(currentDate.getDay(), this._fields.dayOfWeek);
var isDayOfMonthWildcardMatch = isWildcardRange(this._fields.dayOfMonth, CronExpression.constraints[3]);
var isMonthWildcardMatch = isWildcardRange(this._fields.dayOfWeek, CronExpression.constraints[4]);
var isDayOfWeekWildcardMatch = isWildcardRange(this._fields.dayOfWeek, CronExpression.constraints[5]);
// Validate days in month if explicit value is given
if (!isMonthWildcardMatch) {
var currentYear = currentDate.getYear();
var currentMonth = currentDate.getMonth() + 1;
var previousMonth = currentMonth === 1 ? 11 : currentMonth - 1;
var daysInPreviousMonth = CronExpression.daysInMonth[previousMonth - 1];
var daysOfMontRangeMax = this._fields.dayOfMonth[this._fields.dayOfMonth.length - 1];
// Handle leap year
var isLeap = !((currentYear % 4) || (!(currentYear % 100) && (currentYear % 400)));
if (isLeap) {
daysInPreviousMonth = 29;
}
if (this._fields.month[0] === previousMonth && daysInPreviousMonth < daysOfMontRangeMax) {
throw new Error('Invalid explicit day of month definition');
}
}
// Add day if not day of month is set (and no match) and day of week is wildcard
if (!isDayOfMonthWildcardMatch && isDayOfWeekWildcardMatch && !dayOfMonthMatch) {
current.addDay();
currentDate.addDay();
continue;

@@ -437,3 +418,3 @@ }

if (isDayOfMonthWildcardMatch && !isDayOfWeekWildcardMatch && !dayOfWeekMatch) {
current.addDay();
currentDate.addDay();
continue;

@@ -445,9 +426,15 @@ }

!dayOfMonthMatch && !dayOfWeekMatch) {
current.addDay();
currentDate.addDay();
continue;
}
// Match month
if (!matchSchedule(currentDate.getMonth() + 1, this._fields.month)) {
currentDate.addMonth();
continue;
}
// Match hour
if (!CronExpression._matchSchedule(current.getHours(), this._fields.hour)) {
current.addHour();
if (!matchSchedule(currentDate.getHours(), this._fields.hour)) {
currentDate.addHour();
continue;

@@ -457,4 +444,4 @@ }

// Match minute
if (!CronExpression._matchSchedule(current.getMinutes(), this._fields.minute)) {
current.addMinute();
if (!matchSchedule(currentDate.getMinutes(), this._fields.minute)) {
currentDate.addMinute();
continue;

@@ -464,11 +451,10 @@ }

// Match second
if (!CronExpression._matchSchedule(current.getSeconds(), this._fields.second)) {
current.addSecond();
if (!matchSchedule(currentDate.getSeconds(), this._fields.second)) {
currentDate.addSecond();
continue;
}
break;
}
return (this._currentDate = current);
return (this._currentDate = currentDate);
};

@@ -539,3 +525,3 @@

CronExpression.prototype.reset = function reset () {
this._currentDate = new Date(this._options.currentDate.toUTCString());
this._currentDate = new Date(this._options.currentDate);
};

@@ -542,0 +528,0 @@

{
"name": "cron-parser",
"version": "0.4.5",
"version": "0.5.0",
"description": "Node.js library for parsing crontab instructions",

@@ -5,0 +5,0 @@ "main": "lib/parser.js",

var CronExpression = require('./lib/expression');
CronExpression.parse('0 0 0 1 1 *', function(err, interval) {
var count = 5;
while (count) {
try {
console.log(interval.next());
count--;
} catch (e) {
break;
}
}
});
var nextTime = CronExpression.parse("0 4 29 3 *").next();
console.log(nextTime);
//var nextTime = CronExpression.parse("@yearly").next();
//console.log(nextTime)

@@ -531,1 +531,17 @@ var util = require('util');

});
test('day of month value can\'t be larger than days in month maximum value if it\'s defined explicitly', function(t) {
CronExpression.parse('0 4 29 2 *', function(err, interval) {
t.ifError(err, 'Interval parse error');
t.ok(interval, 'Interval parsed');
try {
interval.next();
t.ok(false, 'Should fail');
} catch (e) {
t.ok(true, 'Failed as expected');
}
t.end();
});
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc