cron-allowed-range
Advanced tools
Comparing version 0.0.8 to 0.0.9
#!/usr/bin/env node | ||
const CronAllowedRange = require('../src'); | ||
const usage = `Usage: $0 -e [cron-like expression] | ||
const usage = `Usage: $0 -e [cron-like expression] -t [timezone] | ||
@@ -21,10 +21,12 @@ * represents any value | ||
.usage(usage) | ||
.example('$0 -e "* 9-17 * * *"', 'Check if current date time is between 9 AM to 5 PM (UTC)') | ||
.example('$0 -e "* 9-17 * * *" -t "America/Toronto"', 'Check if current date time is between 9 AM to 6 PM (America/Toronto)') | ||
.alias('h', 'help') | ||
.demandOption(['e']) | ||
.demandOption(['expression', 'timezone']) | ||
.alias('e', 'expression') | ||
.describe('e', 'Cron-like expression') | ||
.alias('t', 'timezone') | ||
.describe('t', 'Timezone') | ||
.argv; | ||
const cr = new CronAllowedRange(argv.expression); | ||
const cr = new CronAllowedRange(argv.expression, argv.timezone); | ||
if(cr.isDateAllowed(new Date())) { | ||
@@ -31,0 +33,0 @@ process.exit(0); |
{ | ||
"name": "cron-allowed-range", | ||
"version": "0.0.8", | ||
"version": "0.0.9", | ||
"description": "Use cron-like expressions to test if a datetime is in an allowed range.", | ||
@@ -35,2 +35,4 @@ "main": "src/index.js", | ||
"dependencies": { | ||
"moment": "^2.24.0", | ||
"moment-timezone": "^0.5.27", | ||
"nyc": "^14.1.1", | ||
@@ -37,0 +39,0 @@ "yargs": "^14.2.0" |
@@ -12,5 +12,2 @@ [![CircleCI](https://circleci.com/gh/neverendingqs/cron-allowed-range.svg?style=svg)](https://circleci.com/gh/neverendingqs/cron-allowed-range) | ||
Note: this library always uses UTC time. It will support timezones in the | ||
future. | ||
### API | ||
@@ -27,3 +24,3 @@ | ||
* - At any minute | ||
* - Between 9 AM - 5 PM | ||
* - Between 9 AM - 6 PM | ||
* - On any day of the month | ||
@@ -33,8 +30,8 @@ * - Between September to June, or on August | ||
*/ | ||
const cr = new CronAllowedRange('* 9-17 * 9-6,8 1-5'); | ||
const cr = new CronAllowedRange('* 9-17 * 9-6,8 1-5', 'America/Toronto'); | ||
cr.isDateAllowed(new Date('December 18, 1995 08:59:59 GMT-0000')); | ||
cr.isDateAllowed(new Date('December 18, 1995 08:59:59 GMT-0500')); | ||
// false | ||
cr.isDateAllowed(new Date('August 18, 1995 17:00:00 GMT-0000')); | ||
cr.isDateAllowed(new Date('August 18, 1995 17:00:00 GMT-0400')); | ||
// true | ||
@@ -48,6 +45,6 @@ ``` | ||
cr -e "* 9-17 * * *" | ||
cr -e "* 9-17 * * *" -t 'America/Toronto' | ||
echo $? | ||
# exit code is 0 if within range, otherwise 1 | ||
# exit code is 0 if current time is within range, otherwise 1 | ||
``` | ||
@@ -54,0 +51,0 @@ |
@@ -0,1 +1,3 @@ | ||
const moment = require('moment-timezone'); | ||
function parsePart(part) { | ||
@@ -40,5 +42,7 @@ if(part === '*') { | ||
return start < end | ||
const isWithinRange = start < end | ||
? value >= start && value <= end | ||
: value >= start || value <= end; | ||
return isWithinRange; | ||
} | ||
@@ -55,3 +59,3 @@ | ||
module.exports = class { | ||
constructor(expression) { | ||
constructor(expression, timezone = 'GMT') { | ||
const parts = expression.trim().split(' '); | ||
@@ -69,11 +73,18 @@ if(parts.length !== 5) { | ||
this.dayOfWeek = parsePart(parts[4]); | ||
if(!moment.tz.zone(timezone)) { | ||
throw new Error(`Invalid timezone string ${timezone}.`); | ||
} | ||
this.timezone = timezone; | ||
} | ||
isDateAllowed(date) { | ||
return isWithinARange(date.getUTCMinutes(), this.minute) && | ||
isWithinARange(date.getUTCHours(), this.hour) && | ||
isWithinARange(date.getUTCDate(), this.dayOfMonth) && | ||
isWithinARange(date.getUTCMonth() + 1, this.month) && | ||
isWithinARange(date.getUTCDay(), this.dayOfWeek); | ||
const dateWithTz = moment(date).tz(this.timezone); | ||
return isWithinARange(dateWithTz.minute(), this.minute) && | ||
isWithinARange(dateWithTz.hour(), this.hour) && | ||
isWithinARange(dateWithTz.date(), this.dayOfMonth) && | ||
isWithinARange(dateWithTz.month() + 1, this.month) && | ||
isWithinARange(dateWithTz.day(), this.dayOfWeek); | ||
} | ||
} |
@@ -6,3 +6,3 @@ const assert = require('chai').assert; | ||
describe('cron-allowed-range', function() { | ||
describe('constructor', function() { | ||
describe('constructor()', function() { | ||
['hello world', '* * * *'].forEach(expression => { | ||
@@ -21,2 +21,6 @@ it(`throws error on invalid expression '${expression}'`, function() { | ||
it('throws error on invalid timezone', function() { | ||
assert.throws(() => new CronAllowedRange('* * * * *', 'not-a-valid-tz')); | ||
}); | ||
it('trims the expression before splitting', function() { | ||
@@ -208,61 +212,130 @@ const cr = new CronAllowedRange(' * * * * * '); | ||
[ | ||
{ | ||
date: new Date('December 18, 1995 08:59:59 GMT-0000'), | ||
reason: 'it is before 9 AM' | ||
}, | ||
{ | ||
date: new Date('December 18, 1995 18:00:00 GMT-0000'), | ||
reason: 'it is after 5 PM' | ||
}, | ||
{ | ||
date: new Date('July 18, 1995 08:30:00 GMT-0000'), | ||
reason: 'it is on July' | ||
}, | ||
{ | ||
date: new Date('December 18, 1995 09:30:00 GMT+0100'), | ||
reason: 'it is before 9 AM UTC time' | ||
}, | ||
{ | ||
date: new Date('December 16, 1995 09:30:00 GMT-0000'), | ||
reason: 'it is a Saturday' | ||
}, | ||
{ | ||
date: new Date('December 17, 1995 09:30:00 GMT-0000'), | ||
reason: 'it is a Sunday' | ||
}, | ||
].forEach(({ date, reason }) => { | ||
it(`returns false because ${reason}`, function() { | ||
/* Allowed if it is: | ||
* - At any minute | ||
* - Between 9 AM - 5 PM | ||
* - On any day of the month | ||
* - Between September to June or on August | ||
* - Between Monday to Friday | ||
*/ | ||
const cr = new CronAllowedRange('* 9-17 * 9-6,8 1-5'); | ||
describe('expression with UTC', function() { | ||
[ | ||
{ | ||
date: new Date('December 18, 1995 08:59:59 GMT-0000'), | ||
reason: 'it is before 9 AM' | ||
}, | ||
{ | ||
date: new Date('December 18, 1995 18:00:00 GMT-0000'), | ||
reason: 'it is after 5 PM' | ||
}, | ||
{ | ||
date: new Date('July 18, 1995 08:30:00 GMT-0000'), | ||
reason: 'it is on July' | ||
}, | ||
{ | ||
date: new Date('December 18, 1995 09:30:00 GMT+0100'), | ||
reason: 'it is before 9 AM UTC time' | ||
}, | ||
{ | ||
date: new Date('December 16, 1995 09:30:00 GMT-0000'), | ||
reason: 'it is a Saturday' | ||
}, | ||
{ | ||
date: new Date('December 17, 1995 09:30:00 GMT-0000'), | ||
reason: 'it is a Sunday' | ||
}, | ||
].forEach(({ date, reason }) => { | ||
it(`returns false because ${reason}`, function() { | ||
/* Allowed if it is: | ||
* - At any minute | ||
* - Between 9 AM - 6 PM | ||
* - On any day of the month | ||
* - Between September to June or on August | ||
* - Between Monday to Friday | ||
*/ | ||
const cr = new CronAllowedRange('* 9-17 * 9-6,8 1-5'); | ||
const actual = cr.isDateAllowed(date); | ||
assert.isFalse(actual); | ||
const actual = cr.isDateAllowed(date); | ||
assert.isFalse(actual); | ||
}); | ||
}); | ||
[ | ||
new Date('December 18, 1995 09:00:00 GMT-0000'), | ||
new Date('August 18, 1995 17:00:00 GMT-0000') | ||
].forEach(date => { | ||
it(`returns true for ${date}`, function() { | ||
/* Allowed if it is: | ||
* - At any minute | ||
* - Between 9 AM - 6 PM | ||
* - On any day of the month | ||
* - Between September to June or on August | ||
* - Between Monday to Friday | ||
*/ | ||
const cr = new CronAllowedRange('* 9-17 * 9-6,8 1-5'); | ||
const actual = cr.isDateAllowed(date); | ||
assert.isTrue(actual); | ||
}); | ||
}); | ||
}); | ||
[ | ||
new Date('December 18, 1995 09:00:00 GMT-0000'), | ||
new Date('August 18, 1995 17:00:00 GMT-0000') | ||
].forEach(date => { | ||
it(`returns true for ${date}`, function() { | ||
/* Allowed if it is: | ||
* - At any minute | ||
* - Between 9 AM - 5 PM | ||
* - On any day of the month | ||
* - Between September to June or on August | ||
* - Between Monday to Friday | ||
*/ | ||
const cr = new CronAllowedRange('* 9-17 * 9-6,8 1-5'); | ||
const actual = cr.isDateAllowed(date); | ||
assert.isTrue(actual); | ||
describe('expressions with timezones', function() { | ||
[ | ||
{ | ||
expression: '* 9-17 * * 1-5', | ||
timezone: 'America/Toronto', | ||
date: new Date('October 23, 2019 18:00:00 GMT-0400'), | ||
reason: 'it is one hour past the allowed range (using GMT-0500)' | ||
}, | ||
{ | ||
expression: '* 9-17 * * 1-5', | ||
timezone: 'America/Toronto', | ||
date: new Date('October 23, 2019 08:59:59 GMT-0400'), | ||
reason: 'it is one hour before the allowed range (using GMT-0500)' | ||
}, | ||
{ | ||
expression: '* 9-17 * * 1-5', | ||
timezone: 'America/Toronto', | ||
date: new Date('October 23, 2019 22:00:00 GMT-0000'), | ||
reason: 'it is one hour past the allowed range (using GMT-0000)' | ||
}, | ||
{ | ||
expression: '* 9-17 * * 1-5', | ||
timezone: 'America/Toronto', | ||
date: new Date('October 23, 2019 12:59:59 GMT-0000'), | ||
reason: 'it is one hour before the allowed range (using GMT-0000)' | ||
}, | ||
{ | ||
expression: '* 9-17 * * 1-5', | ||
timezone: 'America/Toronto', | ||
date: new Date('December 18, 1995 13:59:59 GMT-0000'), | ||
reason: 'it is one hour before the allowed range (using GMT-0000)' | ||
}, | ||
{ | ||
expression: '* 9-17 * * 1-5', | ||
timezone: 'America/Toronto', | ||
date: new Date('December 18, 1995 23:00:00 GMT-0000'), | ||
reason: 'it is one hour past the allowed range (using GMT-0000)' | ||
} | ||
].forEach(({ expression, timezone, date, reason }) => { | ||
it(`returns false because ${reason}`, function() { | ||
const cr = new CronAllowedRange(expression, timezone); | ||
const actual = cr.isDateAllowed(date); | ||
assert.isFalse(actual); | ||
}); | ||
}); | ||
[ | ||
new Date('December 18, 1995 09:00:00 GMT-0500'), | ||
new Date('August 18, 1995 17:00:00 GMT-0400') | ||
].forEach(date => { | ||
it(`returns true for ${date}`, function() { | ||
/* Allowed if it is: | ||
* - At any minute | ||
* - Between 9 AM - 6 PM | ||
* - On any day of the month | ||
* - Between September to June or on August | ||
* - Between Monday to Friday | ||
*/ | ||
const cr = new CronAllowedRange('* 9-17 * * 1-5', 'America/Toronto'); | ||
const actual = cr.isDateAllowed(date); | ||
assert.isTrue(actual); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
30656
404
4
70
+ Addedmoment@^2.24.0
+ Addedmoment-timezone@^0.5.27
+ Addedmoment@2.30.1(transitive)
+ Addedmoment-timezone@0.5.46(transitive)