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.3.6 to 0.4.0

2

component.json

@@ -5,3 +5,3 @@ {

"description": "Node.js library for parsing crontab instructions",
"version": "0.3.1",
"version": "0.4.0",
"keywords": ["cron", "crontab", "parser"],

@@ -8,0 +8,0 @@ "dependencies": {},

'use strict';
Date.prototype.addYear = function() {
/**
* Extends Javascript Date class by adding
* utility methods for basic date incrementation
*/
/**
* Increment year
*/
Date.prototype.addYear = function addYear () {
this.setFullYear(this.getFullYear() + 1);
};
Date.prototype.addMonth = function() {
/**
* Increment month
*/
Date.prototype.addMonth = function addMonth () {
this.setMonth(this.getMonth() + 1);
this.setDate(1);
this.setHours(0);
this.setMinutes(0);
this.setSeconds(0);
};
Date.prototype.addDay = function() {
/**
* Increment day
*/
Date.prototype.addDay = function addDay () {
this.setDate(this.getDate() + 1);
this.setHours(0);
this.setMinutes(0);
this.setSeconds(0);
};
Date.prototype.addHour = function() {
/**
* Increment hour
*/
Date.prototype.addHour = function addHour () {
this.setHours(this.getHours() + 1);
this.setMinutes(0);
this.setSeconds(0);
};
Date.prototype.addMinute = function() {
/**
* Increment minute
*/
Date.prototype.addMinute = function addMinute () {
this.setMinutes(this.getMinutes() + 1);
this.setSeconds(0);
};
Date.prototype.addSecond = function() {
/**
* Increment second
*/
Date.prototype.addSecond = function addSecond () {
this.setSeconds(this.getSeconds() + 1);
};
'use strict';
var date = require('./date');
// Load Date class extensions
require('./date');

@@ -17,3 +18,3 @@ /**

*/
function CronExpression(fields, options) {
function CronExpression (fields, options) {
this._options = options;

@@ -102,9 +103,9 @@ this._currentDate = new Date(options.currentDate.toUTCString());

*
* @param {String} field Field symbolic name
* @param {String} value Field value
* @param {Array} constraints Range upper and lower constraints
* @return {Array} Sequence of sorted values
* @param {String} field Field symbolic name
* @param {String} value Field value
* @param {Array} constraints Range upper and lower constraints
* @return {Array} Sequence of sorted values
* @private
*/
CronExpression._parseField = function(field, value, constraints) {
CronExpression._parseField = function _parseField (field, value, constraints) {
// Replace aliases

@@ -118,2 +119,3 @@ switch (field) {

match = match.toLowerCase();
if (aliases[match]) {

@@ -129,3 +131,3 @@ return aliases[match];

//Check for valid characters.
if(!CronExpression._validateCharacters(value)){
if (!CronExpression._validateCharacters(value)){
throw new Error('Invalid characters, got value: ' + value)

@@ -150,14 +152,14 @@ }

*
* @param {String} val
* @param {String} val
* @return {Array}
* @private
*/
function parseSequence(val) {
function parseSequence (val) {
var stack = [];
function handleResult(result) {
function handleResult (result) {
var max = stack.length > 0 ? Math.max.apply(Math, stack) : -1;
if (result instanceof Array) { // Make sequence linear
result.forEach(function(value, index) {
result.forEach(function (value) {
// Check constraints

@@ -176,3 +178,3 @@ if (!CronExpression._validateConstraint(value, constraints)) {

max = Math.max.apply(Math, stack);
})
});
} else { // Scalar value

@@ -212,6 +214,6 @@ result = parseInt(result, 10);

*
* @param {String} val
* @param {String} val
* @return {Array}
*/
function parseRepeat(val) {
function parseRepeat (val) {
var repeatInterval = 1;

@@ -232,8 +234,8 @@

*
* @param {String} val
* @param {Number} repeatInterval Repetition interval
* @param {String} val
* @param {Number} repeatInterval Repetition interval
* @return {Array}
* @private
*/
function parseRange(val, repeatInterval) {
function parseRange (val, repeatInterval) {
var stack = [];

@@ -286,3 +288,47 @@

CronExpression._validateCharacters = function(value) {
/**
* 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
*
* @param {String} value
* @param {Array} sequence
* @return {Boolean}
* @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;
}
}
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|/|*|\\-|,]+$');

@@ -297,6 +343,6 @@ return regex.test(value);

* @static
* @param {Object} value Value to check
* @return {Boolean} True if validation succeeds, false if not
* @param {Object} value alue to check
* @return {Boolean} True if validation succeeds, false if not
*/
CronExpression._validateConstraint = function(value, constraints) {
CronExpression._validateConstraint = function _validateConstraint (value, constraints) {
if (value < constraints[0] || value > constraints[1]) {

@@ -314,7 +360,7 @@ return false;

* @static
* @param {Date} current Current date
* @param {Date} end End date
* @return {Boolean} Return true if timespan is still valid, otherwise return false
* @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(current, end) {
CronExpression._validateTimespan = function _validateTimespan (current, end) {
if (end && (end.getTime() - current.getTime()) < 0) {

@@ -330,6 +376,6 @@ return false;

*
* @return {Number}
* @return {Date}
* @private
*/
CronExpression.prototype._findSchedule = function() {
CronExpression.prototype._findSchedule = function _findSchedule () {
// Validate timespan

@@ -342,27 +388,4 @@ if (!CronExpression._validateTimespan(this._currentDate, this._endDate)) {

function findNearest(value, sequence) {
for (var i = 0, c = sequence.length; i < c; i++) {
if (sequence[i] >= value) {
return sequence[i];
}
}
return sequence[0];
}
/**
* Match field value
*
* @param {String} value
* @param {Array} sequence
* @return {Boolean}
* @private
*/
function matchSchedule(value, sequence) {
return findNearest(value, sequence) === value;
}
// Reset
if (this._fields.second.length === 1 && this._fields.second[0] === 0) {
current.setSeconds(0);
current.addMinute();

@@ -381,34 +404,45 @@ } else {

// Match month
if (!matchSchedule(current.getMonth() + 1, this._fields.month)) {
if (!CronExpression._matchSchedule(current.getMonth() + 1, this._fields.month)) {
current.addMonth();
current.setDate(1);
current.setHours(0);
current.setMinutes(0);
current.setSeconds(0);
continue;
}
// Match day of month
if (!matchSchedule(current.getDate(), this._fields.dayOfMonth)) {
// Day of month and week matching:
//
// "The day of a command's execution can be specified by two fields --
// day of month, and day of week. If both fields are restricted (ie,
// aren't *), the command will be run when either field matches the cur-
// rent time. For example, "30 4 1,15 * 5" would cause a command to be
// run at 4:30 am on the 1st and 15th of each month, plus every Friday."
//
// http://unixhelp.ed.ac.uk/CGI/man-cgi?crontab+5
//
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]);
// Add day if not day of month is set (and no match) and day of week is wildcard
if (!isDayOfMonthWildcardMatch && isDayOfWeekWildcardMatch && !dayOfMonthMatch) {
current.addDay();
current.setHours(0);
current.setMinutes(0);
current.setSeconds(0);
continue;
}
// Match day of week
if (!matchSchedule(current.getDay(), this._fields.dayOfWeek)) {
// Add day if not day of week is set (and no match) and day of month is wildcard
if (isDayOfMonthWildcardMatch && !isDayOfWeekWildcardMatch && !dayOfWeekMatch) {
current.addDay();
current.setHours(0);
current.setMinutes(0);
current.setSeconds(0);
continue;
}
// Add day if day of mont and week are non-wildcard values and both doesn't match
if (!(isDayOfMonthWildcardMatch && isDayOfWeekWildcardMatch) &&
!dayOfMonthMatch && !dayOfWeekMatch) {
current.addDay();
continue;
}
// Match hour
if (!matchSchedule(current.getHours(), this._fields.hour)) {
if (!CronExpression._matchSchedule(current.getHours(), this._fields.hour)) {
current.addHour();
current.setMinutes(0);
current.setSeconds(0);
continue;

@@ -418,5 +452,4 @@ }

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

@@ -426,3 +459,3 @@ }

// Match second
if (!matchSchedule(current.getSeconds(), this._fields.second)) {
if (!CronExpression._matchSchedule(current.getSeconds(), this._fields.second)) {
current.addSecond();

@@ -444,3 +477,3 @@ continue;

*/
CronExpression.prototype.next = function() {
CronExpression.prototype.next = function next () {
return this._findSchedule();

@@ -456,13 +489,12 @@ };

CronExpression.prototype.hasNext = function() {
var memorized = this._currentDate;
var current = this._currentDate;
try {
this.next();
return true;
}
catch(error) {
} catch (err) {
return false;
} finally {
this._currentDate = current;
}
finally {
this._currentDate = memorized;
}
};

@@ -474,10 +506,10 @@

* @public
* @param {Number} n Numbers of steps to iterate
* @param {Function} callback Optional callback
* @return {Array} Array of the iterated results
* @param {Number} steps Numbers of steps to iterate
* @param {Function} callback Optional callback
* @return {Array} Array of the iterated results
*/
CronExpression.prototype.iterate = function(n, callback) {
CronExpression.prototype.iterate = function iterate (steps, callback) {
var dates = [];
for (var i = 0, c = n; i < c; i++) {
for (var i = 0, c = steps; i < c; i++) {
try {

@@ -491,3 +523,3 @@ var item = this.next();

}
} catch (e) {
} catch (err) {
break;

@@ -505,3 +537,3 @@ }

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

@@ -514,7 +546,7 @@ };

* @public
* @param {String} expression Input expression
* @param {Object} [options] Parsing options
* @param {Function} callback
* @param {String} expression Input expression
* @param {Object} [options] Parsing options
* @param {Function} callback
*/
CronExpression.parse = function(expression, options, callback) {
CronExpression.parse = function parse (expression, options, callback) {
if (typeof options === 'function') {

@@ -524,51 +556,58 @@ callback = options;

}
try {
var cronExpression = CronExpression.parseSync(expression, options);
callback(null, cronExpression);
} catch (e){
callback(e);
}
}
/**
* Parse input expression (sync)
*
* @public
* @param {String} expression Input expression
* @param {Object} [options] Parsing options
*/
CronExpression.parseSync = function(expression, options) {
if (!options) {
options = {};
}
function parse (expression, options) {
if (!options) {
options = {};
}
if (!options.currentDate) {
options.currentDate = new Date();
}
if (!options.currentDate) {
options.currentDate = new Date();
}
// Is input expression predefined?
if (CronExpression.predefined[expression]) {
expression = CronExpression.predefined[expression];
}
// Is input expression predefined?
if (CronExpression.predefined[expression]) {
expression = CronExpression.predefined[expression];
}
// Split fields
var fields = [];
var atoms = expression.split(' ');
// Split fields
var fields = [];
var atoms = expression.split(' ');
// Resolve fields
var start = (CronExpression.map.length - atoms.length);
for (var i = 0, c = CronExpression.map.length; i < c; ++i) {
var field = CronExpression.map[i]; // Field name
var value = atoms[atoms.length > c ? i : i - start]; // Field value
// Resolve fields
var start = (CronExpression.map.length - atoms.length);
for (var i = 0, c = CronExpression.map.length; i < c; ++i) {
var field = CronExpression.map[i]; // Field name
var value = atoms[atoms.length > c ? i : i - start]; // Field value
if (i < start || !value) {
fields.push(this._parseField(field, CronExpression.parseDefaults[i], CronExpression.constraints[i]));
} else { // Use default value
fields.push(this._parseField(field, value, CronExpression.constraints[i]));
if (i < start || !value) {
fields.push(CronExpression._parseField(
field,
CronExpression.parseDefaults[i],
CronExpression.constraints[i])
);
} else { // Use default value
fields.push(CronExpression._parseField(
field,
value,
CronExpression.constraints[i])
);
}
}
return new CronExpression(fields, options);
}
return new CronExpression(fields, options);
// Backward compatibility (<= 0.3.*)
// Will be removed in version 0.5
if (typeof callback === 'function') {
try {
return callback(null, parse(expression, options));
} catch (err) {
return callback(err);
}
} else {
return parse(expression, options);
}
};
module.exports = CronExpression;
'use strict';
var fs = require('fs');
var CronExpression = require('./expression');
function CronParser() {
function CronParser() {}
}
/**

@@ -13,24 +12,18 @@ * Parse crontab entry

* @private
* @param {String} entry Crontab file entry/line
* @param {Function} callback
* @param {String} entry Crontab file entry/line
*/
CronParser._parseEntry = function(entry, callback) {
CronParser._parseEntry = function _parseEntry (entry) {
var atoms = entry.split(' ');
if (atoms.length === 6) {
CronExpression.parse(entry, callback);
return {
interval: CronExpression.parse(entry)
};
} else if (atoms.length > 6) {
CronExpression.parse(entry, function(err, interval) {
if (err) {
callback(err);
return;
}
callback(null, {
interval: interval,
command: atoms.slice(6, atoms.length)
});
});
return {
interval: CronExpression.parse(entry),
command: atoms.slice(6, atoms.length)
};
} else {
callback(new Error('Invalid entry: ' + entry));
throw new Error('Invalid entry: ' + entry);
}

@@ -43,7 +36,7 @@ };

* @public
* @param {String} expression Input expression
* @param {Object} [options] Parsing options
* @param {Function} callback
* @param {String} expression Input expression
* @param {Object} [options] Parsing options
* @return {Object}
*/
CronParser.parseExpression = function(expression, options, callback) {
CronParser.parseExpression = function parseExpression (expression, options, callback) {
return CronExpression.parse(expression, options, callback);

@@ -57,10 +50,8 @@ };

* @public
* @param {String} expression Input expression
* @param {Object} [options] Parsing options
* @deprecated
* @param {String} expression Input expression
* @param {Object} [options] Parsing options
*/
CronParser.parseExpressionSync = function(expression, options) {
return CronExpression.parseSync(expression, options);
};
CronParser.parseExpressionSync = CronParser.parseExpression;
/**

@@ -70,10 +61,8 @@ * Parse content string

* @public
* @param {String} data Crontab content
* @param {Function} callback
* @param {String} data Crontab content
* @return {Object}
*/
CronParser.parseString = function(data, callback) {
CronParser.parseString = function parseString (data) {
var self = this;
var blocks = data.split('\n');
var count = blocks.length;
var called = false;

@@ -86,37 +75,26 @@ var response = {

blocks.forEach(function(entry, index) {
for (var i = 0, c = blocks.length; i < c; i++) {
var block = blocks[i];
var matches = null;
entry = entry.replace(/^\s+|\s+$/g, ''); // Remove surrounding spaces
var entry = block.replace(/^\s+|\s+$/g, ''); // Remove surrounding spaces
if (entry.length > 0) {
if (entry.match(/^#/)) { // Comment
count--;
return;
continue;
} else if ((matches = entry.match(/^(.*)=(.*)$/))) { // Variable
count--;
response.variables[matches[1]] = matches[2];
return;
} else { // Expression?
self._parseEntry('0 ' + entry, function(err, result) {
if (err) {
response.errors[entry] = err;
} else {
response.expressions.push(result.interval);
}
var result = null;
if (!called && --count === 0) {
called = true;
callback(null, response);
}
});
try {
result = self._parseEntry('0 ' + entry);
response.expressions.push(result.interval);
} catch (err) {
response.errors[entry] = err;
}
}
} else {
count--;
}
});
}
if (!called && count === 0) {
called = true;
callback(null, response);
}
return response;
};

@@ -128,7 +106,6 @@

* @public
* @param {String} filePath Path to file
* @param {Function} callback
* @param {String} filePath Path to file
* @param {Function} callback
*/
CronParser.parseFile = function(filePath, callback) {
var fs = require('fs');
CronParser.parseFile = function parseFile (filePath, callback) {
fs.readFile(filePath, function(err, data) {

@@ -140,3 +117,3 @@ if (err) {

CronParser.parseString(data.toString(), callback);
return callback(null, CronParser.parseString(data.toString()));
});

@@ -143,0 +120,0 @@ };

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

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

@@ -40,20 +40,11 @@ cron-parser

parser.parseExpression('*/2 * * * *', function(err, interval) {
if (err) {
console.log('Error: ' + err.message);
return;
}
try {
var interval = parser.parseExpression('*/2 * * * *');
console.log('Date: ', interval.next()); // Sat Dec 29 2012 00:42:00 GMT+0200 (EET)
console.log('Date: ', interval.next()); // Sat Dec 29 2012 00:44:00 GMT+0200 (EET)
});
```
Alternatively this can be done synchronously.
} catch (err) {
console.log('Error: ' + err.message);
}
```javascript
var parser = require('cron-parser');
var interval = parser.parseExpressionSync('*/2 * * * *');
console.log('Date: ', interval.next()); // Sat Dec 29 2012 00:42:00 GMT+0200 (EET)
console.log('Date: ', interval.next()); // Sat Dec 29 2012 00:44:00 GMT+0200 (EET)
```

@@ -71,8 +62,5 @@

parser.parseExpression('*/22 * * * *', options, function(err, interval) {
if (err) {
console.log('Error: ' + err.message);
return;
}
try {
var interval = parser.parseExpression('*/22 * * * *', options);
while (true) {

@@ -92,3 +80,6 @@ try {

// Wed Dec 26 2012 16:22:00 GMT+0200 (EET)
});
} catch (err) {
console.log('Error: ' + err.message);
}
```

@@ -22,3 +22,3 @@ var util = require('util');

test('default expression test', function(t) {
test('default expression test (with callback)', function(t) {
CronExpression.parse('* * * * *', function(err, interval) {

@@ -40,4 +40,4 @@ t.ifError(err, 'Interval parse error');

test('default expression test (sync)', function(t) {
var interval = CronExpression.parseSync('* * * * *');
test('default expression test (without callback)', function(t) {
var interval = CronExpression.parse('* * * * *');
t.ok(interval, 'Interval parsed');

@@ -93,2 +93,3 @@

test('day of the month value out of the range', function(t) {

@@ -145,3 +146,3 @@ CronExpression.parse('* * * 10-15,40 * *', function(err, interval) {

t.equal(next.getMonth(), 7, 'Month matches');
t.equal(next.getDate(), 12, 'Day of month matches');
t.equal(next.getDate(), 3, 'Day of month matches');
t.equal(next.getHours(), 2, 'Hour matches');

@@ -222,3 +223,3 @@ t.equal(next.getMinutes(), 10, 'Minute matches');

t.equal(next.getMonth(), 7, 'Month matches');
t.equal(next.getDate(), 12, 'Day of month matches');
t.equal(next.getDate(), 3, 'Day of month matches');
t.equal(next.getHours(), 2, 'Hour matches');

@@ -246,3 +247,3 @@ t.equal(next.getMinutes(), 10 + i, 'Minute matches');

t.equal(next.getMonth(), 7, 'Month matches');
t.equal(next.getDate(), 12, 'Day of month matches');
t.equal(next.getDate(), 3, 'Day of month matches');
t.equal(next.getHours(), 2, 'Hour matches');

@@ -338,2 +339,3 @@ t.equal(next.getMinutes(), 10 + (i * 2), 'Minute matches');

t.ok(next, 'Found next scheduled interval');

@@ -373,2 +375,37 @@ t.ok(day == 1 || day == 2, "Day matches")

test('day of month and week are both set', function(t) {
CronExpression.parse('10 2 12 8 0', function(err, interval) {
t.ifError(err, 'Interval parse error');
t.ok(interval, 'Interval parsed');
var next = interval.next();
t.ok(next, 'Found next scheduled interval');
t.equal(next.getDay(), 0, 'Day matches');
t.equal(next.getMonth(), 7, 'Month matches');
t.equal(next.getDate(), 3, 'Day of month matches');
next = interval.next();
t.ok(next, 'Found next scheduled interval');
t.equal(next.getDay(), 0, 'Day matches');
t.equal(next.getMonth(), 7, 'Month matches');
t.equal(next.getDate(), 10, 'Day of month matches');
next = interval.next();
t.ok(next, 'Found next scheduled interval');
t.equal(next.getDay(), 2, 'Day matches');
t.equal(next.getMonth(), 7, 'Month matches');
t.equal(next.getDate(), 12, 'Day of month matches');
next = interval.next();
t.ok(next, 'Found next scheduled interval');
t.equal(next.getDay(), 0, 'Day matches');
t.equal(next.getMonth(), 7, 'Month matches');
t.equal(next.getDate(), 17, 'Day of month matches');
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