croner 9.0.0-dev.5 → 9.0.0-dev.7
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/dist/croner.cjs +1 -1189
- package/dist/croner.js +1 -1159
- package/dist/croner.umd.js +1 -1183
- package/package.json +3 -3
package/dist/croner.cjs
CHANGED
|
@@ -1,1189 +1 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
-
var __export = (target, all) => {
|
|
6
|
-
for (var name in all)
|
|
7
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
-
};
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
-
for (let key of __getOwnPropNames(from))
|
|
12
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
-
}
|
|
15
|
-
return to;
|
|
16
|
-
};
|
|
17
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
-
|
|
19
|
-
// src/croner.ts
|
|
20
|
-
var croner_exports = {};
|
|
21
|
-
__export(croner_exports, {
|
|
22
|
-
Cron: () => Cron,
|
|
23
|
-
CronDate: () => CronDate,
|
|
24
|
-
CronOptions: () => CronOptions,
|
|
25
|
-
CronPattern: () => CronPattern,
|
|
26
|
-
default: () => croner_default,
|
|
27
|
-
scheduledJobs: () => scheduledJobs
|
|
28
|
-
});
|
|
29
|
-
module.exports = __toCommonJS(croner_exports);
|
|
30
|
-
|
|
31
|
-
// src/helpers/minitz.ts
|
|
32
|
-
function minitz(y, m, d, h, i, s, tz, throwOnInvalid) {
|
|
33
|
-
return minitz.fromTZ(minitz.tp(y, m, d, h, i, s, tz), throwOnInvalid);
|
|
34
|
-
}
|
|
35
|
-
minitz.fromTZISO = (localTimeStr, tz, throwOnInvalid) => {
|
|
36
|
-
return minitz.fromTZ(parseISOLocal(localTimeStr, tz), throwOnInvalid);
|
|
37
|
-
};
|
|
38
|
-
minitz.fromTZ = function(tp, throwOnInvalid) {
|
|
39
|
-
const inDate = new Date(Date.UTC(
|
|
40
|
-
tp.y,
|
|
41
|
-
tp.m - 1,
|
|
42
|
-
tp.d,
|
|
43
|
-
tp.h,
|
|
44
|
-
tp.i,
|
|
45
|
-
tp.s
|
|
46
|
-
)), offset = getTimezoneOffset(tp.tz, inDate), dateGuess = new Date(inDate.getTime() - offset), dateOffsGuess = getTimezoneOffset(tp.tz, dateGuess);
|
|
47
|
-
if (dateOffsGuess - offset === 0) {
|
|
48
|
-
return dateGuess;
|
|
49
|
-
} else {
|
|
50
|
-
const dateGuess2 = new Date(inDate.getTime() - dateOffsGuess), dateOffsGuess2 = getTimezoneOffset(tp.tz, dateGuess2);
|
|
51
|
-
if (dateOffsGuess2 - dateOffsGuess === 0) {
|
|
52
|
-
return dateGuess2;
|
|
53
|
-
} else if (!throwOnInvalid && dateOffsGuess2 - dateOffsGuess > 0) {
|
|
54
|
-
return dateGuess2;
|
|
55
|
-
} else if (!throwOnInvalid) {
|
|
56
|
-
return dateGuess;
|
|
57
|
-
} else {
|
|
58
|
-
throw new Error("Invalid date passed to fromTZ()");
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
minitz.toTZ = function(d, tzStr) {
|
|
63
|
-
const localDateString = d.toLocaleString("en-US", { timeZone: tzStr }).replace(/[\u202f]/, " ");
|
|
64
|
-
const td = new Date(localDateString);
|
|
65
|
-
return {
|
|
66
|
-
y: td.getFullYear(),
|
|
67
|
-
m: td.getMonth() + 1,
|
|
68
|
-
d: td.getDate(),
|
|
69
|
-
h: td.getHours(),
|
|
70
|
-
i: td.getMinutes(),
|
|
71
|
-
s: td.getSeconds(),
|
|
72
|
-
tz: tzStr
|
|
73
|
-
};
|
|
74
|
-
};
|
|
75
|
-
minitz.tp = (y, m, d, h, i, s, tz) => {
|
|
76
|
-
return { y, m, d, h, i, s, tz };
|
|
77
|
-
};
|
|
78
|
-
function getTimezoneOffset(timeZone, date = /* @__PURE__ */ new Date()) {
|
|
79
|
-
const tz = date.toLocaleString("en-US", { timeZone, timeZoneName: "shortOffset" }).split(" ").slice(-1)[0];
|
|
80
|
-
const dateString = date.toLocaleString("en-US").replace(/[\u202f]/, " ");
|
|
81
|
-
return Date.parse(`${dateString} GMT`) - Date.parse(`${dateString} ${tz}`);
|
|
82
|
-
}
|
|
83
|
-
function parseISOLocal(dtStr, tz) {
|
|
84
|
-
const pd = new Date(Date.parse(dtStr));
|
|
85
|
-
if (isNaN(pd)) {
|
|
86
|
-
throw new Error("minitz: Invalid ISO8601 passed to parser.");
|
|
87
|
-
}
|
|
88
|
-
const stringEnd = dtStr.substring(9);
|
|
89
|
-
if (dtStr.includes("Z") || stringEnd.includes("-") || stringEnd.includes("+")) {
|
|
90
|
-
return minitz.tp(
|
|
91
|
-
pd.getUTCFullYear(),
|
|
92
|
-
pd.getUTCMonth() + 1,
|
|
93
|
-
pd.getUTCDate(),
|
|
94
|
-
pd.getUTCHours(),
|
|
95
|
-
pd.getUTCMinutes(),
|
|
96
|
-
pd.getUTCSeconds(),
|
|
97
|
-
"Etc/UTC"
|
|
98
|
-
);
|
|
99
|
-
} else {
|
|
100
|
-
return minitz.tp(
|
|
101
|
-
pd.getFullYear(),
|
|
102
|
-
pd.getMonth() + 1,
|
|
103
|
-
pd.getDate(),
|
|
104
|
-
pd.getHours(),
|
|
105
|
-
pd.getMinutes(),
|
|
106
|
-
pd.getSeconds(),
|
|
107
|
-
tz
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
minitz.minitz = minitz;
|
|
112
|
-
|
|
113
|
-
// src/pattern.ts
|
|
114
|
-
var LAST_OCCURRENCE = 32;
|
|
115
|
-
var ANY_OCCURRENCE = 1 | 2 | 4 | 8 | 16 | LAST_OCCURRENCE;
|
|
116
|
-
var OCCURRENCE_BITMASKS = [1, 2, 4, 8, 16];
|
|
117
|
-
var CronPattern = class {
|
|
118
|
-
pattern;
|
|
119
|
-
timezone;
|
|
120
|
-
second;
|
|
121
|
-
minute;
|
|
122
|
-
hour;
|
|
123
|
-
day;
|
|
124
|
-
month;
|
|
125
|
-
dayOfWeek;
|
|
126
|
-
lastDayOfMonth;
|
|
127
|
-
starDOM;
|
|
128
|
-
starDOW;
|
|
129
|
-
constructor(pattern, timezone) {
|
|
130
|
-
this.pattern = pattern;
|
|
131
|
-
this.timezone = timezone;
|
|
132
|
-
this.second = Array(60).fill(0);
|
|
133
|
-
this.minute = Array(60).fill(0);
|
|
134
|
-
this.hour = Array(24).fill(0);
|
|
135
|
-
this.day = Array(31).fill(0);
|
|
136
|
-
this.month = Array(12).fill(0);
|
|
137
|
-
this.dayOfWeek = Array(7).fill(0);
|
|
138
|
-
this.lastDayOfMonth = false;
|
|
139
|
-
this.starDOM = false;
|
|
140
|
-
this.starDOW = false;
|
|
141
|
-
this.parse();
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Parse current pattern, will throw on any type of failure
|
|
145
|
-
* @private
|
|
146
|
-
*/
|
|
147
|
-
parse() {
|
|
148
|
-
if (!(typeof this.pattern === "string" || this.pattern instanceof String)) {
|
|
149
|
-
throw new TypeError("CronPattern: Pattern has to be of type string.");
|
|
150
|
-
}
|
|
151
|
-
if (this.pattern.indexOf("@") >= 0) this.pattern = this.handleNicknames(this.pattern).trim();
|
|
152
|
-
const parts = this.pattern.replace(/\s+/g, " ").split(" ");
|
|
153
|
-
if (parts.length < 5 || parts.length > 6) {
|
|
154
|
-
throw new TypeError(
|
|
155
|
-
"CronPattern: invalid configuration format ('" + this.pattern + "'), exactly five or six space separated parts are required."
|
|
156
|
-
);
|
|
157
|
-
}
|
|
158
|
-
if (parts.length === 5) {
|
|
159
|
-
parts.unshift("0");
|
|
160
|
-
}
|
|
161
|
-
if (parts[3].indexOf("L") >= 0) {
|
|
162
|
-
parts[3] = parts[3].replace("L", "");
|
|
163
|
-
this.lastDayOfMonth = true;
|
|
164
|
-
}
|
|
165
|
-
if (parts[3] == "*") {
|
|
166
|
-
this.starDOM = true;
|
|
167
|
-
}
|
|
168
|
-
if (parts[4].length >= 3) parts[4] = this.replaceAlphaMonths(parts[4]);
|
|
169
|
-
if (parts[5].length >= 3) parts[5] = this.replaceAlphaDays(parts[5]);
|
|
170
|
-
if (parts[5] == "*") {
|
|
171
|
-
this.starDOW = true;
|
|
172
|
-
}
|
|
173
|
-
if (this.pattern.indexOf("?") >= 0) {
|
|
174
|
-
const initDate = new CronDate(/* @__PURE__ */ new Date(), this.timezone).getDate(true);
|
|
175
|
-
parts[0] = parts[0].replace("?", initDate.getSeconds().toString());
|
|
176
|
-
parts[1] = parts[1].replace("?", initDate.getMinutes().toString());
|
|
177
|
-
parts[2] = parts[2].replace("?", initDate.getHours().toString());
|
|
178
|
-
if (!this.starDOM) parts[3] = parts[3].replace("?", initDate.getDate().toString());
|
|
179
|
-
parts[4] = parts[4].replace("?", (initDate.getMonth() + 1).toString());
|
|
180
|
-
if (!this.starDOW) parts[5] = parts[5].replace("?", initDate.getDay().toString());
|
|
181
|
-
}
|
|
182
|
-
this.throwAtIllegalCharacters(parts);
|
|
183
|
-
this.partToArray("second", parts[0], 0, 1);
|
|
184
|
-
this.partToArray("minute", parts[1], 0, 1);
|
|
185
|
-
this.partToArray("hour", parts[2], 0, 1);
|
|
186
|
-
this.partToArray("day", parts[3], -1, 1);
|
|
187
|
-
this.partToArray("month", parts[4], -1, 1);
|
|
188
|
-
this.partToArray("dayOfWeek", parts[5], 0, ANY_OCCURRENCE);
|
|
189
|
-
if (this.dayOfWeek[7]) {
|
|
190
|
-
this.dayOfWeek[0] = this.dayOfWeek[7];
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
/**
|
|
194
|
-
* Convert current part (seconds/minutes etc) to an array of 1 or 0 depending on if the part is about to trigger a run or not.
|
|
195
|
-
*/
|
|
196
|
-
partToArray(type, conf, valueIndexOffset, defaultValue) {
|
|
197
|
-
const arr = this[type];
|
|
198
|
-
const lastDayOfMonth = type === "day" && this.lastDayOfMonth;
|
|
199
|
-
if (conf === "" && !lastDayOfMonth) {
|
|
200
|
-
throw new TypeError(
|
|
201
|
-
"CronPattern: configuration entry " + type + " (" + conf + ") is empty, check for trailing spaces."
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
if (conf === "*") return arr.fill(defaultValue);
|
|
205
|
-
const split = conf.split(",");
|
|
206
|
-
if (split.length > 1) {
|
|
207
|
-
for (let i = 0; i < split.length; i++) {
|
|
208
|
-
this.partToArray(type, split[i], valueIndexOffset, defaultValue);
|
|
209
|
-
}
|
|
210
|
-
} else if (conf.indexOf("-") !== -1 && conf.indexOf("/") !== -1) {
|
|
211
|
-
this.handleRangeWithStepping(conf, type, valueIndexOffset, defaultValue);
|
|
212
|
-
} else if (conf.indexOf("-") !== -1) {
|
|
213
|
-
this.handleRange(conf, type, valueIndexOffset, defaultValue);
|
|
214
|
-
} else if (conf.indexOf("/") !== -1) {
|
|
215
|
-
this.handleStepping(conf, type, valueIndexOffset, defaultValue);
|
|
216
|
-
} else if (conf !== "") {
|
|
217
|
-
this.handleNumber(conf, type, valueIndexOffset, defaultValue);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* After converting JAN-DEC, SUN-SAT only 0-9 * , / - are allowed, throw if anything else pops up
|
|
222
|
-
* @throws On error
|
|
223
|
-
*/
|
|
224
|
-
throwAtIllegalCharacters(parts) {
|
|
225
|
-
for (let i = 0; i < parts.length; i++) {
|
|
226
|
-
const reValidCron = i === 5 ? /[^/*0-9,\-#L]+/ : /[^/*0-9,-]+/;
|
|
227
|
-
if (reValidCron.test(parts[i])) {
|
|
228
|
-
throw new TypeError(
|
|
229
|
-
"CronPattern: configuration entry " + i + " (" + parts[i] + ") contains illegal characters."
|
|
230
|
-
);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* Nothing but a number left, handle that
|
|
236
|
-
*
|
|
237
|
-
* @param conf Current part, expected to be a number, as a string
|
|
238
|
-
* @param type One of "seconds", "minutes" etc
|
|
239
|
-
* @param valueIndexOffset -1 for day of month, and month, as they start at 1. 0 for seconds, hours, minutes
|
|
240
|
-
*/
|
|
241
|
-
handleNumber(conf, type, valueIndexOffset, defaultValue) {
|
|
242
|
-
const result = this.extractNth(conf, type);
|
|
243
|
-
const i = parseInt(result[0], 10) + valueIndexOffset;
|
|
244
|
-
if (isNaN(i)) {
|
|
245
|
-
throw new TypeError("CronPattern: " + type + " is not a number: '" + conf + "'");
|
|
246
|
-
}
|
|
247
|
-
this.setPart(type, i, result[1] || defaultValue);
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* Set a specific value for a specific part of the CronPattern.
|
|
251
|
-
*
|
|
252
|
-
* @param part The specific part of the CronPattern, e.g., "second", "minute", etc.
|
|
253
|
-
* @param index The index to modify.
|
|
254
|
-
* @param value The value to set, typically 0 or 1, in case of "nth weekday" it will be the weekday number used for further processing
|
|
255
|
-
*/
|
|
256
|
-
setPart(part, index, value) {
|
|
257
|
-
if (!Object.prototype.hasOwnProperty.call(this, part)) {
|
|
258
|
-
throw new TypeError("CronPattern: Invalid part specified: " + part);
|
|
259
|
-
}
|
|
260
|
-
if (part === "dayOfWeek") {
|
|
261
|
-
if (index === 7) index = 0;
|
|
262
|
-
if (index < 0 || index > 6) {
|
|
263
|
-
throw new RangeError("CronPattern: Invalid value for dayOfWeek: " + index);
|
|
264
|
-
}
|
|
265
|
-
this.setNthWeekdayOfMonth(index, value);
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
if (part === "second" || part === "minute") {
|
|
269
|
-
if (index < 0 || index >= 60) {
|
|
270
|
-
throw new RangeError("CronPattern: Invalid value for " + part + ": " + index);
|
|
271
|
-
}
|
|
272
|
-
} else if (part === "hour") {
|
|
273
|
-
if (index < 0 || index >= 24) {
|
|
274
|
-
throw new RangeError("CronPattern: Invalid value for " + part + ": " + index);
|
|
275
|
-
}
|
|
276
|
-
} else if (part === "day") {
|
|
277
|
-
if (index < 0 || index >= 31) {
|
|
278
|
-
throw new RangeError("CronPattern: Invalid value for " + part + ": " + index);
|
|
279
|
-
}
|
|
280
|
-
} else if (part === "month") {
|
|
281
|
-
if (index < 0 || index >= 12) {
|
|
282
|
-
throw new RangeError("CronPattern: Invalid value for " + part + ": " + index);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
this[part][index] = value;
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* Take care of ranges with stepping (e.g. 3-23/5)
|
|
289
|
-
*
|
|
290
|
-
* @param conf Current part, expected to be a string like 3-23/5
|
|
291
|
-
* @param type One of "seconds", "minutes" etc
|
|
292
|
-
* @param valueIndexOffset -1 for day of month, and month, as they start at 1. 0 for seconds, hours, minutes
|
|
293
|
-
*/
|
|
294
|
-
handleRangeWithStepping(conf, type, valueIndexOffset, defaultValue) {
|
|
295
|
-
const result = this.extractNth(conf, type);
|
|
296
|
-
const matches = result[0].match(/^(\d+)-(\d+)\/(\d+)$/);
|
|
297
|
-
if (matches === null) {
|
|
298
|
-
throw new TypeError("CronPattern: Syntax error, illegal range with stepping: '" + conf + "'");
|
|
299
|
-
}
|
|
300
|
-
const [, lowerMatch, upperMatch, stepMatch] = matches;
|
|
301
|
-
const lower = parseInt(lowerMatch, 10) + valueIndexOffset;
|
|
302
|
-
const upper = parseInt(upperMatch, 10) + valueIndexOffset;
|
|
303
|
-
const steps = parseInt(stepMatch, 10);
|
|
304
|
-
if (isNaN(lower)) throw new TypeError("CronPattern: Syntax error, illegal lower range (NaN)");
|
|
305
|
-
if (isNaN(upper)) throw new TypeError("CronPattern: Syntax error, illegal upper range (NaN)");
|
|
306
|
-
if (isNaN(steps)) throw new TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");
|
|
307
|
-
if (steps === 0) throw new TypeError("CronPattern: Syntax error, illegal stepping: 0");
|
|
308
|
-
if (steps > this[type].length) {
|
|
309
|
-
throw new TypeError(
|
|
310
|
-
"CronPattern: Syntax error, steps cannot be greater than maximum value of part (" + this[type].length + ")"
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
if (lower > upper) {
|
|
314
|
-
throw new TypeError("CronPattern: From value is larger than to value: '" + conf + "'");
|
|
315
|
-
}
|
|
316
|
-
for (let i = lower; i <= upper; i += steps) {
|
|
317
|
-
this.setPart(type, i, result[1] || defaultValue);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
/*
|
|
321
|
-
* Break out nth weekday (#) if exists
|
|
322
|
-
* - only allow if type os dayOfWeek
|
|
323
|
-
*/
|
|
324
|
-
extractNth(conf, type) {
|
|
325
|
-
let rest = conf;
|
|
326
|
-
let nth;
|
|
327
|
-
if (rest.includes("#")) {
|
|
328
|
-
if (type !== "dayOfWeek") {
|
|
329
|
-
throw new Error("CronPattern: nth (#) only allowed in day-of-week field");
|
|
330
|
-
}
|
|
331
|
-
nth = rest.split("#")[1];
|
|
332
|
-
rest = rest.split("#")[0];
|
|
333
|
-
}
|
|
334
|
-
return [rest, nth];
|
|
335
|
-
}
|
|
336
|
-
/**
|
|
337
|
-
* Take care of ranges (e.g. 1-20)
|
|
338
|
-
*
|
|
339
|
-
* @param conf - Current part, expected to be a string like 1-20, can contain L for last
|
|
340
|
-
* @param type - One of "seconds", "minutes" etc
|
|
341
|
-
* @param valueIndexOffset - -1 for day of month, and month, as they start at 1. 0 for seconds, hours, minutes
|
|
342
|
-
*/
|
|
343
|
-
handleRange(conf, type, valueIndexOffset, defaultValue) {
|
|
344
|
-
const result = this.extractNth(conf, type);
|
|
345
|
-
const split = result[0].split("-");
|
|
346
|
-
if (split.length !== 2) {
|
|
347
|
-
throw new TypeError("CronPattern: Syntax error, illegal range: '" + conf + "'");
|
|
348
|
-
}
|
|
349
|
-
const lower = parseInt(split[0], 10) + valueIndexOffset, upper = parseInt(split[1], 10) + valueIndexOffset;
|
|
350
|
-
if (isNaN(lower)) {
|
|
351
|
-
throw new TypeError("CronPattern: Syntax error, illegal lower range (NaN)");
|
|
352
|
-
} else if (isNaN(upper)) {
|
|
353
|
-
throw new TypeError("CronPattern: Syntax error, illegal upper range (NaN)");
|
|
354
|
-
}
|
|
355
|
-
if (lower > upper) {
|
|
356
|
-
throw new TypeError("CronPattern: From value is larger than to value: '" + conf + "'");
|
|
357
|
-
}
|
|
358
|
-
for (let i = lower; i <= upper; i++) {
|
|
359
|
-
this.setPart(type, i, result[1] || defaultValue);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
/**
|
|
363
|
-
* Handle stepping (e.g. * / 14)
|
|
364
|
-
*
|
|
365
|
-
* @param conf Current part, expected to be a string like * /20 (without the space)
|
|
366
|
-
* @param type One of "seconds", "minutes" etc
|
|
367
|
-
*/
|
|
368
|
-
handleStepping(conf, type, valueIndexOffset, defaultValue) {
|
|
369
|
-
const result = this.extractNth(conf, type);
|
|
370
|
-
const split = result[0].split("/");
|
|
371
|
-
if (split.length !== 2) {
|
|
372
|
-
throw new TypeError("CronPattern: Syntax error, illegal stepping: '" + conf + "'");
|
|
373
|
-
}
|
|
374
|
-
if (split[0] === "") {
|
|
375
|
-
split[0] = "*";
|
|
376
|
-
}
|
|
377
|
-
let start = 0;
|
|
378
|
-
if (split[0] !== "*") {
|
|
379
|
-
start = parseInt(split[0], 10) + valueIndexOffset;
|
|
380
|
-
}
|
|
381
|
-
const steps = parseInt(split[1], 10);
|
|
382
|
-
if (isNaN(steps)) throw new TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");
|
|
383
|
-
if (steps === 0) throw new TypeError("CronPattern: Syntax error, illegal stepping: 0");
|
|
384
|
-
if (steps > this[type].length) {
|
|
385
|
-
throw new TypeError(
|
|
386
|
-
"CronPattern: Syntax error, max steps for part is (" + this[type].length + ")"
|
|
387
|
-
);
|
|
388
|
-
}
|
|
389
|
-
for (let i = start; i < this[type].length; i += steps) {
|
|
390
|
-
this.setPart(type, i, result[1] || defaultValue);
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
/**
|
|
394
|
-
* Replace day name with day numbers
|
|
395
|
-
*
|
|
396
|
-
* @param conf Current part, expected to be a string that might contain sun,mon etc.
|
|
397
|
-
*
|
|
398
|
-
* @returns Conf with 0 instead of sun etc.
|
|
399
|
-
*/
|
|
400
|
-
replaceAlphaDays(conf) {
|
|
401
|
-
return conf.replace(/-sun/gi, "-7").replace(/sun/gi, "0").replace(/mon/gi, "1").replace(/tue/gi, "2").replace(/wed/gi, "3").replace(/thu/gi, "4").replace(/fri/gi, "5").replace(/sat/gi, "6");
|
|
402
|
-
}
|
|
403
|
-
/**
|
|
404
|
-
* Replace month name with month numbers
|
|
405
|
-
*
|
|
406
|
-
* @param conf Current part, expected to be a string that might contain jan,feb etc.
|
|
407
|
-
*
|
|
408
|
-
* @returns conf with 0 instead of sun etc.
|
|
409
|
-
*/
|
|
410
|
-
replaceAlphaMonths(conf) {
|
|
411
|
-
return conf.replace(/jan/gi, "1").replace(/feb/gi, "2").replace(/mar/gi, "3").replace(/apr/gi, "4").replace(/may/gi, "5").replace(/jun/gi, "6").replace(/jul/gi, "7").replace(/aug/gi, "8").replace(/sep/gi, "9").replace(/oct/gi, "10").replace(/nov/gi, "11").replace(/dec/gi, "12");
|
|
412
|
-
}
|
|
413
|
-
/**
|
|
414
|
-
* Replace nicknames with actual cron patterns
|
|
415
|
-
*
|
|
416
|
-
* @param pattern Pattern, may contain nicknames, or not
|
|
417
|
-
*
|
|
418
|
-
* @returns Pattern, with cron expression insted of nicknames
|
|
419
|
-
*/
|
|
420
|
-
handleNicknames(pattern) {
|
|
421
|
-
const cleanPattern = pattern.trim().toLowerCase();
|
|
422
|
-
if (cleanPattern === "@yearly" || cleanPattern === "@annually") {
|
|
423
|
-
return "0 0 1 1 *";
|
|
424
|
-
} else if (cleanPattern === "@monthly") {
|
|
425
|
-
return "0 0 1 * *";
|
|
426
|
-
} else if (cleanPattern === "@weekly") {
|
|
427
|
-
return "0 0 * * 0";
|
|
428
|
-
} else if (cleanPattern === "@daily") {
|
|
429
|
-
return "0 0 * * *";
|
|
430
|
-
} else if (cleanPattern === "@hourly") {
|
|
431
|
-
return "0 * * * *";
|
|
432
|
-
} else {
|
|
433
|
-
return pattern;
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
/**
|
|
437
|
-
* Handle the nth weekday of the month logic using hash sign (e.g. FRI#2 for the second Friday of the month)
|
|
438
|
-
*
|
|
439
|
-
* @param index Weekday, example: 5 for friday
|
|
440
|
-
* @param nthWeekday bitmask, 2 (0x00010) for 2nd friday, 31 (ANY_OCCURRENCE, 0b100000) for any day
|
|
441
|
-
*/
|
|
442
|
-
setNthWeekdayOfMonth(index, nthWeekday) {
|
|
443
|
-
if (typeof nthWeekday !== "number" && nthWeekday === "L") {
|
|
444
|
-
this["dayOfWeek"][index] = this["dayOfWeek"][index] | LAST_OCCURRENCE;
|
|
445
|
-
} else if (nthWeekday === ANY_OCCURRENCE) {
|
|
446
|
-
this["dayOfWeek"][index] = ANY_OCCURRENCE;
|
|
447
|
-
} else if (nthWeekday < 6 && nthWeekday > 0) {
|
|
448
|
-
this["dayOfWeek"][index] = this["dayOfWeek"][index] | OCCURRENCE_BITMASKS[nthWeekday - 1];
|
|
449
|
-
} else {
|
|
450
|
-
throw new TypeError(
|
|
451
|
-
`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${nthWeekday}, Type: ${typeof nthWeekday}`
|
|
452
|
-
);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
};
|
|
456
|
-
|
|
457
|
-
// src/date.ts
|
|
458
|
-
var DaysOfMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
459
|
-
var RecursionSteps = [
|
|
460
|
-
["month", "year", 0],
|
|
461
|
-
["day", "month", -1],
|
|
462
|
-
["hour", "day", 0],
|
|
463
|
-
["minute", "hour", 0],
|
|
464
|
-
["second", "minute", 0]
|
|
465
|
-
];
|
|
466
|
-
var CronDate = class _CronDate {
|
|
467
|
-
tz;
|
|
468
|
-
/**
|
|
469
|
-
* Current milliseconds
|
|
470
|
-
* @type {number}
|
|
471
|
-
*/
|
|
472
|
-
ms;
|
|
473
|
-
/**
|
|
474
|
-
* Current second (0-59), in local time or target timezone specified by `this.tz`
|
|
475
|
-
* @type {number}
|
|
476
|
-
*/
|
|
477
|
-
second;
|
|
478
|
-
/**
|
|
479
|
-
* Current minute (0-59), in local time or target timezone specified by `this.tz`
|
|
480
|
-
* @type {number}
|
|
481
|
-
*/
|
|
482
|
-
minute;
|
|
483
|
-
/**
|
|
484
|
-
* Current hour (0-23), in local time or target timezone specified by `this.tz`
|
|
485
|
-
* @type {number}
|
|
486
|
-
*/
|
|
487
|
-
hour;
|
|
488
|
-
/**
|
|
489
|
-
* Current day (1-31), in local time or target timezone specified by `this.tz`
|
|
490
|
-
* @type {number}
|
|
491
|
-
*/
|
|
492
|
-
day;
|
|
493
|
-
/**
|
|
494
|
-
* Current month (1-12), in local time or target timezone specified by `this.tz`
|
|
495
|
-
* @type {number}
|
|
496
|
-
*/
|
|
497
|
-
month;
|
|
498
|
-
/**
|
|
499
|
-
* Current full year, in local time or target timezone specified by `this.tz`
|
|
500
|
-
*/
|
|
501
|
-
year;
|
|
502
|
-
constructor(d, tz) {
|
|
503
|
-
this.tz = tz;
|
|
504
|
-
if (d && d instanceof Date) {
|
|
505
|
-
if (!isNaN(d)) {
|
|
506
|
-
this.fromDate(d);
|
|
507
|
-
} else {
|
|
508
|
-
throw new TypeError("CronDate: Invalid date passed to CronDate constructor");
|
|
509
|
-
}
|
|
510
|
-
} else if (d === void 0) {
|
|
511
|
-
this.fromDate(/* @__PURE__ */ new Date());
|
|
512
|
-
} else if (d && typeof d === "string") {
|
|
513
|
-
this.fromString(d);
|
|
514
|
-
} else if (d instanceof _CronDate) {
|
|
515
|
-
this.fromCronDate(d);
|
|
516
|
-
} else {
|
|
517
|
-
throw new TypeError(
|
|
518
|
-
"CronDate: Invalid type (" + typeof d + ") passed to CronDate constructor"
|
|
519
|
-
);
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
/**
|
|
523
|
-
* Check if the given date is the nth occurrence of a weekday in its month.
|
|
524
|
-
*
|
|
525
|
-
* @param year The year.
|
|
526
|
-
* @param month The month (0 for January, 11 for December).
|
|
527
|
-
* @param day The day of the month.
|
|
528
|
-
* @param nth The nth occurrence (bitmask).
|
|
529
|
-
*
|
|
530
|
-
* @return True if the date is the nth occurrence of its weekday, false otherwise.
|
|
531
|
-
*/
|
|
532
|
-
isNthWeekdayOfMonth(year, month, day, nth) {
|
|
533
|
-
const date = new Date(Date.UTC(year, month, day));
|
|
534
|
-
const weekday = date.getUTCDay();
|
|
535
|
-
let count = 0;
|
|
536
|
-
for (let d = 1; d <= day; d++) {
|
|
537
|
-
if (new Date(Date.UTC(year, month, d)).getUTCDay() === weekday) {
|
|
538
|
-
count++;
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
if (nth & ANY_OCCURRENCE && OCCURRENCE_BITMASKS[count - 1] & nth) {
|
|
542
|
-
return true;
|
|
543
|
-
}
|
|
544
|
-
if (nth & LAST_OCCURRENCE) {
|
|
545
|
-
const daysInMonth = new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
|
|
546
|
-
for (let d = day + 1; d <= daysInMonth; d++) {
|
|
547
|
-
if (new Date(Date.UTC(year, month, d)).getUTCDay() === weekday) {
|
|
548
|
-
return false;
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
return true;
|
|
552
|
-
}
|
|
553
|
-
return false;
|
|
554
|
-
}
|
|
555
|
-
/**
|
|
556
|
-
* Sets internals using a Date
|
|
557
|
-
*/
|
|
558
|
-
fromDate(inDate) {
|
|
559
|
-
if (this.tz !== void 0) {
|
|
560
|
-
if (typeof this.tz === "number") {
|
|
561
|
-
this.ms = inDate.getUTCMilliseconds();
|
|
562
|
-
this.second = inDate.getUTCSeconds();
|
|
563
|
-
this.minute = inDate.getUTCMinutes() + this.tz;
|
|
564
|
-
this.hour = inDate.getUTCHours();
|
|
565
|
-
this.day = inDate.getUTCDate();
|
|
566
|
-
this.month = inDate.getUTCMonth();
|
|
567
|
-
this.year = inDate.getUTCFullYear();
|
|
568
|
-
this.apply();
|
|
569
|
-
} else {
|
|
570
|
-
const d = minitz.toTZ(inDate, this.tz);
|
|
571
|
-
this.ms = inDate.getMilliseconds();
|
|
572
|
-
this.second = d.s;
|
|
573
|
-
this.minute = d.i;
|
|
574
|
-
this.hour = d.h;
|
|
575
|
-
this.day = d.d;
|
|
576
|
-
this.month = d.m - 1;
|
|
577
|
-
this.year = d.y;
|
|
578
|
-
}
|
|
579
|
-
} else {
|
|
580
|
-
this.ms = inDate.getMilliseconds();
|
|
581
|
-
this.second = inDate.getSeconds();
|
|
582
|
-
this.minute = inDate.getMinutes();
|
|
583
|
-
this.hour = inDate.getHours();
|
|
584
|
-
this.day = inDate.getDate();
|
|
585
|
-
this.month = inDate.getMonth();
|
|
586
|
-
this.year = inDate.getFullYear();
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
/**
|
|
590
|
-
* Sets internals by deep copying another CronDate
|
|
591
|
-
*
|
|
592
|
-
* @param {CronDate} d - Input date
|
|
593
|
-
*/
|
|
594
|
-
fromCronDate(d) {
|
|
595
|
-
this.tz = d.tz;
|
|
596
|
-
this.year = d.year;
|
|
597
|
-
this.month = d.month;
|
|
598
|
-
this.day = d.day;
|
|
599
|
-
this.hour = d.hour;
|
|
600
|
-
this.minute = d.minute;
|
|
601
|
-
this.second = d.second;
|
|
602
|
-
this.ms = d.ms;
|
|
603
|
-
}
|
|
604
|
-
/**
|
|
605
|
-
* Reset internal parameters (seconds, minutes, hours) if any of them have exceeded (or could have exceeded) their normal ranges
|
|
606
|
-
*
|
|
607
|
-
* Will alway return true on february 29th, as that is a date that _could_ be out of bounds
|
|
608
|
-
*/
|
|
609
|
-
apply() {
|
|
610
|
-
if (this.month > 11 || this.day > DaysOfMonth[this.month] || this.hour > 59 || this.minute > 59 || this.second > 59 || this.hour < 0 || this.minute < 0 || this.second < 0) {
|
|
611
|
-
const d = new Date(
|
|
612
|
-
Date.UTC(this.year, this.month, this.day, this.hour, this.minute, this.second, this.ms)
|
|
613
|
-
);
|
|
614
|
-
this.ms = d.getUTCMilliseconds();
|
|
615
|
-
this.second = d.getUTCSeconds();
|
|
616
|
-
this.minute = d.getUTCMinutes();
|
|
617
|
-
this.hour = d.getUTCHours();
|
|
618
|
-
this.day = d.getUTCDate();
|
|
619
|
-
this.month = d.getUTCMonth();
|
|
620
|
-
this.year = d.getUTCFullYear();
|
|
621
|
-
return true;
|
|
622
|
-
} else {
|
|
623
|
-
return false;
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
/**
|
|
627
|
-
* Sets internals by parsing a string
|
|
628
|
-
*/
|
|
629
|
-
fromString(str) {
|
|
630
|
-
if (typeof this.tz === "number") {
|
|
631
|
-
const inDate = minitz.fromTZISO(str);
|
|
632
|
-
this.ms = inDate.getUTCMilliseconds();
|
|
633
|
-
this.second = inDate.getUTCSeconds();
|
|
634
|
-
this.minute = inDate.getUTCMinutes();
|
|
635
|
-
this.hour = inDate.getUTCHours();
|
|
636
|
-
this.day = inDate.getUTCDate();
|
|
637
|
-
this.month = inDate.getUTCMonth();
|
|
638
|
-
this.year = inDate.getUTCFullYear();
|
|
639
|
-
this.apply();
|
|
640
|
-
} else {
|
|
641
|
-
return this.fromDate(minitz.fromTZISO(str, this.tz));
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
/**
|
|
645
|
-
* Find next match of current part
|
|
646
|
-
*/
|
|
647
|
-
findNext(options, target, pattern, offset) {
|
|
648
|
-
const originalTarget = this[target];
|
|
649
|
-
let lastDayOfMonth;
|
|
650
|
-
if (pattern.lastDayOfMonth) {
|
|
651
|
-
if (this.month !== 1) {
|
|
652
|
-
lastDayOfMonth = DaysOfMonth[this.month];
|
|
653
|
-
} else {
|
|
654
|
-
lastDayOfMonth = new Date(Date.UTC(this.year, this.month + 1, 0, 0, 0, 0, 0)).getUTCDate();
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
const fDomWeekDay = !pattern.starDOW && target == "day" ? new Date(Date.UTC(this.year, this.month, 1, 0, 0, 0, 0)).getUTCDay() : void 0;
|
|
658
|
-
for (let i = this[target] + offset; i < pattern[target].length; i++) {
|
|
659
|
-
let match = pattern[target][i];
|
|
660
|
-
if (target === "day" && pattern.lastDayOfMonth && i - offset == lastDayOfMonth) {
|
|
661
|
-
match = 1;
|
|
662
|
-
}
|
|
663
|
-
if (target === "day" && !pattern.starDOW) {
|
|
664
|
-
let dowMatch = pattern.dayOfWeek[(fDomWeekDay + (i - offset - 1)) % 7];
|
|
665
|
-
if (dowMatch && dowMatch & ANY_OCCURRENCE) {
|
|
666
|
-
dowMatch = this.isNthWeekdayOfMonth(this.year, this.month, i - offset, dowMatch) ? 1 : 0;
|
|
667
|
-
} else if (dowMatch) {
|
|
668
|
-
throw new Error(`CronDate: Invalid value for dayOfWeek encountered. ${dowMatch}`);
|
|
669
|
-
}
|
|
670
|
-
if (options.legacyMode && !pattern.starDOM) {
|
|
671
|
-
match = match || dowMatch;
|
|
672
|
-
} else {
|
|
673
|
-
match = match && dowMatch;
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
if (match) {
|
|
677
|
-
this[target] = i - offset;
|
|
678
|
-
return originalTarget !== this[target] ? 2 : 1;
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
return 3;
|
|
682
|
-
}
|
|
683
|
-
/**
|
|
684
|
-
* Increment to next run time recursively
|
|
685
|
-
*
|
|
686
|
-
* This function is currently capped at year 3000. Do you have a reason to go further? Open an issue on GitHub!
|
|
687
|
-
*
|
|
688
|
-
* @param pattern The pattern used to increment current state
|
|
689
|
-
* @param options Cron options used for incrementing
|
|
690
|
-
* @param doing Which part to increment, 0 represent first item of RecursionSteps-array etc.
|
|
691
|
-
* @return Returns itthis for chaining, or null if increment wasnt possible
|
|
692
|
-
*/
|
|
693
|
-
recurse(pattern, options, doing) {
|
|
694
|
-
const res = this.findNext(options, RecursionSteps[doing][0], pattern, RecursionSteps[doing][2]);
|
|
695
|
-
if (res > 1) {
|
|
696
|
-
let resetLevel = doing + 1;
|
|
697
|
-
while (resetLevel < RecursionSteps.length) {
|
|
698
|
-
this[RecursionSteps[resetLevel][0]] = -RecursionSteps[resetLevel][2];
|
|
699
|
-
resetLevel++;
|
|
700
|
-
}
|
|
701
|
-
if (res === 3) {
|
|
702
|
-
this[RecursionSteps[doing][1]]++;
|
|
703
|
-
this[RecursionSteps[doing][0]] = -RecursionSteps[doing][2];
|
|
704
|
-
this.apply();
|
|
705
|
-
return this.recurse(pattern, options, 0);
|
|
706
|
-
} else if (this.apply()) {
|
|
707
|
-
return this.recurse(pattern, options, doing - 1);
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
doing += 1;
|
|
711
|
-
if (doing >= RecursionSteps.length) {
|
|
712
|
-
return this;
|
|
713
|
-
} else if (this.year >= 3e3) {
|
|
714
|
-
return null;
|
|
715
|
-
} else {
|
|
716
|
-
return this.recurse(pattern, options, doing);
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
/**
|
|
720
|
-
* Increment to next run time
|
|
721
|
-
*
|
|
722
|
-
* @param pattern The pattern used to increment current state
|
|
723
|
-
* @param options Cron options used for incrementing
|
|
724
|
-
* @param hasPreviousRun If this run should adhere to minimum interval
|
|
725
|
-
* @return Returns itthis for chaining, or null if increment wasnt possible
|
|
726
|
-
*/
|
|
727
|
-
increment(pattern, options, hasPreviousRun) {
|
|
728
|
-
this.second += options.interval !== void 0 && options.interval > 1 && hasPreviousRun ? options.interval : 1;
|
|
729
|
-
this.ms = 0;
|
|
730
|
-
this.apply();
|
|
731
|
-
return this.recurse(pattern, options, 0);
|
|
732
|
-
}
|
|
733
|
-
/**
|
|
734
|
-
* Convert current state back to a javascript Date()
|
|
735
|
-
*
|
|
736
|
-
* @param internal If this is an internal call
|
|
737
|
-
*/
|
|
738
|
-
getDate(internal) {
|
|
739
|
-
if (internal || this.tz === void 0) {
|
|
740
|
-
return new Date(
|
|
741
|
-
this.year,
|
|
742
|
-
this.month,
|
|
743
|
-
this.day,
|
|
744
|
-
this.hour,
|
|
745
|
-
this.minute,
|
|
746
|
-
this.second,
|
|
747
|
-
this.ms
|
|
748
|
-
);
|
|
749
|
-
} else {
|
|
750
|
-
if (typeof this.tz === "number") {
|
|
751
|
-
return new Date(
|
|
752
|
-
Date.UTC(
|
|
753
|
-
this.year,
|
|
754
|
-
this.month,
|
|
755
|
-
this.day,
|
|
756
|
-
this.hour,
|
|
757
|
-
this.minute - this.tz,
|
|
758
|
-
this.second,
|
|
759
|
-
this.ms
|
|
760
|
-
)
|
|
761
|
-
);
|
|
762
|
-
} else {
|
|
763
|
-
return minitz.fromTZ(
|
|
764
|
-
minitz.tp(
|
|
765
|
-
this.year,
|
|
766
|
-
this.month + 1,
|
|
767
|
-
this.day,
|
|
768
|
-
this.hour,
|
|
769
|
-
this.minute,
|
|
770
|
-
this.second,
|
|
771
|
-
this.tz
|
|
772
|
-
),
|
|
773
|
-
false
|
|
774
|
-
);
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
/**
|
|
779
|
-
* Convert current state back to a javascript Date() and return UTC milliseconds
|
|
780
|
-
*/
|
|
781
|
-
getTime() {
|
|
782
|
-
return this.getDate(false).getTime();
|
|
783
|
-
}
|
|
784
|
-
};
|
|
785
|
-
|
|
786
|
-
// src/options.ts
|
|
787
|
-
function CronOptions(options) {
|
|
788
|
-
if (options === void 0) {
|
|
789
|
-
options = {};
|
|
790
|
-
}
|
|
791
|
-
delete options.name;
|
|
792
|
-
options.legacyMode = options.legacyMode === void 0 ? true : options.legacyMode;
|
|
793
|
-
options.paused = options.paused === void 0 ? false : options.paused;
|
|
794
|
-
options.maxRuns = options.maxRuns === void 0 ? Infinity : options.maxRuns;
|
|
795
|
-
options.catch = options.catch === void 0 ? false : options.catch;
|
|
796
|
-
options.interval = options.interval === void 0 ? 0 : parseInt(options.interval.toString(), 10);
|
|
797
|
-
options.utcOffset = options.utcOffset === void 0 ? void 0 : parseInt(options.utcOffset.toString(), 10);
|
|
798
|
-
options.unref = options.unref === void 0 ? false : options.unref;
|
|
799
|
-
if (options.startAt) {
|
|
800
|
-
options.startAt = new CronDate(options.startAt, options.timezone);
|
|
801
|
-
}
|
|
802
|
-
if (options.stopAt) {
|
|
803
|
-
options.stopAt = new CronDate(options.stopAt, options.timezone);
|
|
804
|
-
}
|
|
805
|
-
if (options.interval !== null) {
|
|
806
|
-
if (isNaN(options.interval)) {
|
|
807
|
-
throw new Error("CronOptions: Supplied value for interval is not a number");
|
|
808
|
-
} else if (options.interval < 0) {
|
|
809
|
-
throw new Error("CronOptions: Supplied value for interval can not be negative");
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
if (options.utcOffset !== void 0) {
|
|
813
|
-
if (isNaN(options.utcOffset)) {
|
|
814
|
-
throw new Error(
|
|
815
|
-
"CronOptions: Invalid value passed for utcOffset, should be number representing minutes offset from UTC."
|
|
816
|
-
);
|
|
817
|
-
} else if (options.utcOffset < -870 || options.utcOffset > 870) {
|
|
818
|
-
throw new Error("CronOptions: utcOffset out of bounds.");
|
|
819
|
-
}
|
|
820
|
-
if (options.utcOffset !== void 0 && options.timezone) {
|
|
821
|
-
throw new Error("CronOptions: Combining 'utcOffset' with 'timezone' is not allowed.");
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
if (options.unref !== true && options.unref !== false) {
|
|
825
|
-
throw new Error("CronOptions: Unref should be either true, false or undefined(false).");
|
|
826
|
-
}
|
|
827
|
-
return options;
|
|
828
|
-
}
|
|
829
|
-
|
|
830
|
-
// src/utils.ts
|
|
831
|
-
function isFunction(v) {
|
|
832
|
-
return Object.prototype.toString.call(v) === "[object Function]" || "function" === typeof v || v instanceof Function;
|
|
833
|
-
}
|
|
834
|
-
function unrefTimer(timer) {
|
|
835
|
-
if (typeof Deno !== "undefined" && typeof Deno.unrefTimer !== "undefined") {
|
|
836
|
-
Deno.unrefTimer(timer);
|
|
837
|
-
} else if (timer && typeof timer.unref !== "undefined") {
|
|
838
|
-
timer.unref();
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
// src/croner.ts
|
|
843
|
-
var maxDelay = 30 * 1e3;
|
|
844
|
-
var scheduledJobs = [];
|
|
845
|
-
var Cron = class {
|
|
846
|
-
name;
|
|
847
|
-
options;
|
|
848
|
-
_states;
|
|
849
|
-
fn;
|
|
850
|
-
constructor(pattern, fnOrOptions1, fnOrOptions2) {
|
|
851
|
-
let options, func;
|
|
852
|
-
if (isFunction(fnOrOptions1)) {
|
|
853
|
-
func = fnOrOptions1;
|
|
854
|
-
} else if (typeof fnOrOptions1 === "object") {
|
|
855
|
-
options = fnOrOptions1;
|
|
856
|
-
} else if (fnOrOptions1 !== void 0) {
|
|
857
|
-
throw new Error(
|
|
858
|
-
"Cron: Invalid argument passed for optionsIn. Should be one of function, or object (options)."
|
|
859
|
-
);
|
|
860
|
-
}
|
|
861
|
-
if (isFunction(fnOrOptions2)) {
|
|
862
|
-
func = fnOrOptions2;
|
|
863
|
-
} else if (typeof fnOrOptions2 === "object") {
|
|
864
|
-
options = fnOrOptions2;
|
|
865
|
-
} else if (fnOrOptions2 !== void 0) {
|
|
866
|
-
throw new Error(
|
|
867
|
-
"Cron: Invalid argument passed for funcIn. Should be one of function, or object (options)."
|
|
868
|
-
);
|
|
869
|
-
}
|
|
870
|
-
this.name = options ? options.name : void 0;
|
|
871
|
-
this.options = CronOptions(options);
|
|
872
|
-
this._states = {
|
|
873
|
-
kill: false,
|
|
874
|
-
blocking: false,
|
|
875
|
-
previousRun: void 0,
|
|
876
|
-
currentRun: void 0,
|
|
877
|
-
once: void 0,
|
|
878
|
-
currentTimeout: void 0,
|
|
879
|
-
maxRuns: options ? options.maxRuns : void 0,
|
|
880
|
-
paused: options ? options.paused : false,
|
|
881
|
-
pattern: new CronPattern("* * * * *")
|
|
882
|
-
};
|
|
883
|
-
if (pattern && (pattern instanceof Date || typeof pattern === "string" && pattern.indexOf(":") > 0)) {
|
|
884
|
-
this._states.once = new CronDate(pattern, this.options.timezone || this.options.utcOffset);
|
|
885
|
-
} else {
|
|
886
|
-
this._states.pattern = new CronPattern(pattern, this.options.timezone);
|
|
887
|
-
}
|
|
888
|
-
if (this.name) {
|
|
889
|
-
const existing = scheduledJobs.find((j) => j.name === this.name);
|
|
890
|
-
if (existing) {
|
|
891
|
-
throw new Error(
|
|
892
|
-
"Cron: Tried to initialize new named job '" + this.name + "', but name already taken."
|
|
893
|
-
);
|
|
894
|
-
} else {
|
|
895
|
-
scheduledJobs.push(this);
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
if (func !== void 0 && isFunction(func)) {
|
|
899
|
-
this.fn = func;
|
|
900
|
-
this.schedule();
|
|
901
|
-
}
|
|
902
|
-
return this;
|
|
903
|
-
}
|
|
904
|
-
/**
|
|
905
|
-
* Find next runtime, based on supplied date. Strips milliseconds.
|
|
906
|
-
*
|
|
907
|
-
* @param prev - Date to start from
|
|
908
|
-
* @returns Next run time
|
|
909
|
-
*/
|
|
910
|
-
nextRun(prev) {
|
|
911
|
-
const next = this._next(prev);
|
|
912
|
-
return next ? next.getDate(false) : null;
|
|
913
|
-
}
|
|
914
|
-
/**
|
|
915
|
-
* Find next n runs, based on supplied date. Strips milliseconds.
|
|
916
|
-
*
|
|
917
|
-
* @param n - Number of runs to enumerate
|
|
918
|
-
* @param previous - Date to start from
|
|
919
|
-
* @returns - Next n run times
|
|
920
|
-
*/
|
|
921
|
-
nextRuns(n, previous) {
|
|
922
|
-
if (this._states.maxRuns !== void 0 && n > this._states.maxRuns) {
|
|
923
|
-
n = this._states.maxRuns;
|
|
924
|
-
}
|
|
925
|
-
const enumeration = [];
|
|
926
|
-
let prev = previous || this._states.currentRun || void 0;
|
|
927
|
-
while (n-- && (prev = this.nextRun(prev))) {
|
|
928
|
-
enumeration.push(prev);
|
|
929
|
-
}
|
|
930
|
-
return enumeration;
|
|
931
|
-
}
|
|
932
|
-
/**
|
|
933
|
-
* Return the original pattern, if there was one
|
|
934
|
-
*
|
|
935
|
-
* @returns Original pattern
|
|
936
|
-
*/
|
|
937
|
-
getPattern() {
|
|
938
|
-
return this._states.pattern ? this._states.pattern.pattern : void 0;
|
|
939
|
-
}
|
|
940
|
-
/**
|
|
941
|
-
* Indicates whether or not the cron job is scheduled and running, e.g. awaiting next trigger
|
|
942
|
-
*
|
|
943
|
-
* @returns Running or not
|
|
944
|
-
*/
|
|
945
|
-
isRunning() {
|
|
946
|
-
const nextRunTime = this.nextRun(this._states.currentRun);
|
|
947
|
-
const isRunning = !this._states.paused;
|
|
948
|
-
const isScheduled = this.fn !== void 0;
|
|
949
|
-
const notIsKilled = !this._states.kill;
|
|
950
|
-
return isRunning && isScheduled && notIsKilled && nextRunTime !== null;
|
|
951
|
-
}
|
|
952
|
-
/**
|
|
953
|
-
* Indicates whether or not the cron job is permanently stopped
|
|
954
|
-
*
|
|
955
|
-
* @returns Running or not
|
|
956
|
-
*/
|
|
957
|
-
isStopped() {
|
|
958
|
-
return this._states.kill;
|
|
959
|
-
}
|
|
960
|
-
/**
|
|
961
|
-
* Indicates whether or not the cron job is currently working
|
|
962
|
-
*
|
|
963
|
-
* @returns Running or not
|
|
964
|
-
*/
|
|
965
|
-
isBusy() {
|
|
966
|
-
return this._states.blocking;
|
|
967
|
-
}
|
|
968
|
-
/**
|
|
969
|
-
* Return current/previous run start time
|
|
970
|
-
*
|
|
971
|
-
* @returns Current (if running) or previous run time
|
|
972
|
-
*/
|
|
973
|
-
currentRun() {
|
|
974
|
-
return this._states.currentRun ? this._states.currentRun.getDate() : null;
|
|
975
|
-
}
|
|
976
|
-
/**
|
|
977
|
-
* Return previous run start time
|
|
978
|
-
*
|
|
979
|
-
* @returns Previous run time
|
|
980
|
-
*/
|
|
981
|
-
previousRun() {
|
|
982
|
-
return this._states.previousRun ? this._states.previousRun.getDate() : null;
|
|
983
|
-
}
|
|
984
|
-
/**
|
|
985
|
-
* Returns number of milliseconds to next run
|
|
986
|
-
*
|
|
987
|
-
* @param prev Starting date, defaults to now - minimum interval
|
|
988
|
-
*/
|
|
989
|
-
msToNext(prev) {
|
|
990
|
-
prev = prev || /* @__PURE__ */ new Date();
|
|
991
|
-
const next = this._next(prev);
|
|
992
|
-
if (next) {
|
|
993
|
-
if (prev instanceof CronDate || prev instanceof Date) {
|
|
994
|
-
return next.getTime() - prev.getTime();
|
|
995
|
-
} else {
|
|
996
|
-
return next.getTime() - new CronDate(prev).getTime();
|
|
997
|
-
}
|
|
998
|
-
} else {
|
|
999
|
-
return null;
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
/**
|
|
1003
|
-
* Stop execution
|
|
1004
|
-
*
|
|
1005
|
-
* Running this will forcefully stop the job, and prevent furter exection. `.resume()` will not work after stopping.
|
|
1006
|
-
* It will also be removed from the scheduledJobs array if it were named.
|
|
1007
|
-
*/
|
|
1008
|
-
stop() {
|
|
1009
|
-
this._states.kill = true;
|
|
1010
|
-
if (this._states.currentTimeout) {
|
|
1011
|
-
clearTimeout(this._states.currentTimeout);
|
|
1012
|
-
}
|
|
1013
|
-
const jobIndex = scheduledJobs.indexOf(this);
|
|
1014
|
-
if (jobIndex >= 0) {
|
|
1015
|
-
scheduledJobs.splice(jobIndex, 1);
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
/**
|
|
1019
|
-
* Pause execution
|
|
1020
|
-
*
|
|
1021
|
-
* @returns Wether pause was successful
|
|
1022
|
-
*/
|
|
1023
|
-
pause() {
|
|
1024
|
-
this._states.paused = true;
|
|
1025
|
-
return !this._states.kill;
|
|
1026
|
-
}
|
|
1027
|
-
/**
|
|
1028
|
-
* Resume execution
|
|
1029
|
-
*
|
|
1030
|
-
* @returns Wether resume was successful
|
|
1031
|
-
*/
|
|
1032
|
-
resume() {
|
|
1033
|
-
this._states.paused = false;
|
|
1034
|
-
return !this._states.kill;
|
|
1035
|
-
}
|
|
1036
|
-
/**
|
|
1037
|
-
* Schedule a new job
|
|
1038
|
-
*
|
|
1039
|
-
* @param func - Function to be run each iteration of pattern
|
|
1040
|
-
*/
|
|
1041
|
-
schedule(func) {
|
|
1042
|
-
if (func && this.fn) {
|
|
1043
|
-
throw new Error(
|
|
1044
|
-
"Cron: It is not allowed to schedule two functions using the same Croner instance."
|
|
1045
|
-
);
|
|
1046
|
-
} else if (func) {
|
|
1047
|
-
this.fn = func;
|
|
1048
|
-
}
|
|
1049
|
-
let waitMs = this.msToNext();
|
|
1050
|
-
const target = this.nextRun(this._states.currentRun);
|
|
1051
|
-
if (waitMs === null || waitMs === void 0 || isNaN(waitMs) || target === null) return this;
|
|
1052
|
-
if (waitMs > maxDelay) {
|
|
1053
|
-
waitMs = maxDelay;
|
|
1054
|
-
}
|
|
1055
|
-
this._states.currentTimeout = setTimeout(() => this._checkTrigger(target), waitMs);
|
|
1056
|
-
if (this._states.currentTimeout && this.options.unref) {
|
|
1057
|
-
unrefTimer(this._states.currentTimeout);
|
|
1058
|
-
}
|
|
1059
|
-
return this;
|
|
1060
|
-
}
|
|
1061
|
-
/**
|
|
1062
|
-
* Internal function to trigger a run, used by both scheduled and manual trigger
|
|
1063
|
-
*/
|
|
1064
|
-
async _trigger(initiationDate) {
|
|
1065
|
-
this._states.blocking = true;
|
|
1066
|
-
this._states.currentRun = new CronDate(
|
|
1067
|
-
void 0,
|
|
1068
|
-
// We should use initiationDate, but that does not play well with fake timers in third party tests. In real world there is not much difference though */
|
|
1069
|
-
this.options.timezone || this.options.utcOffset
|
|
1070
|
-
);
|
|
1071
|
-
if (this.options.catch) {
|
|
1072
|
-
try {
|
|
1073
|
-
if (this.fn !== void 0) {
|
|
1074
|
-
await this.fn(this, this.options.context);
|
|
1075
|
-
}
|
|
1076
|
-
} catch (_e) {
|
|
1077
|
-
if (isFunction(this.options.catch)) {
|
|
1078
|
-
this.options.catch(_e, this);
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
} else {
|
|
1082
|
-
if (this.fn !== void 0) {
|
|
1083
|
-
await this.fn(this, this.options.context);
|
|
1084
|
-
}
|
|
1085
|
-
}
|
|
1086
|
-
this._states.previousRun = new CronDate(
|
|
1087
|
-
initiationDate,
|
|
1088
|
-
this.options.timezone || this.options.utcOffset
|
|
1089
|
-
);
|
|
1090
|
-
this._states.blocking = false;
|
|
1091
|
-
}
|
|
1092
|
-
/**
|
|
1093
|
-
* Trigger a run manually
|
|
1094
|
-
*/
|
|
1095
|
-
async trigger() {
|
|
1096
|
-
await this._trigger();
|
|
1097
|
-
}
|
|
1098
|
-
/**
|
|
1099
|
-
* Returns number of runs left, undefined = unlimited
|
|
1100
|
-
*/
|
|
1101
|
-
runsLeft() {
|
|
1102
|
-
return this._states.maxRuns;
|
|
1103
|
-
}
|
|
1104
|
-
/**
|
|
1105
|
-
* Called when it's time to trigger.
|
|
1106
|
-
* Checks if all conditions are currently met,
|
|
1107
|
-
* then instantly triggers the scheduled function.
|
|
1108
|
-
*/
|
|
1109
|
-
_checkTrigger(target) {
|
|
1110
|
-
const now = /* @__PURE__ */ new Date(), shouldRun = !this._states.paused && now.getTime() >= target.getTime(), isBlocked = this._states.blocking && this.options.protect;
|
|
1111
|
-
if (shouldRun && !isBlocked) {
|
|
1112
|
-
if (this._states.maxRuns !== void 0) {
|
|
1113
|
-
this._states.maxRuns--;
|
|
1114
|
-
}
|
|
1115
|
-
this._trigger();
|
|
1116
|
-
} else {
|
|
1117
|
-
if (shouldRun && isBlocked && isFunction(this.options.protect)) {
|
|
1118
|
-
setTimeout(() => this.options.protect(this), 0);
|
|
1119
|
-
}
|
|
1120
|
-
}
|
|
1121
|
-
this.schedule();
|
|
1122
|
-
}
|
|
1123
|
-
/**
|
|
1124
|
-
* Internal version of next. Cron needs millseconds internally, hence _next.
|
|
1125
|
-
*/
|
|
1126
|
-
_next(previousRun) {
|
|
1127
|
-
let hasPreviousRun = previousRun || this._states.currentRun ? true : false;
|
|
1128
|
-
let startAtInFutureWithInterval = false;
|
|
1129
|
-
if (!previousRun && this.options.startAt && this.options.interval) {
|
|
1130
|
-
[previousRun, hasPreviousRun] = this._calculatePreviousRun(previousRun, hasPreviousRun);
|
|
1131
|
-
startAtInFutureWithInterval = !previousRun ? true : false;
|
|
1132
|
-
}
|
|
1133
|
-
previousRun = new CronDate(previousRun, this.options.timezone || this.options.utcOffset);
|
|
1134
|
-
if (this.options.startAt && previousRun && previousRun.getTime() < this.options.startAt.getTime()) {
|
|
1135
|
-
previousRun = this.options.startAt;
|
|
1136
|
-
}
|
|
1137
|
-
let nextRun = this._states.once || new CronDate(previousRun, this.options.timezone || this.options.utcOffset);
|
|
1138
|
-
if (!startAtInFutureWithInterval && nextRun !== this._states.once) {
|
|
1139
|
-
nextRun = nextRun.increment(
|
|
1140
|
-
this._states.pattern,
|
|
1141
|
-
this.options,
|
|
1142
|
-
hasPreviousRun
|
|
1143
|
-
// hasPreviousRun is used to allow
|
|
1144
|
-
);
|
|
1145
|
-
}
|
|
1146
|
-
if (this._states.once && this._states.once.getTime() <= previousRun.getTime()) {
|
|
1147
|
-
return null;
|
|
1148
|
-
} else if (nextRun === null || this._states.maxRuns !== void 0 && this._states.maxRuns <= 0 || this._states.kill || this.options.stopAt && nextRun.getTime() >= this.options.stopAt.getTime()) {
|
|
1149
|
-
return null;
|
|
1150
|
-
} else {
|
|
1151
|
-
return nextRun;
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
|
-
/**
|
|
1155
|
-
* Calculate the previous run if no previous run is supplied, but startAt and interval are set.
|
|
1156
|
-
* This calculation is only necessary if the startAt time is before the current time.
|
|
1157
|
-
* Should only be called from the _next function.
|
|
1158
|
-
*/
|
|
1159
|
-
_calculatePreviousRun(prev, hasPreviousRun) {
|
|
1160
|
-
const now = new CronDate(void 0, this.options.timezone || this.options.utcOffset);
|
|
1161
|
-
let newPrev = prev;
|
|
1162
|
-
if (this.options.startAt.getTime() <= now.getTime()) {
|
|
1163
|
-
newPrev = this.options.startAt;
|
|
1164
|
-
let prevTimePlusInterval = newPrev.getTime() + this.options.interval * 1e3;
|
|
1165
|
-
while (prevTimePlusInterval <= now.getTime()) {
|
|
1166
|
-
newPrev = new CronDate(newPrev, this.options.timezone || this.options.utcOffset).increment(
|
|
1167
|
-
this._states.pattern,
|
|
1168
|
-
this.options,
|
|
1169
|
-
true
|
|
1170
|
-
);
|
|
1171
|
-
prevTimePlusInterval = newPrev.getTime() + this.options.interval * 1e3;
|
|
1172
|
-
}
|
|
1173
|
-
hasPreviousRun = true;
|
|
1174
|
-
}
|
|
1175
|
-
if (newPrev === null) {
|
|
1176
|
-
newPrev = void 0;
|
|
1177
|
-
}
|
|
1178
|
-
return [newPrev, hasPreviousRun];
|
|
1179
|
-
}
|
|
1180
|
-
};
|
|
1181
|
-
var croner_default = Cron;
|
|
1182
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
1183
|
-
0 && (module.exports = {
|
|
1184
|
-
Cron,
|
|
1185
|
-
CronDate,
|
|
1186
|
-
CronOptions,
|
|
1187
|
-
CronPattern,
|
|
1188
|
-
scheduledJobs
|
|
1189
|
-
});
|
|
1
|
+
var v=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var M=Object.prototype.hasOwnProperty;var U=(n,t)=>{for(var e in t)v(n,e,{get:t[e],enumerable:!0})},k=(n,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of x(t))!M.call(n,s)&&s!==e&&v(n,s,{get:()=>t[s],enumerable:!(r=E(t,s))||r.enumerable});return n};var A=n=>k(v({},"__esModule",{value:!0}),n);var F={};U(F,{Cron:()=>w,CronDate:()=>l,CronOptions:()=>S,CronPattern:()=>p,default:()=>I,scheduledJobs:()=>C});module.exports=A(F);function f(n,t,e,r,s,i,a,u){return f.fromTZ(f.tp(n,t,e,r,s,i,a),u)}f.fromTZISO=(n,t,e)=>f.fromTZ(z(n,t),e);f.fromTZ=function(n,t){let e=new Date(Date.UTC(n.y,n.m-1,n.d,n.h,n.i,n.s)),r=O(n.tz,e),s=new Date(e.getTime()-r),i=O(n.tz,s);if(i-r===0)return s;{let a=new Date(e.getTime()-i),u=O(n.tz,a);if(u-i===0)return a;if(!t&&u-i>0)return a;if(t)throw new Error("Invalid date passed to fromTZ()");return s}};f.toTZ=function(n,t){let e=n.toLocaleString("en-US",{timeZone:t}).replace(/[\u202f]/," "),r=new Date(e);return{y:r.getFullYear(),m:r.getMonth()+1,d:r.getDate(),h:r.getHours(),i:r.getMinutes(),s:r.getSeconds(),tz:t}};f.tp=(n,t,e,r,s,i,a)=>({y:n,m:t,d:e,h:r,i:s,s:i,tz:a});function O(n,t=new Date){let e=t.toLocaleString("en-US",{timeZone:n,timeZoneName:"shortOffset"}).split(" ").slice(-1)[0],r=t.toLocaleString("en-US").replace(/[\u202f]/," ");return Date.parse(`${r} GMT`)-Date.parse(`${r} ${e}`)}function z(n,t){let e=new Date(Date.parse(n));if(isNaN(e))throw new Error("minitz: Invalid ISO8601 passed to parser.");let r=n.substring(9);return n.includes("Z")||r.includes("-")||r.includes("+")?f.tp(e.getUTCFullYear(),e.getUTCMonth()+1,e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),"Etc/UTC"):f.tp(e.getFullYear(),e.getMonth()+1,e.getDate(),e.getHours(),e.getMinutes(),e.getSeconds(),t)}f.minitz=f;var b=32,g=31|b,N=[1,2,4,8,16],p=class{pattern;timezone;second;minute;hour;day;month;dayOfWeek;lastDayOfMonth;starDOM;starDOW;constructor(t,e){this.pattern=t,this.timezone=e,this.second=Array(60).fill(0),this.minute=Array(60).fill(0),this.hour=Array(24).fill(0),this.day=Array(31).fill(0),this.month=Array(12).fill(0),this.dayOfWeek=Array(7).fill(0),this.lastDayOfMonth=!1,this.starDOM=!1,this.starDOW=!1,this.parse()}parse(){if(!(typeof this.pattern=="string"||this.pattern instanceof String))throw new TypeError("CronPattern: Pattern has to be of type string.");this.pattern.indexOf("@")>=0&&(this.pattern=this.handleNicknames(this.pattern).trim());let t=this.pattern.replace(/\s+/g," ").split(" ");if(t.length<5||t.length>6)throw new TypeError("CronPattern: invalid configuration format ('"+this.pattern+"'), exactly five or six space separated parts are required.");if(t.length===5&&t.unshift("0"),t[3].indexOf("L")>=0&&(t[3]=t[3].replace("L",""),this.lastDayOfMonth=!0),t[3]=="*"&&(this.starDOM=!0),t[4].length>=3&&(t[4]=this.replaceAlphaMonths(t[4])),t[5].length>=3&&(t[5]=this.replaceAlphaDays(t[5])),t[5]=="*"&&(this.starDOW=!0),this.pattern.indexOf("?")>=0){let e=new l(new Date,this.timezone).getDate(!0);t[0]=t[0].replace("?",e.getSeconds().toString()),t[1]=t[1].replace("?",e.getMinutes().toString()),t[2]=t[2].replace("?",e.getHours().toString()),this.starDOM||(t[3]=t[3].replace("?",e.getDate().toString())),t[4]=t[4].replace("?",(e.getMonth()+1).toString()),this.starDOW||(t[5]=t[5].replace("?",e.getDay().toString()))}this.throwAtIllegalCharacters(t),this.partToArray("second",t[0],0,1),this.partToArray("minute",t[1],0,1),this.partToArray("hour",t[2],0,1),this.partToArray("day",t[3],-1,1),this.partToArray("month",t[4],-1,1),this.partToArray("dayOfWeek",t[5],0,g),this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(t,e,r,s){let i=this[t],a=t==="day"&&this.lastDayOfMonth;if(e===""&&!a)throw new TypeError("CronPattern: configuration entry "+t+" ("+e+") is empty, check for trailing spaces.");if(e==="*")return i.fill(s);let u=e.split(",");if(u.length>1)for(let o=0;o<u.length;o++)this.partToArray(t,u[o],r,s);else e.indexOf("-")!==-1&&e.indexOf("/")!==-1?this.handleRangeWithStepping(e,t,r,s):e.indexOf("-")!==-1?this.handleRange(e,t,r,s):e.indexOf("/")!==-1?this.handleStepping(e,t,r,s):e!==""&&this.handleNumber(e,t,r,s)}throwAtIllegalCharacters(t){for(let e=0;e<t.length;e++)if((e===5?/[^/*0-9,\-#L]+/:/[^/*0-9,-]+/).test(t[e]))throw new TypeError("CronPattern: configuration entry "+e+" ("+t[e]+") contains illegal characters.")}handleNumber(t,e,r,s){let i=this.extractNth(t,e),a=parseInt(i[0],10)+r;if(isNaN(a))throw new TypeError("CronPattern: "+e+" is not a number: '"+t+"'");this.setPart(e,a,i[1]||s)}setPart(t,e,r){if(!Object.prototype.hasOwnProperty.call(this,t))throw new TypeError("CronPattern: Invalid part specified: "+t);if(t==="dayOfWeek"){if(e===7&&(e=0),e<0||e>6)throw new RangeError("CronPattern: Invalid value for dayOfWeek: "+e);this.setNthWeekdayOfMonth(e,r);return}if(t==="second"||t==="minute"){if(e<0||e>=60)throw new RangeError("CronPattern: Invalid value for "+t+": "+e)}else if(t==="hour"){if(e<0||e>=24)throw new RangeError("CronPattern: Invalid value for "+t+": "+e)}else if(t==="day"){if(e<0||e>=31)throw new RangeError("CronPattern: Invalid value for "+t+": "+e)}else if(t==="month"&&(e<0||e>=12))throw new RangeError("CronPattern: Invalid value for "+t+": "+e);this[t][e]=r}handleRangeWithStepping(t,e,r,s){let i=this.extractNth(t,e),a=i[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(a===null)throw new TypeError("CronPattern: Syntax error, illegal range with stepping: '"+t+"'");let[,u,o,h]=a,c=parseInt(u,10)+r,T=parseInt(o,10)+r,y=parseInt(h,10);if(isNaN(c))throw new TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(T))throw new TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(isNaN(y))throw new TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(y===0)throw new TypeError("CronPattern: Syntax error, illegal stepping: 0");if(y>this[e].length)throw new TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+this[e].length+")");if(c>T)throw new TypeError("CronPattern: From value is larger than to value: '"+t+"'");for(let D=c;D<=T;D+=y)this.setPart(e,D,i[1]||s)}extractNth(t,e){let r=t,s;if(r.includes("#")){if(e!=="dayOfWeek")throw new Error("CronPattern: nth (#) only allowed in day-of-week field");s=r.split("#")[1],r=r.split("#")[0]}return[r,s]}handleRange(t,e,r,s){let i=this.extractNth(t,e),a=i[0].split("-");if(a.length!==2)throw new TypeError("CronPattern: Syntax error, illegal range: '"+t+"'");let u=parseInt(a[0],10)+r,o=parseInt(a[1],10)+r;if(isNaN(u))throw new TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(o))throw new TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(u>o)throw new TypeError("CronPattern: From value is larger than to value: '"+t+"'");for(let h=u;h<=o;h++)this.setPart(e,h,i[1]||s)}handleStepping(t,e,r,s){let i=this.extractNth(t,e),a=i[0].split("/");if(a.length!==2)throw new TypeError("CronPattern: Syntax error, illegal stepping: '"+t+"'");a[0]===""&&(a[0]="*");let u=0;a[0]!=="*"&&(u=parseInt(a[0],10)+r);let o=parseInt(a[1],10);if(isNaN(o))throw new TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(o===0)throw new TypeError("CronPattern: Syntax error, illegal stepping: 0");if(o>this[e].length)throw new TypeError("CronPattern: Syntax error, max steps for part is ("+this[e].length+")");for(let h=u;h<this[e].length;h+=o)this.setPart(e,h,i[1]||s)}replaceAlphaDays(t){return t.replace(/-sun/gi,"-7").replace(/sun/gi,"0").replace(/mon/gi,"1").replace(/tue/gi,"2").replace(/wed/gi,"3").replace(/thu/gi,"4").replace(/fri/gi,"5").replace(/sat/gi,"6")}replaceAlphaMonths(t){return t.replace(/jan/gi,"1").replace(/feb/gi,"2").replace(/mar/gi,"3").replace(/apr/gi,"4").replace(/may/gi,"5").replace(/jun/gi,"6").replace(/jul/gi,"7").replace(/aug/gi,"8").replace(/sep/gi,"9").replace(/oct/gi,"10").replace(/nov/gi,"11").replace(/dec/gi,"12")}handleNicknames(t){let e=t.trim().toLowerCase();return e==="@yearly"||e==="@annually"?"0 0 1 1 *":e==="@monthly"?"0 0 1 * *":e==="@weekly"?"0 0 * * 0":e==="@daily"?"0 0 * * *":e==="@hourly"?"0 * * * *":t}setNthWeekdayOfMonth(t,e){if(typeof e!="number"&&e==="L")this.dayOfWeek[t]=this.dayOfWeek[t]|b;else if(e===g)this.dayOfWeek[t]=g;else if(e<6&&e>0)this.dayOfWeek[t]=this.dayOfWeek[t]|N[e-1];else throw new TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${e}, Type: ${typeof e}`)}};var _=[31,28,31,30,31,30,31,31,30,31,30,31],m=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],l=class n{tz;ms;second;minute;hour;day;month;year;constructor(t,e){if(this.tz=e,t&&t instanceof Date)if(!isNaN(t))this.fromDate(t);else throw new TypeError("CronDate: Invalid date passed to CronDate constructor");else if(t===void 0)this.fromDate(new Date);else if(t&&typeof t=="string")this.fromString(t);else if(t instanceof n)this.fromCronDate(t);else throw new TypeError("CronDate: Invalid type ("+typeof t+") passed to CronDate constructor")}isNthWeekdayOfMonth(t,e,r,s){let a=new Date(Date.UTC(t,e,r)).getUTCDay(),u=0;for(let o=1;o<=r;o++)new Date(Date.UTC(t,e,o)).getUTCDay()===a&&u++;if(s&g&&N[u-1]&s)return!0;if(s&b){let o=new Date(Date.UTC(t,e+1,0)).getUTCDate();for(let h=r+1;h<=o;h++)if(new Date(Date.UTC(t,e,h)).getUTCDay()===a)return!1;return!0}return!1}fromDate(t){if(this.tz!==void 0)if(typeof this.tz=="number")this.ms=t.getUTCMilliseconds(),this.second=t.getUTCSeconds(),this.minute=t.getUTCMinutes()+this.tz,this.hour=t.getUTCHours(),this.day=t.getUTCDate(),this.month=t.getUTCMonth(),this.year=t.getUTCFullYear(),this.apply();else{let e=f.toTZ(t,this.tz);this.ms=t.getMilliseconds(),this.second=e.s,this.minute=e.i,this.hour=e.h,this.day=e.d,this.month=e.m-1,this.year=e.y}else this.ms=t.getMilliseconds(),this.second=t.getSeconds(),this.minute=t.getMinutes(),this.hour=t.getHours(),this.day=t.getDate(),this.month=t.getMonth(),this.year=t.getFullYear()}fromCronDate(t){this.tz=t.tz,this.year=t.year,this.month=t.month,this.day=t.day,this.hour=t.hour,this.minute=t.minute,this.second=t.second,this.ms=t.ms}apply(){if(this.month>11||this.day>_[this.month]||this.hour>59||this.minute>59||this.second>59||this.hour<0||this.minute<0||this.second<0){let t=new Date(Date.UTC(this.year,this.month,this.day,this.hour,this.minute,this.second,this.ms));return this.ms=t.getUTCMilliseconds(),this.second=t.getUTCSeconds(),this.minute=t.getUTCMinutes(),this.hour=t.getUTCHours(),this.day=t.getUTCDate(),this.month=t.getUTCMonth(),this.year=t.getUTCFullYear(),!0}else return!1}fromString(t){if(typeof this.tz=="number"){let e=f.fromTZISO(t);this.ms=e.getUTCMilliseconds(),this.second=e.getUTCSeconds(),this.minute=e.getUTCMinutes(),this.hour=e.getUTCHours(),this.day=e.getUTCDate(),this.month=e.getUTCMonth(),this.year=e.getUTCFullYear(),this.apply()}else return this.fromDate(f.fromTZISO(t,this.tz))}findNext(t,e,r,s){let i=this[e],a;r.lastDayOfMonth&&(this.month!==1?a=_[this.month]:a=new Date(Date.UTC(this.year,this.month+1,0,0,0,0,0)).getUTCDate());let u=!r.starDOW&&e=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0;for(let o=this[e]+s;o<r[e].length;o++){let h=r[e][o];if(e==="day"&&r.lastDayOfMonth&&o-s==a&&(h=1),e==="day"&&!r.starDOW){let c=r.dayOfWeek[(u+(o-s-1))%7];if(c&&c&g)c=this.isNthWeekdayOfMonth(this.year,this.month,o-s,c)?1:0;else if(c)throw new Error(`CronDate: Invalid value for dayOfWeek encountered. ${c}`);t.legacyMode&&!r.starDOM?h=h||c:h=h&&c}if(h)return this[e]=o-s,i!==this[e]?2:1}return 3}recurse(t,e,r){let s=this.findNext(e,m[r][0],t,m[r][2]);if(s>1){let i=r+1;for(;i<m.length;)this[m[i][0]]=-m[i][2],i++;if(s===3)return this[m[r][1]]++,this[m[r][0]]=-m[r][2],this.apply(),this.recurse(t,e,0);if(this.apply())return this.recurse(t,e,r-1)}return r+=1,r>=m.length?this:this.year>=3e3?null:this.recurse(t,e,r)}increment(t,e,r){return this.second+=e.interval!==void 0&&e.interval>1&&r?e.interval:1,this.ms=0,this.apply(),this.recurse(t,e,0)}getDate(t){return t||this.tz===void 0?new Date(this.year,this.month,this.day,this.hour,this.minute,this.second,this.ms):typeof this.tz=="number"?new Date(Date.UTC(this.year,this.month,this.day,this.hour,this.minute-this.tz,this.second,this.ms)):f.fromTZ(f.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function S(n){if(n===void 0&&(n={}),delete n.name,n.legacyMode=n.legacyMode===void 0?!0:n.legacyMode,n.paused=n.paused===void 0?!1:n.paused,n.maxRuns=n.maxRuns===void 0?1/0:n.maxRuns,n.catch=n.catch===void 0?!1:n.catch,n.interval=n.interval===void 0?0:parseInt(n.interval.toString(),10),n.utcOffset=n.utcOffset===void 0?void 0:parseInt(n.utcOffset.toString(),10),n.unref=n.unref===void 0?!1:n.unref,n.startAt&&(n.startAt=new l(n.startAt,n.timezone)),n.stopAt&&(n.stopAt=new l(n.stopAt,n.timezone)),n.interval!==null){if(isNaN(n.interval))throw new Error("CronOptions: Supplied value for interval is not a number");if(n.interval<0)throw new Error("CronOptions: Supplied value for interval can not be negative")}if(n.utcOffset!==void 0){if(isNaN(n.utcOffset))throw new Error("CronOptions: Invalid value passed for utcOffset, should be number representing minutes offset from UTC.");if(n.utcOffset<-870||n.utcOffset>870)throw new Error("CronOptions: utcOffset out of bounds.");if(n.utcOffset!==void 0&&n.timezone)throw new Error("CronOptions: Combining 'utcOffset' with 'timezone' is not allowed.")}if(n.unref!==!0&&n.unref!==!1)throw new Error("CronOptions: Unref should be either true, false or undefined(false).");return n}function d(n){return Object.prototype.toString.call(n)==="[object Function]"||typeof n=="function"||n instanceof Function}function P(n){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(n):n&&typeof n.unref<"u"&&n.unref()}var R=30*1e3,C=[],w=class{name;options;_states;fn;constructor(t,e,r){let s,i;if(d(e))i=e;else if(typeof e=="object")s=e;else if(e!==void 0)throw new Error("Cron: Invalid argument passed for optionsIn. Should be one of function, or object (options).");if(d(r))i=r;else if(typeof r=="object")s=r;else if(r!==void 0)throw new Error("Cron: Invalid argument passed for funcIn. Should be one of function, or object (options).");if(this.name=s?s.name:void 0,this.options=S(s),this._states={kill:!1,blocking:!1,previousRun:void 0,currentRun:void 0,once:void 0,currentTimeout:void 0,maxRuns:s?s.maxRuns:void 0,paused:s?s.paused:!1,pattern:new p("* * * * *")},t&&(t instanceof Date||typeof t=="string"&&t.indexOf(":")>0)?this._states.once=new l(t,this.options.timezone||this.options.utcOffset):this._states.pattern=new p(t,this.options.timezone),this.name){if(C.find(u=>u.name===this.name))throw new Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");C.push(this)}return i!==void 0&&d(i)&&(this.fn=i,this.schedule()),this}nextRun(t){let e=this._next(t);return e?e.getDate(!1):null}nextRuns(t,e){this._states.maxRuns!==void 0&&t>this._states.maxRuns&&(t=this._states.maxRuns);let r=[],s=e||this._states.currentRun||void 0;for(;t--&&(s=this.nextRun(s));)r.push(s);return r}getPattern(){return this._states.pattern?this._states.pattern.pattern:void 0}isRunning(){let t=this.nextRun(this._states.currentRun),e=!this._states.paused,r=this.fn!==void 0,s=!this._states.kill;return e&&r&&s&&t!==null}isStopped(){return this._states.kill}isBusy(){return this._states.blocking}currentRun(){return this._states.currentRun?this._states.currentRun.getDate():null}previousRun(){return this._states.previousRun?this._states.previousRun.getDate():null}msToNext(t){t=t||new Date;let e=this._next(t);return e?t instanceof l||t instanceof Date?e.getTime()-t.getTime():e.getTime()-new l(t).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let t=C.indexOf(this);t>=0&&C.splice(t,1)}pause(){return this._states.paused=!0,!this._states.kill}resume(){return this._states.paused=!1,!this._states.kill}schedule(t){if(t&&this.fn)throw new Error("Cron: It is not allowed to schedule two functions using the same Croner instance.");t&&(this.fn=t);let e=this.msToNext(),r=this.nextRun(this._states.currentRun);return e==null||isNaN(e)||r===null?this:(e>R&&(e=R),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(r),e),this._states.currentTimeout&&this.options.unref&&P(this._states.currentTimeout),this)}async _trigger(t){if(this._states.blocking=!0,this._states.currentRun=new l(void 0,this.options.timezone||this.options.utcOffset),this.options.catch)try{this.fn!==void 0&&await this.fn(this,this.options.context)}catch(e){d(this.options.catch)&&this.options.catch(e,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new l(t,this.options.timezone||this.options.utcOffset),this._states.blocking=!1}async trigger(){await this._trigger()}runsLeft(){return this._states.maxRuns}_checkTrigger(t){let e=new Date,r=!this._states.paused&&e.getTime()>=t.getTime(),s=this._states.blocking&&this.options.protect;r&&!s?(this._states.maxRuns!==void 0&&this._states.maxRuns--,this._trigger()):r&&s&&d(this.options.protect)&&setTimeout(()=>this.options.protect(this),0),this.schedule()}_next(t){let e=!!(t||this._states.currentRun),r=!1;!t&&this.options.startAt&&this.options.interval&&([t,e]=this._calculatePreviousRun(t,e),r=!t),t=new l(t,this.options.timezone||this.options.utcOffset),this.options.startAt&&t&&t.getTime()<this.options.startAt.getTime()&&(t=this.options.startAt);let s=this._states.once||new l(t,this.options.timezone||this.options.utcOffset);return!r&&s!==this._states.once&&(s=s.increment(this._states.pattern,this.options,e)),this._states.once&&this._states.once.getTime()<=t.getTime()||s===null||this._states.maxRuns!==void 0&&this._states.maxRuns<=0||this._states.kill||this.options.stopAt&&s.getTime()>=this.options.stopAt.getTime()?null:s}_calculatePreviousRun(t,e){let r=new l(void 0,this.options.timezone||this.options.utcOffset),s=t;if(this.options.startAt.getTime()<=r.getTime()){s=this.options.startAt;let i=s.getTime()+this.options.interval*1e3;for(;i<=r.getTime();)s=new l(s,this.options.timezone||this.options.utcOffset).increment(this._states.pattern,this.options,!0),i=s.getTime()+this.options.interval*1e3;e=!0}return s===null&&(s=void 0),[s,e]}},I=w;0&&(module.exports={Cron,CronDate,CronOptions,CronPattern,scheduledJobs});
|