node-schedule 1.3.2 → 1.3.3
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/README.md +39 -15
- package/lib/nodeVersionUtils.js +30 -0
- package/lib/schedule.js +17 -5
- package/package.json +24 -10
- package/.eslintrc +0 -17
- package/.travis.yml +0 -15
- package/CONTRIBUTING.md +0 -31
- package/test/.eslintrc +0 -5
- package/test/cancel-long-running-jobs.js +0 -24
- package/test/convenience-method-test.js +0 -713
- package/test/date-convenience-methods-test.js +0 -59
- package/test/es6/job-test.js +0 -33
- package/test/job-test.js +0 -555
- package/test/range-test.js +0 -77
- package/test/recurrence-rule-test.js +0 -375
- package/test/schedule-cron-jobs.js +0 -134
- package/test/start-end-test.js +0 -327
package/README.md
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/node-schedule)
|
|
4
4
|
[](https://www.npmjs.com/package/node-schedule)
|
|
5
|
-
[](https://github.com/node-schedule/node-schedule/actions)
|
|
6
|
+
[](https://coveralls.io/r/node-schedule/node-schedule?branch=master)
|
|
6
7
|
[](https://gitter.im/node-schedule/node-schedule?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
7
8
|
|
|
8
9
|
[](https://nodei.co/npm/node-schedule/)
|
|
@@ -43,14 +44,19 @@ Every scheduled job in Node Schedule is represented by a `Job` object. You can
|
|
|
43
44
|
create jobs manually, then execute the `schedule()` method to apply a schedule,
|
|
44
45
|
or use the convenience function `scheduleJob()` as demonstrated below.
|
|
45
46
|
|
|
46
|
-
`Job` objects are `EventEmitter`
|
|
47
|
-
|
|
48
|
-
`
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
47
|
+
`Job` objects are `EventEmitter`s, and emit the following events:
|
|
48
|
+
* A `run` event after each execution.
|
|
49
|
+
* A `scheduled` event each time they're scheduled to run.
|
|
50
|
+
* A `canceled` event when an invocation is canceled before it's executed.
|
|
51
|
+
Note that `canceled` is the single-L American spelling.
|
|
52
|
+
* An `error` event when a job invocation triggered by a schedule throws or returns
|
|
53
|
+
a rejected `Promise`.
|
|
54
|
+
|
|
55
|
+
(Both the `scheduled` and `canceled` events receive a JavaScript date object as
|
|
56
|
+
a parameter).
|
|
57
|
+
Note that jobs are scheduled the first time immediately, so if you create a job
|
|
58
|
+
using the `scheduleJob()` convenience method, you'll miss the first `scheduled`
|
|
59
|
+
event, but you can query the invocation manually (see below).
|
|
54
60
|
|
|
55
61
|
### Cron-style Scheduling
|
|
56
62
|
|
|
@@ -98,9 +104,9 @@ var j = schedule.scheduleJob('0 1 * * *', function(fireDate){
|
|
|
98
104
|
This is useful when you need to check if there is a delay of the job invocation when the system is busy, or save a record of all invocations of a job for audit purpose.
|
|
99
105
|
#### Unsupported Cron Features
|
|
100
106
|
|
|
101
|
-
Currently, `W` (nearest weekday)
|
|
102
|
-
|
|
103
|
-
|
|
107
|
+
Currently, `W` (nearest weekday) and `L` (last day of month/week) are not supported.
|
|
108
|
+
Most other features supported by popular cron implementations should work just fine,
|
|
109
|
+
including `#` (nth weekday of the month).
|
|
104
110
|
|
|
105
111
|
[cron-parser] is used to parse crontab instructions.
|
|
106
112
|
|
|
@@ -163,6 +169,20 @@ var j = schedule.scheduleJob(rule, function(){
|
|
|
163
169
|
});
|
|
164
170
|
```
|
|
165
171
|
|
|
172
|
+
Timezones are also supported. Here is an example of executing at the start of every day in the UTC timezone.
|
|
173
|
+
|
|
174
|
+
```js
|
|
175
|
+
var rule = new schedule.RecurrenceRule();
|
|
176
|
+
rule.hour = 0;
|
|
177
|
+
rule.tz = 'Etc/UTC';
|
|
178
|
+
|
|
179
|
+
var j = schedule.scheduleJob(rule, function(){
|
|
180
|
+
console.log('A new day has begun in the UTC timezone!');
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
A list of acceptable tz (timezone) values can be found at <https://en.wikipedia.org/wiki/List_of_tz_database_time_zones>
|
|
185
|
+
|
|
166
186
|
#### RecurrenceRule properties
|
|
167
187
|
|
|
168
188
|
- `second (0-59)`
|
|
@@ -172,6 +192,8 @@ var j = schedule.scheduleJob(rule, function(){
|
|
|
172
192
|
- `month (0-11)`
|
|
173
193
|
- `year`
|
|
174
194
|
- `dayOfWeek (0-6) Starting with Sunday`
|
|
195
|
+
- `tz`
|
|
196
|
+
|
|
175
197
|
|
|
176
198
|
> **Note**: It's worth noting that the default value of a component of a recurrence rule is
|
|
177
199
|
> `null` (except for second, which is 0 for familiarity with cron). *If we did not
|
|
@@ -231,8 +253,9 @@ This method returns a Date object for the planned next Invocation for this Job.
|
|
|
231
253
|
|
|
232
254
|
## Contributing
|
|
233
255
|
|
|
234
|
-
This module was originally developed by [Matt Patenaude]
|
|
235
|
-
|
|
256
|
+
This module was originally developed by [Matt Patenaude] who eventually passed over maintainer's mantle over to [Tejas Manohar].
|
|
257
|
+
|
|
258
|
+
Currently it is being maintained by [Igor Savin] and [our amazing community].
|
|
236
259
|
|
|
237
260
|
We'd love to get your contributions. Individuals making significant and valuable
|
|
238
261
|
contributions are given commit-access to the project to contribute as they see fit.
|
|
@@ -250,7 +273,8 @@ Licensed under the **[MIT License] [license]**.
|
|
|
250
273
|
[Contributing]: https://github.com/node-schedule/node-schedule/blob/master/CONTRIBUTING.md
|
|
251
274
|
[Matt Patenaude]: https://github.com/mattpat
|
|
252
275
|
[Tejas Manohar]: http://tejas.io
|
|
276
|
+
[Igor Savin]: https://twitter.com/kibertoad
|
|
253
277
|
[license]: https://github.com/node-schedule/node-schedule/blob/master/LICENSE
|
|
254
278
|
[Tejas Manohar]: https://github.com/tejasmanohar
|
|
255
|
-
[
|
|
279
|
+
[our amazing community]: https://github.com/node-schedule/node-schedule/graphs/contributors
|
|
256
280
|
[cron-parser]: https://github.com/harrisiirak/cron-parser
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
var nodeVersionString = process.versions.node
|
|
4
|
+
|
|
5
|
+
function getNodeVersion(nodeVersionString) {
|
|
6
|
+
var versionSplit = nodeVersionString.split('.')
|
|
7
|
+
return {
|
|
8
|
+
majorVersion: Number(versionSplit[0]),
|
|
9
|
+
minorVersion: Number(versionSplit[1])
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function arePromisesSupported(nodeVersion) {
|
|
14
|
+
var majorVersion = nodeVersion.majorVersion
|
|
15
|
+
var minorVersion = nodeVersion.minorVersion
|
|
16
|
+
|
|
17
|
+
if (majorVersion > 0) {
|
|
18
|
+
return true
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (minorVersion < 12) {
|
|
22
|
+
return false
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return true
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
module.exports.nodeVersionString = nodeVersionString;
|
|
29
|
+
module.exports.arePromisesSupported = arePromisesSupported;
|
|
30
|
+
module.exports.getNodeVersion = getNodeVersion;
|
package/lib/schedule.js
CHANGED
|
@@ -11,11 +11,13 @@ var events = require('events'),
|
|
|
11
11
|
cronParser = require('cron-parser'),
|
|
12
12
|
CronDate = require('cron-parser/lib/date'),
|
|
13
13
|
lt = require('long-timeout'),
|
|
14
|
-
sorted = require('sorted-array-functions')
|
|
14
|
+
sorted = require('sorted-array-functions'),
|
|
15
|
+
nodeVersionUtils = require('./nodeVersionUtils')
|
|
15
16
|
|
|
16
17
|
/* Job object */
|
|
17
18
|
var anonJobCounter = 0;
|
|
18
19
|
var scheduledJobs = {};
|
|
20
|
+
var promisesSupported = nodeVersionUtils.arePromisesSupported(nodeVersionUtils.getNodeVersion(nodeVersionUtils.nodeVersionString))
|
|
19
21
|
|
|
20
22
|
function isValidDate(date) {
|
|
21
23
|
// Taken from http://stackoverflow.com/a/12372720/1562178
|
|
@@ -125,7 +127,7 @@ function Job(name, job, callback) {
|
|
|
125
127
|
|
|
126
128
|
cancelInvocation(nextInv);
|
|
127
129
|
|
|
128
|
-
|
|
130
|
+
if (reschedule && (nextInv.recurrenceRule.recurs || nextInv.recurrenceRule.next)) {
|
|
129
131
|
newInv = scheduleNextRecurrence(nextInv.recurrenceRule, this, nextInv.fireDate, nextInv.endDate);
|
|
130
132
|
if (newInv !== null) {
|
|
131
133
|
this.trackInvocation(newInv);
|
|
@@ -170,7 +172,7 @@ util.inherits(Job, events.EventEmitter);
|
|
|
170
172
|
Job.prototype.invoke = function(fireDate) {
|
|
171
173
|
if (typeof this.job == 'function') {
|
|
172
174
|
this.setTriggeredJobs(this.triggeredJobs() + 1);
|
|
173
|
-
this.job(fireDate);
|
|
175
|
+
return this.job(fireDate);
|
|
174
176
|
} else {
|
|
175
177
|
this.job.execute(fireDate);
|
|
176
178
|
}
|
|
@@ -549,8 +551,18 @@ function prepareNextInvocation() {
|
|
|
549
551
|
|
|
550
552
|
job.stopTrackingInvocation(cinv);
|
|
551
553
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
+
try {
|
|
555
|
+
var result = job.invoke(cinv.fireDate instanceof CronDate ? cinv.fireDate.toDate() : cinv.fireDate);
|
|
556
|
+
job.emit('run');
|
|
557
|
+
|
|
558
|
+
if (promisesSupported && result instanceof Promise) {
|
|
559
|
+
result.catch(function (err) {
|
|
560
|
+
job.emit('error', err);
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
} catch (err) {
|
|
564
|
+
job.emit('error', err);
|
|
565
|
+
}
|
|
554
566
|
});
|
|
555
567
|
}
|
|
556
568
|
}
|
package/package.json
CHANGED
|
@@ -1,38 +1,52 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-schedule",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"description": "A cron-like and not-cron-like job scheduler for Node.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"schedule",
|
|
7
7
|
"task",
|
|
8
8
|
"job",
|
|
9
|
-
"cron"
|
|
9
|
+
"cron",
|
|
10
|
+
"in-memory"
|
|
10
11
|
],
|
|
11
12
|
"license": "MIT",
|
|
12
13
|
"main": "./lib/schedule.js",
|
|
13
14
|
"scripts": {
|
|
14
15
|
"test": "nodeunit",
|
|
15
|
-
"
|
|
16
|
+
"test:coverage": "istanbul cover ./node_modules/.bin/nodeunit test",
|
|
17
|
+
"test:coverage-win": "istanbul cover ./node_modules/nodeunit/bin/nodeunit test",
|
|
18
|
+
"lint": "eslint lib test",
|
|
19
|
+
"lint:fix": "eslint --fix lib test"
|
|
16
20
|
},
|
|
17
21
|
"author": {
|
|
18
22
|
"name": "Matt Patenaude",
|
|
19
23
|
"email": "matt@mattpatenaude.com",
|
|
20
24
|
"url": "http://mattpatenaude.com"
|
|
21
25
|
},
|
|
26
|
+
"contributors": [
|
|
27
|
+
{
|
|
28
|
+
"name": "Igor Savin",
|
|
29
|
+
"email": "kibertoad@gmail.com"
|
|
30
|
+
}
|
|
31
|
+
],
|
|
22
32
|
"repository": {
|
|
23
33
|
"type": "git",
|
|
24
34
|
"url": "https://github.com/node-schedule/node-schedule.git"
|
|
25
35
|
},
|
|
26
36
|
"dependencies": {
|
|
27
|
-
"cron-parser": "^2.
|
|
37
|
+
"cron-parser": "^2.18.0",
|
|
28
38
|
"long-timeout": "0.1.1",
|
|
29
|
-
"sorted-array-functions": "^1.
|
|
39
|
+
"sorted-array-functions": "^1.3.0"
|
|
30
40
|
},
|
|
31
41
|
"devDependencies": {
|
|
32
|
-
"
|
|
33
|
-
"eslint": "^3.19.0",
|
|
42
|
+
"eslint": "^7.18.0",
|
|
34
43
|
"istanbul": "^0.4.5",
|
|
35
|
-
"nodeunit": "
|
|
36
|
-
"sinon": "^
|
|
37
|
-
}
|
|
44
|
+
"nodeunit": "~0.10.2",
|
|
45
|
+
"sinon": "^2.4.1"
|
|
46
|
+
},
|
|
47
|
+
"files": [
|
|
48
|
+
"README.md",
|
|
49
|
+
"LICENSE",
|
|
50
|
+
"lib/*"
|
|
51
|
+
]
|
|
38
52
|
}
|
package/.eslintrc
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"env": {
|
|
3
|
-
"node": true,
|
|
4
|
-
"es6": true
|
|
5
|
-
},
|
|
6
|
-
"rules": {
|
|
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"
|
|
16
|
-
}
|
|
17
|
-
}
|
package/.travis.yml
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
language: node_js
|
|
2
|
-
node_js:
|
|
3
|
-
- "0.12"
|
|
4
|
-
- "0.10"
|
|
5
|
-
- "4"
|
|
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
|
|
15
|
-
script: ./node_modules/.bin/istanbul cover ./node_modules/.bin/nodeunit test && cat ./coverage/lcov.info | ./node_modules/.bin/coveralls && rm -rf ./coverage
|
package/CONTRIBUTING.md
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
## Rules
|
|
2
|
-
1. **No `--force` pushes** or modifying the git history in any way
|
|
3
|
-
2. Follow existing code style
|
|
4
|
-
3. Pull requests with tests are much more likely to be accepted
|
|
5
|
-
4. Follow the guidelines below
|
|
6
|
-
|
|
7
|
-
## Bugfix or Feature?
|
|
8
|
-
|
|
9
|
-
This project uses the [gitflow workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow). Simply put, you need to decide if your contribution will be a bug fix that could be released as a patch, or a feature that will end up being a minor or major release.
|
|
10
|
-
|
|
11
|
-
### Found a bug that can be fixed without affecting the API?
|
|
12
|
-
|
|
13
|
-
1. **Fork** this repo
|
|
14
|
-
2. Create a new branch from `master` to work in
|
|
15
|
-
3. **Add tests** if needed
|
|
16
|
-
4. Make sure your code **lints** by running `npm run lint`
|
|
17
|
-
5. Make sure your code **passes tests** by running `npm test`
|
|
18
|
-
6. Submit a **pull request** against the `master` branch
|
|
19
|
-
|
|
20
|
-
### New feature or anything that would result in a change to the API?
|
|
21
|
-
|
|
22
|
-
1. **Fork** this repo
|
|
23
|
-
2. Create a new branch from `develop` to work in
|
|
24
|
-
3. **Add tests** to as needed
|
|
25
|
-
4. Make sure your code **lints** by running `npm run lint`
|
|
26
|
-
5. Make sure your code **passes tests** by running `npm test`
|
|
27
|
-
6. Submit a **pull request** against the `develop` branch
|
|
28
|
-
|
|
29
|
-
## Releases
|
|
30
|
-
|
|
31
|
-
Declaring formal releases remains the prerogative of the project maintainer.
|
package/test/.eslintrc
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var schedule = require('../lib/schedule');
|
|
4
|
-
|
|
5
|
-
module.exports = {
|
|
6
|
-
'Cancel Long Running Job': {
|
|
7
|
-
'should work even when recurring jobs are to be run on the past': function (test) {
|
|
8
|
-
var ok = true;
|
|
9
|
-
var job = schedule.scheduleJob('*/1 * * * * *', function () {
|
|
10
|
-
test.ok(ok);
|
|
11
|
-
var time = Date.now();
|
|
12
|
-
while (ok && (Date.now() - time < 2000)) {
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
test.ok(job);
|
|
17
|
-
setTimeout(function () {
|
|
18
|
-
job.cancel();
|
|
19
|
-
test.done();
|
|
20
|
-
ok = false;
|
|
21
|
-
}, 2100);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
};
|