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 3.2.0 to 3.3.0

index.d.ts

2

component.json

@@ -10,3 +10,3 @@ {

"main": "lib/parser.js",
"scripts": ["lib/parser.js", "lib/expression.js", "lib/date.js"]
"scripts": ["lib/parser.js", "lib/expression.js", "lib/date.js", "lib/field_compactor.js", "lib/field_stringify.js"]
}

@@ -9,2 +9,4 @@ 'use strict';

var stringifyField = require('./field_stringify');
/**

@@ -23,11 +25,3 @@ * Cron iteration loop safety limit

function isWildcardRange(range, constraints) {
if (range instanceof Array && !range.length) {
return false;
}
if (constraints.length !== 2) {
return false;
}
return range.length === (constraints[1] - (constraints[0] < 1 ? - 1 : 0));
return range.length === (constraints.max - (constraints.min < 1 ? - 1 : 0));
}

@@ -57,3 +51,3 @@

this._nthDayOfWeek = options.nthDayOfWeek || 0;
this.fields = Object.freeze(fields);
this.fields = CronExpression._freezeFields(fields);
}

@@ -84,8 +78,8 @@

CronExpression.constraints = [
[ 0, 59 ], // Second
[ 0, 59 ], // Minute
[ 0, 23 ], // Hour
[ 1, 31 ], // Day of month
[ 1, 12 ], // Month
[ 0, 7 ] // Day of week
{ min: 0, max: 59, chars: [] }, // Second
{ min: 0, max: 59, chars: [] }, // Minute
{ min: 0, max: 23, chars: [] }, // Hour
{ min: 1, max: 31, chars: ['L'] }, // Day of month
{ min: 1, max: 12, chars: [] }, // Month
{ min: 0, max: 7, chars: [] }, // Day of week
];

@@ -180,6 +174,6 @@

if (typeof aliases[match] !== undefined) {
if (typeof aliases[match] !== 'undefined') {
return aliases[match];
} else {
throw new Error('Cannot resolve alias "' + match + '"');
throw new Error('Validation error, cannot resolve alias "' + match + '"');
}

@@ -197,5 +191,5 @@ });

if (value.indexOf('*') !== -1) {
value = value.replace(/\*/g, constraints.join('-'));
value = value.replace(/\*/g, constraints.min + '-' + constraints.max);
} else if (value.indexOf('?') !== -1) {
value = value.replace(/\?/g, constraints.join('-'));
value = value.replace(/\?/g, constraints.min + '-' + constraints.max);
}

@@ -226,7 +220,11 @@

