cron-converter-u2q 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -56
- package/lib/converter.d.ts +17 -4
- package/lib/converter.js +93 -28
- package/lib/describer.d.ts +41 -0
- package/lib/describer.js +272 -0
- package/lib/helper.d.ts +7 -0
- package/lib/helper.js +22 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/validator.d.ts +6 -0
- package/lib/validator.js +215 -0
- package/package.json +4 -1
- package/src/__tests__/index.test.ts +194 -34
- package/src/__tests__/specs-compliance.test.ts +137 -0
- package/src/converter.ts +43 -33
- package/src/describer.ts +169 -57
- package/src/helper.ts +2 -2
- package/src/index.ts +1 -0
- package/src/validator.ts +228 -0
- package/types/index.d.ts +15 -5
package/README.md
CHANGED
|
@@ -1,100 +1,131 @@
|
|
|
1
1
|
# cron-converter-u2q
|
|
2
2
|
|
|
3
|
-

|
|
3
|
+
[](https://github.com/rahu619/cron-converter-u2q)
|
|
4
4
|
[](https://www.npmjs.com/package/cron-converter-u2q)
|
|
5
|
-

|
|
6
|
-

|
|
7
|
-

|
|
8
|
-

|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://github.com/rahu619/cron-converter-u2q/actions)
|
|
7
|
+
[](https://github.com/rahu619/cron-converter-u2q/actions)
|
|
8
|
+
[](https://www.typescriptlang.org/)
|
|
9
|
+
[](https://www.npmjs.com/package/cron-converter-u2q)
|
|
9
10
|
|
|
10
11
|
[](https://www.npmjs.com/package/cron-converter-u2q)
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
A powerful TypeScript library for working with cron expressions. Effortlessly convert between Unix and Quartz formats, generate human-readable descriptions, and validate cron expressions with ease.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
## ✨ Features
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
### 🔄 Two-way Conversion
|
|
18
|
+
- **Unix to Quartz**: Convert standard Unix cron expressions to Quartz format
|
|
19
|
+
- **Quartz to Unix**: Convert Quartz cron expressions to standard Unix format
|
|
20
|
+
- **Format Validation**: Built-in validation for both formats
|
|
21
|
+
- **Error Handling**: Clear error messages for invalid expressions
|
|
17
22
|
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
23
|
+
### 📝 Human-readable Descriptions
|
|
24
|
+
- **Natural Language**: Convert cron expressions to plain English
|
|
25
|
+
- **Multiple Languages**: Support for different language descriptions
|
|
26
|
+
- **Customizable**: Extend with your own description templates
|
|
27
|
+
- **Detailed**: Includes all schedule details (minutes, hours, days, etc.)
|
|
21
28
|
|
|
22
|
-
|
|
29
|
+
### 🛠️ Developer Friendly
|
|
30
|
+
- **TypeScript Support**: Full type definitions included
|
|
31
|
+
- **Zero Dependencies**: Lightweight and fast
|
|
32
|
+
- **Well Tested**: Comprehensive test coverage
|
|
33
|
+
- **ES6 Modules**: Support for both CommonJS and ES6 imports
|
|
23
34
|
|
|
24
|
-
|
|
25
|
-
-
|
|
35
|
+
### 🔍 Validation & Error Handling
|
|
36
|
+
- **Format Validation**: Ensures cron expressions are valid
|
|
37
|
+
- **Range Checking**: Validates field values within acceptable ranges
|
|
38
|
+
- **Clear Errors**: Descriptive error messages for debugging
|
|
39
|
+
- **Type Safety**: TypeScript types for better development experience
|
|
26
40
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
Using npm:
|
|
41
|
+
## 📦 Installation
|
|
30
42
|
|
|
31
43
|
```bash
|
|
44
|
+
# Using npm
|
|
32
45
|
npm install cron-converter-u2q
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Using yarn:
|
|
36
46
|
|
|
37
|
-
|
|
47
|
+
# Using yarn
|
|
38
48
|
yarn add cron-converter-u2q
|
|
49
|
+
|
|
50
|
+
# Using pnpm
|
|
51
|
+
pnpm add cron-converter-u2q
|
|
39
52
|
```
|
|
40
53
|
|
|
41
|
-
|
|
54
|
+
## 🚀 Quick Start
|
|
42
55
|
|
|
43
|
-
|
|
56
|
+
```typescript
|
|
57
|
+
import { CronConverterU2Q, CronDescriberU2Q } from 'cron-converter-u2q';
|
|
44
58
|
|
|
45
|
-
|
|
46
|
-
|
|
59
|
+
// Convert Unix to Quartz
|
|
60
|
+
const quartzExpression = CronConverterU2Q.unixToQuartz('5 * * * *');
|
|
61
|
+
console.log(quartzExpression); // "0 5 * * * ? *"
|
|
47
62
|
|
|
48
|
-
|
|
63
|
+
// Convert Quartz to Unix
|
|
64
|
+
const unixExpression = CronConverterU2Q.quartzToUnix('0 0 8 * * ?');
|
|
65
|
+
console.log(unixExpression); // "0 8 * * *"
|
|
66
|
+
// Get human-readable description
|
|
67
|
+
const description = CronDescriberU2Q.describeUnix('*/5 * * * *');
|
|
68
|
+
console.log(description); // "Every 5 minutes"
|
|
49
69
|
```
|
|
50
70
|
|
|
51
|
-
|
|
71
|
+
## 📚 Examples
|
|
52
72
|
|
|
53
|
-
|
|
54
|
-
|
|
73
|
+
### Basic Conversions
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// Unix to Quartz
|
|
77
|
+
CronConverterU2Q.unixToQuartz('0 12 * * *'); // "0 0 12 * * ? *"
|
|
78
|
+
CronConverterU2Q.unixToQuartz('*/15 * * * *'); // "0 */15 * * * ? *"
|
|
79
|
+
// Quartz to Unix
|
|
80
|
+
CronConverterU2Q.quartzToUnix('0 0 8 * * ?'); // "0 8 * * *"
|
|
81
|
+
CronConverterU2Q.quartzToUnix('0 */5 * * * ?'); // "*/5 * * * *"
|
|
55
82
|
```
|
|
56
83
|
|
|
57
|
-
###
|
|
84
|
+
### Human-readable Descriptions
|
|
58
85
|
|
|
59
|
-
|
|
86
|
+
```typescript
|
|
87
|
+
// Unix format descriptions
|
|
88
|
+
CronDescriberU2Q.describeUnix('0 12 * * *'); // "At 12 o'clock"
|
|
89
|
+
CronDescriberU2Q.describeUnix('*/15 * * * *'); // "Every 15 minutes"
|
|
60
90
|
|
|
61
|
-
|
|
62
|
-
|
|
91
|
+
// Quartz format descriptions
|
|
92
|
+
CronDescriberU2Q.describeQuartz('0 0 8 * * ?'); // "At 8 o'clock"
|
|
93
|
+
CronDescriberU2Q.describeQuartz('0 */5 * * * ?'); // "Every 5 minutes"
|
|
63
94
|
```
|
|
64
95
|
|
|
65
|
-
|
|
96
|
+
## 🤝 Contributing
|
|
66
97
|
|
|
67
|
-
|
|
68
|
-
const unixExpression = c2q.quartzToUnix("* */5 * ? * * *");
|
|
69
|
-
```
|
|
98
|
+
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
|
|
70
99
|
|
|
71
|
-
|
|
100
|
+
1. Fork the repository
|
|
101
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
102
|
+
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
103
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
104
|
+
5. Open a Pull Request
|
|
72
105
|
|
|
73
|
-
|
|
106
|
+
## 📄 License
|
|
74
107
|
|
|
75
|
-
|
|
108
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
76
109
|
|
|
77
|
-
|
|
78
|
-
const description = c2q.describeUnix("5 * * * *");
|
|
79
|
-
console.log(description); // Outputs: "Every 5 minutes"
|
|
80
|
-
```
|
|
110
|
+
## 💬 Support
|
|
81
111
|
|
|
82
|
-
|
|
112
|
+
- 📧 Email: rahu619@gmail.com
|
|
113
|
+
- 💻 GitHub Issues: [Create an issue](https://github.com/rahu619/cron-converter-u2q/issues)
|
|
114
|
+
- ⭐ Star the repository if you find it useful!
|
|
83
115
|
|
|
84
|
-
|
|
85
|
-
const description = c2q.describeQuartz("0 0 8 * * ?");
|
|
86
|
-
console.log(description); // Outputs: "At 8 o'clock"
|
|
87
|
-
```
|
|
116
|
+
## 🙏 Acknowledgments
|
|
88
117
|
|
|
89
|
-
|
|
90
|
-
|
|
118
|
+
- Thanks to all contributors who have helped shape this project
|
|
119
|
+
- Inspired by the need for a simple, reliable cron expression converter
|
|
120
|
+
- Built with TypeScript for better developer experience
|
|
91
121
|
|
|
122
|
+
## 📖 Specifications
|
|
92
123
|
|
|
93
|
-
|
|
94
|
-
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
|
|
124
|
+
This library's conversion logic is grounded in the following official specifications:
|
|
95
125
|
|
|
96
|
-
|
|
126
|
+
- **POSIX IEEE Std 1003.1** – Defines the standard Unix cron expression format (5 fields: minute, hour, day-of-month, month, day-of-week).
|
|
127
|
+
[https://pubs.opengroup.org/onlinepubs/9699919799/utilities/crontab.html](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/crontab.html)
|
|
97
128
|
|
|
98
|
-
|
|
99
|
-
|
|
129
|
+
- **Quartz Scheduler** – Defines the extended Quartz cron trigger format (6–7 fields: seconds, minute, hour, day-of-month, month, day-of-week, optional year). Notably, exactly one of `day-of-month` or `day-of-week` must be `?` to avoid scheduling conflicts.
|
|
130
|
+
[https://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html](https://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html)
|
|
100
131
|
|
package/lib/converter.d.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
export declare class CronConverterU2Q {
|
|
2
|
-
static readonly delimiter = " ";
|
|
3
|
-
static readonly unixExpressionLength = 5;
|
|
4
|
-
static readonly quartzExpressionLengths: number[];
|
|
5
2
|
/**
|
|
6
3
|
* Converts a unix cron expression to a quartz cron expression by adding '0' seconds
|
|
7
4
|
* @param unixExpression - the unix expression
|
|
@@ -14,5 +11,21 @@ export declare class CronConverterU2Q {
|
|
|
14
11
|
* @returns the corresponding unix expression
|
|
15
12
|
*/
|
|
16
13
|
static quartzToUnix(quartzExpression: string): string;
|
|
17
|
-
|
|
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
|
+
/**
|
|
20
|
+
* Converts Unix DOW to Quartz DOW, supporting lists, ranges, and special cases.
|
|
21
|
+
* Unix: 0=Sun, 1=Mon, ..., 6=Sat, 7=Sun(alias)
|
|
22
|
+
* Quartz: 1=Sun, 2=Mon, ..., 7=Sat
|
|
23
|
+
*/
|
|
24
|
+
private static unixDowToQuartz;
|
|
25
|
+
/**
|
|
26
|
+
* Converts Quartz DOW to Unix DOW, supporting lists, ranges, and special cases.
|
|
27
|
+
* Quartz: 1=Sun, 2=Mon, ..., 7=Sat
|
|
28
|
+
* Unix: 0=Sun, 1=Mon, ..., 6=Sat
|
|
29
|
+
*/
|
|
30
|
+
static quartzDowToUnix(dow: string): string;
|
|
18
31
|
}
|
package/lib/converter.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CronConverterU2Q = void 0;
|
|
4
|
+
const helper_1 = require("./helper");
|
|
5
|
+
const validator_1 = require("./validator");
|
|
4
6
|
class CronConverterU2Q {
|
|
5
7
|
/**
|
|
6
8
|
* Converts a unix cron expression to a quartz cron expression by adding '0' seconds
|
|
@@ -8,18 +10,21 @@ class CronConverterU2Q {
|
|
|
8
10
|
* @returns the corresponding quartz expression
|
|
9
11
|
*/
|
|
10
12
|
static unixToQuartz(unixExpression) {
|
|
11
|
-
|
|
12
|
-
const parts =
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
validator_1.CronValidatorU2Q.validateUnix(unixExpression);
|
|
14
|
+
const parts = helper_1.ExpressionHelper.GetExpressionParts(unixExpression);
|
|
15
|
+
const [min, hour, dom, month, dow] = parts.map(part => this.convertIntervalParts(part));
|
|
16
|
+
// Enhanced DOW conversion: handle lists, ranges, and special cases
|
|
17
|
+
let quartzDow = this.unixDowToQuartz(dow);
|
|
16
18
|
let quartzDom = dom;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
// Per Quartz spec, exactly one of DOM or DOW must be '?'
|
|
20
|
+
// When DOM is '*' and DOW is specific, DOM gets '?'; otherwise DOW gets '?'
|
|
21
|
+
if (dom === '*' && dow !== '*') {
|
|
19
22
|
quartzDom = '?';
|
|
20
|
-
|
|
23
|
+
}
|
|
24
|
+
else if (dom !== '*' && dow === '*') {
|
|
21
25
|
quartzDow = '?';
|
|
22
|
-
|
|
26
|
+
}
|
|
27
|
+
return `0 ${min} ${hour} ${quartzDom} ${month} ${quartzDow} *`;
|
|
23
28
|
}
|
|
24
29
|
/**
|
|
25
30
|
* Converts a quartz cron expression to a unix cron expression
|
|
@@ -27,27 +32,87 @@ class CronConverterU2Q {
|
|
|
27
32
|
* @returns the corresponding unix expression
|
|
28
33
|
*/
|
|
29
34
|
static quartzToUnix(quartzExpression) {
|
|
30
|
-
|
|
31
|
-
const parts =
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
unixDom = '*';
|
|
35
|
+
validator_1.CronValidatorU2Q.validateQuartz(quartzExpression);
|
|
36
|
+
const parts = helper_1.ExpressionHelper.GetExpressionParts(quartzExpression);
|
|
37
|
+
const [_, min, hour, dom, month, dow] = parts.map(part => this.convertIntervalParts(part, true));
|
|
38
|
+
if (dom.includes('L') || dom.includes('W')) {
|
|
39
|
+
throw new Error("Unix cron does not support 'L' or 'W' in Day of Month");
|
|
40
|
+
}
|
|
41
|
+
if (dow.includes('L') || dow.includes('#')) {
|
|
42
|
+
throw new Error("Unix cron does not support 'L' or '#' in Day of Week");
|
|
43
|
+
}
|
|
44
|
+
// Enhanced DOW conversion: handle lists, ranges, and special cases
|
|
45
|
+
let unixDow = this.quartzDowToUnix(dow);
|
|
46
|
+
let unixDom = dom === '?' ? '*' : dom;
|
|
43
47
|
return `${min} ${hour} ${unixDom} ${month} ${unixDow}`;
|
|
44
48
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
+
/**
|
|
60
|
+
* Converts Unix DOW to Quartz DOW, supporting lists, ranges, and special cases.
|
|
61
|
+
* Unix: 0=Sun, 1=Mon, ..., 6=Sat, 7=Sun(alias)
|
|
62
|
+
* Quartz: 1=Sun, 2=Mon, ..., 7=Sat
|
|
63
|
+
*/
|
|
64
|
+
static unixDowToQuartz(dow) {
|
|
65
|
+
if (dow === '*' || dow === '?')
|
|
66
|
+
return dow;
|
|
67
|
+
if (dow.includes(','))
|
|
68
|
+
return dow.split(',').map(d => this.unixDowToQuartz(d)).join(',');
|
|
69
|
+
if (dow.includes('-'))
|
|
70
|
+
return dow.split('-').map(d => this.unixDowToQuartz(d)).join('-');
|
|
71
|
+
if (dow.endsWith('L')) {
|
|
72
|
+
const day = dow.slice(0, -1);
|
|
73
|
+
return `${this.unixDowToQuartz(day)}L`;
|
|
74
|
+
}
|
|
75
|
+
if (dow.includes('#')) {
|
|
76
|
+
const [day, nth] = dow.split('#');
|
|
77
|
+
return `${this.unixDowToQuartz(day)}#${nth}`;
|
|
78
|
+
}
|
|
79
|
+
if (dow === '0' || dow === '7')
|
|
80
|
+
return '1'; // Sunday
|
|
81
|
+
const num = parseInt(dow, 10);
|
|
82
|
+
if (!isNaN(num) && num >= 1 && num <= 6)
|
|
83
|
+
return (num + 1).toString(); // Mon(1)→2 … Sat(6)→7
|
|
84
|
+
return dow;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Converts Quartz DOW to Unix DOW, supporting lists, ranges, and special cases.
|
|
88
|
+
* Quartz: 1=Sun, 2=Mon, ..., 7=Sat
|
|
89
|
+
* Unix: 0=Sun, 1=Mon, ..., 6=Sat
|
|
90
|
+
*/
|
|
91
|
+
static quartzDowToUnix(dow) {
|
|
92
|
+
if (dow === '*' || dow === '?')
|
|
93
|
+
return dow === '?' ? '*' : dow;
|
|
94
|
+
// Split compound expressions so each element is converted individually
|
|
95
|
+
if (dow.includes(','))
|
|
96
|
+
return dow.split(',').map(d => this.quartzDowToUnix(d)).join(',');
|
|
97
|
+
if (dow.includes('-'))
|
|
98
|
+
return dow.split('-').map(d => this.quartzDowToUnix(d)).join('-');
|
|
99
|
+
// Last (L) — convert the numeric day part, preserve L suffix
|
|
100
|
+
if (dow.endsWith('L')) {
|
|
101
|
+
const day = dow.slice(0, -1);
|
|
102
|
+
return `${this.quartzDowToUnix(day)}L`;
|
|
103
|
+
}
|
|
104
|
+
// Nth weekday (#) — convert the numeric day part, preserve #N
|
|
105
|
+
if (dow.includes('#')) {
|
|
106
|
+
const [day, nth] = dow.split('#');
|
|
107
|
+
return `${this.quartzDowToUnix(day)}#${nth}`;
|
|
108
|
+
}
|
|
109
|
+
// Numeric mapping
|
|
110
|
+
if (dow === '1')
|
|
111
|
+
return '0'; // Sunday
|
|
112
|
+
const num = parseInt(dow, 10);
|
|
113
|
+
if (!isNaN(num) && num >= 2 && num <= 7)
|
|
114
|
+
return (num - 1).toString(); // Mon(2)→1 … Sat(7)→6
|
|
115
|
+
return dow;
|
|
48
116
|
}
|
|
49
117
|
}
|
|
50
118
|
exports.CronConverterU2Q = CronConverterU2Q;
|
|
51
|
-
CronConverterU2Q.delimiter = ' ';
|
|
52
|
-
CronConverterU2Q.unixExpressionLength = 5;
|
|
53
|
-
CronConverterU2Q.quartzExpressionLengths = [6, 7];
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export declare class CronDescriberU2Q {
|
|
2
|
+
/**
|
|
3
|
+
* Generates a human-readable description for a Unix-style cron expression.
|
|
4
|
+
*
|
|
5
|
+
* Unix-style cron expressions consist of 5 parts:
|
|
6
|
+
* - Minute (0-59)
|
|
7
|
+
* - Hour (0-23)
|
|
8
|
+
* - Day of Month (1-31)
|
|
9
|
+
* - Month (1-12)
|
|
10
|
+
* - Day of Week (0-6, where 0 = Sunday)
|
|
11
|
+
* @param unixExpression - A string containing the Unix-style cron expression.
|
|
12
|
+
* @returns A human-readable description or an error message if invalid.
|
|
13
|
+
*/
|
|
14
|
+
static describeUnix(unixExpression: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Generates a human-readable description for a Quartz-style cron expression.
|
|
17
|
+
*
|
|
18
|
+
* Quartz-style cron expressions consist of 6 or 7 parts:
|
|
19
|
+
* - Second (0-59)
|
|
20
|
+
* - Minute (0-59)
|
|
21
|
+
* - Hour (0-23)
|
|
22
|
+
* - Day of Month (1-31)
|
|
23
|
+
* - Month (1-12)
|
|
24
|
+
* - Day of Week (1-7, where 1 = Sunday)
|
|
25
|
+
* - Year (optional)
|
|
26
|
+
* @param quartzExpression - A string containing the Quartz-style cron expression.
|
|
27
|
+
* @returns A human-readable description or an error message if invalid.
|
|
28
|
+
*/
|
|
29
|
+
static describeQuartz(quartzExpression: string): string;
|
|
30
|
+
private static describeSecond;
|
|
31
|
+
private static describeMinute;
|
|
32
|
+
private static describeHour;
|
|
33
|
+
private static describeDayOfMonth;
|
|
34
|
+
private static describeMonth;
|
|
35
|
+
private static describeDayOfWeek;
|
|
36
|
+
private static describeYear;
|
|
37
|
+
private static resolveValue;
|
|
38
|
+
private static describeField;
|
|
39
|
+
private static ordinalSuffix;
|
|
40
|
+
private static combineDescriptions;
|
|
41
|
+
}
|