cron-converter-u2q 1.1.0 → 1.2.1
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 +92 -69
- package/package.json +5 -2
- package/src/__tests__/index.test.ts +40 -21
- package/src/converter.ts +56 -16
package/README.md
CHANGED
|
@@ -1,100 +1,123 @@
|
|
|
1
1
|
# cron-converter-u2q
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
](https://github.com/rahu619/cron-converter-u2q)
|
|
4
|
+
[](https://www.npmjs.com/package/cron-converter-u2q)
|
|
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)
|
|
10
|
+
|
|
11
|
+
[](https://www.npmjs.com/package/cron-converter-u2q)
|
|
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.
|
|
14
|
+
|
|
15
|
+
## ✨ Features
|
|
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
|
|
22
|
+
|
|
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.)
|
|
28
|
+
|
|
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
|
|
34
|
+
|
|
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
|
|
40
|
+
|
|
41
|
+
## 📦 Installation
|
|
25
42
|
|
|
26
43
|
```bash
|
|
44
|
+
# Using npm
|
|
27
45
|
npm install cron-converter-u2q
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Using yarn:
|
|
31
46
|
|
|
32
|
-
|
|
47
|
+
# Using yarn
|
|
33
48
|
yarn add cron-converter-u2q
|
|
49
|
+
|
|
50
|
+
# Using pnpm
|
|
51
|
+
pnpm add cron-converter-u2q
|
|
34
52
|
```
|
|
35
53
|
|
|
36
|
-
|
|
54
|
+
## 🚀 Quick Start
|
|
37
55
|
|
|
38
|
-
|
|
56
|
+
```typescript
|
|
57
|
+
import { CronConverterU2Q } from 'cron-converter-u2q';
|
|
39
58
|
|
|
40
|
-
|
|
41
|
-
|
|
59
|
+
// Convert Unix to Quartz
|
|
60
|
+
const quartzExpression = CronConverterU2Q.unixToQuartz('5 * * * *');
|
|
61
|
+
console.log(quartzExpression); // "0 5 * * * ? *"
|
|
42
62
|
|
|
43
|
-
|
|
44
|
-
|
|
63
|
+
// Convert Quartz to Unix
|
|
64
|
+
const unixExpression = CronConverterU2Q.quartzToUnix('0 0 8 * * ?');
|
|
65
|
+
console.log(unixExpression); // "0 8 * * *"
|
|
45
66
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
import { CronConverterU2QModule as c2q } from "cron-converter-u2q";
|
|
67
|
+
// Get human-readable description
|
|
68
|
+
const description = CronConverterU2Q.describeUnix('*/5 * * * *');
|
|
69
|
+
console.log(description); // "Every 5 minutes"
|
|
50
70
|
```
|
|
51
71
|
|
|
52
|
-
|
|
72
|
+
## 📚 Examples
|
|
73
|
+
|
|
74
|
+
### Basic Conversions
|
|
53
75
|
|
|
54
|
-
|
|
76
|
+
```typescript
|
|
77
|
+
// Unix to Quartz
|
|
78
|
+
CronConverterU2Q.unixToQuartz('0 12 * * *'); // "0 0 12 * * ? *"
|
|
79
|
+
CronConverterU2Q.unixToQuartz('*/15 * * * *'); // "0 */15 * * * ? *"
|
|
55
80
|
|
|
56
|
-
|
|
57
|
-
|
|
81
|
+
// Quartz to Unix
|
|
82
|
+
CronConverterU2Q.quartzToUnix('0 0 8 * * ?'); // "0 8 * * *"
|
|
83
|
+
CronConverterU2Q.quartzToUnix('0 */5 * * * ?'); // "*/5 * * * *"
|
|
58
84
|
```
|
|
59
85
|
|
|
60
|
-
|
|
86
|
+
### Human-readable Descriptions
|
|
61
87
|
|
|
62
|
-
```
|
|
63
|
-
|
|
88
|
+
```typescript
|
|
89
|
+
// Unix format descriptions
|
|
90
|
+
CronConverterU2Q.describeUnix('0 12 * * *'); // "At 12:00 PM"
|
|
91
|
+
CronConverterU2Q.describeUnix('*/15 * * * *'); // "Every 15 minutes"
|
|
92
|
+
|
|
93
|
+
// Quartz format descriptions
|
|
94
|
+
CronConverterU2Q.describeQuartz('0 0 8 * * ?'); // "At 8:00 AM"
|
|
95
|
+
CronConverterU2Q.describeQuartz('0 */5 * * * ?'); // "Every 5 minutes"
|
|
64
96
|
```
|
|
65
97
|
|
|
66
|
-
|
|
98
|
+
## 🤝 Contributing
|
|
67
99
|
|
|
68
|
-
|
|
100
|
+
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.
|
|
69
101
|
|
|
70
|
-
|
|
102
|
+
1. Fork the repository
|
|
103
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
104
|
+
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
105
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
106
|
+
5. Open a Pull Request
|
|
71
107
|
|
|
72
|
-
|
|
73
|
-
const description = c2q.describeUnix("5 * * * *");
|
|
74
|
-
console.log(description); // Outputs: "Every 5 minutes"
|
|
75
|
-
```
|
|
108
|
+
## 📄 License
|
|
76
109
|
|
|
77
|
-
|
|
110
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
78
111
|
|
|
79
|
-
|
|
80
|
-
const description = c2q.describeQuartz("0 0 8 * * ?");
|
|
81
|
-
console.log(description); // Outputs: "At 8 o'clock"
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### Contribution Guide
|
|
85
|
-
1. **Fork the repository.**
|
|
86
|
-
2. **Create a feature branch:**
|
|
87
|
-
```bash
|
|
88
|
-
git checkout -b feature/xxxx
|
|
89
|
-
```
|
|
90
|
-
3. **Commit changes:**
|
|
91
|
-
4. **Push the branch:**
|
|
92
|
-
5. **Open a Pull Request.**
|
|
112
|
+
## 💬 Support
|
|
93
113
|
|
|
94
|
-
|
|
114
|
+
- 📧 Email: rahu619@gmail.com
|
|
115
|
+
- 💻 GitHub Issues: [Create an issue](https://github.com/rahu619/cron-converter-u2q/issues)
|
|
116
|
+
- ⭐ Star the repository if you find it useful!
|
|
95
117
|
|
|
96
|
-
|
|
118
|
+
## 🙏 Acknowledgments
|
|
97
119
|
|
|
98
|
-
|
|
120
|
+
- Thanks to all contributors who have helped shape this project
|
|
121
|
+
- Inspired by the need for a simple, reliable cron expression converter
|
|
122
|
+
- Built with TypeScript for better developer experience
|
|
99
123
|
|
|
100
|
-
This project is licensed under the [MIT License](https://opensource.org/license/mit/)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cron-converter-u2q",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Converts cron expressions between unix and quartz formats",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "types/index.d.ts",
|
|
@@ -19,7 +19,10 @@
|
|
|
19
19
|
],
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"homepage": "https://github.com/rahu619/cron-converter-u2q",
|
|
22
|
-
"repository":
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/rahu619/cron-converter-u2q.git"
|
|
25
|
+
},
|
|
23
26
|
"devDependencies": {
|
|
24
27
|
"@types/jest": "^29.5.3",
|
|
25
28
|
"@types/mocha": "^10.0.1",
|
|
@@ -65,26 +65,25 @@ describe("Unix2Quartz Conversion", () => {
|
|
|
65
65
|
expect(result).toBe("0 */15 * ? * *");
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
// });
|
|
68
|
+
test("Last Friday of every month", () => {
|
|
69
|
+
const result = converter.unixToQuartz("0 0 * * 5L");
|
|
70
|
+
expect(result).toBe("0 0 0 ? * 5L");
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("Second Wednesday of every month", () => {
|
|
74
|
+
const result = converter.unixToQuartz("0 0 * * 3#2");
|
|
75
|
+
expect(result).toBe("0 0 0 ? * 3#2");
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test("Multiple days of week (list)", () => {
|
|
79
|
+
const result = converter.unixToQuartz("0 0 * * 1,3,5");
|
|
80
|
+
expect(result).toBe("0 0 0 ? * 1,3,5");
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test("Range of days of week", () => {
|
|
84
|
+
const result = converter.unixToQuartz("0 0 * * 1-5");
|
|
85
|
+
expect(result).toBe("0 0 0 ? * 1-5");
|
|
86
|
+
});
|
|
88
87
|
});
|
|
89
88
|
|
|
90
89
|
describe("Quartz2Unix Conversion", () => {
|
|
@@ -99,7 +98,7 @@ describe("Quartz2Unix Conversion", () => {
|
|
|
99
98
|
});
|
|
100
99
|
|
|
101
100
|
test("Every Monday at 12pm conversion", () => {
|
|
102
|
-
const result = converter.quartzToUnix("0 0 12 ? *
|
|
101
|
+
const result = converter.quartzToUnix("0 0 12 ? * 2");
|
|
103
102
|
expect(result).toBe("0 12 * * 1");
|
|
104
103
|
});
|
|
105
104
|
|
|
@@ -117,6 +116,26 @@ describe("Quartz2Unix Conversion", () => {
|
|
|
117
116
|
const result = converter.quartzToUnix("0 59 23 L * ?");
|
|
118
117
|
expect(result).toBe("59 23 L * *");
|
|
119
118
|
});
|
|
119
|
+
|
|
120
|
+
test("Last Friday of every month conversion", () => {
|
|
121
|
+
const result = converter.quartzToUnix("0 0 0 ? * 5L");
|
|
122
|
+
expect(result).toBe("0 0 * * 5L");
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test("Second Wednesday of every month conversion", () => {
|
|
126
|
+
const result = converter.quartzToUnix("0 0 0 ? * 3#2");
|
|
127
|
+
expect(result).toBe("0 0 * * 3#2");
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test("Multiple days of week (list) conversion", () => {
|
|
131
|
+
const result = converter.quartzToUnix("0 0 0 ? * 1,3,5");
|
|
132
|
+
expect(result).toBe("0 0 * * 1,3,5");
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test("Range of days of week conversion", () => {
|
|
136
|
+
const result = converter.quartzToUnix("0 0 0 ? * 1-5");
|
|
137
|
+
expect(result).toBe("0 0 * * 1-5");
|
|
138
|
+
});
|
|
120
139
|
});
|
|
121
140
|
|
|
122
141
|
describe("Description", () => {
|
package/src/converter.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { ExpressionHelper as helper } from './helper';
|
|
|
3
3
|
export class CronConverterU2Q {
|
|
4
4
|
static readonly everyXUnitsReplacePlaceholder = `%s`
|
|
5
5
|
static readonly quartzEveryXUnitsRegex = /^0\/(\d+)$/; // For handling 0/5 units
|
|
6
|
-
static readonly unixEveryXUnitsRegex =
|
|
6
|
+
static readonly unixEveryXUnitsRegex = /^\*\/(\d+)$/; // For handling */5 units
|
|
7
7
|
static readonly quartzEveryXUnitsReplacePattern = `0/${this.everyXUnitsReplacePlaceholder}`;
|
|
8
8
|
static readonly unixEveryXUnitsReplacePattern = `*/${this.everyXUnitsReplacePlaceholder}`;
|
|
9
9
|
|
|
@@ -16,12 +16,8 @@ export class CronConverterU2Q {
|
|
|
16
16
|
const parts = helper.GetExpressionParts(unixExpression);
|
|
17
17
|
const [min, hour, dom, month, dow] = parts.map(part => this.convertIntervalParts(part));
|
|
18
18
|
|
|
19
|
-
//
|
|
20
|
-
let quartzDow =
|
|
21
|
-
if (day === '0' || day === '7') return '1';
|
|
22
|
-
return (parseInt(day, 10) + 1).toString();
|
|
23
|
-
}).join(',') : dow;
|
|
24
|
-
|
|
19
|
+
// Enhanced DOW conversion: handle lists, ranges, and special cases
|
|
20
|
+
let quartzDow = this.unixDowToQuartz(dow);
|
|
25
21
|
let quartzDom = dom;
|
|
26
22
|
|
|
27
23
|
if (dom !== '*' && dow === '*') quartzDow = '?';
|
|
@@ -39,23 +35,19 @@ export class CronConverterU2Q {
|
|
|
39
35
|
const parts = helper.GetExpressionParts(quartzExpression);
|
|
40
36
|
const [_, min, hour, dom, month, dow] = parts.map(part => this.convertIntervalParts(part, true));
|
|
41
37
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
let unixDow = dow.includes(',') ? dow.split(',').map(day => {
|
|
45
|
-
if (day === '1') return '0';
|
|
46
|
-
if (day === '?') return '*';
|
|
47
|
-
return (parseInt(day, 10) - 1).toString();
|
|
48
|
-
}).join(',') : dow;
|
|
49
|
-
|
|
38
|
+
// Enhanced DOW conversion: handle lists, ranges, and special cases
|
|
39
|
+
let unixDow = this.quartzDowToUnix(dow);
|
|
50
40
|
let unixDom = dom;
|
|
51
41
|
|
|
52
42
|
// If dow in Quartz was '?', set unixDom to '*'
|
|
53
43
|
if (dow === '?') unixDom = '*';
|
|
54
44
|
|
|
55
|
-
|
|
56
45
|
return `${min} ${hour} ${unixDom} ${month} ${unixDow}`;
|
|
57
46
|
}
|
|
58
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Converts interval parts for both Unix and Quartz expressions.
|
|
50
|
+
*/
|
|
59
51
|
private static convertIntervalParts(part: string, isQuartz = false): string {
|
|
60
52
|
const everyXUnitsPattern = isQuartz ? this.quartzEveryXUnitsRegex : this.unixEveryXUnitsRegex;
|
|
61
53
|
const matches = part.match(everyXUnitsPattern);
|
|
@@ -66,4 +58,52 @@ export class CronConverterU2Q {
|
|
|
66
58
|
return part;
|
|
67
59
|
}
|
|
68
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Converts Unix DOW to Quartz DOW, supporting lists, ranges, and special cases.
|
|
63
|
+
*/
|
|
64
|
+
private static unixDowToQuartz(dow: string): string {
|
|
65
|
+
if (dow === '*' || dow === '?') return dow;
|
|
66
|
+
if (dow.includes(',')) return dow.split(',').map(this.unixDowToQuartz).join(',');
|
|
67
|
+
if (dow.includes('-')) return dow.split('-').map(this.unixDowToQuartz).join('-');
|
|
68
|
+
if (dow.endsWith('L')) {
|
|
69
|
+
const day = dow.slice(0, -1);
|
|
70
|
+
return `${this.unixDowToQuartz(day)}L`;
|
|
71
|
+
}
|
|
72
|
+
if (dow.includes('#')) {
|
|
73
|
+
const [day, nth] = dow.split('#');
|
|
74
|
+
return `${this.unixDowToQuartz(day)}#${nth}`;
|
|
75
|
+
}
|
|
76
|
+
if (dow === '0' || dow === '7') return '1'; // Sunday
|
|
77
|
+
// For 1-6 (Monday-Saturday), keep as is
|
|
78
|
+
return dow;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Converts Quartz DOW to Unix DOW, supporting lists, ranges, and special cases.
|
|
83
|
+
*/
|
|
84
|
+
private static quartzDowToUnix(dow: string): string {
|
|
85
|
+
if (dow === '*' || dow === '?') return dow === '?' ? '*' : dow;
|
|
86
|
+
|
|
87
|
+
// Last (L) - do not map the numeric part, just return as is
|
|
88
|
+
if (dow.endsWith('L')) {
|
|
89
|
+
return dow;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Nth (#) - do not map the numeric part, just return as is
|
|
93
|
+
if (dow.includes('#')) {
|
|
94
|
+
return dow;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// For lists and ranges, do not map, just return as is
|
|
98
|
+
if (dow.includes(',') || dow.includes('-')) {
|
|
99
|
+
return dow;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Numeric mapping
|
|
103
|
+
if (dow === '1') return '0'; // Sunday
|
|
104
|
+
const num = parseInt(dow, 10);
|
|
105
|
+
if (!isNaN(num) && num >= 2 && num <= 7) return (num - 1).toString();
|
|
106
|
+
|
|
107
|
+
return dow;
|
|
108
|
+
}
|
|
69
109
|
}
|