if (typeof value === 'string' && constraints.chars.indexOf(value) > -1) {
stack.push(value);
continue;
}
// Check constraints
if (value < constraints[0] || value > constraints[1]) {
if (typeof value !== 'number' || safeIsNaN(value) || value < constraints.min || value > constraints.max) {
throw new Error(
'Constraint error, got value ' + value + ' expected range ' +
constraints[0] + '-' + constraints[1]
constraints.min + '-' + constraints.max
);

@@ -238,4 +236,4 @@ }

} else { // Scalar value
//TODO: handle the cases when there is a range and L, or list of dates and L
if (field === 'dayOfMonth' && result === 'L') {
if (typeof result === 'string' && constraints.chars.indexOf(result) > -1) {
stack.push(result);

@@ -245,17 +243,17 @@ return;

result = +result;
var numResult = +result;
// Check constraints
if (result < constraints[0] || result > constraints[1]) {
if (safeIsNaN(numResult) || numResult < constraints.min || numResult > constraints.max) {
throw new Error(
'Constraint error, got value ' + result + ' expected range ' +
constraints[0] + '-' + constraints[1]
constraints.min + '-' + constraints.max
);
}
if (field == 'dayOfWeek') {
result = result % 7;
if (field === 'dayOfWeek') {
numResult = numResult % 7;
}
stack.push(result);
stack.push(numResult);
}

@@ -279,5 +277,3 @@ }

stack.sort(function(a, b) {
return a - b;
});
stack.sort(CronExpression._sortCompareFn);

@@ -299,3 +295,3 @@ return stack;

if (atoms[0] == +atoms[0]) {
atoms = [atoms[0] + '-' + constraints[1], atoms[1]];
atoms = [atoms[0] + '-' + constraints.max, atoms[1]];
}

@@ -339,3 +335,3 @@ return parseRange(atoms[0], atoms[atoms.length - 1]);

if (safeIsNaN(min) || safeIsNaN(max) ||
min < constraints[0] || max > constraints[1]) {
min < constraints.min || max > constraints.max) {
throw new Error(

@@ -345,3 +341,3 @@ 'Constraint error, got range ' +

' expected range ' +
constraints[0] + '-' + constraints[1]
constraints.min + '-' + constraints.max
);

@@ -371,3 +367,3 @@ } else if (min >= max) {

return isNaN(+val) ? val : +val;
return safeIsNaN(+val) ? val : +val;
}

@@ -378,2 +374,47 @@

CronExpression._sortCompareFn = function(a, b) {
var aIsNumber = typeof a === 'number';
var bIsNumber = typeof b === 'number';
if (aIsNumber && bIsNumber) {
return a - b;
}
if (!aIsNumber && bIsNumber) {
return 1;
}
if (aIsNumber && !bIsNumber) {
return -1;
}
return a.localeCompare(b);
};
CronExpression._handleMaxDaysInMonth = function(mappedFields) {
// Filter out any day of month value that is larger than given month expects
if (mappedFields.month.length === 1) {
var daysInMonth = CronExpression.daysInMonth[mappedFields.month[0] - 1];
if (mappedFields.dayOfMonth[0] > daysInMonth) {
throw new Error('Invalid explicit day of month definition');
}
return mappedFields.dayOfMonth
.filter(function(dayOfMonth) {
return dayOfMonth === 'L' ? true : dayOfMonth <= daysInMonth;
})
.sort(CronExpression._sortCompareFn);
}
};
CronExpression._freezeFields = function(fields) {
for (var i = 0, c = CronExpression.map.length; i < c; ++i) {
var field = CronExpression.map[i]; // Field name
var value = fields[field];
fields[field] = Object.freeze(value);
}
return Object.freeze(fields);
};
CronExpression.prototype._applyTimezoneShift = function(currentDate, dateMathVerb, method) {

@@ -760,2 +801,20 @@ if ((method === 'Month') || (method === 'Day')) {

/**
* Stringify the expression
*
* @public
* @param {Boolean} [includeSeconds] Should stringify seconds
* @return {String}
*/
CronExpression.prototype.stringify = function stringify(includeSeconds) {
var resultArr = [];
for (var i = includeSeconds ? 0 : 1, c = CronExpression.map.length; i < c; ++i) {
var field = CronExpression.map[i];
var value = this.fields[field];
var constraint = CronExpression.constraints[i];
resultArr.push(stringifyField(value, constraint.min, constraint.max));
}
return resultArr.join(' ');
};
/**
* Parse input expression (async)

@@ -766,8 +825,6 @@ *

* @param {Object} [options] Parsing options
* @param {Function} [callback]
*/
CronExpression.parse = function parse(expression, options, callback) {
CronExpression.parse = function parse(expression, options) {
var self = this;
if (typeof options === 'function') {
callback = options;
options = {};

@@ -808,3 +865,4 @@ }

CronExpression.parseDefaults[i],
CronExpression.constraints[i])
CronExpression.constraints[i]
)
);

@@ -817,3 +875,4 @@ } else {

val,
CronExpression.constraints[i])
CronExpression.constraints[i]
)
);

@@ -826,34 +885,7 @@ }

