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 CHANGED
@@ -1,100 +1,123 @@
1
1
  # cron-converter-u2q
2
2
 
3
- Easily work with cron expressions using the `cron-converter-u2q` package. Effortlessly convert between Unix and Quartz formats and describe cron schedules in plain language for better understanding and usability.
4
-
5
- ![example event parameter](https://github.com/rahu619/cron-converter-u2q/actions/workflows/integration.yml/badge.svg?branch=main)
6
- ![example event parameter](https://github.com/rahu619/cron-converter-u2q/actions/workflows/release.yml/badge.svg?event=workflow_dispatch)
7
- [![NPM version](https://badge.fury.io/js/cron-converter-u2q.svg)](https://www.npmjs.com/package/cron-converter-u2q)
8
-
9
- ### Features
10
-
11
- :arrows_counterclockwise: **Two-way conversion**
12
-
13
- Effortlessly convert cron expressions:
14
- - From Unix to Quartz
15
- - From Quartz to Unix
16
-
17
- :memo: **Human-readable Descriptions**
18
-
19
- Translate cron schedules into plain, understandable text:
20
- - Example: `*/5 * * * *` -> "Every 5 minutes"
21
-
22
- ### Installation
23
-
24
- Using npm:
3
+ [![Github Repo Stars](https://img.shields.io/github/stars/rahu619/cron-converter-u2q?style=social)](https://github.com/rahu619/cron-converter-u2q)
4
+ [![NPM version](https://img.shields.io/npm/v/cron-converter-u2q)](https://www.npmjs.com/package/cron-converter-u2q)
5
+ [![GitHub License](https://img.shields.io/github/license/rahu619/cron-converter-u2q?style=plastic)](LICENSE)
6
+ [![GitHub Build](https://github.com/rahu619/cron-converter-u2q/actions/workflows/integration.yml/badge.svg?branch=main)](https://github.com/rahu619/cron-converter-u2q/actions)
7
+ [![Github Release](https://github.com/rahu619/cron-converter-u2q/actions/workflows/release.yml/badge.svg?event=workflow_dispatch)](https://github.com/rahu619/cron-converter-u2q/actions)
8
+ [![Github Top Language](https://img.shields.io/github/languages/top/rahu619/cron-converter-u2q?style=plastic)](https://www.typescriptlang.org/)
9
+ [![npm downloads](https://img.shields.io/npm/dm/cron-converter-u2q)](https://www.npmjs.com/package/cron-converter-u2q)
10
+
11
+ [![https://nodei.co/npm/cron-converter-u2q.png?downloads=true&downloadRank=true&stars=true](https://nodei.co/npm/cron-converter-u2q.png?downloads=true&downloadRank=true&stars=true)](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
- ```bash
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
- ### Usage
54
+ ## 🚀 Quick Start
37
55
 
38
- Firstly, import the CronConverterU2Q module:
56
+ ```typescript
57
+ import { CronConverterU2Q } from 'cron-converter-u2q';
39
58
 
40
- ```javascript
41
- var cron_converter_u2q = require("cron-converter-u2q");
59
+ // Convert Unix to Quartz
60
+ const quartzExpression = CronConverterU2Q.unixToQuartz('5 * * * *');
61
+ console.log(quartzExpression); // "0 5 * * * ? *"
42
62
 
43
- var c2q = cron_converter_u2q.CronConverterU2Q;
44
- ```
63
+ // Convert Quartz to Unix
64
+ const unixExpression = CronConverterU2Q.quartzToUnix('0 0 8 * * ?');
65
+ console.log(unixExpression); // "0 8 * * *"
45
66
 
46
- If you're using ES6 Modules
47
-
48
- ```javascript
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
- ### Conversion Methods
72
+ ## 📚 Examples
73
+
74
+ ### Basic Conversions
53
75
 
54
- #### Convert from Unix to Quartz:
76
+ ```typescript
77
+ // Unix to Quartz
78
+ CronConverterU2Q.unixToQuartz('0 12 * * *'); // "0 0 12 * * ? *"
79
+ CronConverterU2Q.unixToQuartz('*/15 * * * *'); // "0 */15 * * * ? *"
55
80
 
56
- ```javascript
57
- const quartzExpression = c2q.unixToQuartz("5 * * * *");
81
+ // Quartz to Unix
82
+ CronConverterU2Q.quartzToUnix('0 0 8 * * ?'); // "0 8 * * *"
83
+ CronConverterU2Q.quartzToUnix('0 */5 * * * ?'); // "*/5 * * * *"
58
84
  ```
59
85
 
60
- #### Convert from Quartz to Unix:
86
+ ### Human-readable Descriptions
61
87
 
62
- ```javascript
63
- const unixExpression = c2q.quartzToUnix("* */5 * ? * * *");
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
- ### Description Methods
98
+ ## 🤝 Contributing
67
99
 
68
- You can now generate human-readable descriptions for Unix and Quartz cron expressions.
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
- #### Describe Unix Cron Expressions:
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
- ```javascript
73
- const description = c2q.describeUnix("5 * * * *");
74
- console.log(description); // Outputs: "Every 5 minutes"
75
- ```
108
+ ## 📄 License
76
109
 
77
- #### Describe Quartz Cron Expressions:
110
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
78
111
 
79
- ```javascript
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
- ### Development Notice
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
- Any feedback, suggestions, or contributions are highly appreciated!
118
+ ## 🙏 Acknowledgments
97
119
 
98
- ## License
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.0",
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": "https://github.com/rahu619/cron-converter-u2q",
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
- //Include
69
- // test('Last day of every month at 4:45 PM conversion', () => {
70
- // const result = converter.unixToQuartz('45 16 28-31 * *');
71
- // expect(result).toBe('45 16 L * ?');
72
- // });
73
-
74
- // test('Last Sunday of every month at 4:45 PM conversion', () => {
75
- // const result = converter.unixToQuartz('45 16 22-31 * 0');
76
- // expect(result).toBe('45 16 ? * 7L');
77
- // });
78
-
79
- // test('Second Wednesday of every month at 1:00 AM conversion', () => {
80
- // const result = converter.quartzToUnix('0 1 ? * 3#2');
81
- // expect(result).toBe('Not directly possible without additional logic');
82
- // });
83
-
84
- // test('Every last Friday of the month conversion', () => {
85
- // const result = converter.unixToQuartz('0 0 * * 5'); //Find equivalent unix expression
86
- // expect(result).toBe("0 0 0 ? * 5L");
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 ? * 1");
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 = /^\/(\d+)$/; // For handling */5 units
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
- // Converting Unix DOW to Quartz DOW
20
- let quartzDow = dow.includes(',') ? dow.split(',').map(day => {
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
- // Converting Quartz DOW to Unix DOW
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
  }