@iobroker/adapter-react-v5 4.11.3 → 4.11.4

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.
Files changed (38) hide show
  1. package/Components/IconPicker.d.ts +9 -3
  2. package/Components/IconSelector.d.ts +1 -1
  3. package/Components/SimpleCron/cron2text.d.ts +4 -6
  4. package/Components/SimpleCron/cron2text.js +463 -481
  5. package/Components/SimpleCron/cronText.d.ts +1 -1
  6. package/Components/SimpleCron/cronText.js +46 -48
  7. package/Components/SimpleCron/index.d.ts +38 -7
  8. package/Components/SimpleCron/index.js +579 -729
  9. package/Components/SimpleCron/jquery.cron.locale.d.ts +28 -1
  10. package/Components/SimpleCron/jquery.cron.locale.js +530 -336
  11. package/Dialogs/ComplexCron.d.ts +13 -12
  12. package/Dialogs/ComplexCron.js +59 -130
  13. package/Dialogs/Cron.d.ts +17 -14
  14. package/Dialogs/Cron.js +92 -183
  15. package/Dialogs/SimpleCron.d.ts +11 -11
  16. package/Dialogs/SimpleCron.js +49 -119
  17. package/GenericApp.d.ts +7 -2
  18. package/GenericApp.js +3 -25
  19. package/README.md +3 -0
  20. package/i18n/de.json +2 -1
  21. package/i18n/en.json +2 -1
  22. package/i18n/es.json +2 -1
  23. package/i18n/fr.json +2 -1
  24. package/i18n/it.json +2 -1
  25. package/i18n/nl.json +2 -1
  26. package/i18n/pl.json +2 -1
  27. package/i18n/pt.json +2 -1
  28. package/i18n/ru.json +2 -1
  29. package/i18n/uk.json +2 -1
  30. package/i18n/zh-cn.json +2 -1
  31. package/package.json +1 -1
  32. package/Components/SimpleCron/cron2text.js.map +0 -1
  33. package/Components/SimpleCron/cronText.js.map +0 -1
  34. package/Components/SimpleCron/index.js.map +0 -1
  35. package/Components/SimpleCron/jquery.cron.locale.js.map +0 -1
  36. package/Dialogs/ComplexCron.js.map +0 -1
  37. package/Dialogs/Cron.js.map +0 -1
  38. package/Dialogs/SimpleCron.js.map +0 -1
@@ -1,508 +1,490 @@
1
1
  "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports["default"] = void 0;
2
+ Object.defineProperty(exports, "__esModule", { value: true });
7
3
  /**
8
- * Given a cronspec, return the human-readable string.
9
- * @param {string} cronspec
10
- * @param withSeconds
11
- * @param {Object=} locale
4
+ * Given a cronSpec, return the human-readable string.
12
5
  */