var key = CronExpression.map[i];
mappedFields[key] = Object.freeze(fields[i]);
mappedFields[key] = fields[i];
}
// Filter out any day of month value that is larger than given month expects
if (mappedFields.month.length === 1) {
var daysInMonth = CronExpression.daysInMonth[mappedFields.month[0] - 1];
if (mappedFields.dayOfMonth[0] > daysInMonth) {
throw new Error('Invalid explicit day of month definition');
}
mappedFields.dayOfMonth = mappedFields.dayOfMonth.filter(function(dayOfMonth) {
return dayOfMonth === 'L' ? true : dayOfMonth <= daysInMonth;
});
//sort
mappedFields.dayOfMonth.sort(function(a,b) {
var aIsNumber = typeof a === 'number';
var bIsNumber = typeof b === 'number';
if (aIsNumber && bIsNumber) {
return a - b;
}
if(!aIsNumber) {
return 1;
}
return -1;
});
}
var dayOfMonth = CronExpression._handleMaxDaysInMonth(mappedFields);
mappedFields.dayOfMonth = dayOfMonth || mappedFields.dayOfMonth;
return new CronExpression(mappedFields, options);

@@ -898,2 +930,62 @@

/**
* Convert cron fields back to Cron Expression
*
* @public
* @param {Object} fields Input fields
* @param {Object} [options] Parsing options
* @return {Object}
*/
CronExpression.fieldsToExpression = function fieldsToExpression(fields, options) {
function validateConstraints (field, values, constraints) {
if (!values) {
throw new Error('Validation error, Field ' + field + ' is missing');
}
if (values.length === 0) {
throw new Error('Validation error, Field ' + field + ' contains no values');
}
for (var i = 0, c = values.length; i < c; i++) {
var value = values[i];
if (typeof value === 'string' && constraints.chars.indexOf(value) > -1) {
continue;
}
// Check constraints
if (typeof value !== 'number' || safeIsNaN(value) || value < constraints.min || value > constraints.max) {
throw new Error(
'Constraint error, got value ' + value + ' expected range ' +
constraints.min + '-' + constraints.max
);
}
}
}
var mappedFields = {};
for (var i = 0, c = CronExpression.map.length; i < c; ++i) {
var field = CronExpression.map[i]; // Field name
var values = fields[field];
validateConstraints(
field,
values,
CronExpression.constraints[i]
);
var copy = [];
var j = -1;
while (++j < values.length) {
copy[j] = values[j];
}
values = copy.sort(CronExpression._sortCompareFn)
.filter(function(item, pos, ary) {
return !pos || item !== ary[pos - 1];
});
if (values.length !== copy.length) {
throw new Error('Validation error, Field ' + field + ' contains duplicate values');
}
mappedFields[field] = values;
}
var dayOfMonth = CronExpression._handleMaxDaysInMonth(mappedFields);
mappedFields.dayOfMonth = dayOfMonth || mappedFields.dayOfMonth;
return new CronExpression(mappedFields, options || {});
};
module.exports = CronExpression;

@@ -40,7 +40,19 @@ 'use strict';

