node-schedule 1.2.1 → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc CHANGED
@@ -1,16 +1,17 @@
1
1
  {
2
2
  "env": {
3
- "node": true
3
+ "node": true,
4
+ "es6": true
4
5
  },
5
6
  "rules": {
6
- "eqeqeq": [2, "smart"],
7
- "indent": [2, 2],
8
- "no-constant-condition": false,
9
- "no-redeclare": 1,
10
- "no-underscore-dangle": false,
11
- "no-use-before-define": [true,"nofunc"],
12
- "quotes": [2, "single"],
13
- "space-before-blocks": 2,
14
- "strict": 2
7
+ "eqeqeq": ["error", "smart"],
8
+ "indent": ["error", 2, { "SwitchCase": 1 }],
9
+ "no-constant-condition": "off",
10
+ "no-redeclare": "warn",
11
+ "no-underscore-dangle": "off",
12
+ "no-use-before-define": ["warn","nofunc"],
13
+ "quotes": ["error", "single"],
14
+ "space-before-blocks": "error",
15
+ "strict": "error"
15
16
  }
16
17
  }
package/.travis.yml CHANGED
@@ -3,6 +3,13 @@ node_js:
3
3
  - "0.12"
4
4
  - "0.10"
5
5
  - "4"
6
- - "5"
7
- before_script: npm run lint
6
+ - "6"
7
+ - "7"
8
+ before_script: >
9
+ if nvm ls-remote --lts | grep "$(nvm current)"; then
10
+ echo "running on a LTS node version, linting"
11
+ npm test
12
+ else
13
+ echo "running on a non-LTS node version, skipping linting"
14
+ fi
8
15
  script: ./node_modules/.bin/istanbul cover ./node_modules/.bin/nodeunit test && cat ./coverage/lcov.info | ./node_modules/.bin/coveralls && rm -rf ./coverage
package/README.md CHANGED
@@ -48,8 +48,9 @@ They also emit a `scheduled` event each time they're scheduled to run, and a
48
48
  `canceled` event when an invocation is canceled before it's executed (both events
49
49
  receive a JavaScript date object as a parameter). Note that jobs are scheduled the
50
50
  first time immediately, so if you create a job using the `scheduleJob()`
51
- convenience method, you'll miss the first `scheduled` event. Also note that
52
- `canceled` is the single-L American spelling.
51
+ convenience method, you'll miss the first `scheduled` event, but you can query the
52
+ invocation manually (see below). Also note that `canceled` is the single-L American
53
+ spelling.
53
54
 
54
55
  ### Cron-style Scheduling
55
56
 
@@ -110,12 +111,6 @@ var j = schedule.scheduleJob(date, function(){
110
111
  });
111
112
  ```
112
113
 
113
- You can invalidate the job with the `cancel()` method:
114
-
115
- ```js
116
- j.cancel();
117
- ```
118
-
119
114
  To use current data in the future you can use binding:
120
115
 
121
116
  ```js
@@ -200,6 +195,32 @@ var j = schedule.scheduleJob({ start: startTime, end: endTime, rule: '*/1 * * *
200
195
  });