13
- function cronToText(cronspec, withSeconds, locale) {
14
- // Constant array to convert valid names to values
15
- var NAMES = {
16
- JAN: 1,
17
- FEB: 2,
18
- MAR: 3,
19
- APR: 4,
20
- MAY: 5,
21
- JUN: 6,
22
- JUL: 7,
23
- AUG: 8,
24
- SEP: 9,
25
- OCT: 10,
26
- NOV: 11,
27
- DEC: 12,
28
- SUN: 1,
29
- MON: 2,
30
- TUE: 3,
31
- WED: 4,
32
- THU: 5,
33
- FRI: 6,
34
- SAT: 7
35
- };
36
-
37
- // Parsable replacements for common expressions
38
- var REPLACEMENTS = {
39
- '* * * * * *': '0/1 * * * * *',
40
- '@YEARLY': '0 0 1 1 *',
41
- '@ANNUALLY': '0 0 1 1 *',
42
- '@MONTHLY': '0 0 1 * *',
43
- '@WEEKLY': '0 0 * * 0',
44
- '@DAILY': '0 0 * * *',
45
- '@HOURLY': '0 * * * *'
46
- };
47
-
48
- // Contains the index, min, and max for each of the constraints
49
- var FIELDS = {
50
- s: [0, 0, 59],
51
- // seconds
52
- m: [1, 0, 59],
53
- // minutes
54
- h: [2, 0, 23],
55
- // hours
56
- D: [3, 1, 31],
57
- // day of month
58
- M: [4, 1, 12],
59
- // month
60
- Y: [6, 1970, 2099],
61
- // year
62
- d: [5, 1, 7, 1] // day of week
63
- };
64
-
65
- /**
66
- * Returns the value + offset if value is a number, otherwise it
67
- * attempts to look up the value in the NAMES table and returns
68
- * that result instead.
69
- *
70
- * @param {Number,String} value: The value that should be parsed
71
- * @param {Number=} offset: Any offset that must be added to the value
72
- * @param {Number=} max
73
- * @returns {Number|null}
74
- */
75
- function getValue(value) {
76
- var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];
77
- var max = arguments.length <= 2 || arguments[2] === undefined ? 9999 : arguments[2];
78
- return Number.isNaN(value) ? NAMES[value] || null : Math.min(+value + offset, max);
79
- }
80
-
81
- /**
82
- * Returns a deep clone of a schedule skipping any day of week
83
- * constraints.
84
- *
85
- * @param {Object} sched: The schedule that will be cloned
86
- * @returns {Object}
87
- */
88
- function cloneSchedule(sched) {
89
- var clone = {};
90
- var field;
91
- for (field in sched) {
92
- if (field !== 'dc' && field !== 'd') {
93
- clone[field] = sched[field].slice(0);
94
- }
95
- }
96
- return clone;
97
- }
98
-
99
- /**
100
- * Adds values to the specified constraint in the current schedule.
101
- *
102
- * @param {Object} sched: The schedule to add the constraint to
103
- * @param {String} name: Name of constraint to add
104
- * @param {Number} min: Minimum value for this constraint
105
- * @param {Number} max: Maximum value for this constraint
106
- */
107
- function add(sched, name, min, max) {
108
- var inc = arguments.length <= 4 || arguments[4] === undefined ? 0 : arguments[4];
109
- var i = min;
110
- if (!sched[name]) {
111
- sched[name] = [];
112
- }
113
- while (i <= max) {
114
- if (sched[name].indexOf(i) < 0) {
115
- sched[name].push(i);
116
- }
117
- i += inc || 1;
6
+ function cronToText(cronSpec, withSeconds, locale) {
7
+ // Constant array to convert valid names to values
8
+ const NAMES = {
9
+ JAN: 1,
10
+ FEB: 2,
11
+ MAR: 3,
12
+ APR: 4,
13
+ MAY: 5,
14
+ JUN: 6,
15
+ JUL: 7,
16
+ AUG: 8,
17
+ SEP: 9,
18
+ OCT: 10,
19
+ NOV: 11,
20
+ DEC: 12,
21
+ SUN: 1,
22
+ MON: 2,
23
+ TUE: 3,
24
+ WED: 4,
25
+ THU: 5,
26
+ FRI: 6,
27
+ SAT: 7,
28
+ };
29
+ // Parsable replacements for common expressions
30
+ const REPLACEMENTS = {
31
+ '* * * * * *': '0/1 * * * * *',
32
+ '@YEARLY': '0 0 1 1 *',
33
+ '@ANNUALLY': '0 0 1 1 *',
34
+ '@MONTHLY': '0 0 1 * *',
35
+ '@WEEKLY': '0 0 * * 0',
36
+ '@DAILY': '0 0 * * *',
37
+ '@HOURLY': '0 * * * *',
38
+ };
39
+ // Contains the index, min, and max for each of the constraints
40
+ const FIELDS = {
41
+ s: [0, 0, 59], // seconds
42
+ m: [1, 0, 59], // minutes
43
+ h: [2, 0, 23], // hours
44
+ D: [3, 1, 31], // day of month
45
+ M: [4, 1, 12], // month
46
+ Y: [6, 1970, 2099], // year
47
+ d: [5, 1, 7, 1], // day of the week
48
+ };
49
+ /**
50
+ * Returns the value + offset if value is a number, otherwise it
51
+ * attempts to look up the value in the NAMES table and returns
52
+ * that result instead.
53
+ */
54
+ function getValue(
55
+ /** the value that should be parsed */
56
+ value,
57
+ /** Any offset that must be added to the value */
58
+ offset = 0, max = 9999) {
59
+ return Number.isNaN(value) ? NAMES[value] || null : Math.min(+value + offset, max);
118
60
  }
119
- sched[name].sort(function (a, b) {
120
- return a - b;
121
- });
122
- }
123
-
124
- /**
125
- * Adds a hash item (of the form x#y or xL) to the schedule.
126
- *
127
- * @param {Object} schedules: The current schedule array to add to
128
- * @param {Object} curSched: The current schedule to add to
129
- * @param {Number} value: The value to add (x of x#y or xL)
130
- * @param {Number} hash: The hash value to add (y of x#y)
131
- */
132
- function addHash(schedules, curSched, value, hash) {
133
- // if there are any existing day of week constraints that
134
- // aren't equal to the one we're adding, create a new
135
- // composite schedule
136
- if (curSched.d && !curSched.dc || curSched.dc && curSched.dc.indexOf(hash) < 0) {
137
- schedules.push(cloneSchedule(curSched));
138
- curSched = schedules[schedules.length - 1];
61
+ /**
62
+ * Returns a deep clone of a schedule skipping any day of week
63
+ * constraints.
64
+ */
65
+ function cloneSchedule(
66
+ /** The schedule that will be cloned */
67
+ sched) {
68
+ const clone = {};
69
+ let field;
70
+ for (field in sched) {
71
+ if (field !== 'dc' && field !== 'd') {
72
+ clone[field] = sched[field].slice(0);
73
+ }
74
+ }
75
+ return clone;
139
76
  }
140
- add(curSched, 'd', value, value);
141
- add(curSched, 'dc', hash, hash);
142
- }
143
-
144
- /**
145
- *
146
- * @param {Object} s: The existing set of schedules
147
- * @param {Object} curSched: The current schedule to add to
148
- * @param {Number} value
149
- */
150
- function addWeekday(s, curSched, value) {
151
- var except1 = {};
152
- var except2 = {};
153
- if (value === 1) {
154
- // cron doesn't pass month boundaries, so if 1st is a
155
- // weekend then we need to use 2nd or 3rd instead
156
- add(curSched, 'D', 1, 3);
157
- add(curSched, 'd', NAMES.MON, NAMES.FRI);
158
- add(except1, 'D', 2, 2);
159
- add(except1, 'd', NAMES.TUE, NAMES.FRI);
160
- add(except2, 'D', 3, 3);
161
- add(except2, 'd', NAMES.TUE, NAMES.FRI);
162
- } else {
163
- // normally you want the closest day, so if v is a
164
- // Saturday, use the previous Friday. If it's a
165
- // sunday, use the following Monday.
166
- add(curSched, 'D', value - 1, value + 1);
167
- add(curSched, 'd', NAMES.MON, NAMES.FRI);
168
- add(except1, 'D', value - 1, value - 1);
169
- add(except1, 'd', NAMES.MON, NAMES.THU);
170
- add(except2, 'D', value + 1, value + 1);
171
- add(except2, 'd', NAMES.TUE, NAMES.FRI);
77
+ /**
78
+ * Adds values to the specified constraint in the current schedule.
79
+ */
80
+ function add(
81
+ /** The schedule to add the constraint to */
82
+ sched,
83
+ /** The name of the constraint to add */
84
+ name,
85
+ /** The minimum value for this constraint */
86
+ min,
87
+ /** The maximum value for this constraint */
88
+ max,
89
+ /** The increment value for this constraint */
90
+ inc = 0) {
91
+ let i = min;
92
+ if (!sched[name]) {
93
+ sched[name] = [];
94
+ }
95
+ while (i <= max) {
96
+ if (sched[name].indexOf(i) < 0) {
97
+ sched[name].push(i);
98
+ }
99
+ i += inc || 1;
100
+ }
101
+ sched[name].sort((a, b) => a - b);
172
102
  }
173
- s.exceptions.push(except1);
174
- s.exceptions.push(except2);
175
- }
176
-
177
- /**
178
- * Adds a range item (of the form x-y/z) to the schedule.
179
- *
180
- * @param {String} item: The cron expression item to add
181
- * @param {Object} curSched: The current schedule to add to
182
- * @param {String} name: The name to use for this constraint
183
- * @param {Number} min: The min value for the constraint
184
- * @param {Number} max: The max value for the constraint
185
- * @param {Number} offset: The offset to apply to the cron value
186
- */
187
- function addRange(item, curSched, name, min, max, offset) {
188
- // parse range/x
189
- var incSplit = item.split('/');
190
- var inc = +incSplit[1];
191
- var range = incSplit[0];
192
-
193
- // parse x-y or * or 0
194
- if (range !== '*' && range !== '0') {
195
- var rangeSplit = range.split('-');
196
- min = getValue(rangeSplit[0], offset, max);
197
-
198
- // fix for issue #13, range may be a single digit
199
- max = getValue(rangeSplit[1], offset, max) || max;
103
+ /**
104
+ * Adds a hash item (of the form x#y or xL) to the schedule.
105
+ */
106
+ function addHash(
107
+ /** The current set of schedules */
108
+ schedules,
109
+ /** The current schedule to add to */
110
+ curSched,
111
+ /** The value to add (x of x#y or xL) */
112
+ value,
113
+ /** The hash value to add (y of x#y) */
114
+ hash) {
115
+ // if there are any existing days of week constraints that
116
+ // aren't equal to the one we're adding, create a new
117
+ // composite schedule
118
+ if ((curSched.d && !curSched.dc) || (curSched.dc && !curSched.dc.includes(hash))) {
119
+ schedules.push(cloneSchedule(curSched));
120
+ curSched = schedules[schedules.length - 1];
121
+ }
122
+ add(curSched, 'd', value, value);
123
+ add(curSched, 'dc', hash, hash);
200
124
  }
201
- add(curSched, name, min, max, inc);
202
- }
203
-
204
- /**
205
- * Parses a particular item within a cron expression.
206
- *
207
- * @param {String} item: The cron expression item to parse
208
- * @param {Object} s: The existing set of schedules
209
- * @param {String} name: The name to use for this constraint
210
- * @param {Number} min: The min value for the constraint
211
- * @param {Number} max: The max value for the constraint
212
- * @param {Number} offset: The offset to apply to the cron value
213
- */
214
- function parse(item, s, name, min, max, offset) {
215
- var value;
216
- var split;
217
- var schedules = s.schedules;
218
- var curSched = schedules[schedules.length - 1];
219
-
220
- // L just means min - 1 (this also makes it work for any field)
221
- if (item === 'L') {
222
- item = (min - 1).toString(10);
125
+ function addWeekday(
126
+ /** The existing set of schedules */
127
+ s,
128
+ /** The current schedule to add to */
129
+ curSched, value) {
130
+ const except1 = {};
131
+ const except2 = {};
132
+ if (value === 1) {
133
+ // cron doesn't pass month boundaries, so if 1st is a
134
+ // weekend then we need to use 2nd or 3rd instead
135
+ add(curSched, 'D', 1, 3);
136
+ add(curSched, 'd', NAMES.MON, NAMES.FRI);
137
+ add(except1, 'D', 2, 2);
138
+ add(except1, 'd', NAMES.TUE, NAMES.FRI);
139
+ add(except2, 'D', 3, 3);
140
+ add(except2, 'd', NAMES.TUE, NAMES.FRI);
141
+ }
142
+ else {
143
+ // normally you want the closest day, so if v is a
144
+ // Saturday, use the previous Friday. If it's a
145
+ // sunday, use the following Monday.
146
+ add(curSched, 'D', value - 1, value + 1);
147
+ add(curSched, 'd', NAMES.MON, NAMES.FRI);
148
+ add(except1, 'D', value - 1, value - 1);
149
+ add(except1, 'd', NAMES.MON, NAMES.THU);
150
+ add(except2, 'D', value + 1, value + 1);
151
+ add(except2, 'd', NAMES.TUE, NAMES.FRI);
152
+ }
153
+ s.exceptions.push(except1);
154
+ s.exceptions.push(except2);
223
155
  }
224
-
225
- // parse x
226
- if ((value = getValue(item, offset, max)) !== null) {
227
- add(curSched, name, value, value);
228
- } else if ((value = getValue(item.replace('W', ''), offset, max)) !== null) {
229
- // parse xW
230
- addWeekday(s, curSched, value);
231
- } else if ((value = getValue(item.replace('L', ''), offset, max)) !== null) {
232
- // parse xL
233
- addHash(schedules, curSched, value, min - 1);
234
- } else if ((split = item.split('#')).length === 2) {
235
- // parse x#y
236
- value = getValue(split[0], offset, max);
237
- addHash(schedules, curSched, value, getValue(split[1]));
238
- } else {
239
- // parse x-y or x-y/z or */z or 0/z
240
- addRange(item, curSched, name, min, max, offset);
156
+ /**
157
+ * Adds a range item (of the form x-y/z) to the schedule.
158
+ */
159
+ function addRange(
160
+ /** The cron expression item to add */
161
+ item,
162
+ /** The current schedule to add to */
163
+ curSched,
164
+ /** The name to use for this constraint */
165
+ name,
166
+ /** The min value for the constraint */
167
+ min,
168
+ /** The max value for the constraint */
169
+ max,
170
+ /** The offset to apply to the cron value */
171
+ offset) {
172
+ // parse range/x
173
+ const incSplit = item.split('/');
174
+ const inc = +incSplit[1];
175
+ const range = incSplit[0];
176
+ // parse x-y or * or 0
177
+ if (range !== '*' && range !== '0') {
178
+ const rangeSplit = range.split('-');
179
+ min = getValue(rangeSplit[0], offset, max) || offset;
180
+ // fix for issue #13, range may be a single digit
181
+ max = getValue(rangeSplit[1], offset, max) || max;
182
+ }
183
+ add(curSched, name, min, max, inc);
241
184
  }
242
- }
243
-
244
- /**
245
- * Returns true if the item is either of the form x#y or xL.
246
- *
247
- * @param {String} item: The expression item to check
248
- */
249
- function isHash(item) {
250
- return item.indexOf('#') > -1 || item.indexOf('L') > 0;
251
- }
252
- function itemSorter(a, b) {
253
- return isHash(a) && !isHash(b) ? 1 : a - b;
254
- }
255
-
256
- /**
257
- * Parses each of the fields in a cron expression. The expression must
258
- * include the seconds field, the year field is optional.
259
- *
260
- * @param {String} expr: The cron expression to parse
261
- */
262
- function parseExpr(expr) {
263
- var schedule = {
264
- schedules: [{}],
265
- exceptions: []
266
- };
267
- var components = expr.replace(/(\s)+/g, ' ').split(' ');
268
- var field;
269
- var f;
270
- var component;
271
- var items;
272
- for (field in FIELDS) {
273
- f = FIELDS[field];
274
- component = components[f[0]];
275
- if (component && component !== '*' && component !== '?') {
276
- // need to sort so that any #'s come last, otherwise
277
- // schedule clones to handle # won't contain all of the
278
- // other constraints
279
- items = component.split(',').sort(itemSorter);
280
- var i = void 0;
281
- var length = items.length;
282
- for (i = 0; i < length; i++) {
283
- parse(items[i], schedule, field, f[1], f[2], f[3]);
185
+ /**
186
+ * Parses a particular item within a cron expression.
187
+ */
188
+ function parse(
189
+ /** The cron expression item to parse */
190
+ item,
191
+ /** The existing set of schedules */
192
+ s,
193
+ /** The name to use for this constraint */
194
+ name,
195
+ /** The min value for the constraint */
196
+ min,
197
+ /** The max value for the constraint */
198
+ max,
199
+ /** The offset to apply to the cron value */
200
+ offset) {
201
+ let value;
202
+ let split;
203
+ const schedules = s.schedules;
204
+ const curSched = schedules[schedules.length - 1];
205
+ // L just means min - 1 (this also makes it work for any field)
206
+ if (item === 'L') {
207
+ item = (min - 1).toString(10);
208
+ }
209
+ // parse x
210
+ if ((value = getValue(item, offset, max)) !== null) {
211
+ add(curSched, name, value, value);
212
+ }
213
+ else if ((value = getValue(item.replace('W', ''), offset, max)) !== null) {
214
+ // parse xW
215
+ addWeekday(s, curSched, value);
216
+ }
217
+ else if ((value = getValue(item.replace('L', ''), offset, max)) !== null) {
218
+ // parse xL
219
+ addHash(schedules, curSched, value, min - 1);
220
+ }
221
+ else if ((split = item.split('#')).length === 2) {
222
+ // parse x#y
223
+ value = getValue(split[0], offset, max) || offset;
224
+ addHash(schedules, curSched, value, getValue(split[1]) || 0);
225
+ }
226
+ else {
227
+ // parse x-y or x-y/z or */z or 0/z
228
+ addRange(item, curSched, name, min, max, offset);
284
229
  }
285
- }
286
230
  }
287
- return schedule;
288
- }
289
-
290
- /**
291
- * Make cron expression parsable.
292
- *
293
- * @param {String} expr: The cron expression to prepare
294
- */
295
- function prepareExpr(expr) {
296
- var prepared = expr.toUpperCase();
297
- return REPLACEMENTS[prepared] || prepared;
298
- }
299
- function parseCron(expr, hasSeconds) {
300
- var e = prepareExpr(expr);
301
- return parseExpr(hasSeconds ? e : "0 ".concat(e));
302
- }
303
- var schedule = parseCron(cronspec, withSeconds);
304
- function absFloor(number) {
305
- if (number < 0) {
306
- return Math.ceil(number);
231
+ /**
232
+ * Returns true if the item is either of the form x#y or xL.
233
+ */
234
+ function isHash(
235
+ /** The expression item to check */
236
+ item) {
237
+ return item.includes('#') || item.indexOf('L') > 0;
307
238
  }
308
- return Math.floor(number);
309
- }
310
- function toInt(argumentForCoercion) {
311
- var coercedNumber = +argumentForCoercion;
312
- var value = 0;
313
- if (coercedNumber !== 0 && isFinite(coercedNumber)) {
314
- value = absFloor(coercedNumber);
239
+ function itemSorter(a, b) {
240
+ return isHash(a) && !isHash(b) ? 1 : (a > b ? 1 : (a < b ? -1 : 0));
315
241
  }
316
- return value;
317
- }
318
- function ordinal(number) {
319
- var b = number % 10;
320
- var output = toInt(number % 100 / 10) === 1 ? locale.ORDINALS.th : b === 1 ? locale.ORDINALS.st : b === 2 ? locale.ORDINALS.nd : b === 3 ? locale.ORDINALS.rd : locale.ORDINALS.th;
321
- return number + output;
322
- }
323
-
324
- /**
325
- * For an array of numbers, e.g. a list of hours in a schedule,
326
- * return a string listing out all of the values (complete with
327
- * "and" plus ordinal text on the last item).
328
- * @param {Number[]} numbers
329
- * @returns {string}
330
- */
331
- function numberList(numbers) {
332
- if (numbers.length < 2) {
333
- return ordinal(numbers);
242
+ /**
243
+ * Parses each of the fields in a cron expression. The expression must
244
+ * include the second's field, the year field is optional.
245
+ *
246
+ */
247
+ function parseExpr(
248
+ /** The cron expression to parse */
249
+ expr) {
250
+ const schedule = { schedules: [{}], exceptions: [] };
251
+ const components = expr.replace(/(\s)+/g, ' ').split(' ');
252
+ let field;
253
+ let f;
254
+ let component;
255
+ let items;
256
+ for (field in FIELDS) {
257
+ f = FIELDS[field];
258
+ component = components[f[0]];
259
+ if (component && component !== '*' && component !== '?') {
260
+ // need to sort so that any #'s come last, otherwise
261
+ // schedule clones to handle # won't contain all of the
262
+ // other constraints
263
+ items = component.split(',').sort(itemSorter);
264
+ let i;
265
+ const length = items.length;
266
+ for (i = 0; i < length; i++) {
267
+ parse(items[i], schedule, field, f[1], f[2], f[3]);
268
+ }
269
+ }
270
+ }
271
+ return schedule;
334
272
  }
335
- var lastVal = numbers.pop();
336
- return "".concat(numbers.join(', '), " ").concat(locale.and, " ").concat(ordinal(lastVal));
337
- }
338
-
339
- /**
340
- * Parse a number into day of week, or a month name;
341
- * used in dateList below.
342
- * @param {Number|String} value
343
- * @param {String} type
344
- * @returns {String}
345
- */
346
- function numberToDateName(value, type) {
347
- if (type === 'dow') {
348
- return locale.DOW[value - 1];
273
+ /**
274
+ * Make cron expression parsable.
275
+ */
276
+ function prepareExpr(
277
+ /** The cron expression to prepare */
278
+ expr) {
279
+ const prepared = expr.toUpperCase();
280
+ return REPLACEMENTS[prepared] || prepared;
349
281
  }
350
- if (type === 'mon') {
351
- return locale.MONTH[value - 1];
282
+ function parseCron(expr, hasSeconds) {
283
+ const e = prepareExpr(expr);
284
+ return parseExpr(hasSeconds ? e : `0 ${e}`);
352
285
  }
353
- return value;
354
- }
355
-
356
- /**
357
- * From an array of numbers corresponding to dates (given in type: either
358
- * days of the week, or months), return a string listing all the values.
359
- * @param {Number[]} numbers
360
- * @param {String} type
361
- * @returns {String}
362
- */
363
- function dateList(numbers, type) {
364
- if (numbers.length < 2) {
365
- return numberToDateName("".concat(numbers[0]), type);
286
+ const schedule = parseCron(cronSpec, withSeconds);
287
+ function absFloor(number) {
288
+ if (number < 0) {
289
+ return Math.ceil(number);
290
+ }
291
+ return Math.floor(number);
292
+ }
293
+ function toInt(argumentForCoercion) {
294
+ const coercedNumber = +argumentForCoercion;
295
+ let value = 0;
296
+ if (coercedNumber !== 0 && isFinite(coercedNumber)) {
297
+ value = absFloor(coercedNumber);
298
+ }
299
+ return value;
366
300
  }
367
- var lastVal = "".concat(numbers.pop());
368
- var outputText = '';
369
- for (var i = 0, value; value = numbers[i]; i++) {
370
- if (outputText.length > 0) {
371
- outputText += ', ';
372
- }
373
- outputText += numberToDateName(value, type);
301
+ function ordinal(number) {
302
+ const b = number % 10;
303
+ const output = (toInt(number % 100 / 10) === 1) ? locale.ORDINALS.th :
304
+ b === 1 ? locale.ORDINALS.st :
305
+ b === 2 ? locale.ORDINALS.nd :
306
+ b === 3 ? locale.ORDINALS.rd : locale.ORDINALS.th;
307
+ return number + output;
374
308
  }
375
- return "".concat(outputText, " ").concat(locale.and, " ").concat(numberToDateName(lastVal, type));
376
- }
377
-
378
- /**
379
- * Pad to equivalent of sprintf('%02d').
380
- * @param {Number} x
381
- * @returns {string}
382
- */
383
- function zeroPad(x) {
384
- return x < 10 ? "0".concat(x) : x;
385
- }
386
-
387
- //----------------
388
-
389
- /**
390
- * Given a schedule, generate a friendly sentence description.
391
- * @param {Object} _schedule
392
- * @param {boolean} _withSeconds
393
- * @returns {string}
394
- */
395
- function scheduleToSentence(_schedule, _withSeconds) {
396
- var outputText = "".concat(locale.Every, " ");
397
- if (_schedule.h && _schedule.m && _schedule.h.length <= 2 && _schedule.m.length <= 2 && _withSeconds && _schedule.s && _schedule.s.length <= 2) {
398
- // If there are only one or two specified values for
399
- // hour or minute, print them in HH:MM:SS format
400
-
401
- var hm = [];
402
- for (var i = 0; i < _schedule.h.length; i++) {
403
- for (var j = 0; j < _schedule.m.length; j++) {
404
- for (var k = 0; k < _schedule.s.length; k++) {
405
- hm.push("".concat(zeroPad(_schedule.h[i]), ":").concat(zeroPad(_schedule.m[j]), ":").concat(zeroPad(_schedule.s[k])));
406
- }
309
+ /**
310
+ * For an array of numbers, e.g., a list of hours in a schedule,
311
+ * return a string listing out all of the values (complete with
312
+ * "and" plus ordinal text on the last item).
313
+ */
314
+ function numberList(numbers) {
315
+ if (numbers.length < 2) {
316
+ return ordinal(numbers[0]);
407
317
  }
408
- }
409
- if (hm.length < 2) {
410
- outputText = "".concat(locale.At, " ").concat(hm[0]);
411
- } else {
412
- var lastVal = hm.pop();
413
- outputText = "".concat(locale.At, " ").concat(hm.join(', '), " ").concat(locale.and, " ").concat(lastVal);
414
- }
415
- if (!_schedule.d && !_schedule.D) {
416
- outputText += " ".concat(locale['every day'], " ");
417
- }
418
- } else if (_schedule.h && _schedule.m && _schedule.h.length <= 2 && _schedule.m.length <= 2) {
419
- // If there are only one or two specified values for
420
- // hour or minute, print them in HH:MM format
421
-
422
- var _hm = [];
423
- for (var _i = 0; _i < _schedule.h.length; _i++) {
424
- for (var _j = 0; _j < _schedule.m.length; _j++) {
425
- _hm.push("".concat(zeroPad(_schedule.h[_i]), ":").concat(zeroPad(_schedule.m[_j])));
318
+ const lastVal = numbers.pop() || 0;
319
+ return `${numbers.join(', ')} ${locale.and} ${ordinal(lastVal)}`;
320
+ }
321
+ /**
322
+ * Parse a number into day of week, or a month name;
323
+ * used in dateList below.
324
+ * @param {Number|String} value
325
+ * @param {String} type
326
+ * @returns {String}
327
+ */
328
+ function numberToDateName(value, type) {
329
+ if (type === 'dow') {
330
+ return locale.DOW[value - 1];
426
331
  }
427
- }
428
- if (_hm.length < 2) {
429
- outputText = "".concat(locale.At, " ").concat(_hm[0]);
430
- } else {
431
- var _lastVal = _hm.pop();
432
- outputText = "".concat(locale.At, " ").concat(_hm.join(', '), " ").concat(locale.and, " ").concat(_lastVal);
433
- }
434
- if (!_schedule.d && !_schedule.D) {
435
- outputText += " ".concat(locale['every day'], " ");
436
- }
437
- } else if (_schedule.h) {
438
- // runs only at specific hours
439
- // Otherwise, list out every specified hour/minute value.
440
- if (_schedule.m) {
441
- // and only at specific minutes
442
- if (_withSeconds) {
443
- if (!_schedule.s || _schedule.s.length === 60) {
444
- outputText += "".concat(locale['second of every'], " ").concat(numberList(_schedule.m), " ").concat(locale['minute past the'], " ").concat(numberList(_schedule.h), " ").concat(locale.hour);
445
- } else {
446
- outputText += "".concat(numberList(_schedule.s), " ").concat(locale['second of every'], " ").concat(numberList(_schedule.m), " ").concat(locale['minute past the'], " ").concat(numberList(_schedule.h), " ").concat(locale.hour);
447
- }
448
- } else {
449
- outputText += "".concat(numberList(_schedule.m), " ").concat(locale['minute past the'], " ").concat(numberList(_schedule.h), " ").concat(locale.hour);
332
+ if (type === 'mon') {
333
+ return locale.MONTH[value - 1];
450
334
  }
451
- } else if (_withSeconds) {
452
- // specific hours, but every minute
453
- if (!_schedule.s || _schedule.s.length === 60) {
454
- outputText += "".concat(locale['second of every'], " ").concat(locale['minute of'], " ").concat(numberList(_schedule.h), " ").concat(locale.hour);
455
- } else {
456
- outputText += "".concat(numberList(_schedule.s), " ").concat(locale['second of every'], " ").concat(locale['minute of'], " ").concat(numberList(_schedule.h), " ").concat(locale.hour);
335
+ return value;
336
+ }
337
+ /**
338
+ * From an array of numbers corresponding to dates (given in type: either
339
+ * days of the week, or months), return a string listing all the values.
340
+ * @param {Number[]} numbers
341
+ * @param {String} type
342
+ * @returns {String}
343
+ */
344
+ function dateList(numbers, type) {
345
+ if (numbers.length < 2) {
346
+ return numberToDateName(numbers[0], type);
457
347
  }
458
- } else {
459
- outputText += "".concat(locale['minute of'], " ").concat(numberList(_schedule.h), " ").concat(locale.hour);
460
- }
461
- } else if (_schedule.m) {
462
- // every hour, but specific minutes
463
- if (_withSeconds) {
464
- if (!_schedule.s || _schedule.s.length === 60) {
465
- outputText += "".concat(locale['second of every'], " ").concat(numberList(_schedule.m), " ").concat(locale['minute every hour']);
466
- } else {
467
- outputText += "".concat(numberList(_schedule.s), " ").concat(locale['second of every'], " ").concat(numberList(_schedule.m), " ").concat(locale['minute every hour']);
348
+ const lastVal = numbers.pop() || 0;
349
+ let outputText = '';
350
+ for (let i = 0, value; (value = numbers[i]); i++) {
351
+ if (outputText.length > 0) {
352
+ outputText += ', ';
353
+ }
354
+ outputText += numberToDateName(value, type);
468
355
  }
469
- } else {
470
- outputText += "".concat(numberList(_schedule.m), " ").concat(locale['minute every hour']);
471
- }
472
- } else if (_withSeconds) {
473
- if (!_schedule.s || _schedule.s.length === 60) {
474
- outputText += locale.second;
475
- } else {
476
- outputText += "".concat(numberList(_schedule.s), " ").concat(locale.second);
477
- }
478
- } else {
479
- // cronspec has "*" for both hour and minute
480
- outputText += locale.minute;
356
+ return `${outputText} ${locale.and} ${numberToDateName(lastVal, type)}`;
481
357
  }
482
- if (_schedule.D) {
483
- // runs only on specific day(s) of month
484
- outputText += (locale['on the'] ? " ".concat(locale['on the'], " ") : ' ') + numberList(_schedule.D);
485
- if (!_schedule.M) {
486
- outputText += " ".concat(locale['of every month']);
487
- }
358
+ /**
359
+ * Pad to the equivalent of sprintf('%02d').
360
+ * @param {Number} x
361
+ * @returns {string}
362
+ */
363
+ function zeroPad(x) {
364
+ return x < 10 ? `0${x}` : x.toString();
488
365
  }
489
- if (_schedule.d) {
490
- // runs only on specific day(s) of week
491
- if (_schedule.D) {
492
- // if both day fields are specified, cron uses both; superuser.com/a/348372
493
- outputText += " ".concat(locale['and every'], " ");
494
- } else {
495
- outputText += " ".concat(locale.on, " ");
496
- }
497
- outputText += dateList(_schedule.d, 'dow');
498
- }
499
- if (_schedule.M) {
500
- // runs only in specific months; put this output last
501
- outputText += " ".concat(locale["in"], " ").concat(dateList(_schedule.M, 'mon'));
366
+ //----------------
367
+ /**
368
+ * Given a schedule, generate a friendly sentence description.
369
+ */
370
+ function scheduleToSentence(_schedule, _withSeconds) {
371
+ let outputText = `${locale.Every} `;
372
+ if (_schedule.h && _schedule.m && _schedule.h.length <= 2 && _schedule.m.length <= 2 && _withSeconds && _schedule.s && _schedule.s.length <= 2) {
373
+ // If there are only one or two specified values for
374
+ // hour or minute, print them in HH:MM:SS format
375
+ const hm = [];
376
+ for (let i = 0; i < _schedule.h.length; i++) {
377
+ for (let j = 0; j < _schedule.m.length; j++) {
378
+ for (let k = 0; k < _schedule.s.length; k++) {
379
+ hm.push(`${zeroPad(_schedule.h[i])}:${zeroPad(_schedule.m[j])}:${zeroPad(_schedule.s[k])}`);
380
+ }
381
+ }
382
+ }
383
+ if (hm.length < 2) {
384
+ outputText = `${locale.At} ${hm[0]}`;
385
+ }
386
+ else {
387
+ const lastVal = hm.pop();
388
+ outputText = `${locale.At} ${hm.join(', ')} ${locale.and} ${lastVal}`;
389
+ }
390
+ if (!_schedule.d && !_schedule.D) {
391
+ outputText += ` ${locale['every day']} `;
392
+ }
393
+ }
394
+ else if (_schedule.h && _schedule.m && _schedule.h.length <= 2 && _schedule.m.length <= 2) {
395
+ // If there are only one or two specified values for
396
+ // hour or minute, print them in HH:MM format
397
+ const hm = [];
398
+ for (let i = 0; i < _schedule.h.length; i++) {
399
+ for (let j = 0; j < _schedule.m.length; j++) {
400
+ hm.push(`${zeroPad(_schedule.h[i])}:${zeroPad(_schedule.m[j])}`);
401
+ }
402
+ }
403
+ if (hm.length < 2) {
404
+ outputText = `${locale.At} ${hm[0]}`;
405
+ }
406
+ else {
407
+ const lastVal = hm.pop();
408
+ outputText = `${locale.At} ${hm.join(', ')} ${locale.and} ${lastVal}`;
409
+ }
410
+ if (!_schedule.d && !_schedule.D) {
411
+ outputText += ` ${locale['every day']} `;
412
+ }
413
+ }
414
+ else if (_schedule.h) { // runs only at specific hours
415
+ // Otherwise, list out every specified hour/minute value.
416
+ if (_schedule.m) { // and only at specific minutes
417
+ if (_withSeconds) {
418
+ if (!_schedule.s || _schedule.s.length === 60) {
419
+ outputText += `${locale['second of every']} ${numberList(_schedule.m)} ${locale['minute past the']} ${numberList(_schedule.h)} ${locale.hour}`;
420
+ }
421
+ else {
422
+ outputText += `${numberList(_schedule.s)} ${locale['second of every']} ${numberList(_schedule.m)} ${locale['minute past the']} ${numberList(_schedule.h)} ${locale.hour}`;
423
+ }
424
+ }
425
+ else {
426
+ outputText += `${numberList(_schedule.m)} ${locale['minute past the']} ${numberList(_schedule.h)} ${locale.hour}`;
427
+ }
428
+ }
429
+ else if (_withSeconds) {
430
+ // specific hours, but every minute
431
+ if (!_schedule.s || _schedule.s.length === 60) {
432
+ outputText += `${locale['second of every']} ${locale['minute of']} ${numberList(_schedule.h)} ${locale.hour}`;
433
+ }
434
+ else {
435
+ outputText += `${numberList(_schedule.s)} ${locale['second of every']} ${locale['minute of']} ${numberList(_schedule.h)} ${locale.hour}`;
436
+ }
437
+ }
438
+ else {
439
+ outputText += `${locale['minute of']} ${numberList(_schedule.h)} ${locale.hour}`;
440
+ }
441
+ }
442
+ else if (_schedule.m) { // every hour, but specific minutes
443
+ if (_withSeconds) {
444
+ if (!_schedule.s || _schedule.s.length === 60) {
445
+ outputText += `${locale['second of every']} ${numberList(_schedule.m)} ${locale['minute every hour']}`;
446
+ }
447
+ else {
448
+ outputText += `${numberList(_schedule.s)} ${locale['second of every']} ${numberList(_schedule.m)} ${locale['minute every hour']}`;
449
+ }
450
+ }
451
+ else {
452
+ outputText += `${numberList(_schedule.m)} ${locale['minute every hour']}`;
453
+ }
454
+ }
455
+ else if (_withSeconds) {
456
+ if (!_schedule.s || _schedule.s.length === 60) {
457
+ outputText += locale.second;
458
+ }
459
+ else {
460
+ outputText += `${numberList(_schedule.s)} ${locale.second}`;
461
+ }
462
+ }
463
+ else { // cronSpec has "*" for both hour and minute
464
+ outputText += locale.minute;
465
+ }
466
+ if (_schedule.D) { // runs only on specific day(s) of month
467
+ outputText += (locale['on the'] ? ` ${locale['on the']} ` : ' ') + numberList(_schedule.D);
468
+ if (!_schedule.M) {
469
+ outputText += ` ${locale['of every month']}`;
470
+ }
471
+ }
472
+ if (_schedule.d) { // runs only on specific day(s) of week
473
+ if (_schedule.D) {
474
+ // if both day fields are specified, cron uses both; superuser.com/a/348372
475
+ outputText += ` ${locale['and every']} `;
476
+ }
477
+ else {
478
+ outputText += ` ${locale.on} `;
479
+ }
480
+ outputText += dateList(_schedule.d, 'dow');
481
+ }
482
+ if (_schedule.M) {
483
+ // runs only in specific months; put this output last
484
+ outputText += ` ${locale.in} ${dateList(_schedule.M, 'mon')}`;
485
+ }
486
+ return outputText;
502
487
  }
503
- return outputText;
504
- }
505
- return scheduleToSentence(schedule.schedules[0], withSeconds);
488
+ return scheduleToSentence(schedule.schedules[0], withSeconds);
506
489
  }
507
- var _default = exports["default"] = cronToText;
508
- //# sourceMappingURL=cron2text.js.map
490
+ exports.default = cronToText;