*/
CronParser.parseExpression = function parseExpression (expression, options, callback) {
return CronExpression.parse(expression, options, callback);
CronParser.parseExpression = function parseExpression (expression, options) {
return CronExpression.parse(expression, options);
};
/**
* Wrapper for CronExpression.fieldsToExpression method
*
* @public
* @param {Object} fields Input fields
* @param {Object} [options] Parsing options
* @return {Object}
*/
CronParser.fieldsToExpression = function fieldsToExpression (fields, options) {
return CronExpression.fieldsToExpression(fields, options);
};
/**
* Parse content string

@@ -53,3 +65,2 @@ *

CronParser.parseString = function parseString (data) {
var self = this;
var blocks = data.split('\n');

@@ -77,3 +88,3 @@

try {
result = self._parseEntry('0 ' + entry);
result = CronParser._parseEntry('0 ' + entry);
response.expressions.push(result.interval);

@@ -80,0 +91,0 @@ } catch (err) {

{
"name": "cron-parser",
"version": "3.2.0",
"version": "3.3.0",
"description": "Node.js library for parsing crontab instructions",
"main": "lib/parser.js",
"types": "lib/index.d.ts",
"types": "index.d.ts",
"typesVersions": {
"<4.1": {
"*": [
"types/ts3/*"
]
}
},
"directories": {

@@ -13,2 +20,3 @@ "test": "test"

"test:unit": "TZ=UTC tap ./test/*.js",
"test:cover": "TZ=UTC tap --coverage-report=html ./test/*.js",
"lint": "eslint .",

@@ -47,3 +55,4 @@ "lint:fix": "eslint --fix .",

"Ian Graves <ian+diskimage@iangrav.es>",
"Andy Thompson <me@andytson.com>"
"Andy Thompson <me@andytson.com>",
"Regev Brody <regevbr@gmail.com>"
],

@@ -68,4 +77,10 @@ "license": "MIT",

"tsd": {
"directory": "test"
"directory": "test",
"compilerOptions": {
"lib": [
"es2017",
"dom"
]
}
}
}

@@ -7,4 +7,8 @@ cron-parser

Node.js library for parsing crontab instructions. It includes support for timezones and DST transitions.
Node.js library for parsing and manipulating crontab instructions. It includes support for timezones and DST transitions.
__Compatibility__
Node >= 0.8
Typescript <= 4.2
Setup

@@ -25,3 +29,3 @@ ========

│ │ │ │ └───── month (1 - 12)
│ │ │ └────────── day of month (1 - 31)
│ │ │ └────────── day of month (1 - 31, L)
│ │ └─────────────── hour (0 - 23)

@@ -112,2 +116,17 @@ │ └──────────────────── minute (0 - 59)

Manipulation
```javascript
var parser = require('cron-parser');
var interval = parser.parseExpression('0 7 * * 0-4');
var fields = JSON.parse(JSON.stringify(interval.fields)); // Fields is immutable
fields.hour = [8];
fields.minute = [29];
fields.dayOfWeek = [1,3,4,5,6,7];
var modifiedInterval = parser.fieldsToExpression(fields);
var cronString = modifiedInterval.stringify();
console.log(cronString); // "29 8 * * 1,3-7"
```
Options

@@ -114,0 +133,0 @@ ========

@@ -594,2 +594,10 @@ var test = require('tap').test;

test('expression using days of week strings - wrong alias', function(t) {
t.throws(function () {
CronExpression.parse('15 10 * * MON-TUR');
}, new Error('Validation error, cannot resolve alias "tur"'));
t.end();
});
test('expression using mixed days of week strings', function(t) {

@@ -596,0 +604,0 @@ try {

@@ -1,11 +0,138 @@

import {expectType} from 'tsd';
import * as CronExpression from '../lib';
import {expectAssignable, expectError, expectNotAssignable, expectType} from 'tsd';
import {
CronDate,
CronExpression,
CronFields, DateType,
parseExpression,
parseFile, ParserOptions,
parseString,
fieldsToExpression,
StringResult
} from '../index';
const interval = CronExpression.parseExpression('0 1 2 3 * 1-3,5');
const interval = parseExpression('0 1 2 3 * 1-3,5');
const intervalIterator = parseExpression('0 1 2 3 * 1-3,5', {iterator: true});
expectType<readonly number[]>(interval.fields.second);
expectType<readonly number[]>(interval.fields.minute);
expectType<readonly number[]>(interval.fields.hour);
expectType<readonly number[]>(interval.fields.dayOfMonth);
expectType<readonly number[]>(interval.fields.month);
expectType<readonly number[]>(interval.fields.dayOfWeek);
expectError(interval.fields = interval.fields);
expectError(interval.fields.second = []);
expectError(interval.fields.second.push(1));
expectError(interval.fields.minute = []);
expectError(interval.fields.minute.push(1));
expectError(interval.fields.hour = []);
expectError(interval.fields.hour.push(1));
expectError(interval.fields.dayOfMonth = []);
expectError(interval.fields.dayOfMonth.push(1));
expectError(interval.fields.month = []);
expectError(interval.fields.month.push(1));
expectError(interval.fields.dayOfWeek = []);
expectError(interval.fields.dayOfWeek.push(1));
expectAssignable<typeof interval.fields.second[0]>(0);
expectAssignable<typeof interval.fields.second[0]>(59);
expectNotAssignable<typeof interval.fields.second[0]>(-1);
expectNotAssignable<typeof interval.fields.second[0]>(60);
expectAssignable<typeof interval.fields.minute[0]>(0);
expectAssignable<typeof interval.fields.minute[0]>(59);
expectNotAssignable<typeof interval.fields.minute[0]>(-1);
expectNotAssignable<typeof interval.fields.minute[0]>(60);
expectAssignable<typeof interval.fields.hour[0]>(0);
expectAssignable<typeof interval.fields.hour[0]>(23);
expectNotAssignable<typeof interval.fields.hour[0]>(-1);
expectNotAssignable<typeof interval.fields.hour[0]>(24);
expectAssignable<typeof interval.fields.dayOfMonth[0]>(1);
expectAssignable<typeof interval.fields.dayOfMonth[0]>(31);
expectAssignable<typeof interval.fields.dayOfMonth[0]>('L');
expectNotAssignable<typeof interval.fields.dayOfMonth[0]>(0);
expectNotAssignable<typeof interval.fields.dayOfMonth[0]>(32);
expectAssignable<typeof interval.fields.month[0]>(1);
expectAssignable<typeof interval.fields.month[0]>(12);
expectNotAssignable<typeof interval.fields.month[0]>(0);
expectNotAssignable<typeof interval.fields.month[0]>(13);
expectAssignable<typeof interval.fields.dayOfWeek[0]>(0);
expectAssignable<typeof interval.fields.dayOfWeek[0]>(7);
expectNotAssignable<typeof interval.fields.dayOfWeek[0]>(-1);
expectNotAssignable<typeof interval.fields.dayOfWeek[0]>(8);
const parseOptions: ParserOptions<true> = {
currentDate: 'f',
startDate: 4,
endDate: new Date(),
iterator: true,
utc: true,
tz: 'f',
nthDayOfWeek: 5,
}
expectAssignable<{
currentDate?: string | number | Date
startDate?: string | number | Date
endDate?: string | number | Date
iterator?: boolean
utc?: boolean
tz?: string
nthDayOfWeek?: number
}>(parseOptions)
expectType<CronExpression>(parseExpression('0 1 2 3 * 1-3,5'))
expectType<CronExpression<true>>(parseExpression('0 1 2 3 * 1-3,5', parseOptions))
const fields: CronFields = {
second: [1, 1],
minute: [1],
hour: [1],
dayOfMonth: [1],
month: [1],
dayOfWeek: [1],
}
expectType<CronExpression>(fieldsToExpression(fields))
expectType<CronExpression<true>>(fieldsToExpression(fields, parseOptions))
expectType<string>(fieldsToExpression(fields).stringify())
expectType<string>(fieldsToExpression(fields, parseOptions).stringify())
expectType<string>(fieldsToExpression(fields, parseOptions).stringify(true))
expectType<void>(parseFile('path', (err: any, data: StringResult) => console.log(data)))
expectType<StringResult>(parseString('path'))
const stringResult = parseString('path');
expectType<{
variables: Record<string, string>,
expressions: CronExpression[],
errors: Record<string, any>,
}>(stringResult)
expectType<CronFields>(interval.fields)
expectType<CronDate>(interval.next())
expectType<CronDate>(interval.prev())
expectType<boolean>(interval.hasNext())
expectType<boolean>(interval.hasPrev())
expectType<string>(interval.stringify())
expectType<string>(interval.stringify(true))
expectType<void>(interval.reset())
expectType<void>(interval.reset("Sdf"))
expectType<void>(interval.reset(5))
expectType<void>(interval.reset(new Date()))
expectType<CronDate[]>(interval.iterate(5))
expectType<CronDate[]>(interval.iterate(5, (item: CronDate, i: number) => {}))
expectAssignable<DateType>(new Date())
expectAssignable<DateType>(5)
expectAssignable<DateType>("SDf")
expectType<IteratorResult<CronDate, CronDate>>(intervalIterator.next())
expectType<IteratorResult<CronDate, CronDate>>(intervalIterator.prev())
expectType<IteratorResult<CronDate, CronDate>[]>(intervalIterator.iterate(5))
expectType<IteratorResult<CronDate, CronDate>[]>(intervalIterator.iterate(5, (item: IteratorResult<CronDate, CronDate>, i: number) => {}))
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