cron-converter-u2q 1.3.1 → 1.3.2
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/lib/converter.d.ts +1 -6
- package/lib/converter.js +19 -18
- package/lib/helper.js +2 -2
- package/package.json +1 -1
- package/src/__tests__/index.test.ts +43 -0
- package/src/converter.ts +18 -17
- package/src/helper.ts +2 -2
- package/types/index.d.ts +1 -1
package/lib/converter.d.ts
CHANGED
|
@@ -4,18 +4,13 @@ export declare class CronConverterU2Q {
|
|
|
4
4
|
* @param unixExpression - the unix expression
|
|
5
5
|
* @returns the corresponding quartz expression
|
|
6
6
|
*/
|
|
7
|
-
static unixToQuartz(unixExpression: string): string;
|
|
7
|
+
static unixToQuartz(unixExpression: string, year?: string): string;
|
|
8
8
|
/**
|
|
9
9
|
* Converts a quartz cron expression to a unix cron expression
|
|
10
10
|
* @param quartzExpression - the quartz expression
|
|
11
11
|
* @returns the corresponding unix expression
|
|
12
12
|
*/
|
|
13
13
|
static quartzToUnix(quartzExpression: string): string;
|
|
14
|
-
/**
|
|
15
|
-
* Converts interval parts for both Unix and Quartz expressions.
|
|
16
|
-
* In both directions, normalises step notation to the Unix `*\/N` format.
|
|
17
|
-
*/
|
|
18
|
-
private static convertIntervalParts;
|
|
19
14
|
/**
|
|
20
15
|
* Converts Unix DOW to Quartz DOW, supporting lists, ranges, and special cases.
|
|
21
16
|
* Unix: 0=Sun, 1=Mon, ..., 6=Sat, 7=Sun(alias)
|
package/lib/converter.js
CHANGED
|
@@ -9,10 +9,10 @@ class CronConverterU2Q {
|
|
|
9
9
|
* @param unixExpression - the unix expression
|
|
10
10
|
* @returns the corresponding quartz expression
|
|
11
11
|
*/
|
|
12
|
-
static unixToQuartz(unixExpression) {
|
|
12
|
+
static unixToQuartz(unixExpression, year = '*') {
|
|
13
13
|
validator_1.CronValidatorU2Q.validateUnix(unixExpression);
|
|
14
14
|
const parts = helper_1.ExpressionHelper.GetExpressionParts(unixExpression);
|
|
15
|
-
const [min, hour, dom, month, dow] = parts
|
|
15
|
+
const [min, hour, dom, month, dow] = parts;
|
|
16
16
|
// Enhanced DOW conversion: handle lists, ranges, and special cases
|
|
17
17
|
let quartzDow = this.unixDowToQuartz(dow);
|
|
18
18
|
let quartzDom = dom;
|
|
@@ -24,7 +24,14 @@ class CronConverterU2Q {
|
|
|
24
24
|
else if (dom !== '*' && dow === '*') {
|
|
25
25
|
quartzDow = '?';
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
else if (dom !== '*' && dow !== '*') {
|
|
28
|
+
throw new Error("Quartz cron does not support specifying both Day of Month and Day of Week");
|
|
29
|
+
}
|
|
30
|
+
const result = `0 ${min} ${hour} ${quartzDom} ${month} ${quartzDow} ${year}`;
|
|
31
|
+
if (year !== '*') {
|
|
32
|
+
validator_1.CronValidatorU2Q.validateQuartz(result);
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
28
35
|
}
|
|
29
36
|
/**
|
|
30
37
|
* Converts a quartz cron expression to a unix cron expression
|
|
@@ -34,7 +41,7 @@ class CronConverterU2Q {
|
|
|
34
41
|
static quartzToUnix(quartzExpression) {
|
|
35
42
|
validator_1.CronValidatorU2Q.validateQuartz(quartzExpression);
|
|
36
43
|
const parts = helper_1.ExpressionHelper.GetExpressionParts(quartzExpression);
|
|
37
|
-
const [_, min, hour, dom, month, dow] = parts.map(part =>
|
|
44
|
+
const [_, min, hour, dom, month, dow] = parts.map(part => part.replace(/^0\/(\d+)$/, '*/$1'));
|
|
38
45
|
if (dom.includes('L') || dom.includes('W')) {
|
|
39
46
|
throw new Error("Unix cron does not support 'L' or 'W' in Day of Month");
|
|
40
47
|
}
|
|
@@ -46,16 +53,6 @@ class CronConverterU2Q {
|
|
|
46
53
|
let unixDom = dom === '?' ? '*' : dom;
|
|
47
54
|
return `${min} ${hour} ${unixDom} ${month} ${unixDow}`;
|
|
48
55
|
}
|
|
49
|
-
/**
|
|
50
|
-
* Converts interval parts for both Unix and Quartz expressions.
|
|
51
|
-
* In both directions, normalises step notation to the Unix `*\/N` format.
|
|
52
|
-
*/
|
|
53
|
-
static convertIntervalParts(part, isQuartz = false) {
|
|
54
|
-
if (isQuartz) {
|
|
55
|
-
return part.replace(/^0\/(\d+)$/, '*/$1');
|
|
56
|
-
}
|
|
57
|
-
return part;
|
|
58
|
-
}
|
|
59
56
|
/**
|
|
60
57
|
* Converts Unix DOW to Quartz DOW, supporting lists, ranges, and special cases.
|
|
61
58
|
* Unix: 0=Sun, 1=Mon, ..., 6=Sat, 7=Sun(alias)
|
|
@@ -64,8 +61,10 @@ class CronConverterU2Q {
|
|
|
64
61
|
static unixDowToQuartz(dow) {
|
|
65
62
|
if (dow === '*' || dow === '?')
|
|
66
63
|
return dow;
|
|
67
|
-
if (dow.includes(','))
|
|
68
|
-
|
|
64
|
+
if (dow.includes(',')) {
|
|
65
|
+
const mapped = dow.split(',').map(d => this.unixDowToQuartz(d));
|
|
66
|
+
return Array.from(new Set(mapped)).join(',');
|
|
67
|
+
}
|
|
69
68
|
if (dow.includes('-'))
|
|
70
69
|
return dow.split('-').map(d => this.unixDowToQuartz(d)).join('-');
|
|
71
70
|
if (dow.endsWith('L')) {
|
|
@@ -92,8 +91,10 @@ class CronConverterU2Q {
|
|
|
92
91
|
if (dow === '*' || dow === '?')
|
|
93
92
|
return dow === '?' ? '*' : dow;
|
|
94
93
|
// Split compound expressions so each element is converted individually
|
|
95
|
-
if (dow.includes(','))
|
|
96
|
-
|
|
94
|
+
if (dow.includes(',')) {
|
|
95
|
+
const mapped = dow.split(',').map(d => this.quartzDowToUnix(d));
|
|
96
|
+
return Array.from(new Set(mapped)).join(',');
|
|
97
|
+
}
|
|
97
98
|
if (dow.includes('-'))
|
|
98
99
|
return dow.split('-').map(d => this.quartzDowToUnix(d)).join('-');
|
|
99
100
|
// Last (L) — convert the numeric day part, preserve L suffix
|
package/lib/helper.js
CHANGED
|
@@ -4,10 +4,10 @@ exports.ExpressionHelper = void 0;
|
|
|
4
4
|
class ExpressionHelper {
|
|
5
5
|
static GetExpressionParts(expression) {
|
|
6
6
|
this.validateIfNullOrEmpty(expression);
|
|
7
|
-
const parts = expression.
|
|
7
|
+
const parts = expression.trim().split(/\s+/);
|
|
8
8
|
if (this.quartzExpressionLengths.includes(parts.length))
|
|
9
9
|
return parts;
|
|
10
|
-
if (this.unixExpressionLength
|
|
10
|
+
if (this.unixExpressionLength === parts.length)
|
|
11
11
|
return parts;
|
|
12
12
|
throw new Error(`Invalid cron expression!`);
|
|
13
13
|
}
|
package/package.json
CHANGED
|
@@ -290,6 +290,49 @@ describe("Converter: error handling", () => {
|
|
|
290
290
|
test("quartzToUnix throws on 8-field expression", () => {
|
|
291
291
|
expect(() => converter.quartzToUnix("* * * * * * * *")).toThrow();
|
|
292
292
|
});
|
|
293
|
+
|
|
294
|
+
test("unixToQuartz throws when both DOM and DOW are specific", () => {
|
|
295
|
+
expect(() => converter.unixToQuartz("0 0 15 * 1")).toThrow("Quartz cron does not support specifying both Day of Month and Day of Week");
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
describe("Converter: deduplication of DOW values", () => {
|
|
300
|
+
test("unixToQuartz deduplicates redundant DOW values (e.g. 0,7)", () => {
|
|
301
|
+
expect(converter.unixToQuartz("0 0 * * 0,7")).toBe("0 0 0 ? * 1 *");
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
test("quartzToUnix deduplicates redundant DOW values (e.g. 2,2)", () => {
|
|
305
|
+
expect(converter.quartzToUnix("0 0 0 ? * 2,2")).toBe("0 0 * * 1");
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
describe("ExpressionHelper whitespace robustness", () => {
|
|
310
|
+
test("handles multiple spaces, tabs, and leading/trailing whitespace correctly", () => {
|
|
311
|
+
expect(converter.unixToQuartz(" 0 12 * * * ")).toBe("0 0 12 * * * *");
|
|
312
|
+
expect(converter.unixToQuartz("0\t12\t*\t*\t*")).toBe("0 0 12 * * * *");
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
describe("Converter: optional year parameter", () => {
|
|
317
|
+
test("unixToQuartz accepts specific year", () => {
|
|
318
|
+
expect(converter.unixToQuartz("0 12 * * 1", "2026")).toBe("0 0 12 ? * 2 2026");
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
test("unixToQuartz throws on invalid specific year", () => {
|
|
322
|
+
expect(() => converter.unixToQuartz("0 12 * * 1", "invalid_year")).toThrow();
|
|
323
|
+
expect(() => converter.unixToQuartz("0 12 * * 1", "1969")).toThrow(); // out of range
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
test("round-tripping Quartz -> Unix -> Quartz with specific years", () => {
|
|
327
|
+
const originalQuartz = "0 0 12 ? * 2 2026";
|
|
328
|
+
const unix = converter.quartzToUnix(originalQuartz); // "0 12 * * 1"
|
|
329
|
+
|
|
330
|
+
const parts = originalQuartz.split(/\s+/);
|
|
331
|
+
const year = parts.length === 7 ? parts[6] : "*";
|
|
332
|
+
|
|
333
|
+
const reconstructedQuartz = converter.unixToQuartz(unix, year);
|
|
334
|
+
expect(reconstructedQuartz).toBe(originalQuartz);
|
|
335
|
+
});
|
|
293
336
|
});
|
|
294
337
|
|
|
295
338
|
describe("Validator Checks", () => {
|
package/src/converter.ts
CHANGED
|
@@ -7,10 +7,10 @@ export class CronConverterU2Q {
|
|
|
7
7
|
* @param unixExpression - the unix expression
|
|
8
8
|
* @returns the corresponding quartz expression
|
|
9
9
|
*/
|
|
10
|
-
public static unixToQuartz(unixExpression: string): string {
|
|
10
|
+
public static unixToQuartz(unixExpression: string, year = '*'): string {
|
|
11
11
|
CronValidatorU2Q.validateUnix(unixExpression);
|
|
12
12
|
const parts = helper.GetExpressionParts(unixExpression);
|
|
13
|
-
const [min, hour, dom, month, dow] = parts
|
|
13
|
+
const [min, hour, dom, month, dow] = parts;
|
|
14
14
|
|
|
15
15
|
// Enhanced DOW conversion: handle lists, ranges, and special cases
|
|
16
16
|
let quartzDow = this.unixDowToQuartz(dow);
|
|
@@ -22,9 +22,15 @@ export class CronConverterU2Q {
|
|
|
22
22
|
quartzDom = '?';
|
|
23
23
|
} else if (dom !== '*' && dow === '*') {
|
|
24
24
|
quartzDow = '?';
|
|
25
|
+
} else if (dom !== '*' && dow !== '*') {
|
|
26
|
+
throw new Error("Quartz cron does not support specifying both Day of Month and Day of Week");
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
const result = `0 ${min} ${hour} ${quartzDom} ${month} ${quartzDow} ${year}`;
|
|
30
|
+
if (year !== '*') {
|
|
31
|
+
CronValidatorU2Q.validateQuartz(result);
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
/**
|
|
@@ -35,7 +41,7 @@ export class CronConverterU2Q {
|
|
|
35
41
|
public static quartzToUnix(quartzExpression: string): string {
|
|
36
42
|
CronValidatorU2Q.validateQuartz(quartzExpression);
|
|
37
43
|
const parts = helper.GetExpressionParts(quartzExpression);
|
|
38
|
-
const [_, min, hour, dom, month, dow] = parts.map(part =>
|
|
44
|
+
const [_, min, hour, dom, month, dow] = parts.map(part => part.replace(/^0\/(\d+)$/, '*/$1'));
|
|
39
45
|
|
|
40
46
|
if (dom.includes('L') || dom.includes('W')) {
|
|
41
47
|
throw new Error("Unix cron does not support 'L' or 'W' in Day of Month");
|
|
@@ -51,17 +57,6 @@ export class CronConverterU2Q {
|
|
|
51
57
|
return `${min} ${hour} ${unixDom} ${month} ${unixDow}`;
|
|
52
58
|
}
|
|
53
59
|
|
|
54
|
-
/**
|
|
55
|
-
* Converts interval parts for both Unix and Quartz expressions.
|
|
56
|
-
* In both directions, normalises step notation to the Unix `*\/N` format.
|
|
57
|
-
*/
|
|
58
|
-
private static convertIntervalParts(part: string, isQuartz = false): string {
|
|
59
|
-
if (isQuartz) {
|
|
60
|
-
return part.replace(/^0\/(\d+)$/, '*/$1');
|
|
61
|
-
}
|
|
62
|
-
return part;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
60
|
/**
|
|
66
61
|
* Converts Unix DOW to Quartz DOW, supporting lists, ranges, and special cases.
|
|
67
62
|
* Unix: 0=Sun, 1=Mon, ..., 6=Sat, 7=Sun(alias)
|
|
@@ -69,7 +64,10 @@ export class CronConverterU2Q {
|
|
|
69
64
|
*/
|
|
70
65
|
private static unixDowToQuartz(dow: string): string {
|
|
71
66
|
if (dow === '*' || dow === '?') return dow;
|
|
72
|
-
if (dow.includes(','))
|
|
67
|
+
if (dow.includes(',')) {
|
|
68
|
+
const mapped = dow.split(',').map(d => this.unixDowToQuartz(d));
|
|
69
|
+
return Array.from(new Set(mapped)).join(',');
|
|
70
|
+
}
|
|
73
71
|
if (dow.includes('-')) return dow.split('-').map(d => this.unixDowToQuartz(d)).join('-');
|
|
74
72
|
if (dow.endsWith('L')) {
|
|
75
73
|
const day = dow.slice(0, -1);
|
|
@@ -94,7 +92,10 @@ export class CronConverterU2Q {
|
|
|
94
92
|
if (dow === '*' || dow === '?') return dow === '?' ? '*' : dow;
|
|
95
93
|
|
|
96
94
|
// Split compound expressions so each element is converted individually
|
|
97
|
-
if (dow.includes(','))
|
|
95
|
+
if (dow.includes(',')) {
|
|
96
|
+
const mapped = dow.split(',').map(d => this.quartzDowToUnix(d));
|
|
97
|
+
return Array.from(new Set(mapped)).join(',');
|
|
98
|
+
}
|
|
98
99
|
if (dow.includes('-')) return dow.split('-').map(d => this.quartzDowToUnix(d)).join('-');
|
|
99
100
|
|
|
100
101
|
// Last (L) — convert the numeric day part, preserve L suffix
|
package/src/helper.ts
CHANGED
|
@@ -5,9 +5,9 @@ export class ExpressionHelper {
|
|
|
5
5
|
|
|
6
6
|
public static GetExpressionParts(expression: string): string[] {
|
|
7
7
|
this.validateIfNullOrEmpty(expression);
|
|
8
|
-
const parts = expression.
|
|
8
|
+
const parts = expression.trim().split(/\s+/);
|
|
9
9
|
if (this.quartzExpressionLengths.includes(parts.length)) return parts;
|
|
10
|
-
if (this.unixExpressionLength
|
|
10
|
+
if (this.unixExpressionLength === parts.length) return parts;
|
|
11
11
|
|
|
12
12
|
throw new Error(`Invalid cron expression!`)
|
|
13
13
|
}
|
package/types/index.d.ts
CHANGED