201
196
  ```
202
197
 
198
+ ### Handle Jobs and Job Invocations
199
+
200
+ There are some function to get informations for a Job and to handle the Job and
201
+ Invocations.
202
+
203
+
204
+ #### job.cancel(reshedule)
205
+ You can invalidate any job with the `cancel()` method:
206
+
207
+ ```js
208
+ j.cancel();
209
+ ```
210
+ All planned invocations will be canceled. When you set the parameter ***reschedule***
211
+ to true then the Job is newly scheduled afterwards.
212
+
213
+ #### job.cancelNext(reshedule)
214
+ This method invalidates the next planned invocation or the job.
215
+ When you set the parameter ***reschedule*** to true then the Job is newly scheduled
216
+ afterwards.
217
+
218
+ #### job.reschedule(spec)
219
+ This method cancels all pending invocation and registers the Job completely new again using the given specification.
220
+ Return true/false on success/failure.
221
+
222
+ #### job.nextInvocation()
223
+ This method returns a Date object for the planned next Invocation for this Job. If no invocation is planned the method returns null.
203
224
 
204
225
  ## Contributing
205
226
 
package/lib/schedule.js CHANGED
@@ -15,6 +15,7 @@ var events = require('events'),
15
15
 
16
16
  /* Job object */
17
17
  var anonJobCounter = 0;
18
+ var scheduledJobs = {};
18
19
 
19
20
  function isValidDate(date) {
20
21
  // Taken from http://stackoverflow.com/a/12372720/1562178
@@ -185,33 +186,40 @@ Job.prototype.schedule = function(spec) {
185
186
  var inv;
186
187
  var start;
187
188
  var end;
189
+ var tz;
188
190
 
189
191
  if (typeof spec === 'object' && spec.rule) {
190
- start = spec.start || null;
191
- end = spec.end || null;
192
+ start = spec.start || undefined;
193
+ end = spec.end || undefined;
194
+ tz = spec.tz;
192
195
  spec = spec.rule;
193
196
 
194
- if (start != null) {
197
+ if (start) {
195
198
  if (!(start instanceof Date)) {
196
199
  start = new Date(start);
197
200
  }
201
+
202
+ start = new CronDate(start, tz);
198
203
  if (!isValidDate(start) || start.getTime() < Date.now()) {
199
- start = null;
204
+ start = undefined;
200
205
  }
201
206
  }
202
207
 
203
- if (end != null && !(end instanceof Date) && !isValidDate(end = new Date(end))) {
204
- end = null;
208
+ if (end && !(end instanceof Date) && !isValidDate(end = new Date(end))) {
209
+ end = undefined;
210
+ }
211
+
212
+ if (end) {
213
+ end = new CronDate(end, tz);
205
214
  }
206
215
  }
207
216
 
208
217
  try {
209
- var res = cronParser.parseExpression(spec, { currentDate: start });
218
+ var res = cronParser.parseExpression(spec, { currentDate: start, tz: tz });
210
219
  inv = scheduleNextRecurrence(res, self, start, end);
211
220
  if (inv !== null) {
212
221
  success = self.trackInvocation(inv);
213
222
  }
214
-
215
223
  } catch (err) {
216
224
  var type = typeof spec;
217
225
  if ((type === 'string') || (type === 'number')) {
@@ -219,6 +227,7 @@ Job.prototype.schedule = function(spec) {
219
227
  }
220
228
 
221
229
  if ((spec instanceof Date) && (isValidDate(spec))) {
230
+ spec = new CronDate(spec);
222
231
  if (spec.getTime() >= Date.now()) {
223
232
  inv = new Invocation(self, spec);
224
233
  scheduleInvocation(inv);
@@ -252,6 +261,7 @@ Job.prototype.schedule = function(spec) {
252
261
  spec = r;
253
262
  }
254
263
 
264
+ spec.tz = tz;
255
265
  inv = scheduleNextRecurrence(spec, self, start, end);
256
266
  if (inv !== null) {
257
267
  success = self.trackInvocation(inv);
@@ -336,13 +346,68 @@ function RecurrenceRule(year, month, date, dayOfWeek, hour, minute, second) {
336
346
  this.second = (second == null) ? 0 : second;
337
347
  }
338
348
 
349
+ RecurrenceRule.prototype.isValid = function() {
350
+ function isValidType(num) {
351
+ if (Array.isArray(num) || (num instanceof Array)) {
352
+ return num.every(function(e) {
353
+ return isValidType(e);
354
+ });
355
+ }
356
+ return !(Number.isNaN(Number(num)) && !(num instanceof Range));
357
+ }
358
+ if (this.month !== null && (this.month < 0 || this.month > 11 || !isValidType(this.month))) {
359
+ return false;
360
+ }
361
+ if (this.dayOfWeek !== null && (this.dayOfWeek < 0 || this.dayOfWeek > 6 || !isValidType(this.dayOfWeek))) {
362
+ return false;
363
+ }
364
+ if (this.hour !== null && (this.hour < 0 || this.hour > 23 || !isValidType(this.hour))) {
365
+ return false;
366
+ }
367
+ if (this.minute !== null && (this.minute < 0 || this.minute > 59 || !isValidType(this.minute))) {
368
+ return false;
369
+ }
370
+ if (this.second !== null && (this.second < 0 || this.second > 59 || !isValidType(this.second))) {
371
+ return false;
372
+ }
373
+ if (this.date !== null) {
374
+ if(!isValidType(this.date)) {
375
+ return false;
376
+ }
377
+ switch (this.month) {
378
+ case 3:
379
+ case 5:
380
+ case 8:
381
+ case 10:
382
+ if (this.date < 1 || this. date > 30) {
383
+ return false;
384
+ }
385
+ break;
386
+ case 1:
387
+ if (this.date < 1 || this. date > 29) {
388
+ return false;
389
+ }
390
+ break;
391
+ default:
392
+ if (this.date < 1 || this. date > 31) {
393
+ return false;
394
+ }
395
+ }
396
+ }
397
+ return true;
398
+ };
399
+
339
400
  RecurrenceRule.prototype.nextInvocationDate = function(base) {
340
- base = (base instanceof Date) ? base : (new Date());
401
+ base = ((base instanceof CronDate) || (base instanceof Date)) ? base : (new Date());
341
402
  if (!this.recurs) {
342
403
  return null;
343
404
  }
344
405
 
345
- var now = new Date();
406
+ if(!this.isValid()) {
407
+ return null;
408
+ }
409
+
410
+ var now = new CronDate(Date.now(), this.tz);
346
411
  var fullYear = now.getFullYear();
347
412
  if ((this.year !== null) &&
348
413
  (typeof this.year == 'number') &&
@@ -350,7 +415,7 @@ RecurrenceRule.prototype.nextInvocationDate = function(base) {
350
415
  return null;
351
416
  }
352
417
 
353
- var next = new CronDate(base.getTime());
418
+ var next = new CronDate(base.getTime(), this.tz);
354
419
  next.addSecond();
355
420
 
356
421
  while (true) {
@@ -399,7 +464,7 @@ RecurrenceRule.prototype.nextInvocationDate = function(base) {
399
464
  break;
400
465
  }
401
466
 
402
- return next;
467
+ return next ? next.toDate() : null;
403
468
  };
404
469
 
405
470
  function recurMatch(val, matcher) {
@@ -407,8 +472,10 @@ function recurMatch(val, matcher) {
407
472
  return true;
408
473
  }
409
474
 
410
- if (typeof matcher === 'number' || typeof matcher === 'string') {
475
+ if (typeof matcher === 'number') {
411
476
  return (val === matcher);
477
+ } else if(typeof matcher === 'string') {
478
+ return (val === Number(matcher));
412
479
  } else if (matcher instanceof Range) {
413
480
  return matcher.contains(val);
414
481
  } else if (Array.isArray(matcher) || (matcher instanceof Array)) {
@@ -426,13 +493,8 @@ function recurMatch(val, matcher) {
426
493
  function runOnDate(date, job) {
427
494
  var now = (new Date()).getTime();
428
495
  var then = date.getTime();
429
-
430
- if (then < now) {
431
- setImmediate(job);
432
- return null;
433
- }
434
-
435
- return lt.setTimeout(job, (then - now));
496
+
497
+ return lt.setTimeout(job, (then < now ? 0 : then - now));
436
498
  }
437
499
 
438
500
  var invocations = [];
@@ -441,7 +503,8 @@ var currentInvocation = null;
441
503
  function scheduleInvocation(invocation) {
442
504
  sorted.add(invocations, invocation, sorter);
443
505
  prepareNextInvocation();
444
- invocation.job.emit('scheduled', invocation.fireDate);
506
+ var date = invocation.fireDate instanceof CronDate ? invocation.fireDate.toDate() : invocation.fireDate;
507
+ invocation.job.emit('scheduled', date);
445
508
  }
446
509
 
447
510
  function prepareNextInvocation() {
@@ -504,14 +567,14 @@ function cancelInvocation(invocation) {
504
567
  /* Recurrence scheduler */
505
568
  function scheduleNextRecurrence(rule, job, prevDate, endDate) {
506
569
 
507
- prevDate = (prevDate instanceof Date) ? prevDate : (new Date());
570
+ prevDate = (prevDate instanceof CronDate) ? prevDate : new CronDate();
508
571
 
509
572
  var date = (rule instanceof RecurrenceRule) ? rule.nextInvocationDate(prevDate) : rule.next();
510
573
  if (date === null) {
511
574
  return null;
512
575
  }
513
576
 
514
- if ((endDate instanceof Date) && date.getTime() > endDate.getTime()) {
577
+ if ((endDate instanceof CronDate) && date.getTime() > endDate.getTime()) {
515
578
  return null;
516
579
  }
517
580
 
@@ -522,8 +585,6 @@ function scheduleNextRecurrence(rule, job, prevDate, endDate) {
522
585
  }
523
586
 
524
587
  /* Convenience methods */
525
- var scheduledJobs = {};
526
-
527
588
  function scheduleJob() {
528
589
  if (arguments.length < 2) {
529
590
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-schedule",
3
- "version": "1.2.1",
3
+ "version": "1.2.5",
4
4
  "description": "A cron-like and not-cron-like job scheduler for Node.",
5
5
  "keywords": [
6
6
  "schedule",
@@ -12,7 +12,7 @@
12
12
  "main": "./lib/schedule.js",
13
13
  "scripts": {
14
14
  "test": "nodeunit",
15
- "lint": "eslint lib"
15
+ "lint": "eslint lib test"
16
16
  },
17
17
  "author": {
18
18
  "name": "Matt Patenaude",
@@ -24,13 +24,13 @@
24
24
  "url": "https://github.com/node-schedule/node-schedule.git"
25
25
  },
26
26
  "dependencies": {
27
- "cron-parser": "1.1.0",
27
+ "cron-parser": "^2.4.0",
28
28
  "long-timeout": "0.1.1",
29
29
  "sorted-array-functions": "^1.0.0"
30
30
  },
31
31
  "devDependencies": {
32
32
  "coveralls": "^2.11.2",
33
- "eslint": "^0.15.1",
33
+ "eslint": "^3.19.0",
34
34
  "istanbul": "^0.4.5",
35
35
  "nodeunit": "^0.10.2",
36
36
  "sinon": "^1.14.1"